summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2021-06-19 12:01:15 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2021-06-19 12:01:15 +0000
commit42313980c6dd3d1903172f72e3d01852ceff4922 (patch)
treedaf45d522673930ba2a90970d64295962b9ce13e
parent83b9892b84200128c2347ee35283a8c970085b75 (diff)
parent8687a85bc0e6ef46bac3bce290cca2cddc7d6720 (diff)
downloadbouncycastle-android12-mainline-media-swcodec-release.tar.gz
Change-Id: Ib3a8f3f2512b55882cc72ba19833aad06fc14250
-rw-r--r--Android.bp79
-rw-r--r--METADATA3
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java5
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateIssuer.java2
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/CertUtils.java108
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java9
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java27
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java7
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java219
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPResp.java3
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReq.java12
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPResp.java2
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/ocsp/RespData.java13
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java7
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/package.html2
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java2
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java16
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java2
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java37
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java25
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/RecipientOperator.java20
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java15
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java19
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java21
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java44
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java2
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java128
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java207
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java30
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/pkcs/bc/package.html2
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCRLUtil.java56
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RFC3280CertPathUtilities.java65
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RevocationUtilities.java733
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitString.java102
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Boolean.java104
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java142
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java73
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1External.java14
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java182
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Generator.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java126
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java176
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Null.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Object.java49
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java41
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java73
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1OutputStream.java263
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java24
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java246
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java452
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java31
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java107
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1UTCTime.java30
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERFactory.java14
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERGenerator.java36
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BEROctetString.java110
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java23
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BEROutputStream.java43
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERSequence.java46
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERSet.java57
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java123
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ConstructedOctetStream.java46
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java71
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java46
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERBoolean.java22
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERExternal.java16
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERFactory.java14
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralizedTime.java16
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERGraphicString.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERNull.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DEROctetString.java23
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DEROutputStream.java20
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERSequence.java104
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERSequenceParser.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java116
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERSetParser.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERTaggedObject.java98
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java24
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERVideotexString.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DLApplicationSpecific.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java32
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DLExternal.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DLFactory.java27
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DLOutputStream.java23
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DLSequence.java93
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DLSequenceParser.java60
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DLSet.java91
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DLSetParser.java60
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DLTaggedObject.java91
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java40
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/LazyConstructionEnumeration.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/LazyEncodedSequence.java115
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/LimitedInputStream.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/StreamUtil.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java24
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/Attribute.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/Attributes.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAttributes.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/GCMParameters.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/SignedData.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/SignerIdentifier.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/SignerInfo.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/Time.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/BasicOCSPResponse.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CertID.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CrlID.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPObjectIdentifiers.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPRequest.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPResponse.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPResponseStatus.java24
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/Request.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponseBytes.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponseData.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/RevokedInfo.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/Signature.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/SingleResponse.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/TBSRequest.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/Attribute.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequest.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/DHParameter.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/MacData.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBEParameter.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Parameters.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java75
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java19
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPublicKey.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SignedData.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java391
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x500/RDN.java27
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x500/X500Name.java107
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java20
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java186
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/Attribute.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificate.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java21
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLDistPoint.java20
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLReason.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/CertificateList.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/DSAParameter.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/DigestInfo.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java41
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/Extensions.java24
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtensionsGenerator.java88
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralName.java29
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralNames.java20
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralSubtree.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/Holder.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyUsage.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraints.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/OtherName.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java289
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyConstraints.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyInformation.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java78
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificateStructure.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/V2Form.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Name.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/X509NameEntryConverter.java34
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java29
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/DHDomainParameters.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/DomainParameters.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java16
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java563
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X9Curve.java18
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParameters.java32
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECPoint.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X9FieldID.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesRegistrar.java49
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/KeyGenerationParameters.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/StagedAgreement.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java26
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/XofUtils.java48
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java278
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java1
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java27
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java149
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java149
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/BlowfishEngine.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java28
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/AEADBlockCipher.java137
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/AEADCipher.java138
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java14
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/OFBBlockCipher.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java86
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/DESParameters.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/DHParameters.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/DHPublicKeyParameters.java104
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java71
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/ECKeyParameters.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/ECPublicKeyParameters.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/ParametersWithRandom.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java24
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java26
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/tls/CertificateType.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsCloseable.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java69
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java140
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/util/SSHNamedCurves.java130
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/AesCcmCiphertext.java59
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/BitmapSspRange.java72
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/CertificateBase.java66
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/CertificateType.java50
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/CircularRegion.java41
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/Duration.java28
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/EncryptedData.java33
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/EndEntityType.java54
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/EtsiTs103097Module.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/ExplicitCertificate.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/GeographicRegion.java26
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/GroupLinkageValue.java67
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/HashAlgorithm.java50
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/HashedData.java46
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/HeaderInfo.java52
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/IValue.java52
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/Ieee1609Dot2Content.java46
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/Ieee1609Dot2Data.java57
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/ImplicitCertificate.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/IssuerIdentifier.java26
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/Latitude.java24
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/LinkageData.java58
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/LinkageValue.java42
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/Longitude.java24
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/PKRecipientInfo.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/PolygonalRegion.java18
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/PsidGroupPermissions.java59
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/PsidSspRange.java89
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/RecipientInfo.java16
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/RectangularRegion.java41
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfCertificate.java22
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfOctetString.java68
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfPsidGroupPermissions.java22
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfRecipientInfo.java22
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfRectangularRegion.java32
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/ServiceSpecificPermissions.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/Signature.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/SignedData.java27
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/SignedDataPayload.java26
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/SignerIdentifier.java29
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/SspRange.java140
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/SubjectPermissions.java39
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/SymmAlgorithm.java53
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/SymmRecipientInfo.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/ToBeSignedCertificate.java54
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/ToBeSignedData.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/TwoDLocation.java21
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/Utils.java36
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/ValidityPeriod.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/its/asn1/VerificationKeyIndicator.java24
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java103
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java103
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertRevocationChecker.java15
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertRevocationCheckerParameters.java56
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStoreSelector.java15
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedParameters.java55
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/interfaces/BCX509Certificate.java31
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java35
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java29
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/X509.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java36
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java24
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java24
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java52
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java26
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java62
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java56
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java27
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java56
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java36
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java146
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java42
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java124
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureCreator.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java27
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java736
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java29
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java650
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java940
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java29
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java781
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java135
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java23
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/MD5.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA1.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA224.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA384.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA512.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java22
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java257
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java22
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/ARC4.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java31
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java33
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC2.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java94
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java428
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java17
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java21
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java18
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java132
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java14
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/SpecUtil.java36
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java65
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/spec/DHExtendedPrivateKeySpec.java37
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/spec/DHExtendedPublicKeySpec.java37
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/spec/OpenSSHPrivateKeySpec.java58
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/spec/OpenSSHPublicKeySpec.java77
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/AnnotatedPrivateKey.java116
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java45
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/ECKeyUtil.java106
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java27
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java45
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/PrivateKeyAnnotator.java31
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java45
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java1
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java84
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/CertBlocklist.java (renamed from bcprov/src/main/java/org/bouncycastle/jce/provider/CertBlacklist.java)61
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java550
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java37
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java54
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java37
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java75
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java1872
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java14
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/PrincipalUtils.java128
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/ProvCrlRevocationChecker.java67
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java378
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/RecoverableCertPathValidatorException.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/WrappedRevocationChecker.java36
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java27
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/AbstractECLookupTable.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java167
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java242
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java99
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/ECLookupTable.java1
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java253
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/GLVMultiplier.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/ScaleXNegateYPointMap.java16
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/ScaleYNegateXPointMap.java16
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/WNafL2RMultiplier.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/WNafPreCompInfo.java51
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/WNafUtil.java224
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java57
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java47
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java52
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java62
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java47
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java51
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java60
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java47
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java52
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java62
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java50
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java51
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java53
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java49
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java52
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java62
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java49
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java51
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java62
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java51
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java51
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java62
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java44
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java51
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/endo/EndoPreCompInfo.java31
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/endo/EndoUtil.java73
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeAEndomorphism.java40
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeAParameters.java31
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java32
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java80
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/endo/ScalarSplitParameters.java68
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/field/FiniteFields.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/raw/Bits.java26
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/raw/Interleave.java133
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/raw/Mod.java578
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/raw/Nat.java308
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/raw/Nat192.java28
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/raw/Nat224.java21
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java28
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Arrays.java880
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/BigIntegers.java149
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Doubles.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Integers.java20
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Longs.java29
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Objects.java14
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Pack.java99
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Properties.java128
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java145
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/encoders/Hex.java60
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java142
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/io/TeeInputStream.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/io/pem/PemReader.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateHolder.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateIssuer.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/x509/CertPathReviewerMessages.properties8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/x509/X509Util.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/x509/X509V2AttributeCertificate.java2
-rw-r--r--bouncycastle.version2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ApplicationSpecific.java10
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BitString.java104
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Boolean.java104
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Encodable.java1
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1EncodableVector.java145
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Enumerated.java73
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1External.java14
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GeneralizedTime.java182
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Generator.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1InputStream.java132
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Integer.java178
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Null.java5
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Object.java53
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ObjectIdentifier.java45
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OctetString.java76
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OutputStream.java263
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Primitive.java27
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Sequence.java250
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Set.java452
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1StreamParser.java31
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1TaggedObject.java110
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UTCTime.java30
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERApplicationSpecific.java12
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERFactory.java14
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERGenerator.java36
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetString.java110
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetStringGenerator.java23
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROutputStream.java44
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSequence.java46
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSet.java57
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTaggedObject.java123
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ConstructedOctetStream.java46
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERApplicationSpecific.java8
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBMPString.java71
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBitString.java48
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBoolean.java24
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEREncodableVector.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERExternal.java16
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERFactory.java14
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralString.java9
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralizedTime.java16
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGraphicString.java8
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERIA5String.java12
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERInteger.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNull.java14
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNumericString.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERObjectIdentifier.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROctetString.java27
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROutputStream.java22
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERPrintableString.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequence.java107
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequenceParser.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSet.java118
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSetParser.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERT61String.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERTaggedObject.java100
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUTF8String.java8
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUniversalString.java24
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVideotexString.java8
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVisibleString.java8
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLApplicationSpecific.java8
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLBitString.java32
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLExternal.java13
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLFactory.java28
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLOutputStream.java24
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequence.java93
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequenceParser.java62
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSet.java91
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSetParser.java62
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLTaggedObject.java91
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DefiniteLengthInputStream.java40
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyConstructionEnumeration.java13
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyEncodedSequence.java115
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LimitedInputStream.java5
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/StreamUtil.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java24
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Attribute.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Attributes.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/CMSAttributes.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/ContentInfo.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/GCMParameters.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignedData.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignerIdentifier.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignerInfo.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Time.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java13
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java8
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/Attribute.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java11
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CRLBag.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertBag.java7
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequest.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/ContentInfo.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/DHParameter.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedData.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/MacData.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBEParameter.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBES2Parameters.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBKDF2Params.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java78
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/Pfx.java8
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java23
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java9
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java9
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPublicKey.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/SafeBag.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/SignedData.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKey.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/SECNamedCurves.java391
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/util/ASN1Dump.java11
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/RDN.java27
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/X500Name.java107
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java3
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/BCStyle.java28
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/IETFUtils.java186
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Attribute.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificate.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java21
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/BasicConstraints.java11
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLDistPoint.java20
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLReason.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Certificate.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CertificateList.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DSAParameter.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DigestInfo.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DistributionPoint.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java10
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extension.java41
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extensions.java22
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ExtensionsGenerator.java88
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralName.java36
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralNames.java20
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralSubtree.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Holder.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuerSerial.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyPurposeId.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyUsage.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/NameConstraints.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ObjectDigestInfo.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/OtherName.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java289
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyConstraints.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyInformation.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertList.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificate.java79
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificateStructure.java7
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Time.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java13
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V2Form.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java23
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Extensions.java13
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Name.java26
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509NameEntryConverter.java34
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java29
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DHDomainParameters.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DHValidationParms.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DomainParameters.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ECNamedCurveTable.java16
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ValidationParams.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962NamedCurves.java563
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962Parameters.java8
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9Curve.java18
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECParameters.java32
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECPoint.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9FieldID.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CipherParameters.java1
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesRegistrar.java49
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/KeyGenerationParameters.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/PBEParametersGenerator.java3
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/StagedAgreement.java13
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/GeneralDigest.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/MD4Digest.java3
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA1Digest.java3
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA256Digest.java26
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/XofUtils.java52
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/ec/CustomNamedCurves.java278
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/OAEPEncoding.java1
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/PKCS1Encoding.java27
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESEngine.java149
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESFastEngine.java149
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESWrapEngine.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/BlowfishEngine.java3
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESedeWrapEngine.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RSABlindedEngine.java28
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DSAParametersGenerator.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java8
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/AEADBlockCipher.java137
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/AEADCipher.java140
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CCMBlockCipher.java14
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CFBBlockCipher.java5
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/OFBBlockCipher.java11
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/GCMUtil.java86
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java9
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DESParameters.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DHParameters.java3
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DHPublicKeyParameters.java104
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECDomainParameters.java71
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECKeyParameters.java13
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECNamedDomainParameters.java7
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java9
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECPublicKeyParameters.java12
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/KeyParameter.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ParametersWithRandom.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/RSAKeyParameters.java24
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/DSASigner.java8
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/ECDSASigner.java7
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/RSADigestSigner.java26
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/tls/CertificateType.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/tls/TlsCloseable.java13
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PrivateKeyFactory.java69
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PublicKeyFactory.java140
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/SSHNamedCurves.java134
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/AesCcmCiphertext.java61
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/BitmapSspRange.java74
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/CertificateBase.java68
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/CertificateType.java52
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/CircularRegion.java43
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Duration.java30
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EncryptedData.java35
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EndEntityType.java56
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EtsiTs103097Module.java10
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ExplicitCertificate.java16
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/GeographicRegion.java28
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/GroupLinkageValue.java69
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/HashAlgorithm.java52
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/HashedData.java48
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/HeaderInfo.java54
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/IValue.java54
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Ieee1609Dot2Content.java48
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Ieee1609Dot2Data.java59
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ImplicitCertificate.java16
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/IssuerIdentifier.java28
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Latitude.java26
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/LinkageData.java60
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/LinkageValue.java44
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Longitude.java26
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PKRecipientInfo.java27
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PolygonalRegion.java20
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PsidGroupPermissions.java61
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PsidSspRange.java91
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/RecipientInfo.java18
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/RectangularRegion.java43
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfCertificate.java24
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfOctetString.java70
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfPsidGroupPermissions.java24
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfRecipientInfo.java24
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfRectangularRegion.java34
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ServiceSpecificPermissions.java10
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Signature.java27
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SignedData.java29
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SignedDataPayload.java28
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SignerIdentifier.java31
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SspRange.java142
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SubjectPermissions.java41
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SymmAlgorithm.java57
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SymmRecipientInfo.java27
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ToBeSignedCertificate.java56
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ToBeSignedData.java27
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/TwoDLocation.java23
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Utils.java37
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ValidityPeriod.java27
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/VerificationKeyIndicator.java26
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePrivateKey.java105
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePublicKey.java105
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXCertRevocationChecker.java19
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXCertRevocationCheckerParameters.java60
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXCertStoreSelector.java15
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXExtendedParameters.java55
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/interfaces/BCX509Certificate.java33
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/EC.java35
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/RSA.java29
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/X509.java10
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java9
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java10
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java36
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java24
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java9
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java10
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java24
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java3
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java52
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java26
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java62
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java56
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java27
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java56
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java39
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java11
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java146
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java42
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java7
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java124
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureCreator.java12
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java27
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java737
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java30
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java650
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java941
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java30
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java781
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java135
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java23
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/MD5.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA1.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA224.java7
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA256.java12
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA384.java7
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA512.java12
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java22
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java257
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/AES.java22
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/ARC4.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/DESede.java31
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java33
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/RC2.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java94
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java411
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java17
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java21
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java18
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java136
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java14
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/SpecUtil.java37
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java72
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/DHExtendedPrivateKeySpec.java39
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/DHExtendedPublicKeySpec.java39
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/OpenSSHPrivateKeySpec.java60
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/OpenSSHPublicKeySpec.java79
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/AnnotatedPrivateKey.java118
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/BCJcaJceHelper.java7
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java47
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/ECKeyUtil.java108
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/JcaJceHelper.java27
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java45
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/PrivateKeyAnnotator.java33
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java45
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/PKCS10CertificationRequest.java1
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/X509Principal.java3
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java5
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/netscape/NetscapeCertRequest.java8
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProvider.java86
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertBlocklist.java (renamed from repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertBlacklist.java)61
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java550
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPrivateKey.java9
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPublicKey.java37
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCRLUtil.java54
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java37
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java75
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java1872
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java14
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PrincipalUtils.java128
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/ProvCrlRevocationChecker.java68
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java378
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/RecoverableCertPathValidatorException.java14
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/WrappedRevocationChecker.java37
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CRLObject.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CertificateObject.java29
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/AbstractECLookupTable.java14
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECAlgorithms.java167
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECCurve.java242
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECFieldElement.java99
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECLookupTable.java1
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECPoint.java253
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/GLVMultiplier.java8
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ScaleXNegateYPointMap.java20
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ScaleYNegateXPointMap.java20
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafL2RMultiplier.java25
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafPreCompInfo.java51
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafUtil.java224
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java57
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java47
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java11
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java52
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java62
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java47
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java9
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java51
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java60
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java47
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java11
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java52
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java62
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java50
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java10
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java51
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java53
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java49
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java11
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java52
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java62
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java49
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java9
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java51
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java62
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java51
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java9
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java51
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java62
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java44
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java9
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java51
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/EndoPreCompInfo.java35
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/EndoUtil.java77
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeAEndomorphism.java44
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeAParameters.java35
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java32
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java80
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/ScalarSplitParameters.java72
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/field/FiniteFields.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Bits.java30
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Interleave.java133
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Mod.java578
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat.java308
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat192.java28
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat224.java21
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat256.java28
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Arrays.java880
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/BigIntegers.java149
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Doubles.java13
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Integers.java20
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Iterable.java1
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Longs.java33
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Objects.java18
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Pack.java99
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Properties.java128
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base64Encoder.java145
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Hex.java60
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/HexEncoder.java142
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/TeeInputStream.java5
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemHeader.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemObject.java5
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemObjectGenerator.java1
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemReader.java8
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemWriter.java3
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/AttributeCertificateHolder.java5
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/AttributeCertificateIssuer.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509Util.java4
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V1CertificateGenerator.java10
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V2AttributeCertificate.java2
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V3CertificateGenerator.java10
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecific.java248
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java21
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitString.java328
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Boolean.java182
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Choice.java29
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Encodable.java15
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1EncodableVector.java161
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Encoding.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Enumerated.java213
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Exception.java46
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1External.java294
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralizedTime.java510
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Generator.java32
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1InputStream.java508
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Integer.java290
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Null.java84
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Object.java106
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectIdentifier.java485
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetString.java303
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetStringParser.java19
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OutputStream.java323
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ParsingException.java44
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Primitive.java123
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Sequence.java418
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1SequenceParser.java21
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Set.java609
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1SetParser.java21
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1StreamParser.java256
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1String.java15
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObject.java189
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObjectParser.java29
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTCTime.java330
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecific.java112
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecificParser.java61
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERConstructedOctetString.java146
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERFactory.java28
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERGenerator.java84
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetString.java195
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringGenerator.java133
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringParser.java62
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROutputStream.java23
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequence.java67
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequenceParser.java60
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSet.java82
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSetParser.java60
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObject.java140
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObjectParser.java100
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTags.java40
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ConstructedOctetStream.java124
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERApplicationSpecific.java126
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBMPString.java217
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBitString.java160
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEREncodableVector.java20
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEREnumerated.java39
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternal.java97
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternalParser.java70
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERFactory.java28
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralString.java150
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralizedTime.java126
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGraphicString.java126
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERIA5String.java192
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERInteger.java32
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNull.java37
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNumericString.java196
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERObjectIdentifier.java26
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetString.java65
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetStringParser.java60
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROutputStream.java35
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERPrintableString.java239
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequence.java147
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequenceParser.java60
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSet.java160
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSetParser.java60
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERT61String.java151
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTaggedObject.java86
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTags.java11
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTCTime.java29
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTF8String.java138
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUniversalString.java150
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVideotexString.java126
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVisibleString.java143
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLApplicationSpecific.java126
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitString.java144
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLExternal.java92
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLFactory.java28
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLOutputStream.java27
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequence.java133
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequenceParser.java62
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSet.java175
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSetParser.java62
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLTaggedObject.java75
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DateUtil.java81
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DefiniteLengthInputStream.java145
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/InMemoryRepresentable.java19
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/IndefiniteLengthInputStream.java112
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyConstructionEnumeration.java47
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyEncodedSequence.java129
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LimitedInputStream.java35
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/OIDTokenizer.java65
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/StreamUtil.java119
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java183
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Attribute.java112
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/AttributeTable.java242
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Attributes.java95
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java138
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/CMSAttributes.java38
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/CMSObjectIdentifiers.java47
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/ContentInfo.java132
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/GCMParameters.java104
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java140
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignedData.java332
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignerIdentifier.java116
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignerInfo.java284
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Time.java208
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java112
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java88
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/iana/IANAObjectIdentifiers.java62
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java212
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java33
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java155
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeCertType.java56
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java22
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/VerisignCzagExtension.java22
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTNamedCurves.java101
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java163
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nsri/NSRIObjectIdentifiers.java62
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java27
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/BasicOCSPResponse.java124
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CertID.java109
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CertStatus.java112
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CrlID.java114
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPObjectIdentifiers.java36
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPRequest.java94
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPResponse.java103
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPResponseStatus.java97
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/Request.java95
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponderID.java108
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseBytes.java95
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseData.java194
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/RevokedInfo.java96
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/Signature.java115
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/SingleResponse.java166
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/TBSRequest.java176
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/oiw/OIWObjectIdentifiers.java52
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Attribute.java92
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java80
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CRLBag.java88
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertBag.java71
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequest.java96
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java186
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/ContentInfo.java106
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/DHParameter.java108
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedData.java115
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java90
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptionScheme.java66
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java89
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/KeyDerivationFunc.java60
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/MacData.java111
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBEParameter.java77
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBES2Parameters.java81
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBKDF2Params.java265
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java73
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java481
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Pfx.java87
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java260
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java159
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java192
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java192
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPublicKey.java99
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java176
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SafeBag.java100
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SignedData.java169
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKey.java184
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java130
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECNamedCurves.java1039
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java112
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/teletrust/TeleTrusTObjectIdentifiers.java79
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/util/ASN1Dump.java420
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java77
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/DirectoryString.java130
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/RDN.java149
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500Name.java314
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500NameBuilder.java145
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500NameStyle.java81
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java194
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStrictStyle.java38
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStyle.java358
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/IETFUtils.java577
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/RFC4519Style.java252
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java92
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java110
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttCertIssuer.java95
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java88
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Attribute.java97
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificate.java101
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java184
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java239
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/BasicConstraints.java163
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLDistPoint.java102
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLNumber.java56
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLReason.java153
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Certificate.java133
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CertificateList.java146
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DSAParameter.java96
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DigestInfo.java89
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPoint.java164
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPointName.java141
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java194
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extension.java367
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extensions.java249
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtensionsGenerator.java201
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralName.java438
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralNames.java116
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralSubtree.java220
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Holder.java247
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuerSerial.java127
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java277
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyPurposeId.java187
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyUsage.java115
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/NameConstraintValidator.java22
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/NameConstraintValidatorException.java14
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/NameConstraints.java131
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ObjectDigestInfo.java192
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/OtherName.java94
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java2167
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyConstraints.java108
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyInformation.java120
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierId.java33
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java119
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java100
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ReasonFlags.java87
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java71
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java156
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertList.java315
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificate.java293
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificateStructure.java196
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Time.java181
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java147
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V2Form.java161
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java215
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509CertificateStructure.java131
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java67
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extension.java251
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extensions.java480
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ExtensionsGenerator.java96
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Name.java1383
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameEntryConverter.java88
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameTokenizer.java106
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java114
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHDomainParameters.java168
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHPublicKey.java100
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHValidationParms.java84
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DomainParameters.java225
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ECNamedCurveTable.java258
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ValidationParams.java104
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962NamedCurves.java617
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962Parameters.java108
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9Curve.java162
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParameters.java234
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParametersHolder.java23
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECPoint.java80
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9FieldElement.java72
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9FieldID.java150
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9IntegerConverter.java72
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java226
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AsymmetricBlockCipher.java47
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AsymmetricCipherKeyPair.java63
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AsymmetricCipherKeyPairGenerator.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BasicAgreement.java28
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BlockCipher.java58
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BufferedBlockCipher.java322
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CipherKeyGenerator.java40
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CipherParameters.java10
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoException.java50
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesPermission.java83
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesRegistrar.java447
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DSA.java38
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DSAExt.java18
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DataLengthException.java31
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DerivationFunction.java14
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DerivationParameters.java10
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Digest.java53
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/ExtendedDigest.java17
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/InvalidCipherTextException.java42
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/KeyGenerationParameters.java50
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Mac.java73
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/OutputLengthException.java14
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/PBEParametersGenerator.java173
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/RawAgreement.java14
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/RuntimeCryptoException.java28
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Signer.java45
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SignerWithRecovery.java36
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SkippingCipher.java33
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SkippingStreamCipher.java11
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StagedAgreement.java13
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StreamBlockCipher.java59
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StreamCipher.java56
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Wrapper.java22
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/DHBasicAgreement.java89
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java80
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactory.java111
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactoryBouncyCastle.java44
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactoryInterface.java29
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactoryOpenSSL.java44
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/EncodableDigest.java19
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/GeneralDigest.java162
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/LongDigest.java411
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD4Digest.java293
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD5Digest.java363
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/NullDigest.java69
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/OpenSSLDigest.java117
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA1Digest.java355
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA224Digest.java363
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA256Digest.java359
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA384Digest.java118
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA512Digest.java121
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/XofUtils.java52
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/ec/CustomNamedCurves.java792
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/OAEPEncoding.java366
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/PKCS1Encoding.java431
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESEngine.java630
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESFastEngine.java1011
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESWrapEngine.java31
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/BlowfishEngine.java580
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESEngine.java485
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeEngine.java129
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeWrapEngine.java356
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC2Engine.java319
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC4Engine.java150
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java197
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSABlindedEngine.java150
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSACoreEngine.java214
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/TwofishEngine.java682
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESKeyGenerator.java52
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java68
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java44
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHKeyGeneratorHelper.java68
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHParametersGenerator.java57
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHParametersHelper.java111
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java71
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DSAParametersGenerator.java416
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java78
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java137
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java222
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java121
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java160
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java234
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/DigestInputStream.java56
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/DigestOutputStream.java46
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/MacInputStream.java56
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/MacOutputStream.java46
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java231
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/HMac.java239
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/AEADBlockCipher.java19
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/AEADCipher.java140
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CBCBlockCipher.java255
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CCMBlockCipher.java471
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBBlockCipher.java276
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CTSBlockCipher.java290
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/GCMBlockCipher.java692
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/OFBBlockCipher.java185
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/SICBlockCipher.java292
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java41
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMExponentiator.java11
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMMultiplier.java11
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMUtil.java449
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java63
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java71
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java83
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/BlockCipherPadding.java50
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java75
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java79
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PKCS7Padding.java79
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java301
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/TBCPadding.java91
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/X923Padding.java82
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ZeroBytePadding.java75
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/AEADParameters.java65
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/AsymmetricKeyParameter.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DESParameters.java111
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DESedeParameters.java110
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHKeyGenerationParameters.java34
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHKeyParameters.java58
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHParameters.java198
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHPrivateKeyParameters.java45
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHPublicKeyParameters.java168
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHValidationParameters.java54
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAKeyGenerationParameters.java29
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAKeyParameters.java25
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAParameterGenerationParameters.java84
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAParameters.java78
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAPrivateKeyParameters.java27
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAPublicKeyParameters.java48
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAValidationParameters.java69
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECDomainParameters.java182
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECKeyGenerationParameters.java29
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECKeyParameters.java30
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECNamedDomainParameters.java53
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java27
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECPublicKeyParameters.java27
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/KDFParameters.java33
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/KeyParameter.java34
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ParametersWithID.java32
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ParametersWithIV.java43
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ParametersWithRandom.java41
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RC2Parameters.java30
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyGenerationParameters.java52
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyParameters.java79
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java71
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSAEncoding.java33
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSAKCalculator.java43
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSASigner.java184
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/ECDSASigner.java261
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/PlainDSAEncoding.java66
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/RSADigestSigner.java279
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/RandomDSAKCalculator.java49
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/StandardDSAEncoding.java68
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/tls/CertificateType.java19
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/tls/TlsCloseable.java13
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java23
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/Pack.java206
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PrivateKeyFactory.java309
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PublicKeyFactory.java566
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/SSHNamedCurves.java134
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/iana/AEADAlgorithm.java59
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/AesCcmCiphertext.java61
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/BitmapSspRange.java74
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/CertificateBase.java68
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/CertificateType.java52
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/CircularRegion.java43
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Duration.java30
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EncryptedData.java35
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EndEntityType.java56
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EtsiTs103097Module.java10
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ExplicitCertificate.java16
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/GeographicRegion.java28
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/GroupLinkageValue.java69
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/HashAlgorithm.java52
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/HashedData.java48
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/HeaderInfo.java54
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/IValue.java54
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Ieee1609Dot2Content.java48
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Ieee1609Dot2Data.java59
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ImplicitCertificate.java16
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/IssuerIdentifier.java28
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Latitude.java26
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/LinkageData.java60
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/LinkageValue.java44
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Longitude.java26
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PKRecipientInfo.java27
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PolygonalRegion.java20
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PsidGroupPermissions.java61
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PsidSspRange.java91
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/RecipientInfo.java18
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/RectangularRegion.java43
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfCertificate.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfOctetString.java70
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfPsidGroupPermissions.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfRecipientInfo.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfRectangularRegion.java34
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ServiceSpecificPermissions.java10
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Signature.java27
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SignedData.java29
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SignedDataPayload.java28
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SignerIdentifier.java31
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SspRange.java142
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SubjectPermissions.java41
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SymmAlgorithm.java57
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SymmRecipientInfo.java27
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ToBeSignedCertificate.java56
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ToBeSignedData.java27
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/TwoDLocation.java23
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Utils.java37
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ValidityPeriod.java27
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/VerificationKeyIndicator.java26
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePrivateKey.java105
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePublicKey.java105
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PBKDFKey.java13
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKCS12Key.java89
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKCS12KeyWithParameters.java71
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKCS12StoreParameter.java64
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCRLStore.java29
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java350
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertRevocationChecker.java19
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertRevocationCheckerParameters.java60
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertStore.java29
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertStoreSelector.java137
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXExtendedBuilderParameters.java144
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXExtendedParameters.java356
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/interfaces/BCX509Certificate.java33
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/DigestUpdatingOutputStream.java35
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/MacUpdatingOutputStream.java36
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/OutputStreamFactory.java48
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java57
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/DH.java109
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/DSA.java107
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/EC.java285
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/RSA.java311
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/X509.java40
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java78
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParametersSpi.java146
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java271
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java285
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/DHUtil.java46
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java730
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyFactorySpi.java140
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java153
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java115
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.java135
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPrivateKey.java185
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java222
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java400
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSAUtil.java113
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java238
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java180
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java189
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java409
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java349
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java98
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java834
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java411
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java333
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java400
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java286
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java297
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java208
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java203
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java627
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java453
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java295
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java108
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java89
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java355
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAlgorithmParameterGeneratorSpi.java29
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java258
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java81
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/DHUtil.java57
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/DSABase.java114
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/DSAEncoder.java18
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java372
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java451
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ExtendedInvalidKeySpecException.java25
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/KeyUtil.java76
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java127
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/PrimeCertaintyCalculator.java25
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java460
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/ExtCRLException.java21
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/KeyFactory.java99
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java175
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java382
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureCreator.java12
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java328
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java737
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java30
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java150
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java941
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java30
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java423
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java205
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java59
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/PKCS12StoreParameter.java34
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java26
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ProviderConfigurationPermission.java161
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java72
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java37
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/MD5.java95
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA1.java134
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA224.java97
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA256.java120
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA384.java114
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA512.java213
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/BC.java35
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/PKCS12.java41
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java1100
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java1938
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java1151
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/ARC4.java147
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java114
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/DES.java589
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/DESede.java512
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java68
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java692
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java130
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBES2AlgorithmParameters.java367
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/RC2.java566
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/SymmetricAlgorithmProvider.java52
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/Twofish.java158
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java236
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameterGenerator.java45
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameters.java33
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java1579
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseKeyGenerator.java87
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java283
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java97
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java438
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java609
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BlockCipherProvider.java12
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java49
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java136
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.java122
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java547
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBESecretKeyFactory.java72
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/SpecUtil.java37
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AlgorithmProvider.java12
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java62
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AsymmetricKeyInfoConverter.java21
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/BadBlockException.java25
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/DigestFactory.java238
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/SecretKeyUtil.java44
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/AEADParameterSpec.java75
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java72
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/DHDomainParameterSpec.java131
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/DHExtendedPrivateKeySpec.java39
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/DHExtendedPublicKeySpec.java39
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/OpenSSHPrivateKeySpec.java60
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/OpenSSHPublicKeySpec.java79
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/PBKDF2KeySpec.java56
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java25
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/AlgorithmParametersUtils.java67
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/AnnotatedPrivateKey.java118
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/BCJcaJceHelper.java43
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java153
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/ECKeyUtil.java108
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/JcaJceHelper.java95
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/JcaJceUtils.java135
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/MessageDigestUtils.java73
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java160
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/PrivateKeyAnnotator.java33
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java160
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/ECNamedCurveTable.java78
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/PKCS10CertificationRequest.java661
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/PrincipalUtil.java83
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/X509Principal.java167
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/exception/ExtCertPathBuilderException.java33
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java39
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/exception/ExtException.java23
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/BCKeyStore.java16
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECKey.java17
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECPointEncoder.java22
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECPrivateKey.java18
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECPublicKey.java19
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/PKCS12BagAttributeCarrier.java23
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/netscape/NetscapeCertRequest.java301
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/AnnotatedException.java36
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java431
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java229
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertBlocklist.java238
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java1434
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertStatus.java47
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertStoreCollectionSpi.java108
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/DHUtil.java52
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/ExtCRLException.java21
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPrivateKey.java191
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPublicKey.java182
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPrivateKey.java476
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPublicKey.java523
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JDKDSAPrivateKey.java182
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JDKDSAPublicKey.java181
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JDKPKCS12StoreParameter.java53
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PEMUtil.java98
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCRLUtil.java120
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java273
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java568
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java139
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java28
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXPolicyNode.java177
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PrincipalUtils.java142
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/ProvCrlRevocationChecker.java68
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java2534
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/ReasonsMask.java102
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/RecoverableCertPathValidatorException.java14
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/WrappedRevocationChecker.java37
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CRLEntryObject.java321
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CRLObject.java666
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CertificateObject.java932
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509SignatureUtil.java148
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECKeySpec.java28
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveGenParameterSpec.java30
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveParameterSpec.java64
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveSpec.java119
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECParameterSpec.java123
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECPrivateKeySpec.java37
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECPublicKeySpec.java44
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/Primes.java678
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/AbstractECLookupTable.java14
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/AbstractECMultiplier.java35
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECAlgorithms.java620
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECConstants.java17
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECCurve.java1406
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECFieldElement.java920
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECLookupTable.java12
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECMultiplier.java21
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECPoint.java2133
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECPointMap.java10
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/FixedPointCombMultiplier.java60
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/FixedPointPreCompInfo.java53
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/FixedPointUtil.java91
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/GLVMultiplier.java48
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/LongArray.java2203
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/PreCompCallback.java10
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/PreCompInfo.java12
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ScaleXNegateYPointMap.java20
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ScaleXPointMap.java20
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ScaleYNegateXPointMap.java20
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/SimpleBigDecimal.java248
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/Tnaf.java850
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ValidityPrecompInfo.java41
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafL2RMultiplier.java89
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafPreCompInfo.java109
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafUtil.java685
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WTauNafMultiplier.java128
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WTauNafPreCompInfo.java26
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ZTauElement.java38
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java165
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java220
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java218
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java260
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java167
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java329
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java195
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java273
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java171
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java221
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java248
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java260
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java167
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java342
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java279
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java271
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java164
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java222
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java220
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java260
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java167
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java356
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java194
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java271
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java167
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java339
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java216
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java272
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java167
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java200
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java174
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java296
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/ECEndomorphism.java14
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/EndoPreCompInfo.java35
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/EndoUtil.java77
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVEndomorphism.java12
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeAEndomorphism.java44
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeAParameters.java35
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java44
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java102
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/ScalarSplitParameters.java72
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/ExtensionField.java12
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteField.java14
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteFields.java57
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/GF2Polynomial.java43
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/GenericPolynomialExtensionField.java63
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/Polynomial.java16
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/PolynomialExtensionField.java10
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/PrimeField.java43
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Bits.java30
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Interleave.java216
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Mod.java589
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat.java1431
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat192.java1081
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat224.java1200
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat256.java1423
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat384.java47
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat512.java47
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Arrays.java1165
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/BigIntegers.java352
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/CollectionStore.java64
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Doubles.java13
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Encodable.java20
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Fingerprint.java182
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/IPAddress.java193
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Integers.java44
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Iterable.java19
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Longs.java33
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Memoable.java29
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Objects.java18
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Pack.java339
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Properties.java209
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Selector.java22
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Store.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/StoreException.java29
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/StringList.java44
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Strings.java347
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64.java177
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64Encoder.java405
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/DecoderException.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Encoder.java19
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/EncoderException.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Hex.java189
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/HexEncoder.java266
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/UTF8.java158
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/SimpleOutputStream.java25
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/StreamOverflowException.java17
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/Streams.java153
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/TeeInputStream.java78
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/TeeOutputStream.java64
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemGenerationException.java30
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemHeader.java77
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemObject.java66
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemObjectGenerator.java18
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemObjectParser.java21
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemReader.java96
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemWriter.java140
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/AttributeCertificateHolder.java421
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/AttributeCertificateIssuer.java210
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/ExtCertificateEncodingException.java21
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/ExtendedPKIXBuilderParameters.java213
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/ExtendedPKIXParameters.java662
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/NoSuchStoreException.java14
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/PKIXAttrCertChecker.java60
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509Attribute.java82
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509AttributeCertificate.java104
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509CRLStoreSelector.java332
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509CertStoreSelector.java90
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509CollectionStoreParameters.java72
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509StoreParameters.java9
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509StoreSpi.java16
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509Util.java425
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V1CertificateGenerator.java381
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V2AttributeCertificate.java352
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V3CertificateGenerator.java535
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/extension/AuthorityKeyIdentifierStructure.java149
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/extension/X509ExtensionUtil.java115
-rw-r--r--srcgen/core-platform-api.txt173
-rw-r--r--srcgen/unsupported-app-usage.json48
-rwxr-xr-xsrcgen_platform/generate_android_src.sh45
1810 files changed, 179982 insertions, 20796 deletions
diff --git a/Android.bp b/Android.bp
index ba0a3bc0..aefddc2c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -16,6 +16,34 @@
package {
default_visibility: ["//visibility:private"],
+ default_applicable_licenses: ["external_bouncycastle_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+ name: "external_bouncycastle_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ "SPDX-license-identifier-BSD",
+ "SPDX-license-identifier-MIT",
+ ],
+ license_text: [
+ "NOTICE",
+ ],
}
java_defaults {
@@ -57,20 +85,23 @@ filegroup {
}
// A bouncycastle library repackaged in com.android.org.bouncycastle for use
-// in the Android platform where it is important not to conflict with the
+// in the ART module. Repackaging is needed to avoid conflict with the
// original org.bouncycastle package.
java_library {
name: "bouncycastle",
// Restrict visibility to only those targets that need to access it.
visibility: [
"//art/build/apex",
+ "//art/build/sdk",
"//external/wycheproof",
"//libcore",
+ "//packages/modules/ArtPrebuilt",
],
apex_available: [
- "com.android.art.release",
+ "com.android.art",
"com.android.art.debug",
],
+ min_sdk_version: "31",
defaults: ["bouncycastle-defaults"],
installable: true,
@@ -82,30 +113,28 @@ java_library {
system_modules: "art-module-intra-core-api-stubs-system-modules",
}
-// A guaranteed unstripped version of bouncycastle.
-// The build system may or may not strip the bouncycastle jar, but this one will
-// not be stripped. See b/24535627.
+// A bouncycastle library repackaged in com.android.internal.org.bouncycastle
+// for use in the Android platform where it is important not to conflict with
+// the original org.bouncycastle package or the one in the ART module.
java_library {
- name: "bouncycastle-testdex",
+ name: "bouncycastle-repackaged-unbundled",
visibility: [
- "//art:__subpackages__",
+ "//cts/tests/libcore/wycheproof-bc",
+ "//external/sl4a/Common",
+ "//external/wycheproof",
+ "//frameworks/base",
+ "//frameworks/base/packages/Connectivity/tests/unit",
+ "//frameworks/base/tests/net",
+ "//packages/modules/Connectivity/tests/unit",
],
defaults: ["bouncycastle-defaults"],
installable: true,
-
- srcs: [":bouncycastle_java_files"],
-
- libs: ["unsupportedappusage"],
-
- sdk_version: "none",
- system_modules: "art-module-intra-core-api-stubs-system-modules",
- dex_preopt: {
- enabled: false,
- },
- java_version: "1.7",
+ sdk_version: "core_current",
+ srcs: ["repackaged_platform/bcprov/src/main/java/**/*.java"],
}
unbundled_visibility = [
+ "//art/build/sdk",
"//build/make/tools/signapk",
"//build/make/tools/signtos",
"//cts/hostsidetests/devicepolicy/app/DeviceOwner",
@@ -120,11 +149,16 @@ unbundled_visibility = [
"//external/robolectric-shadows/shadows/httpclient",
"//frameworks/opt/net/wifi/service",
"//frameworks/opt/net/wifi/tests/wifitests",
+ "//packages/apps/CertInstaller",
+ "//packages/apps/KeyChain",
+ "//packages/apps/RemoteProvisioner/tests/unittests",
"//packages/modules/Connectivity/tests/cts/net",
"//packages/modules/Wifi/service",
"//packages/modules/Wifi/service/tests/wifitests",
"//libcore",
"//system/extras/verity",
+ "//tools/security/remote_provisioning/attestation_testing",
+ "//vendor:__subpackages__",
]
// A bouncycastle library in the original org.bouncycastle package for use
@@ -189,15 +223,18 @@ java_library_host {
static_libs: ["bouncycastle-unbundled"],
}
-// Bouncycastle subset for use by platform/packages/modules/IPsec project.
+// Bouncycastle subset for use by frameworks/opt/net/ike project.
//
-// Avoids including the whole of bouncycastle_unbundled in IPsec.
+// Avoids including the whole of bouncycastle_unbundled in ike.
//
// Specifically, SHA1Digest and MD4Digest (and their dependencies) must be used by IKEv2 to support
// legacy authentication methods.
java_library {
name: "bouncycastle_ike_digests",
- visibility: ["//packages/modules/IPsec"],
+ visibility: [
+ "//art/build/sdk",
+ "//packages/modules/IPsec",
+ ],
apex_available: [
"com.android.ipsec",
"test_com.android.ipsec",
diff --git a/METADATA b/METADATA
new file mode 100644
index 00000000..d97975ca
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+ license_type: NOTICE
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java
index 0fc34330..d0b1259d 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java
@@ -137,8 +137,7 @@ public class AttributeCertificateHolder
{
if (holder.getObjectDigestInfo() != null)
{
- return holder.getObjectDigestInfo().getDigestedObjectType()
- .getValue().intValue();
+ return holder.getObjectDigestInfo().getDigestedObjectType().intValueExact();
}
return -1;
}
@@ -291,7 +290,7 @@ public class AttributeCertificateHolder
if (holder.getBaseCertificateID() != null)
{
- return holder.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber())
+ return holder.getBaseCertificateID().getSerial().hasValue(x509Cert.getSerialNumber())
&& matchesDN(x509Cert.getIssuer(), holder.getBaseCertificateID().getIssuer());
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateIssuer.java b/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateIssuer.java
index b5084c94..6217102c 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateIssuer.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/AttributeCertificateIssuer.java
@@ -123,7 +123,7 @@ public class AttributeCertificateIssuer
V2Form issuer = (V2Form)form;
if (issuer.getBaseCertificateID() != null)
{
- return issuer.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber())
+ return issuer.getBaseCertificateID().getSerial().hasValue(x509Cert.getSerialNumber())
&& matchesDN(x509Cert.getIssuer(), issuer.getBaseCertificateID().getIssuer());
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/CertUtils.java b/bcpkix/src/main/java/org/bouncycastle/cert/CertUtils.java
index 87cddd9e..c71be36b 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/CertUtils.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/CertUtils.java
@@ -7,29 +7,33 @@ 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 org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1GeneralizedTime;
+import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERNull;
-import org.bouncycastle.asn1.DEROutputStream;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.AttributeCertificate;
import org.bouncycastle.asn1.x509.AttributeCertificateInfo;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.asn1.x509.CertificateList;
+import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
import org.bouncycastle.asn1.x509.TBSCertList;
import org.bouncycastle.asn1.x509.TBSCertificate;
import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.util.Properties;
class CertUtils
{
@@ -48,6 +52,7 @@ class CertUtils
return p;
}
+
static X509CertificateHolder generateFullCert(ContentSigner signer, TBSCertificate tbsCert)
{
try
@@ -84,14 +89,11 @@ class CertUtils
}
}
- private static byte[] generateSig(ContentSigner signer, ASN1Encodable tbsObj)
+ private static byte[] generateSig(ContentSigner signer, ASN1Object tbsObj)
throws IOException
{
OutputStream sOut = signer.getOutputStream();
- DEROutputStream dOut = new DEROutputStream(sOut);
-
- dOut.writeObject(tbsObj);
-
+ tbsObj.encodeTo(sOut, ASN1Encoding.DER);
sOut.close();
return signer.getSignature();
@@ -228,30 +230,100 @@ class CertUtils
static boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2)
{
if (!id1.getAlgorithm().equals(id2.getAlgorithm()))
- {
- return false;
- }
+ {
+ return false;
+ }
+
+ if (Properties.isOverrideSet("org.bouncycastle.x509.allow_absent_equiv_NULL"))
+ {
+ if (id1.getParameters() == null)
+ {
+ if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ 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;
+ }
- if (id1.getParameters() == null)
+ static ExtensionsGenerator doReplaceExtension(ExtensionsGenerator extGenerator, Extension ext)
+ {
+ boolean isReplaced = false;
+ Extensions exts = extGenerator.generate();
+ extGenerator = new ExtensionsGenerator();
+
+ for (Enumeration en = exts.oids(); en.hasMoreElements();)
{
- if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE))
+ ASN1ObjectIdentifier extOid = (ASN1ObjectIdentifier)en.nextElement();
+
+ if (extOid.equals(ext.getExtnId()))
+ {
+ isReplaced = true;
+ extGenerator.addExtension(ext);
+ }
+ else
{
- return false;
+ extGenerator.addExtension(exts.getExtension(extOid));
}
+ }
- return true;
+ if (!isReplaced)
+ {
+ throw new IllegalArgumentException("replace - original extension (OID = " + ext.getExtnId() + ") not found");
}
- if (id2.getParameters() == null)
+ 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();)
{
- if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE))
+ ASN1ObjectIdentifier extOid = (ASN1ObjectIdentifier)en.nextElement();
+
+ if (extOid.equals(oid))
+ {
+ isRemoved = true;
+ }
+ else
{
- return false;
+ extGenerator.addExtension(exts.getExtension(extOid));
}
+ }
- return true;
+ if (!isRemoved)
+ {
+ throw new IllegalArgumentException("remove - extension (OID = " + oid + ") not found");
}
- return id1.getParameters().equals(id2.getParameters());
+ return extGenerator;
}
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java
index 082f582e..94fa910b 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java
@@ -11,9 +11,9 @@ import java.util.Date;
import java.util.List;
import java.util.Set;
+import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Sequence;
-import org.bouncycastle.asn1.DEROutputStream;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.AttCertValidityPeriod;
import org.bouncycastle.asn1.x509.Attribute;
@@ -97,7 +97,7 @@ public class X509AttributeCertificateHolder
public int getVersion()
{
- return attrCert.getAcinfo().getVersion().getValue().intValue() + 1;
+ return attrCert.getAcinfo().getVersion().intValueExact() + 1;
}
/**
@@ -338,10 +338,7 @@ public class X509AttributeCertificateHolder
verifier = verifierProvider.get((acinfo.getSignature()));
OutputStream sOut = verifier.getOutputStream();
- DEROutputStream dOut = new DEROutputStream(sOut);
-
- dOut.writeObject(acinfo);
-
+ acinfo.encodeTo(sOut, ASN1Encoding.DER);
sOut.close();
}
catch (Exception e)
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java
index ef89601d..93b86456 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java
@@ -10,14 +10,15 @@ 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 org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.DEROutputStream;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.CertificateList;
import org.bouncycastle.asn1.x509.Extension;
@@ -26,6 +27,7 @@ import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.IssuingDistributionPoint;
import org.bouncycastle.asn1.x509.TBSCertList;
+import org.bouncycastle.asn1.x509.Time;
import org.bouncycastle.operator.ContentVerifier;
import org.bouncycastle.operator.ContentVerifierProvider;
import org.bouncycastle.util.Encodable;
@@ -141,6 +143,22 @@ public class X509CRLHolder
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;
@@ -148,7 +166,7 @@ public class X509CRLHolder
{
TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)en.nextElement();
- if (entry.getUserCertificate().getValue().equals(serialNumber))
+ if (entry.getUserCertificate().hasValue(serialNumber))
{
return new X509CRLEntryHolder(entry, isIndirect, currentCA);
}
@@ -296,10 +314,7 @@ public class X509CRLHolder
verifier = verifierProvider.get((tbsCRL.getSignature()));
OutputStream sOut = verifier.getOutputStream();
- DEROutputStream dOut = new DEROutputStream(sOut);
-
- dOut.writeObject(tbsCRL);
-
+ tbsCRL.encodeTo(sOut, ASN1Encoding.DER);
sOut.close();
}
catch (Exception e)
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java
index 0fb86731..d78b6a56 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java
@@ -10,8 +10,8 @@ import java.util.Date;
import java.util.List;
import java.util.Set;
+import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.DEROutputStream;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.Certificate;
@@ -287,10 +287,7 @@ public class X509CertificateHolder
verifier = verifierProvider.get((tbsCert.getSignature()));
OutputStream sOut = verifier.getOutputStream();
- DEROutputStream dOut = new DEROutputStream(sOut);
-
- dOut.writeObject(tbsCert);
-
+ tbsCert.encodeTo(sOut, ASN1Encoding.DER);
sOut.close();
}
catch (Exception e)
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java b/bcpkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java
index 5cb131bc..3562cbf8 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java
@@ -1,17 +1,28 @@
package 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 org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.DERBitString;
+import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.asn1.x509.TBSCertificate;
import org.bouncycastle.asn1.x509.Time;
import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
import org.bouncycastle.operator.ContentSigner;
@@ -81,6 +92,60 @@ public class X509v3CertificateBuilder
}
/**
+ * 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.
@@ -88,7 +153,7 @@ public class X509v3CertificateBuilder
*/
public X509v3CertificateBuilder setSubjectUniqueID(boolean[] uniqueID)
{
- tbsGen.setSubjectUniqueID(CertUtils.booleanToBitString(uniqueID));
+ tbsGen.setSubjectUniqueID(booleanToBitString(uniqueID));
return this;
}
@@ -101,7 +166,7 @@ public class X509v3CertificateBuilder
*/
public X509v3CertificateBuilder setIssuerUniqueID(boolean[] uniqueID)
{
- tbsGen.setIssuerUniqueID(CertUtils.booleanToBitString(uniqueID));
+ tbsGen.setIssuerUniqueID(booleanToBitString(uniqueID));
return this;
}
@@ -113,6 +178,8 @@ public class X509v3CertificateBuilder
* @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,
@@ -120,7 +187,14 @@ public class X509v3CertificateBuilder
ASN1Encodable value)
throws CertIOException
{
- CertUtils.addExtension(extGenerator, oid, isCritical, value);
+ try
+ {
+ extGenerator.addExtension(oid, isCritical, value);
+ }
+ catch (IOException e)
+ {
+ throw new CertIOException("cannot encode extension: " + e.getMessage(), e);
+ }
return this;
}
@@ -130,6 +204,8 @@ public class X509v3CertificateBuilder
*
* @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)
@@ -148,6 +224,8 @@ public class X509v3CertificateBuilder
* @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,
@@ -161,6 +239,89 @@ public class X509v3CertificateBuilder
}
/**
+ * 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.
*
@@ -205,6 +366,56 @@ public class X509v3CertificateBuilder
tbsGen.setExtensions(extGenerator.generate());
}
- return CertUtils.generateFullCert(signer, tbsGen.generateTBSCertificate());
+ 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/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPResp.java b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPResp.java
index d74bef00..ed68f7d9 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPResp.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPResp.java
@@ -22,6 +22,7 @@ import org.bouncycastle.operator.ContentVerifierProvider;
import org.bouncycastle.util.Encodable;
/**
+ * OCSP RFC 2560, RFC 6960
* <pre>
* BasicOCSPResponse ::= SEQUENCE {
* tbsResponseData ResponseData,
@@ -73,7 +74,7 @@ public class BasicOCSPResp
public int getVersion()
{
- return data.getVersion().getValue().intValue() + 1;
+ return data.getVersion().intValueExact() + 1;
}
public RespID getResponderId()
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReq.java b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReq.java
index 437d37be..bfe0e102 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReq.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReq.java
@@ -103,7 +103,7 @@ public class OCSPReq
public int getVersionNumber()
{
- return req.getTbsRequest().getVersion().getValue().intValue() + 1;
+ return req.getTbsRequest().getVersion().intValueExact() + 1;
}
public GeneralName getRequestorName()
@@ -246,14 +246,8 @@ public class OCSPReq
/**
* return the ASN.1 encoded representation of this object.
*/
- public byte[] getEncoded()
- throws IOException
+ public byte[] getEncoded() throws IOException
{
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
- aOut.writeObject(req);
-
- return bOut.toByteArray();
+ return req.getEncoded();
}
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPResp.java b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPResp.java
index ed3918ac..6e7d8933 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPResp.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPResp.java
@@ -74,7 +74,7 @@ public class OCSPResp
public int getStatus()
{
- return this.resp.getResponseStatus().getValue().intValue();
+ return this.resp.getResponseStatus().getIntValue();
}
public Object getResponseObject()
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/RespData.java b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/RespData.java
index 6960fa8f..1192e165 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/RespData.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/RespData.java
@@ -7,6 +7,17 @@ import org.bouncycastle.asn1.ocsp.ResponseData;
import org.bouncycastle.asn1.ocsp.SingleResponse;
import org.bouncycastle.asn1.x509.Extensions;
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * ResponseData ::= SEQUENCE {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * responderID ResponderID,
+ * producedAt GeneralizedTime,
+ * responses SEQUENCE OF SingleResponse,
+ * responseExtensions [1] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ */
public class RespData
{
private ResponseData data;
@@ -19,7 +30,7 @@ public class RespData
public int getVersion()
{
- return data.getVersion().getValue().intValue() + 1;
+ return data.getVersion().intValueExact() + 1;
}
public RespID getResponderId()
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java
index 94bf52f0..78ed990f 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java
@@ -2,6 +2,8 @@ package org.bouncycastle.cert.ocsp.jcajce;
import java.security.PublicKey;
+import javax.security.auth.x500.X500Principal;
+
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder;
import org.bouncycastle.cert.ocsp.OCSPException;
@@ -10,6 +12,11 @@ import org.bouncycastle.operator.DigestCalculator;
public class JcaBasicOCSPRespBuilder
extends BasicOCSPRespBuilder
{
+ public JcaBasicOCSPRespBuilder(X500Principal principal)
+ {
+ super(new JcaRespID(principal));
+ }
+
public JcaBasicOCSPRespBuilder(PublicKey key, DigestCalculator digCalc)
throws OCSPException
{
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/package.html b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/package.html
index cfe87f22..b9e5cae4 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/package.html
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/package.html
@@ -1,5 +1,5 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
- "http://www.w3.org/TR/html4/loose.dtd">
+ "https://www.w3.org/TR/html4/loose.dtd">
<html>
<body bgcolor="#ffffff">
JCA extensions to the OCSP online certificate status package.
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java b/bcpkix/src/main/java/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java
index 5af58606..15329d68 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java
@@ -121,7 +121,7 @@ public class X509CertificateHolderSelector
IssuerAndSerialNumber iAndS = new IssuerAndSerialNumber(certHldr.toASN1Structure());
return iAndS.getName().equals(this.issuer)
- && iAndS.getSerialNumber().getValue().equals(this.serialNumber);
+ && iAndS.getSerialNumber().hasValue(this.serialNumber);
}
else if (subjectKeyId != null)
{
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java
index b3a39a92..3110fa65 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java
@@ -22,6 +22,7 @@ import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.BERSequence;
import org.bouncycastle.asn1.DERSet;
+import org.bouncycastle.asn1.DLSet;
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.asn1.cms.SignedData;
import org.bouncycastle.asn1.cms.SignerInfo;
@@ -232,7 +233,7 @@ public class CMSSignedData
*/
public int getVersion()
{
- return signedData.getVersion().getValue().intValue();
+ return signedData.getVersion().intValueExact();
}
/**
@@ -390,6 +391,17 @@ public class CMSSignedData
// 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.
*
@@ -515,7 +527,7 @@ public class CMSSignedData
}
ASN1Set digests = new DERSet(digestAlgs);
- ASN1Set signers = new DERSet(vec);
+ ASN1Set signers = new DLSet(vec);
ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive();
vec = new ASN1EncodableVector();
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java
index 959a7ba3..2d38b536 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java
@@ -249,7 +249,7 @@ class CMSUtils
{
OCSPResponse resp = OCSPResponse.getInstance(infoFormat.getInfo());
- if (resp.getResponseStatus().getValue().intValue() != OCSPResponseStatus.SUCCESSFUL)
+ if (OCSPResponseStatus.SUCCESSFUL != resp.getResponseStatus().getIntValue())
{
throw new IllegalArgumentException("cannot add unsuccessful OCSP response to CMS SignedData");
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
index 459b7df4..f2e1377b 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
@@ -9,6 +9,7 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier;
// 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.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -94,12 +95,22 @@ public class DefaultCMSSignatureAlgorithmNameGenerator
addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1", "RSAandMGF1");
addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256", "RSAandMGF1");
// BEGIN Android-removed: Unsupported algorithms
- // addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1", "PLAIN-ECDSA");
- // addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224", "PLAIN-ECDSA");
- // addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256", "PLAIN-ECDSA");
- // addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384", "PLAIN-ECDSA");
- // addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512", "PLAIN-ECDSA");
- // addEntries(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160", "PLAIN-ECDSA");
+ /*
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_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");
@@ -119,7 +130,6 @@ public class DefaultCMSSignatureAlgorithmNameGenerator
encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3410");
encryptionAlgs.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, "ECGOST3410-2012-256");
encryptionAlgs.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, "ECGOST3410-2012-512");
- encryptionAlgs.put(GMObjectIdentifiers.sm2sign_with_sm3, "SM2");
digestAlgs.put(PKCSObjectIdentifiers.md2, "MD2");
digestAlgs.put(PKCSObjectIdentifiers.md4, "MD4");
@@ -210,6 +220,19 @@ public class DefaultCMSSignatureAlgorithmNameGenerator
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()))
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
index fb537438..4e3c9676 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
@@ -1,11 +1,15 @@
package org.bouncycastle.cms;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.bouncycastle.asn1.DERNull;
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+// import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers;
import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
@@ -13,6 +17,7 @@ public class DefaultCMSSignatureEncryptionAlgorithmFinder
implements CMSSignatureEncryptionAlgorithmFinder
{
private static final Set RSA_PKCS1d5 = new HashSet();
+ private static final Map GOST_ENC = new HashMap();
static
{
@@ -35,9 +40,17 @@ public class DefaultCMSSignatureEncryptionAlgorithmFinder
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);
+ /*
+ 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
}
@@ -48,7 +61,11 @@ public class DefaultCMSSignatureEncryptionAlgorithmFinder
{
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/bcpkix/src/main/java/org/bouncycastle/cms/RecipientOperator.java b/bcpkix/src/main/java/org/bouncycastle/cms/RecipientOperator.java
index 7b3e3e58..82814472 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/RecipientOperator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/RecipientOperator.java
@@ -1,26 +1,24 @@
package org.bouncycastle.cms;
import java.io.InputStream;
+import java.io.OutputStream;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+// import org.bouncycastle.operator.InputAEADDecryptor;
import org.bouncycastle.operator.InputDecryptor;
import org.bouncycastle.operator.MacCalculator;
import org.bouncycastle.util.io.TeeInputStream;
public class RecipientOperator
{
- private final AlgorithmIdentifier algorithmIdentifier;
private final Object operator;
public RecipientOperator(InputDecryptor decryptor)
{
- this.algorithmIdentifier = decryptor.getAlgorithmIdentifier();
this.operator = decryptor;
}
public RecipientOperator(MacCalculator macCalculator)
{
- this.algorithmIdentifier = macCalculator.getAlgorithmIdentifier();
this.operator = macCalculator;
}
@@ -36,6 +34,20 @@ public class RecipientOperator
}
}
+ // 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;
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java
index e1b0ce1f..b26dddbb 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java
@@ -14,6 +14,8 @@ import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.cms.AttributeTable;
import org.bouncycastle.asn1.cms.SignerIdentifier;
import org.bouncycastle.asn1.cms.SignerInfo;
+// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
+// import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.operator.ContentSigner;
@@ -230,6 +232,19 @@ public class SignerInfoGenerator
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);
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
index 40edbfce..96440a52 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
@@ -94,13 +94,26 @@ public class SignerInformation
/**
* 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 overridng methods like getSignedAttributes().
+ * 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.info = baseInfo.info;
+ 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();
@@ -147,7 +160,7 @@ public class SignerInformation
*/
public int getVersion()
{
- return info.getVersion().getValue().intValue();
+ return info.getVersion().intValueExact();
}
public AlgorithmIdentifier getDigestAlgorithmID()
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
index b7c47689..119d1b14 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
@@ -3,6 +3,7 @@ package org.bouncycastle.operator;
import java.util.HashMap;
import java.util.Map;
+import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERNull;
// Android-removed: Unsupported algorithms
@@ -11,6 +12,7 @@ import org.bouncycastle.asn1.DERNull;
// 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.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -34,6 +36,7 @@ public class DefaultDigestAlgorithmIdentifierFinder
// 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);
@@ -104,6 +107,12 @@ public class DefaultDigestAlgorithmIdentifierFinder
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
@@ -163,6 +172,18 @@ public class DefaultDigestAlgorithmIdentifierFinder
{
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);
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
index cf23be3f..9c567b47 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
@@ -15,6 +15,8 @@ import org.bouncycastle.asn1.DERNull;
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
// import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
+// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
+// import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -143,6 +145,16 @@ public class DefaultSignatureAlgorithmIdentifierFinder
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);
@@ -165,19 +177,20 @@ public class DefaultSignatureAlgorithmIdentifierFinder
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-I", BCObjectIdentifiers.qTESLA_I);
- algorithms.put("QTESLA-III-SIZE", BCObjectIdentifiers.qTESLA_III_size);
- algorithms.put("QTESLA-III-SPEED", BCObjectIdentifiers.qTESLA_III_speed);
algorithms.put("QTESLA-P-I", BCObjectIdentifiers.qTESLA_p_I);
algorithms.put("QTESLA-P-III", BCObjectIdentifiers.qTESLA_p_III);
*/
@@ -193,6 +206,9 @@ public class DefaultSignatureAlgorithmIdentifierFinder
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);
@@ -243,19 +259,28 @@ public class DefaultSignatureAlgorithmIdentifierFinder
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_I);
- noParams.add(BCObjectIdentifiers.qTESLA_III_size);
- noParams.add(BCObjectIdentifiers.qTESLA_III_speed);
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
@@ -367,6 +392,13 @@ public class DefaultSignatureAlgorithmIdentifierFinder
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
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java
index 4d029dd8..b01b3706 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java
@@ -2,11 +2,9 @@ package org.bouncycastle.operator.bc;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.Map;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.ExtendedDigest;
import org.bouncycastle.operator.DigestCalculator;
import org.bouncycastle.operator.DigestCalculatorProvider;
import org.bouncycastle.operator.OperatorCreationException;
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
index b8344587..f219b11b 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
@@ -1,5 +1,6 @@
package org.bouncycastle.operator.jcajce;
+import java.io.IOException;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
@@ -10,12 +11,21 @@ import java.security.SignatureException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PSSParameterSpec;
+import java.util.List;
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERBitString;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.jcajce.CompositePrivateKey;
import org.bouncycastle.jcajce.io.OutputStreamFactory;
+import org.bouncycastle.jcajce.spec.CompositeAlgorithmSpec;
import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
@@ -25,6 +35,8 @@ import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.RuntimeOperatorException;
+import org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder;
+import org.bouncycastle.util.io.TeeOutputStream;
public class JcaContentSignerBuilder
{
@@ -53,6 +65,14 @@ public class JcaContentSignerBuilder
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: "
@@ -84,6 +104,11 @@ public class JcaContentSignerBuilder
public ContentSigner build(PrivateKey privateKey)
throws OperatorCreationException
{
+ if (privateKey instanceof CompositePrivateKey)
+ {
+ return buildComposite((CompositePrivateKey)privateKey);
+ }
+
try
{
final Signature sig = helper.createSignature(sigAlgId);
@@ -131,6 +156,81 @@ public class JcaContentSignerBuilder
}
}
+ private ContentSigner buildComposite(CompositePrivateKey privateKey)
+ throws OperatorCreationException
+ {
+ try
+ {
+ List<PrivateKey> privateKeys = privateKey.getPrivateKeys();
+ final ASN1Sequence sigAlgIds = ASN1Sequence.getInstance(sigAlgId.getParameters());
+ final Signature[] sigs = new Signature[sigAlgIds.size()];
+
+ for (int i = 0; i != sigAlgIds.size(); i++)
+ {
+ sigs[i] = helper.createSignature(AlgorithmIdentifier.getInstance(sigAlgIds.getObjectAt(i)));
+
+ if (random != null)
+ {
+ sigs[i].initSign(privateKeys.get(i), random);
+ }
+ else
+ {
+ sigs[i].initSign(privateKeys.get(i));
+ }
+ }
+
+ OutputStream sStream = OutputStreamFactory.createStream(sigs[0]);
+ for (int i = 1; i != sigs.length; i++)
+ {
+ sStream = new TeeOutputStream(sStream, OutputStreamFactory.createStream(sigs[i]));
+ }
+
+ final OutputStream sigStream = sStream;
+
+ return new ContentSigner()
+ {
+ OutputStream stream = sigStream;
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return sigAlgId;
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return stream;
+ }
+
+ public byte[] getSignature()
+ {
+ try
+ {
+ ASN1EncodableVector sigV = new ASN1EncodableVector();
+
+ for (int i = 0; i != sigs.length; i++)
+ {
+ sigV.add(new DERBitString(sigs[i].sign()));
+ }
+
+ return new DERSequence(sigV).getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeOperatorException("exception encoding signature: " + e.getMessage(), e);
+ }
+ catch (SignatureException e)
+ {
+ throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e);
+ }
+ }
+ };
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new OperatorCreationException("cannot create signer: " + e.getMessage(), e);
+ }
+ }
+
private static RSASSAPSSparams createPSSParams(PSSParameterSpec pssSpec)
{
DigestAlgorithmIdentifierFinder digFinder = new DefaultDigestAlgorithmIdentifierFinder();
@@ -143,4 +243,32 @@ public class JcaContentSignerBuilder
new ASN1Integer(pssSpec.getSaltLength()),
new ASN1Integer(pssSpec.getTrailerField()));
}
+
+ private static ASN1Sequence createCompParams(CompositeAlgorithmSpec compSpec)
+ {
+ SignatureAlgorithmIdentifierFinder algFinder = new DefaultSignatureAlgorithmIdentifierFinder();
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ List<String> algorithmNames = compSpec.getAlgorithmNames();
+ List<AlgorithmParameterSpec> algorithmSpecs = compSpec.getParameterSpecs();
+
+ for (int i = 0; i != algorithmNames.size(); i++)
+ {
+ AlgorithmParameterSpec sigSpec = algorithmSpecs.get(i);
+ if (sigSpec == null)
+ {
+ v.add(algFinder.find(algorithmNames.get(i)));
+ }
+ else if (sigSpec instanceof PSSParameterSpec)
+ {
+ v.add(createPSSParams((PSSParameterSpec)sigSpec));
+ }
+ else
+ {
+ throw new IllegalArgumentException("unrecognized parameterSpec");
+ }
+ }
+
+ return new DERSequence(v);
+ }
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
index 67150bc0..8f2102b4 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
@@ -9,11 +9,16 @@ import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.util.List;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERBitString;
+import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.bouncycastle.jcajce.CompositePublicKey;
import org.bouncycastle.jcajce.io.OutputStreamFactory;
import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
@@ -23,6 +28,7 @@ import org.bouncycastle.operator.ContentVerifierProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.RawContentVerifier;
import org.bouncycastle.operator.RuntimeOperatorException;
+import org.bouncycastle.util.io.TeeOutputStream;
public class JcaContentVerifierProviderBuilder
{
@@ -81,27 +87,34 @@ public class JcaContentVerifierProviderBuilder
public ContentVerifier get(AlgorithmIdentifier algorithm)
throws OperatorCreationException
{
- 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)
+ if (algorithm.getAlgorithm().equals(MiscObjectIdentifiers.id_alg_composite))
{
- return new RawSigVerifier(algorithm, sig, rawSig);
+ return createCompositeVerifier(algorithm, certificate.getPublicKey());
}
else
{
- return new SigVerifier(algorithm, sig);
+ 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);
+ }
}
}
};
@@ -125,17 +138,54 @@ public class JcaContentVerifierProviderBuilder
public ContentVerifier get(AlgorithmIdentifier algorithm)
throws OperatorCreationException
{
- Signature sig = createSignature(algorithm, publicKey);
-
- Signature rawSig = createRawSig(algorithm, publicKey);
+ if (algorithm.getAlgorithm().equals(MiscObjectIdentifiers.id_alg_composite))
+ {
+ return createCompositeVerifier(algorithm, publicKey);
+ }
- if (rawSig != null)
+ if (publicKey instanceof CompositePublicKey)
{
- return new RawSigVerifier(algorithm, sig, rawSig);
+ List<PublicKey> keys = ((CompositePublicKey)publicKey).getPublicKeys();
+
+ for (int i = 0; i != keys.size(); i++)
+ {
+ try
+ {
+ Signature sig = createSignature(algorithm, (PublicKey)keys.get(i));
+
+ Signature rawSig = createRawSig(algorithm, (PublicKey)keys.get(i));
+
+ if (rawSig != null)
+ {
+ return new RawSigVerifier(algorithm, sig, rawSig);
+ }
+ else
+ {
+ return new SigVerifier(algorithm, sig);
+ }
+ }
+ catch (OperatorCreationException e)
+ {
+ // skip incorrect keys
+ }
+ }
+
+ throw new OperatorCreationException("no matching algorithm found for key");
}
else
{
- return new SigVerifier(algorithm, sig);
+ 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);
+ }
}
}
};
@@ -147,6 +197,51 @@ public class JcaContentVerifierProviderBuilder
return this.build(helper.convertPublicKey(publicKey));
}
+ private ContentVerifier createCompositeVerifier(AlgorithmIdentifier compAlgId, PublicKey publicKey)
+ throws OperatorCreationException
+ {
+ if (publicKey instanceof CompositePublicKey)
+ {
+ List<PublicKey> pubKeys = ((CompositePublicKey)publicKey).getPublicKeys();
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(compAlgId.getParameters());
+ Signature[] sigs = new Signature[keySeq.size()];
+ for (int i = 0; i != keySeq.size(); i++)
+ {
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ if (pubKeys.get(i) != null)
+ {
+ sigs[i] = createSignature(sigAlg, (PublicKey)pubKeys.get(i));
+ }
+ else
+ {
+ sigs[i] = null;
+ }
+ }
+
+ return new CompositeVerifier(sigs);
+ }
+ else
+ {
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(compAlgId.getParameters());
+ Signature[] sigs = new Signature[keySeq.size()];
+ for (int i = 0; i != keySeq.size(); i++)
+ {
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ try
+ {
+ sigs[i] = createSignature(sigAlg, publicKey);
+ }
+ catch (Exception e)
+ {
+ sigs[i] = null;
+ // continue
+ }
+ }
+
+ return new CompositeVerifier(sigs);
+ }
+ }
+
private Signature createSignature(AlgorithmIdentifier algorithm, PublicKey publicKey)
throws OperatorCreationException
{
@@ -286,4 +381,70 @@ public class JcaContentVerifierProviderBuilder
}
}
}
+
+ 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/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
index 6e6f0a62..eb8b2d53 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
@@ -24,6 +24,7 @@ import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERNull;
@@ -31,6 +32,8 @@ import org.bouncycastle.asn1.DERNull;
// 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 org.bouncycastle.asn1.kisa.KISAObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
@@ -70,6 +73,8 @@ class OperatorHelper
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");
@@ -85,6 +90,8 @@ class OperatorHelper
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
@@ -353,7 +360,14 @@ class OperatorHelper
try
{
- dig = helper.createDigest(MessageDigestUtils.getDigestName(digAlgId.getAlgorithm()));
+ 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)
{
@@ -364,7 +378,7 @@ class OperatorHelper
{
String digestAlgorithm = (String)oids.get(digAlgId.getAlgorithm());
- dig = helper.createDigest(digestAlgorithm);
+ dig = helper.createMessageDigest(digestAlgorithm);
}
else
{
@@ -378,18 +392,26 @@ class OperatorHelper
Signature createSignature(AlgorithmIdentifier sigAlgId)
throws GeneralSecurityException
{
+ String sigName = getSignatureName(sigAlgId);
Signature sig;
try
{
- sig = helper.createSignature(getSignatureName(sigAlgId));
+ sig = helper.createSignature(sigName);
}
catch (NoSuchAlgorithmException e)
{
//
// try an alternate
//
- if (oids.get(sigAlgId.getAlgorithm()) != null)
+ 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());
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/package.html b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/package.html
index bb47e1a0..cb085598 100644
--- a/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/package.html
+++ b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/package.html
@@ -1,5 +1,5 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
- "http://www.w3.org/TR/html4/loose.dtd">
+ "https://www.w3.org/TR/html4/loose.dtd">
<html>
<body bgcolor="#ffffff">
BC lightweight API extensions and operators for the PKCS#10 certification request package.
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCRLUtil.java b/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCRLUtil.java
index 19e02cea..bf3b7de6 100644
--- a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCRLUtil.java
+++ b/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/PKIXCRLUtil.java
@@ -4,7 +4,6 @@ import java.security.cert.CertStore;
import java.security.cert.CertStoreException;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
-import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
@@ -15,18 +14,18 @@ import org.bouncycastle.jcajce.PKIXCRLStoreSelector;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.StoreException;
-class PKIXCRLUtil
+abstract class PKIXCRLUtil
{
- public Set findCRLs(PKIXCRLStoreSelector crlselect, Date validityDate, List certStores, List pkixCrlStores)
+ static Set findCRLs(PKIXCRLStoreSelector crlselect, Date validityDate, List certStores, List pkixCrlStores)
throws AnnotatedException
{
- Set initialSet = new HashSet();
+ HashSet initialSet = new HashSet();
// get complete CRL(s)
try
{
- initialSet.addAll(findCRLs(crlselect, pkixCrlStores));
- initialSet.addAll(findCRLs(crlselect, certStores));
+ findCRLs(initialSet, crlselect, pkixCrlStores);
+ findCRLs(initialSet, crlselect, certStores);
}
catch (AnnotatedException e)
{
@@ -44,14 +43,7 @@ class PKIXCRLUtil
{
X509Certificate cert = crlselect.getCertificateChecking();
- if (cert != null)
- {
- if (crl.getThisUpdate().before(cert.getNotAfter()))
- {
- finalSet.add(crl);
- }
- }
- else
+ if (null == cert || crl.getThisUpdate().before(cert.getNotAfter()))
{
finalSet.add(crl);
}
@@ -62,35 +54,28 @@ class PKIXCRLUtil
}
/**
- * Return a Collection of all CRLs found in the X509Store's that are
- * matching the crlSelect criteriums.
- *
- * @param crlSelect a {@link PKIXCRLStoreSelector} object that will be used
- * to select the CRLs
- * @param crlStores a List containing only
- * {@link Store} objects.
- * These are used to search for CRLs
+ * Add to a HashSet any and all CRLs found in the X509Store's that are matching the crlSelect
+ * criteria.
*
- * @return a Collection of all found {@link X509CRL X509CRL} objects. May be
- * empty but never <code>null</code>.
+ * @param crls
+ * the {@link HashSet} to add the CRLs to.
+ * @param crlSelect
+ * a {@link PKIXCRLStoreSelector} object that will be used to select the CRLs
+ * @param crlStores
+ * a List containing only {@link Store} objects. These are used to search for CRLs
*/
- private final Collection findCRLs(PKIXCRLStoreSelector crlSelect,
- List crlStores) throws AnnotatedException
+ private static void findCRLs(HashSet crls, PKIXCRLStoreSelector crlSelect, List crlStores) throws AnnotatedException
{
- Set crls = new HashSet();
- Iterator iter = crlStores.iterator();
-
AnnotatedException lastException = null;
boolean foundValidStore = false;
+ Iterator iter = crlStores.iterator();
while (iter.hasNext())
{
Object obj = iter.next();
-
if (obj instanceof Store)
{
Store store = (Store)obj;
-
try
{
crls.addAll(store.getMatches(crlSelect));
@@ -98,14 +83,12 @@ class PKIXCRLUtil
}
catch (StoreException e)
{
- lastException = new AnnotatedException(
- "Exception searching in X.509 CRL store.", e);
+ lastException = new AnnotatedException("Exception searching in X.509 CRL store.", e);
}
}
else
{
CertStore store = (CertStore)obj;
-
try
{
crls.addAll(PKIXCRLStoreSelector.getCRLs(crlSelect, store));
@@ -113,8 +96,7 @@ class PKIXCRLUtil
}
catch (CertStoreException e)
{
- lastException = new AnnotatedException(
- "Exception searching in X.509 CRL store.", e);
+ lastException = new AnnotatedException("Exception searching in X.509 CRL store.", e);
}
}
}
@@ -122,7 +104,5 @@ class PKIXCRLUtil
{
throw lastException;
}
- return crls;
}
-
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RFC3280CertPathUtilities.java b/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RFC3280CertPathUtilities.java
index 728528ac..83b8ddc4 100644
--- a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RFC3280CertPathUtilities.java
+++ b/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RFC3280CertPathUtilities.java
@@ -11,11 +11,11 @@ import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.security.cert.X509Extension;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -38,12 +38,11 @@ import org.bouncycastle.jcajce.PKIXCRLStoreSelector;
import org.bouncycastle.jcajce.PKIXCertStoreSelector;
import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
import org.bouncycastle.jcajce.PKIXExtendedParameters;
+import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.util.Arrays;
class RFC3280CertPathUtilities
{
- private static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil();
-
/**
* If the complete CRL includes an issuing distribution point (IDP) CRL
* extension check the following:
@@ -386,7 +385,7 @@ class RFC3280CertPathUtilities
* @param defaultCRLSignCert The issuer certificate of the certificate <code>cert</code>.
* @param defaultCRLSignKey The public key of the issuer certificate
* <code>defaultCRLSignCert</code>.
- * @param paramsPKIX paramsPKIX PKIX parameters.
+ * @param paramsPKIX PKIX parameters.
* @param certPathCerts The certificates on the certification path.
* @return A <code>Set</code> with all keys of possible CRL issuer
* certificates.
@@ -400,7 +399,7 @@ class RFC3280CertPathUtilities
PublicKey defaultCRLSignKey,
PKIXExtendedParameters paramsPKIX,
List certPathCerts,
- PKIXJcaJceHelper helper)
+ JcaJceHelper helper)
throws AnnotatedException
{
// (f)
@@ -421,11 +420,11 @@ class RFC3280CertPathUtilities
PKIXCertStoreSelector selector = new PKIXCertStoreSelector.Builder(certSelector).build();
// get CRL signing certs
- Collection coll;
+ LinkedHashSet coll = new LinkedHashSet();
try
{
- coll = RevocationUtilities.findCertificates(selector, paramsPKIX.getCertificateStores());
- coll.addAll(RevocationUtilities.findCertificates(selector, paramsPKIX.getCertStores()));
+ RevocationUtilities.findCertificates(coll, selector, paramsPKIX.getCertificateStores());
+ RevocationUtilities.findCertificates(coll, selector, paramsPKIX.getCertStores());
}
catch (AnnotatedException e)
{
@@ -434,11 +433,10 @@ class RFC3280CertPathUtilities
coll.add(defaultCRLSignCert);
- Iterator cert_it = coll.iterator();
-
List validCerts = new ArrayList();
List validKeys = new ArrayList();
+ Iterator cert_it = coll.iterator();
while (cert_it.hasNext())
{
X509Certificate signingCert = (X509Certificate)cert_it.next();
@@ -506,9 +504,9 @@ class RFC3280CertPathUtilities
for (int i = 0; i < validCerts.size(); i++)
{
X509Certificate signCert = (X509Certificate)validCerts.get(i);
- boolean[] keyusage = signCert.getKeyUsage();
+ boolean[] keyUsage = signCert.getKeyUsage();
- if (keyusage != null && (keyusage.length < 7 || !keyusage[CRL_SIGN]))
+ if (keyUsage != null && (keyUsage.length <= CRL_SIGN || !keyUsage[CRL_SIGN]))
{
lastException = new AnnotatedException(
"Issuer certificate key usage extension does not permit CRL signing.");
@@ -582,8 +580,8 @@ class RFC3280CertPathUtilities
}
protected static Set processCRLA1i(
- Date currentDate,
PKIXExtendedParameters paramsPKIX,
+ Date currentDate,
X509Certificate cert,
X509CRL crl)
throws AnnotatedException
@@ -644,13 +642,13 @@ class RFC3280CertPathUtilities
}
protected static Set[] processCRLA1ii(
- Date currentDate,
PKIXExtendedParameters paramsPKIX,
+ Date currentDate,
+ Date validityDate,
X509Certificate cert,
X509CRL crl)
throws AnnotatedException
{
- Set deltaSet = new HashSet();
X509CRLSelector crlselect = new X509CRLSelector();
crlselect.setCertificateChecking(cert);
@@ -665,14 +663,9 @@ class RFC3280CertPathUtilities
PKIXCRLStoreSelector extSelect = new PKIXCRLStoreSelector.Builder(crlselect).setCompleteCRLEnabled(true).build();
- Date validityDate = currentDate;
-
- if (paramsPKIX.getDate() != null)
- {
- validityDate = paramsPKIX.getDate();
- }
-
- Set completeSet = CRL_UTIL.findCRLs(extSelect, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores());
+ Set completeSet = PKIXCRLUtil.findCRLs(extSelect, validityDate, paramsPKIX.getCertStores(),
+ paramsPKIX.getCRLStores());
+ Set deltaSet = new HashSet();
if (paramsPKIX.isUseDeltasEnabled())
{
@@ -686,14 +679,9 @@ class RFC3280CertPathUtilities
throw new AnnotatedException("Exception obtaining delta CRLs.", e);
}
}
- return new Set[]
- {
- completeSet,
- deltaSet};
+ return new Set[]{ completeSet, deltaSet };
}
-
-
/**
* If use-deltas is set, verify the issuer and scope of the delta CRL.
*
@@ -856,18 +844,18 @@ class RFC3280CertPathUtilities
static void checkCRL(
DistributionPoint dp,
PKIXExtendedParameters paramsPKIX,
+ Date currentDate,
+ Date validityDate,
X509Certificate cert,
- Date validDate,
X509Certificate defaultCRLSignCert,
PublicKey defaultCRLSignKey,
CertStatus certStatus,
ReasonsMask reasonMask,
List certPathCerts,
- PKIXJcaJceHelper helper)
+ JcaJceHelper helper)
throws AnnotatedException, CRLNotFoundException
{
- Date currentDate = new Date(System.currentTimeMillis());
- if (validDate.getTime() > currentDate.getTime())
+ if (validityDate.getTime() > currentDate.getTime())
{
throw new AnnotatedException("Validation time is in future.");
}
@@ -880,13 +868,6 @@ class RFC3280CertPathUtilities
* getAdditionalStore()
*/
- Date validityDate = currentDate;
-
- if (paramsPKIX.getDate() != null)
- {
- validityDate = paramsPKIX.getDate();
- }
-
Set crls = RevocationUtilities.getCompleteCRLs(dp, cert, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores());
boolean validCrlFound = false;
AnnotatedException lastException = null;
@@ -964,10 +945,10 @@ class RFC3280CertPathUtilities
RFC3280CertPathUtilities.processCRLC(deltaCRL, crl, paramsPKIX);
// (i)
- RFC3280CertPathUtilities.processCRLI(validDate, deltaCRL, cert, certStatus, paramsPKIX);
+ RFC3280CertPathUtilities.processCRLI(validityDate, deltaCRL, cert, certStatus, paramsPKIX);
// (j)
- RFC3280CertPathUtilities.processCRLJ(validDate, crl, cert, certStatus);
+ RFC3280CertPathUtilities.processCRLJ(validityDate, crl, cert, certStatus);
// (k)
if (certStatus.getCertStatus() == CRLReason.removeFromCRL)
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RevocationUtilities.java b/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RevocationUtilities.java
index 6af44e3b..13548619 100644
--- a/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RevocationUtilities.java
+++ b/bcpkix/src/main/java/org/bouncycastle/pkix/jcajce/RevocationUtilities.java
@@ -2,26 +2,20 @@ package org.bouncycastle.pkix.jcajce;
import java.io.IOException;
import java.math.BigInteger;
-import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.cert.CRLException;
-import java.security.cert.CertPath;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertStore;
import java.security.cert.CertStoreException;
import java.security.cert.Certificate;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.TrustAnchor;
import java.security.cert.X509CRL;
import java.security.cert.X509CRLEntry;
import java.security.cert.X509CRLSelector;
-import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.DSAPublicKeySpec;
-import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -36,18 +30,12 @@ import java.util.Set;
import javax.security.auth.x500.X500Principal;
import org.bouncycastle.asn1.ASN1Enumerated;
-import org.bouncycastle.asn1.ASN1GeneralizedTime;
-import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.DEROctetString;
-import org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.style.RFC4519Style;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
import org.bouncycastle.asn1.x509.CRLDistPoint;
import org.bouncycastle.asn1.x509.CRLReason;
import org.bouncycastle.asn1.x509.DistributionPoint;
@@ -56,10 +44,8 @@ import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.IssuingDistributionPoint;
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.jcajce.PKIXCRLStore;
import org.bouncycastle.jcajce.PKIXCRLStoreSelector;
-import org.bouncycastle.jcajce.PKIXCertStore;
import org.bouncycastle.jcajce.PKIXCertStoreSelector;
import org.bouncycastle.jcajce.PKIXExtendedParameters;
import org.bouncycastle.jcajce.util.JcaJceHelper;
@@ -69,257 +55,34 @@ import org.bouncycastle.util.StoreException;
class RevocationUtilities
{
- protected static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil();
-
- protected static final String CERTIFICATE_POLICIES = Extension.certificatePolicies.getId();
- protected static final String BASIC_CONSTRAINTS = Extension.basicConstraints.getId();
- protected static final String POLICY_MAPPINGS = Extension.policyMappings.getId();
- protected static final String SUBJECT_ALTERNATIVE_NAME = Extension.subjectAlternativeName.getId();
- protected static final String NAME_CONSTRAINTS = Extension.nameConstraints.getId();
- protected static final String KEY_USAGE = Extension.keyUsage.getId();
- protected static final String INHIBIT_ANY_POLICY = Extension.inhibitAnyPolicy.getId();
protected static final String ISSUING_DISTRIBUTION_POINT = Extension.issuingDistributionPoint.getId();
- protected static final String DELTA_CRL_INDICATOR = Extension.deltaCRLIndicator.getId();
- protected static final String POLICY_CONSTRAINTS = Extension.policyConstraints.getId();
- protected static final String FRESHEST_CRL = Extension.freshestCRL.getId();
- protected static final String CRL_DISTRIBUTION_POINTS = Extension.cRLDistributionPoints.getId();
- protected static final String AUTHORITY_KEY_IDENTIFIER = Extension.authorityKeyIdentifier.getId();
-
- protected static final String ANY_POLICY = "2.5.29.32.0";
-
- protected static final String CRL_NUMBER = Extension.cRLNumber.getId();
-
- /*
- * key usage bits
- */
- protected static final int KEY_CERT_SIGN = 5;
- protected static final int CRL_SIGN = 6;
-
- protected static final String[] crlReasons = new String[]{
- "unspecified",
- "keyCompromise",
- "cACompromise",
- "affiliationChanged",
- "superseded",
- "cessationOfOperation",
- "certificateHold",
- "unknown",
- "removeFromCRL",
- "privilegeWithdrawn",
- "aACompromise"};
-
- /**
- * Search the given Set of TrustAnchor's for one that is the
- * issuer of the given X509 certificate. Uses the default provider
- * for signature verification.
- *
- * @param cert the X509 certificate
- * @param trustAnchors a Set of TrustAnchor's
- * @return the <code>TrustAnchor</code> object if found or
- * <code>null</code> if not.
- * @throws AnnotatedException if a TrustAnchor was found but the signature verification
- * on the given certificate has thrown an exception.
- */
- protected static TrustAnchor findTrustAnchor(
- X509Certificate cert,
- Set trustAnchors)
- throws AnnotatedException
- {
- return findTrustAnchor(cert, trustAnchors, null);
- }
-
- /**
- * Search the given Set of TrustAnchor's for one that is the
- * issuer of the given X509 certificate. Uses the specified
- * provider for signature verification, or the default provider
- * if null.
- *
- * @param cert the X509 certificate
- * @param trustAnchors a Set of TrustAnchor's
- * @param sigProvider the provider to use for signature verification
- * @return the <code>TrustAnchor</code> object if found or
- * <code>null</code> if not.
- * @throws AnnotatedException if a TrustAnchor was found but the signature verification
- * on the given certificate has thrown an exception.
- */
- protected static TrustAnchor findTrustAnchor(
- X509Certificate cert,
- Set trustAnchors,
- String sigProvider)
- throws AnnotatedException
- {
- TrustAnchor trust = null;
- PublicKey trustPublicKey = null;
- Exception invalidKeyEx = null;
-
- X509CertSelector certSelectX509 = new X509CertSelector();
- X500Name certIssuer = X500Name.getInstance(cert.getIssuerX500Principal());
-
- try
- {
- certSelectX509.setSubject(certIssuer.getEncoded());
- }
- catch (IOException ex)
- {
- throw new AnnotatedException("Cannot set subject search criteria for trust anchor.", ex);
- }
-
- Iterator iter = trustAnchors.iterator();
- while (iter.hasNext() && trust == null)
- {
- trust = (TrustAnchor)iter.next();
- if (trust.getTrustedCert() != null)
- {
- if (certSelectX509.match(trust.getTrustedCert()))
- {
- trustPublicKey = trust.getTrustedCert().getPublicKey();
- }
- else
- {
- trust = null;
- }
- }
- else if (trust.getCAName() != null
- && trust.getCAPublicKey() != null)
- {
- try
- {
- X500Name caName = X500Name.getInstance(trust.getCA().getEncoded());
- if (certIssuer.equals(caName))
- {
- trustPublicKey = trust.getCAPublicKey();
- }
- else
- {
- trust = null;
- }
- }
- catch (IllegalArgumentException ex)
- {
- trust = null;
- }
- }
- else
- {
- trust = null;
- }
-
- if (trustPublicKey != null)
- {
- try
- {
- verifyX509Certificate(cert, trustPublicKey, sigProvider);
- }
- catch (Exception ex)
- {
- invalidKeyEx = ex;
- trust = null;
- trustPublicKey = null;
- }
- }
- }
-
- if (trust == null && invalidKeyEx != null)
- {
- throw new AnnotatedException("TrustAnchor found but certificate validation failed.", invalidKeyEx);
- }
-
- return trust;
- }
-
- static boolean isIssuerTrustAnchor(
- X509Certificate cert,
- Set trustAnchors,
- String sigProvider)
- throws AnnotatedException
- {
- try
- {
- return findTrustAnchor(cert, trustAnchors, sigProvider) != null;
- }
- catch (Exception e)
- {
- return false;
- }
- }
-
- static List<PKIXCertStore> getAdditionalStoresFromAltNames(
- byte[] issuerAlternativeName,
- Map<GeneralName, PKIXCertStore> altNameCertStoreMap)
- throws CertificateParsingException
- {
- // if in the IssuerAltName extension an URI
- // is given, add an additional X.509 store
- if (issuerAlternativeName != null)
- {
- GeneralNames issuerAltName = GeneralNames.getInstance(ASN1OctetString.getInstance(issuerAlternativeName).getOctets());
-
- GeneralName[] names = issuerAltName.getNames();
- List<PKIXCertStore> stores = new ArrayList<PKIXCertStore>();
-
- for (int i = 0; i != names.length; i++)
- {
- GeneralName altName = names[i];
-
- PKIXCertStore altStore = altNameCertStoreMap.get(altName);
-
- if (altStore != null)
- {
- stores.add(altStore);
- }
- }
-
- return stores;
- }
- else
- {
- return Collections.EMPTY_LIST;
- }
- }
- protected static Date getValidDate(PKIXExtendedParameters paramsPKIX)
+ protected static Date getValidityDate(PKIXExtendedParameters paramsPKIX, Date currentDate)
{
- Date validDate = paramsPKIX.getDate();
+ Date validityDate = paramsPKIX.getValidityDate();
- if (validDate == null)
- {
- validDate = new Date();
- }
-
- return validDate;
+ return null == validityDate ? currentDate : validityDate;
}
- protected static boolean isSelfIssued(X509Certificate cert)
- {
- return cert.getSubjectDN().equals(cert.getIssuerDN());
- }
-
-
/**
* Extract the value of the given extension, if it exists.
*
- * @param ext The extension object.
- * @param oid The object identifier to obtain.
- * @throws AnnotatedException if the extension cannot be read.
+ * @param ext
+ * The extension object.
+ * @param oid
+ * The object identifier to obtain.
+ * @throws AnnotatedException
+ * if the extension cannot be read.
*/
- protected static ASN1Primitive getExtensionValue(
- java.security.cert.X509Extension ext,
- ASN1ObjectIdentifier oid)
+ protected static ASN1Primitive getExtensionValue(java.security.cert.X509Extension ext, ASN1ObjectIdentifier oid)
throws AnnotatedException
{
byte[] bytes = ext.getExtensionValue(oid.getId());
- if (bytes == null)
- {
- return null;
- }
- return getObject(oid, bytes);
+ return null == bytes ? null : getObject(oid, bytes);
}
- private static ASN1Primitive getObject(
- ASN1ObjectIdentifier oid,
- byte[] ext)
- throws AnnotatedException
+ private static ASN1Primitive getObject(ASN1ObjectIdentifier oid, byte[] ext) throws AnnotatedException
{
try
{
@@ -331,44 +94,24 @@ class RevocationUtilities
}
}
- protected static AlgorithmIdentifier getAlgorithmIdentifier(
- PublicKey key)
- throws CertPathValidatorException
- {
- try
- {
- ASN1InputStream aIn = new ASN1InputStream(key.getEncoded());
-
- SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(aIn.readObject());
-
- return info.getAlgorithm();
- }
- catch (Exception e)
- {
- throw new CertPathValidatorException("subject public key cannot be decoded", e);
- }
- }
-
- // crl checking
-
/**
- * Return a Collection of all certificates or attribute certificates found
- * in the X509Store's that are matching the certSelect criteriums.
+ * Add to a LinkedHashSet all certificates or attribute certificates found in the X509Store's
+ * that are matching the certSelect criteria.
*
- * @param certSelect a {@link Selector} object that will be used to select
- * the certificates
- * @param certStores a List containing only {@link Store} objects. These
- * are used to search for certificates.
- * @return a Collection of all found {@link X509Certificate}
- * May be empty but never <code>null</code>.
+ * @param certs
+ * a {@link LinkedHashSet} to which the certificates will be added.
+ * @param certSelect
+ * a {@link Selector} object that will be used to select the certificates
+ * @param certStores
+ * a List containing only {@link Store} objects. These are used to search for
+ * certificates.
+ * @return a Collection of all found {@link X509Certificate} May be empty but never
+ * <code>null</code>.
*/
- protected static Collection findCertificates(PKIXCertStoreSelector certSelect,
- List certStores)
+ protected static void findCertificates(LinkedHashSet certs, PKIXCertStoreSelector certSelect, List certStores)
throws AnnotatedException
{
- Set certs = new LinkedHashSet();
Iterator iter = certStores.iterator();
-
while (iter.hasNext())
{
Object obj = iter.next();
@@ -382,75 +125,64 @@ class RevocationUtilities
}
catch (StoreException e)
{
- throw new AnnotatedException(
- "Problem while picking certificates from X.509 store.", e);
+ throw new AnnotatedException("Problem while picking certificates from X.509 store.", e);
}
}
else
{
CertStore certStore = (CertStore)obj;
-
try
{
certs.addAll(PKIXCertStoreSelector.getCertificates(certSelect, certStore));
}
catch (CertStoreException e)
{
- throw new AnnotatedException(
- "Problem while picking certificates from certificate store.",
- e);
+ throw new AnnotatedException("Problem while picking certificates from certificate store.", e);
}
}
}
- return certs;
}
- static List<PKIXCRLStore> getAdditionalStoresFromCRLDistributionPoint(CRLDistPoint crldp, Map<GeneralName, PKIXCRLStore> namedCRLStoreMap)
- throws AnnotatedException
+ static List<PKIXCRLStore> getAdditionalStoresFromCRLDistributionPoint(CRLDistPoint crldp,
+ Map<GeneralName, PKIXCRLStore> namedCRLStoreMap) throws AnnotatedException
{
- if (crldp != null)
+ if (crldp == null)
{
- DistributionPoint dps[] = null;
- try
- {
- dps = crldp.getDistributionPoints();
- }
- catch (Exception e)
- {
- throw new AnnotatedException(
- "Distribution points could not be read.", e);
- }
- List<PKIXCRLStore> stores = new ArrayList<PKIXCRLStore>();
+ return Collections.emptyList();
+ }
+
+ DistributionPoint dps[];
+ try
+ {
+ dps = crldp.getDistributionPoints();
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("Distribution points could not be read.", e);
+ }
+
+ List<PKIXCRLStore> stores = new ArrayList<PKIXCRLStore>();
- for (int i = 0; i < dps.length; i++)
+ for (int i = 0; i < dps.length; i++)
+ {
+ DistributionPointName dpn = dps[i].getDistributionPoint();
+ // look for URIs in fullName
+ if (dpn != null && dpn.getType() == DistributionPointName.FULL_NAME)
{
- DistributionPointName dpn = dps[i].getDistributionPoint();
- // look for URIs in fullName
- if (dpn != null)
+ GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames();
+
+ for (int j = 0; j < genNames.length; j++)
{
- if (dpn.getType() == DistributionPointName.FULL_NAME)
+ PKIXCRLStore store = namedCRLStoreMap.get(genNames[j]);
+ if (store != null)
{
- GeneralName[] genNames = GeneralNames.getInstance(
- dpn.getName()).getNames();
-
- for (int j = 0; j < genNames.length; j++)
- {
- PKIXCRLStore store = namedCRLStoreMap.get(genNames[j]);
- if (store != null)
- {
- stores.add(store);
- }
- }
+ stores.add(store);
}
}
}
-
- return stores;
- }
- else
- {
- return Collections.EMPTY_LIST;
}
+
+ return stores;
}
/**
@@ -469,11 +201,8 @@ class RevocationUtilities
* @throws ClassCastException if <code>issuerPrincipals</code> does not
* contain only <code>X500Name</code>s.
*/
- protected static void getCRLIssuersFromDistributionPoint(
- DistributionPoint dp,
- Collection issuerPrincipals,
- X509CRLSelector selector)
- throws AnnotatedException
+ protected static void getCRLIssuersFromDistributionPoint(DistributionPoint dp, Collection issuerPrincipals,
+ X509CRLSelector selector) throws AnnotatedException
{
List issuers = new ArrayList();
// indirect CRL
@@ -487,14 +216,12 @@ class RevocationUtilities
{
try
{
- issuers.add(X500Name.getInstance(genNames[j].getName()
- .toASN1Primitive().getEncoded()));
+ issuers.add(X500Name.getInstance(genNames[j].getName()));
}
- catch (IOException e)
+ catch (IllegalArgumentException e)
{
throw new AnnotatedException(
- "CRL issuer information from distribution point cannot be decoded.",
- e);
+ "CRL issuer information from distribution point cannot be decoded.", e);
}
}
}
@@ -575,21 +302,9 @@ class RevocationUtilities
}
}
- private static BigInteger getSerialNumber(
- Object cert)
- {
- return ((X509Certificate)cert).getSerialNumber();
- }
-
- protected static void getCertStatus(
- Date validDate,
- X509CRL crl,
- Object cert,
- CertStatus certStatus)
+ protected static void getCertStatus(Date validDate, X509CRL crl, Object cert, CertStatus certStatus)
throws AnnotatedException
{
- X509CRLEntry crl_entry = null;
-
boolean isIndirect;
try
{
@@ -600,119 +315,113 @@ class RevocationUtilities
throw new AnnotatedException("Failed check for indirect CRL.", exception);
}
- if (isIndirect)
- {
- crl_entry = crl.getRevokedCertificate(getSerialNumber(cert));
+ X509Certificate x509Cert = (X509Certificate)cert;
+ X500Name x509CertIssuer = getIssuer(x509Cert);
- if (crl_entry == null)
+ if (!isIndirect)
+ {
+ X500Name crlIssuer = getIssuer(crl);
+ if (!x509CertIssuer.equals(crlIssuer))
{
return;
}
+ }
+
+ X509CRLEntry crl_entry = crl.getRevokedCertificate(x509Cert.getSerialNumber());
+ if (null == crl_entry)
+ {
+ return;
+ }
+ if (isIndirect)
+ {
X500Principal certificateIssuer = crl_entry.getCertificateIssuer();
- X500Name certIssuer;
- if (certificateIssuer == null)
+ X500Name expectedCertIssuer;
+ if (null == certificateIssuer)
{
- certIssuer = X500Name.getInstance(crl.getIssuerX500Principal());
+ expectedCertIssuer = getIssuer(crl);
}
else
{
- certIssuer = X500Name.getInstance(certificateIssuer.getEncoded());
+ expectedCertIssuer = getX500Name(certificateIssuer);
}
- if (!X500Name.getInstance(((X509Certificate)cert).getIssuerX500Principal().getEncoded()).equals(certIssuer))
+ if (!x509CertIssuer.equals(expectedCertIssuer))
{
return;
}
}
- else if (!X500Name.getInstance(((X509Certificate)cert).getIssuerX500Principal().getEncoded()).equals(X500Name.getInstance(crl.getIssuerX500Principal().getEncoded())))
- {
- return; // not for our issuer, ignore
- }
- else
- {
- crl_entry = crl.getRevokedCertificate(getSerialNumber(cert));
- if (crl_entry == null)
- {
- return;
- }
- }
+ int reasonCodeValue = CRLReason.unspecified;
- ASN1Enumerated reasonCode = null;
if (crl_entry.hasExtensions())
{
try
{
- reasonCode = ASN1Enumerated
- .getInstance(RevocationUtilities
- .getExtensionValue(crl_entry,
- Extension.reasonCode));
+ ASN1Primitive extValue = RevocationUtilities.getExtensionValue(crl_entry, Extension.reasonCode);
+ ASN1Enumerated reasonCode = ASN1Enumerated.getInstance(extValue);
+ if (null != reasonCode)
+ {
+ reasonCodeValue = reasonCode.intValueExact();
+ }
}
catch (Exception e)
{
- throw new AnnotatedException(
- "Reason code CRL entry extension could not be decoded.",
- e);
+ throw new AnnotatedException("Reason code CRL entry extension could not be decoded.", e);
}
}
- // for reason keyCompromise, caCompromise, aACompromise or
- // unspecified
- if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime())
- || reasonCode == null
- || reasonCode.getValue().intValue() == 0
- || reasonCode.getValue().intValue() == 1
- || reasonCode.getValue().intValue() == 2
- || reasonCode.getValue().intValue() == 8)
- {
+ Date revocationDate = crl_entry.getRevocationDate();
- // (i) or (j) (1)
- if (reasonCode != null)
- {
- certStatus.setCertStatus(reasonCode.getValue().intValue());
- }
- // (i) or (j) (2)
- else
+ if (validDate.before(revocationDate))
+ {
+ switch (reasonCodeValue)
{
- certStatus.setCertStatus(CRLReason.unspecified);
+ case CRLReason.unspecified:
+ case CRLReason.keyCompromise:
+ case CRLReason.cACompromise:
+ case CRLReason.aACompromise:
+ break;
+ default:
+ return;
}
- certStatus.setRevocationDate(crl_entry.getRevocationDate());
}
+
+ // (i) or (j)
+ certStatus.setCertStatus(reasonCodeValue);
+ certStatus.setRevocationDate(revocationDate);
}
/**
* Fetches delta CRLs according to RFC 3280 section 5.2.4.
*
- * @param validityDate The date for which the delta CRLs must be valid.
- * @param completeCRL The complete CRL the delta CRL is for.
+ * @param validityDate
+ * The date for which the delta CRLs must be valid.
+ * @param completeCRL
+ * The complete CRL the delta CRL is for.
* @return A <code>Set</code> of <code>X509CRL</code>s with delta CRLs.
- * @throws AnnotatedException if an exception occurs while picking the delta
- * CRLs.
+ * @throws AnnotatedException
+ * if an exception occurs while picking the delta CRLs.
*/
- protected static Set getDeltaCRLs(Date validityDate,
- X509CRL completeCRL, List<CertStore> certStores, List<PKIXCRLStore> pkixCrlStores)
- throws AnnotatedException
+ protected static Set getDeltaCRLs(Date validityDate, X509CRL completeCRL, List<CertStore> certStores,
+ List<PKIXCRLStore> pkixCrlStores) throws AnnotatedException
{
X509CRLSelector baseDeltaSelect = new X509CRLSelector();
// 5.2.4 (a)
try
{
- baseDeltaSelect.addIssuerName(X500Name.getInstance(completeCRL.getIssuerX500Principal().getEncoded()).getEncoded());
+ baseDeltaSelect.addIssuerName(completeCRL.getIssuerX500Principal().getEncoded());
}
catch (IOException e)
{
throw new AnnotatedException("cannot extract issuer from CRL.", e);
}
-
-
BigInteger completeCRLNumber = null;
try
{
- ASN1Primitive derObject = RevocationUtilities.getExtensionValue(completeCRL,
- Extension.cRLNumber);
+ ASN1Primitive derObject = RevocationUtilities.getExtensionValue(completeCRL, Extension.cRLNumber);
if (derObject != null)
{
completeCRLNumber = ASN1Integer.getInstance(derObject).getPositiveValue();
@@ -725,16 +434,14 @@ class RevocationUtilities
}
// 5.2.4 (b)
- byte[] idp = null;
+ byte[] idp;
try
{
idp = completeCRL.getExtensionValue(ISSUING_DISTRIBUTION_POINT);
}
catch (Exception e)
{
- throw new AnnotatedException(
- "issuing distribution point extension value could not be read",
- e);
+ throw new AnnotatedException("issuing distribution point extension value could not be read", e);
}
// 5.2.4 (d)
@@ -753,7 +460,7 @@ class RevocationUtilities
PKIXCRLStoreSelector deltaSelect = selBuilder.build();
// find delta CRLs
- Set temp = CRL_UTIL.findCRLs(deltaSelect, validityDate, certStores, pkixCrlStores);
+ Set temp = PKIXCRLUtil.findCRLs(deltaSelect, validityDate, certStores, pkixCrlStores);
Set result = new HashSet();
@@ -774,24 +481,19 @@ class RevocationUtilities
{
Set critical = crl.getCriticalExtensionOIDs();
- if (critical == null)
- {
- return false;
- }
-
- return critical.contains(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR);
+ return null == critical ? false : critical.contains(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR);
}
/**
* Fetches complete CRLs according to RFC 3280.
*
- * @param dp The distribution point for which the complete CRL
- * @param cert The <code>X509Certificate</code> for
- * which the CRL should be searched.
- * @return A <code>Set</code> of <code>X509CRL</code>s with complete
- * CRLs.
- * @throws AnnotatedException if an exception occurs while picking the CRLs
- * or no CRLs are found.
+ * @param dp
+ * The distribution point for which the complete CRL
+ * @param cert
+ * The <code>X509Certificate</code> for which the CRL should be searched.
+ * @return A <code>Set</code> of <code>X509CRL</code>s with complete CRLs.
+ * @throws AnnotatedException
+ * if an exception occurs while picking the CRLs or no CRLs are found.
*/
protected static Set getCompleteCRLs(DistributionPoint dp, Object cert, Date validityDate, List certStores, List crlStores)
throws AnnotatedException, CRLNotFoundException
@@ -801,8 +503,7 @@ class RevocationUtilities
try
{
Set issuers = new HashSet();
-
- issuers.add(X500Name.getInstance(((X509Certificate)cert).getIssuerX500Principal().getEncoded()));
+ issuers.add(getIssuer((X509Certificate)cert));
RevocationUtilities.getCRLIssuersFromDistributionPoint(dp, issuers, baseCrlSelect);
}
@@ -819,77 +520,13 @@ class RevocationUtilities
PKIXCRLStoreSelector crlSelect = new PKIXCRLStoreSelector.Builder(baseCrlSelect).setCompleteCRLEnabled(true).build();
- Set crls = CRL_UTIL.findCRLs(crlSelect, validityDate, certStores, crlStores);
+ Set crls = PKIXCRLUtil.findCRLs(crlSelect, validityDate, certStores, crlStores);
checkCRLsNotEmpty(crls, cert);
return crls;
}
- protected static Date getValidCertDateFromValidityModel(
- PKIXExtendedParameters paramsPKIX, CertPath certPath, int index)
- throws AnnotatedException
- {
- if (paramsPKIX.getValidityModel() == PKIXExtendedParameters.CHAIN_VALIDITY_MODEL)
- {
- // if end cert use given signing/encryption/... time
- if (index <= 0)
- {
- return RevocationUtilities.getValidDate(paramsPKIX);
- // else use time when previous cert was created
- }
- else
- {
- if (index - 1 == 0)
- {
- ASN1GeneralizedTime dateOfCertgen = null;
- try
- {
- byte[] extBytes = ((X509Certificate)certPath.getCertificates().get(index - 1)).getExtensionValue(ISISMTTObjectIdentifiers.id_isismtt_at_dateOfCertGen.getId());
- if (extBytes != null)
- {
- dateOfCertgen = ASN1GeneralizedTime.getInstance(ASN1Primitive.fromByteArray(extBytes));
- }
- }
- catch (IOException e)
- {
- throw new AnnotatedException(
- "Date of cert gen extension could not be read.");
- }
- catch (IllegalArgumentException e)
- {
- throw new AnnotatedException(
- "Date of cert gen extension could not be read.");
- }
- if (dateOfCertgen != null)
- {
- try
- {
- return dateOfCertgen.getDate();
- }
- catch (ParseException e)
- {
- throw new AnnotatedException(
- "Date from date of cert gen extension could not be parsed.",
- e);
- }
- }
- return ((X509Certificate)certPath.getCertificates().get(
- index - 1)).getNotBefore();
- }
- else
- {
- return ((X509Certificate)certPath.getCertificates().get(
- index - 1)).getNotBefore();
- }
- }
- }
- else
- {
- return getValidDate(paramsPKIX);
- }
- }
-
/**
* Return the next working key inheriting DSA parameters if necessary.
* <p>
@@ -955,94 +592,6 @@ class RevocationUtilities
throw new CertPathValidatorException("DSA parameters cannot be inherited from previous certificate.");
}
- /**
- * Find the issuer certificates of a given certificate.
- *
- * @param cert The certificate for which an issuer should be found.
- * @return A <code>Collection</code> object containing the issuer
- * <code>X509Certificate</code>s. Never <code>null</code>.
- * @throws AnnotatedException if an error occurs.
- */
- static Collection findIssuerCerts(
- X509Certificate cert,
- List<CertStore> certStores,
- List<PKIXCertStore> pkixCertStores)
- throws AnnotatedException
- {
- X509CertSelector selector = new X509CertSelector();
-
- try
- {
- selector.setSubject(((X509Certificate)cert).getIssuerX500Principal().getEncoded());
- }
- catch (IOException e)
- {
- throw new AnnotatedException(
- "Subject criteria for certificate selector to find issuer certificate could not be set.", e);
- }
-
- try
- {
- byte[] akiExtensionValue = cert.getExtensionValue(AUTHORITY_KEY_IDENTIFIER);
- if (akiExtensionValue != null)
- {
- ASN1OctetString aki = ASN1OctetString.getInstance(akiExtensionValue);
- byte[] authorityKeyIdentifier = AuthorityKeyIdentifier.getInstance(aki.getOctets()).getKeyIdentifier();
- if (authorityKeyIdentifier != null)
- {
- selector.setSubjectKeyIdentifier(new DEROctetString(authorityKeyIdentifier).getEncoded());
- }
- }
- }
- catch (Exception e)
- {
- // authority key identifier could not be retrieved from target cert, just search without it
- }
-
- PKIXCertStoreSelector certSelect = new PKIXCertStoreSelector.Builder(selector).build();
- Set certs = new LinkedHashSet();
-
- Iterator iter;
-
- try
- {
- List matches = new ArrayList();
-
- matches.addAll(RevocationUtilities.findCertificates(certSelect, certStores));
- matches.addAll(RevocationUtilities.findCertificates(certSelect, pkixCertStores));
-
- iter = matches.iterator();
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Issuer certificate cannot be searched.", e);
- }
-
- X509Certificate issuer = null;
- while (iter.hasNext())
- {
- issuer = (X509Certificate)iter.next();
- // issuer cannot be verified because possible DSA inheritance
- // parameters are missing
- certs.add(issuer);
- }
- return certs;
- }
-
- protected static void verifyX509Certificate(X509Certificate cert, PublicKey publicKey,
- String sigProvider)
- throws GeneralSecurityException
- {
- if (sigProvider == null)
- {
- cert.verify(publicKey);
- }
- else
- {
- cert.verify(publicKey, sigProvider);
- }
- }
-
static void checkCRLsNotEmpty(Set crls, Object cert)
throws CRLNotFoundException
{
@@ -1056,15 +605,15 @@ class RevocationUtilities
// }
// else
{
- X509Certificate xCert = (X509Certificate)cert;
+ X500Name certIssuer = getIssuer((X509Certificate)cert);
- throw new CRLNotFoundException("No CRLs found for issuer \"" + RFC4519Style.INSTANCE.toString(X500Name.getInstance(((X509Certificate)xCert).getIssuerX500Principal().getEncoded())) + "\"");
+ throw new CRLNotFoundException(
+ "No CRLs found for issuer \"" + RFC4519Style.INSTANCE.toString(certIssuer) + "\"");
}
}
}
- public static boolean isIndirectCRL(X509CRL crl)
- throws CRLException
+ public static boolean isIndirectCRL(X509CRL crl) throws CRLException
{
try
{
@@ -1074,8 +623,22 @@ class RevocationUtilities
}
catch (Exception e)
{
- throw new CRLException(
- "exception reading IssuingDistributionPoint", e);
+ throw new CRLException("exception reading IssuingDistributionPoint", e);
}
}
+
+ private static X500Name getIssuer(X509Certificate cert)
+ {
+ return getX500Name(cert.getIssuerX500Principal());
+ }
+
+ private static X500Name getIssuer(X509CRL crl)
+ {
+ return getX500Name(crl.getIssuerX500Principal());
+ }
+
+ private static X500Name getX500Name(X500Principal principal)
+ {
+ return X500Name.getInstance(principal.getEncoded());
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
index 770af15c..ac5db1c1 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
@@ -154,17 +154,17 @@ public abstract class ASN1ApplicationSpecific
/* (non-Javadoc)
* @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
*/
- void encode(ASN1OutputStream out) throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- int classBits = BERTags.APPLICATION;
+ int flags = BERTags.APPLICATION;
if (isConstructed)
{
- classBits |= BERTags.CONSTRUCTED;
+ flags |= BERTags.CONSTRUCTED;
}
- out.writeEncoded(classBits, tag, octets);
+ out.writeEncoded(withTag, flags, tag, octets);
}
-
+
boolean asn1Equals(
ASN1Primitive o)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitString.java
index e1aba657..95abee1a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitString.java
@@ -1,6 +1,5 @@
package org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
@@ -100,6 +99,17 @@ public abstract class ASN1BitString
return result;
}
+ protected ASN1BitString(byte data, int padBits)
+ {
+ if (padBits > 7 || padBits < 0)
+ {
+ throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
+ }
+
+ this.data = new byte[]{ data };
+ this.padBits = padBits;
+ }
+
/**
* Base constructor.
*
@@ -112,7 +122,7 @@ public abstract class ASN1BitString
{
if (data == null)
{
- throw new NullPointerException("data cannot be null");
+ throw new NullPointerException("'data' cannot be null");
}
if (data.length == 0 && padBits != 0)
{
@@ -134,21 +144,18 @@ public abstract class ASN1BitString
*/
public String getString()
{
- StringBuffer buf = new StringBuffer("#");
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
+ StringBuffer buf = new StringBuffer("#");
+ byte[] string;
try
{
- aOut.writeObject(this);
+ string = getEncoded();
}
catch (IOException e)
{
throw new ASN1ParsingException("Internal error encoding BitString: " + e.getMessage(), e);
}
- byte[] string = bOut.toByteArray();
-
for (int i = 0; i != string.length; i++)
{
buf.append(table[(string[i] >>> 4) & 0xf]);
@@ -164,18 +171,16 @@ public abstract class ASN1BitString
public int intValue()
{
int value = 0;
- byte[] string = data;
-
- if (padBits > 0 && data.length <= 4)
+ int end = Math.min(4, data.length - 1);
+ for (int i = 0; i < end; ++i)
{
- string = derForm(data, padBits);
+ value |= (data[i] & 0xFF) << (8 * i);
}
-
- for (int i = 0; i != string.length && i != 4; i++)
+ if (0 <= end && end < 4)
{
- value |= (string[i] & 0xff) << (8 * i);
+ byte der = (byte)(data[end] & (0xFF << padBits));
+ value |= (der & 0xFF) << (8 * end);
}
-
return value;
}
@@ -198,7 +203,15 @@ public abstract class ASN1BitString
public byte[] getBytes()
{
- return derForm(data, padBits);
+ if (0 == data.length)
+ {
+ return data;
+ }
+
+ byte[] rv = Arrays.clone(data);
+ // DER requires pad bits be zero
+ rv[data.length - 1] &= (0xFF << padBits);
+ return rv;
}
public int getPadBits()
@@ -213,10 +226,21 @@ public abstract class ASN1BitString
public int hashCode()
{
- return padBits ^ Arrays.hashCode(this.getBytes());
+ int end = data.length;
+ if (--end < 0)
+ {
+ return 1;
+ }
+
+ byte der = (byte)(data[end] & (0xFF << padBits));
+
+ int hc = Arrays.hashCode(data, 0, end);
+ hc *= 257;
+ hc ^= der;
+ return hc ^ padBits;
}
- protected boolean asn1Equals(
+ boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof ASN1BitString))
@@ -225,21 +249,32 @@ public abstract class ASN1BitString
}
ASN1BitString other = (ASN1BitString)o;
-
- return this.padBits == other.padBits
- && Arrays.areEqual(this.getBytes(), other.getBytes());
- }
-
- protected static byte[] derForm(byte[] data, int padBits)
- {
- byte[] rv = Arrays.clone(data);
- // DER requires pad bits be zero
- if (padBits > 0)
+ if (padBits != other.padBits)
+ {
+ return false;
+ }
+ byte[] a = data, b = other.data;
+ int end = a.length;
+ if (end != b.length)
+ {
+ return false;
+ }
+ if (--end < 0)
+ {
+ return true;
+ }
+ for (int i = 0; i < end; ++i)
{
- rv[data.length - 1] &= 0xff << padBits;
+ if (a[i] != b[i])
+ {
+ return false;
+ }
}
- return rv;
+ byte derA = (byte)(a[end] & (0xFF << padBits));
+ byte derB = (byte)(b[end] & (0xFF << padBits));
+
+ return derA == derB;
}
static ASN1BitString fromInputStream(int length, InputStream stream)
@@ -262,7 +297,7 @@ public abstract class ASN1BitString
if (padBits > 0 && padBits < 8)
{
- if (data[data.length - 1] != (byte)(data[data.length - 1] & (0xff << padBits)))
+ if (data[data.length - 1] != (byte)(data[data.length - 1] & (0xFF << padBits)))
{
return new DLBitString(data, padBits);
}
@@ -287,6 +322,5 @@ public abstract class ASN1BitString
return new DLBitString(data, padBits);
}
- abstract void encode(ASN1OutputStream out)
- throws IOException;
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Boolean.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Boolean.java
index e968660f..93b40ec5 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Boolean.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Boolean.java
@@ -2,12 +2,10 @@ package org.bouncycastle.asn1;
import java.io.IOException;
-import org.bouncycastle.util.Arrays;
-
/**
* Public facade of ASN.1 Boolean data.
* <p>
- * Use following to place a new instance of ASN.1 Boolean in your dataset:
+ * Use following to place a new instance of ASN.1 Boolean in your data:
* <ul>
* <li> ASN1Boolean.TRUE literal</li>
* <li> ASN1Boolean.FALSE literal</li>
@@ -18,13 +16,13 @@ import org.bouncycastle.util.Arrays;
public class ASN1Boolean
extends ASN1Primitive
{
- private static final byte[] TRUE_VALUE = new byte[] { (byte)0xff };
- private static final byte[] FALSE_VALUE = new byte[] { 0 };
+ private static final byte FALSE_VALUE = 0x00;
+ private static final byte TRUE_VALUE = (byte)0xFF;
- private final byte[] value;
+ public static final ASN1Boolean FALSE = new ASN1Boolean(FALSE_VALUE);
+ public static final ASN1Boolean TRUE = new ASN1Boolean(TRUE_VALUE);
- public static final ASN1Boolean FALSE = new ASN1Boolean(false);
- public static final ASN1Boolean TRUE = new ASN1Boolean(true);
+ private final byte value;
/**
* Return a boolean from the passed in object.
@@ -62,10 +60,9 @@ public class ASN1Boolean
* @param value true or false depending on the ASN1Boolean wanted.
* @return an ASN1Boolean instance.
*/
- public static ASN1Boolean getInstance(
- boolean value)
+ public static ASN1Boolean getInstance(boolean value)
{
- return (value ? TRUE : FALSE);
+ return value ? TRUE : FALSE;
}
/**
@@ -73,10 +70,9 @@ public class ASN1Boolean
* @param value non-zero (true) or zero (false) depending on the ASN1Boolean wanted.
* @return an ASN1Boolean instance.
*/
- public static ASN1Boolean getInstance(
- int value)
+ public static ASN1Boolean getInstance(int value)
{
- return (value != 0 ? TRUE : FALSE);
+ return value != 0 ? TRUE : FALSE;
}
// BEGIN Android-added: Unknown reason
@@ -100,9 +96,7 @@ public class ASN1Boolean
* be converted.
* @return an ASN1Boolean instance.
*/
- public static ASN1Boolean getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1Boolean getInstance(ASN1TaggedObject obj, boolean explicit)
{
ASN1Primitive o = obj.getObject();
@@ -112,46 +106,18 @@ public class ASN1Boolean
}
else
{
- return ASN1Boolean.fromOctetString(((ASN1OctetString)o).getOctets());
+ return ASN1Boolean.fromOctetString(ASN1OctetString.getInstance(o).getOctets());
}
}
- ASN1Boolean(
- byte[] value)
+ private ASN1Boolean(byte value)
{
- if (value.length != 1)
- {
- throw new IllegalArgumentException("byte value should have 1 byte in it");
- }
-
- if (value[0] == 0)
- {
- this.value = FALSE_VALUE;
- }
- else if ((value[0] & 0xff) == 0xff)
- {
- this.value = TRUE_VALUE;
- }
- else
- {
- this.value = Arrays.clone(value);
- }
- }
-
- /**
- * @deprecated use getInstance(boolean) method.
- * @param value true or false.
- */
- // Android-changed: Reduce visibility to protected
- protected ASN1Boolean(
- boolean value)
- {
- this.value = (value) ? TRUE_VALUE : FALSE_VALUE;
+ this.value = value;
}
public boolean isTrue()
{
- return (value[0] != 0);
+ return value != FALSE_VALUE;
}
boolean isConstructed()
@@ -164,33 +130,36 @@ public class ASN1Boolean
return 3;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.BOOLEAN, value);
+ out.writeEncoded(withTag, BERTags.BOOLEAN, value);
}
- protected boolean asn1Equals(
- ASN1Primitive o)
+ boolean asn1Equals(ASN1Primitive other)
{
- if (o instanceof ASN1Boolean)
+ if (!(other instanceof ASN1Boolean))
{
- return (value[0] == ((ASN1Boolean)o).value[0]);
+ return false;
}
- return false;
+ ASN1Boolean that = (ASN1Boolean)other;
+
+ return this.isTrue() == that.isTrue();
}
public int hashCode()
{
- return value[0];
+ return isTrue() ? 1 : 0;
}
+ ASN1Primitive toDERObject()
+ {
+ return isTrue() ? TRUE : FALSE;
+ }
public String toString()
{
- return (value[0] != 0) ? "TRUE" : "FALSE";
+ return isTrue() ? "TRUE" : "FALSE";
}
static ASN1Boolean fromOctetString(byte[] value)
@@ -200,17 +169,12 @@ public class ASN1Boolean
throw new IllegalArgumentException("BOOLEAN value should have 1 byte in it");
}
- if (value[0] == 0)
- {
- return FALSE;
- }
- else if ((value[0] & 0xff) == 0xff)
- {
- return TRUE;
- }
- else
+ byte b = value[0];
+ switch (b)
{
- return new ASN1Boolean(value);
+ case FALSE_VALUE: return FALSE;
+ case TRUE_VALUE: return TRUE;
+ default: return new ASN1Boolean(b);
}
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java
index 0971748a..9baff445 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java
@@ -1,43 +1,87 @@
package org.bouncycastle.asn1;
-import java.util.Enumeration;
-import java.util.Vector;
-
/**
* Mutable class for building ASN.1 constructed objects such as SETs or SEQUENCEs.
*/
public class ASN1EncodableVector
{
- private final Vector v = new Vector();
+ static final ASN1Encodable[] EMPTY_ELEMENTS = new ASN1Encodable[0];
+
+ private static final int DEFAULT_CAPACITY = 10;
+
+ private ASN1Encodable[] elements;
+ private int elementCount;
+ private boolean copyOnWrite;
- /**
- * Base constructor.
- */
public ASN1EncodableVector()
{
+ this(DEFAULT_CAPACITY);
}
- /**
- * Add an encodable to the vector.
- *
- * @param obj the encodable to add.
- */
- public void add(ASN1Encodable obj)
+ public ASN1EncodableVector(int initialCapacity)
{
- v.addElement(obj);
+ if (initialCapacity < 0)
+ {
+ throw new IllegalArgumentException("'initialCapacity' must not be negative");
+ }
+
+ this.elements = (initialCapacity == 0) ? EMPTY_ELEMENTS : new ASN1Encodable[initialCapacity];
+ this.elementCount = 0;
+ this.copyOnWrite = false;
+ }
+
+ public void add(ASN1Encodable element)
+ {
+ if (null == element)
+ {
+ throw new NullPointerException("'element' cannot be null");
+ }
+
+ int capacity = elements.length;
+ int minCapacity = elementCount + 1;
+ if ((minCapacity > capacity) | copyOnWrite)
+ {
+ reallocate(minCapacity);
+ }
+
+ this.elements[elementCount] = element;
+ this.elementCount = minCapacity;
}
- /**
- * Add the contents of another vector.
- *
- * @param other the vector to add.
- */
public void addAll(ASN1EncodableVector other)
{
- for (Enumeration en = other.v.elements(); en.hasMoreElements();)
+ if (null == other)
+ {
+ throw new NullPointerException("'other' cannot be null");
+ }
+
+ int otherElementCount = other.size();
+ if (otherElementCount < 1)
+ {
+ return;
+ }
+
+ int capacity = elements.length;
+ int minCapacity = elementCount + otherElementCount;
+ if ((minCapacity > capacity) | copyOnWrite)
+ {
+ reallocate(minCapacity);
+ }
+
+ int i = 0;
+ do
{
- v.addElement(en.nextElement());
+ ASN1Encodable otherElement = other.get(i);
+ if (null == otherElement)
+ {
+ throw new NullPointerException("'other' elements cannot be null");
+ }
+
+ this.elements[elementCount + i] = otherElement;
}
+ while (++i < otherElementCount);
+
+ this.elementCount = minCapacity;
}
/**
@@ -48,7 +92,12 @@ public class ASN1EncodableVector
*/
public ASN1Encodable get(int i)
{
- return (ASN1Encodable)v.elementAt(i);
+ if (i >= elementCount)
+ {
+ throw new ArrayIndexOutOfBoundsException(i + " >= " + elementCount);
+ }
+
+ return elements[i];
}
/**
@@ -58,6 +107,53 @@ public class ASN1EncodableVector
*/
public int size()
{
- return v.size();
+ return elementCount;
+ }
+
+ ASN1Encodable[] copyElements()
+ {
+ if (0 == elementCount)
+ {
+ return EMPTY_ELEMENTS;
+ }
+
+ ASN1Encodable[] copy = new ASN1Encodable[elementCount];
+ System.arraycopy(elements, 0, copy, 0, elementCount);
+ return copy;
+ }
+
+ ASN1Encodable[] takeElements()
+ {
+ if (0 == elementCount)
+ {
+ return EMPTY_ELEMENTS;
+ }
+
+ if (elements.length == elementCount)
+ {
+ this.copyOnWrite = true;
+ return elements;
+ }
+
+ ASN1Encodable[] copy = new ASN1Encodable[elementCount];
+ System.arraycopy(elements, 0, copy, 0, elementCount);
+ return copy;
+ }
+
+ private void reallocate(int minCapacity)
+ {
+ int oldCapacity = elements.length;
+ int newCapacity = Math.max(oldCapacity, minCapacity + (minCapacity >> 1));
+
+ ASN1Encodable[] copy = new ASN1Encodable[newCapacity];
+ System.arraycopy(elements, 0, copy, 0, elementCount);
+
+ this.elements = copy;
+ this.copyOnWrite = false;
+ }
+
+ static ASN1Encodable[] cloneElements(ASN1Encodable[] elements)
+ {
+ return elements.length < 1 ? EMPTY_ELEMENTS : (ASN1Encodable[])elements.clone();
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java
index aa89eb5d..eff24a9f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java
@@ -4,7 +4,6 @@ import java.io.IOException;
import java.math.BigInteger;
import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Properties;
/**
* Class representing the ASN.1 ENUMERATED type.
@@ -13,6 +12,7 @@ public class ASN1Enumerated
extends ASN1Primitive
{
private final byte[] bytes;
+ private final int start;
/**
* return an enumerated from the passed in object
@@ -66,7 +66,7 @@ public class ASN1Enumerated
}
else
{
- return fromOctetString(((ASN1OctetString)o).getOctets());
+ return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -75,10 +75,15 @@ public class ASN1Enumerated
*
* @param value the value of this enumerated.
*/
- public ASN1Enumerated(
- int value)
+ public ASN1Enumerated(int value)
{
- bytes = BigInteger.valueOf(value).toByteArray();
+ if (value < 0)
+ {
+ throw new IllegalArgumentException("enumerated must be non-negative");
+ }
+
+ this.bytes = BigInteger.valueOf(value).toByteArray();
+ this.start = 0;
}
/**
@@ -86,10 +91,15 @@ public class ASN1Enumerated
*
* @param value the value of this enumerated.
*/
- public ASN1Enumerated(
- BigInteger value)
+ public ASN1Enumerated(BigInteger value)
{
- bytes = value.toByteArray();
+ if (value.signum() < 0)
+ {
+ throw new IllegalArgumentException("enumerated must be non-negative");
+ }
+
+ this.bytes = value.toByteArray();
+ this.start = 0;
}
/**
@@ -97,17 +107,19 @@ public class ASN1Enumerated
*
* @param bytes the value of this enumerated as an encoded BigInteger (signed).
*/
- public ASN1Enumerated(
- byte[] bytes)
+ public ASN1Enumerated(byte[] bytes)
{
- if (!Properties.isOverrideSet("org.bouncycastle.asn1.allow_unsafe_integer"))
+ if (ASN1Integer.isMalformed(bytes))
{
- if (ASN1Integer.isMalformed(bytes))
- {
- throw new IllegalArgumentException("malformed enumerated");
- }
+ throw new IllegalArgumentException("malformed enumerated");
}
+ if (0 != (bytes[0] & 0x80))
+ {
+ throw new IllegalArgumentException("enumerated must be non-negative");
+ }
+
this.bytes = Arrays.clone(bytes);
+ this.start = ASN1Integer.signBytesToSkip(bytes);
}
public BigInteger getValue()
@@ -115,6 +127,25 @@ public class ASN1Enumerated
return new BigInteger(bytes);
}
+ public boolean hasValue(BigInteger x)
+ {
+ return null != x
+ // Fast check to avoid allocation
+ && ASN1Integer.intValue(bytes, start, ASN1Integer.SIGN_EXT_SIGNED) == x.intValue()
+ && getValue().equals(x);
+ }
+
+ public int intValueExact()
+ {
+ int count = bytes.length - start;
+ if (count > 4)
+ {
+ throw new ArithmeticException("ASN.1 Enumerated out of int range");
+ }
+
+ return ASN1Integer.intValue(bytes, start, ASN1Integer.SIGN_EXT_SIGNED);
+ }
+
boolean isConstructed()
{
return false;
@@ -125,13 +156,11 @@ public class ASN1Enumerated
return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.ENUMERATED, bytes);
+ out.writeEncoded(withTag, BERTags.ENUMERATED, bytes);
}
-
+
boolean asn1Equals(
ASN1Primitive o)
{
@@ -167,14 +196,14 @@ public class ASN1Enumerated
if (value >= cache.length)
{
- return new ASN1Enumerated(Arrays.clone(enc));
+ return new ASN1Enumerated(enc);
}
ASN1Enumerated possibleMatch = cache[value];
if (possibleMatch == null)
{
- possibleMatch = cache[value] = new ASN1Enumerated(Arrays.clone(enc));
+ possibleMatch = cache[value] = new ASN1Enumerated(enc);
}
return possibleMatch;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1External.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1External.java
index 7db80fff..082605d8 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1External.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1External.java
@@ -106,14 +106,14 @@ public abstract class ASN1External
}
ASN1Primitive toDERObject()
- {
- if (this instanceof DERExternal)
- {
- return this;
- }
+ {
+ return new DERExternal(directReference, indirectReference, dataValueDescriptor, encoding, externalContent);
+ }
- return new DERExternal(directReference, indirectReference, dataValueDescriptor, encoding, externalContent);
- }
+ ASN1Primitive toDLObject()
+ {
+ return new DLExternal(directReference, indirectReference, dataValueDescriptor, encoding, externalContent);
+ }
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java
index ba8de8da..3d076cca 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java
@@ -100,7 +100,7 @@ public class ASN1GeneralizedTime
}
else
{
- return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets());
+ return new ASN1GeneralizedTime(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -169,7 +169,16 @@ public class ASN1GeneralizedTime
ASN1GeneralizedTime(
byte[] bytes)
{
+ if (bytes.length < 4)
+ {
+ throw new IllegalArgumentException("GeneralizedTime string too short");
+ }
this.time = bytes;
+
+ if (!(isDigit(0) && isDigit(1) && isDigit(2) && isDigit(3)))
+ {
+ throw new IllegalArgumentException("illegal characters in GeneralizedTime string");
+ }
}
/**
@@ -208,8 +217,16 @@ public class ASN1GeneralizedTime
}
else
{
- int signPos = stime.length() - 5;
+ int signPos = stime.length() - 6;
char sign = stime.charAt(signPos);
+ if ((sign == '-' || sign == '+') && stime.indexOf("GMT") == signPos - 3)
+ {
+ // already a GMT string!
+ return stime;
+ }
+
+ signPos = stime.length() - 5;
+ sign = stime.charAt(signPos);
if (sign == '-' || sign == '+')
{
return stime.substring(0, signPos)
@@ -218,23 +235,21 @@ public class ASN1GeneralizedTime
+ ":"
+ stime.substring(signPos + 3);
}
- else
+
+ signPos = stime.length() - 3;
+ sign = stime.charAt(signPos);
+ if (sign == '-' || sign == '+')
{
- signPos = stime.length() - 3;
- sign = stime.charAt(signPos);
- if (sign == '-' || sign == '+')
- {
- return stime.substring(0, signPos)
- + "GMT"
- + stime.substring(signPos)
- + ":00";
- }
+ return stime.substring(0, signPos)
+ + "GMT"
+ + stime.substring(signPos)
+ + ":00";
}
}
- return stime + calculateGMTOffset();
+ return stime + calculateGMTOffset(stime);
}
- private String calculateGMTOffset()
+ private String calculateGMTOffset(String stime)
{
String sign = "+";
TimeZone timeZone = TimeZone.getDefault();
@@ -249,9 +264,18 @@ public class ASN1GeneralizedTime
try
{
- if (timeZone.useDaylightTime() && timeZone.inDaylightTime(this.getDate()))
+ if (timeZone.useDaylightTime())
{
- hours += sign.equals("+") ? 1 : -1;
+ if (hasFractionalSeconds())
+ {
+ stime = pruneFractionalSeconds(stime);
+ }
+ SimpleDateFormat dateF = calculateGMTDateFormat();
+ if (timeZone.inDaylightTime(
+ dateF.parse(stime + "GMT" + sign + convert(hours) + ":" + convert(minutes))))
+ {
+ hours += sign.equals("+") ? 1 : -1;
+ }
}
}
catch (ParseException e)
@@ -262,6 +286,64 @@ public class ASN1GeneralizedTime
return "GMT" + sign + convert(hours) + ":" + convert(minutes);
}
+ private SimpleDateFormat calculateGMTDateFormat()
+ {
+ SimpleDateFormat dateF;
+
+ if (hasFractionalSeconds())
+ {
+ dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz");
+ }
+ else if (hasSeconds())
+ {
+ dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
+ }
+ else if (hasMinutes())
+ {
+ dateF = new SimpleDateFormat("yyyyMMddHHmmz");
+ }
+ else
+ {
+ dateF = new SimpleDateFormat("yyyyMMddHHz");
+ }
+
+ dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
+ return dateF;
+ }
+
+ private String pruneFractionalSeconds(String origTime)
+ {
+ // java misinterprets extra digits as being milliseconds...
+ String frac = origTime.substring(14);
+ int index;
+ for (index = 1; index < frac.length(); index++)
+ {
+ char ch = frac.charAt(index);
+ if (!('0' <= ch && ch <= '9'))
+ {
+ break;
+ }
+ }
+
+ if (index - 1 > 3)
+ {
+ frac = frac.substring(0, 4) + frac.substring(index);
+ origTime = origTime.substring(0, 14) + frac;
+ }
+ else if (index - 1 == 1)
+ {
+ frac = frac.substring(0, index) + "00" + frac.substring(index);
+ origTime = origTime.substring(0, 14) + frac;
+ }
+ else if (index - 1 == 2)
+ {
+ frac = frac.substring(0, index) + "0" + frac.substring(index);
+ origTime = origTime.substring(0, 14) + frac;
+ }
+
+ return origTime;
+ }
+
private String convert(int time)
{
if (time < 10)
@@ -311,32 +393,7 @@ public class ASN1GeneralizedTime
else if (stime.indexOf('-') > 0 || stime.indexOf('+') > 0)
{
d = this.getTime();
- if (hasFractionalSeconds())
- {
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz");
- dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz", Locale.US);
- }
- else if (hasSeconds())
- {
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
- dateF = new SimpleDateFormat("yyyyMMddHHmmssz", Locale.US);
- }
- else if (hasMinutes())
- {
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmmz");
- dateF = new SimpleDateFormat("yyyyMMddHHmmz", Locale.US);
- }
- else
- {
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHz");
- dateF = new SimpleDateFormat("yyyyMMddHHz", Locale.US);
- }
-
- dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
+ dateF = calculateGMTDateFormat();
}
else
{
@@ -370,35 +427,9 @@ public class ASN1GeneralizedTime
if (hasFractionalSeconds())
{
- // java misinterprets extra digits as being milliseconds...
- String frac = d.substring(14);
- int index;
- for (index = 1; index < frac.length(); index++)
- {
- char ch = frac.charAt(index);
- if (!('0' <= ch && ch <= '9'))
- {
- break;
- }
- }
-
- if (index - 1 > 3)
- {
- frac = frac.substring(0, 4) + frac.substring(index);
- d = d.substring(0, 14) + frac;
- }
- else if (index - 1 == 1)
- {
- frac = frac.substring(0, index) + "00" + frac.substring(index);
- d = d.substring(0, 14) + frac;
- }
- else if (index - 1 == 2)
- {
- frac = frac.substring(0, index) + "0" + frac.substring(index);
- d = d.substring(0, 14) + frac;
- }
+ d = pruneFractionalSeconds(d);
}
-
+
return DateUtil.epochAdjust(dateF.parse(d));
}
@@ -444,11 +475,9 @@ public class ASN1GeneralizedTime
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.GENERALIZED_TIME, time);
+ out.writeEncoded(withTag, BERTags.GENERALIZED_TIME, time);
}
ASN1Primitive toDERObject()
@@ -456,6 +485,11 @@ public class ASN1GeneralizedTime
return new DERGeneralizedTime(time);
}
+ ASN1Primitive toDLObject()
+ {
+ return new DERGeneralizedTime(time);
+ }
+
boolean asn1Equals(
ASN1Primitive o)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Generator.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Generator.java
index 3817d82c..a9b9f5ba 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Generator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Generator.java
@@ -7,12 +7,14 @@ import java.io.OutputStream;
*/
public abstract class ASN1Generator
{
+ // TODO This is problematic if we want an isolating buffer for all ASN.1 writes
protected OutputStream _out;
/**
* Base constructor.
*
- * @param out the end output stream that object encodings are written to.
+ * @param out
+ * the end output stream that object encodings are written to.
*/
public ASN1Generator(OutputStream out)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java
index 92d8cbb0..ca8257b3 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java
@@ -109,7 +109,7 @@ public class ASN1InputStream
protected int readLength()
throws IOException
{
- return readLength(this, limit);
+ return readLength(this, limit, false);
}
protected void readFully(
@@ -139,7 +139,7 @@ public class ASN1InputStream
{
boolean isConstructed = (tag & CONSTRUCTED) != 0;
- DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length);
+ DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length, limit);
if ((tag & APPLICATION) != 0)
{
@@ -160,12 +160,20 @@ public class ASN1InputStream
//
// yes, people actually do this...
//
- ASN1EncodableVector v = buildDEREncodableVector(defIn);
+ ASN1EncodableVector v = readVector(defIn);
ASN1OctetString[] strings = new ASN1OctetString[v.size()];
for (int i = 0; i != strings.length; i++)
{
- strings[i] = (ASN1OctetString)v.get(i);
+ ASN1Encodable asn1Obj = v.get(i);
+ if (asn1Obj instanceof ASN1OctetString)
+ {
+ strings[i] = (ASN1OctetString)asn1Obj;
+ }
+ else
+ {
+ throw new ASN1Exception("unknown object encountered in constructed OCTET STRING: " + asn1Obj.getClass());
+ }
}
return new BEROctetString(strings);
@@ -176,12 +184,12 @@ public class ASN1InputStream
}
else
{
- return DERFactory.createSequence(buildDEREncodableVector(defIn));
+ return DLFactory.createSequence(readVector(defIn));
}
case SET:
- return DERFactory.createSet(buildDEREncodableVector(defIn));
+ return DLFactory.createSet(readVector(defIn));
case EXTERNAL:
- return new DLExternal(buildDEREncodableVector(defIn));
+ return new DLExternal(readVector(defIn));
default:
throw new IOException("unknown tag " + tagNo + " encountered");
}
@@ -190,26 +198,23 @@ public class ASN1InputStream
return createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
}
- ASN1EncodableVector buildEncodableVector()
- throws IOException
+ ASN1EncodableVector readVector(DefiniteLengthInputStream dIn) throws IOException
{
- ASN1EncodableVector v = new ASN1EncodableVector();
- ASN1Primitive o;
-
- while ((o = readObject()) != null)
+ if (dIn.getRemaining() < 1)
{
- v.add(o);
+ return new ASN1EncodableVector(0);
}
+ ASN1InputStream subStream = new ASN1InputStream(dIn);
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1Primitive p;
+ while ((p = subStream.readObject()) != null)
+ {
+ v.add(p);
+ }
return v;
}
- ASN1EncodableVector buildDEREncodableVector(
- DefiniteLengthInputStream dIn) throws IOException
- {
- return new ASN1InputStream(dIn).buildEncodableVector();
- }
-
public ASN1Primitive readObject()
throws IOException
{
@@ -323,7 +328,7 @@ public class ASN1InputStream
return tagNo;
}
- static int readLength(InputStream s, int limit)
+ static int readLength(InputStream s, int limit, boolean isParsing)
throws IOException
{
int length = s.read();
@@ -365,9 +370,9 @@ public class ASN1InputStream
throw new IOException("corrupted stream - negative length found");
}
- if (length >= limit) // after all we must have read at least 1 byte
+ if (length >= limit && !isParsing) // after all we must have read at least 1 byte
{
- throw new IOException("corrupted stream - out of bounds length found");
+ throw new IOException("corrupted stream - out of bounds length found: " + length + " >= " + limit);
}
}
@@ -378,47 +383,72 @@ public class ASN1InputStream
throws IOException
{
int len = defIn.getRemaining();
- if (defIn.getRemaining() < tmpBuffers.length)
+ if (len >= tmpBuffers.length)
{
- byte[] buf = tmpBuffers[len];
-
- if (buf == null)
- {
- buf = tmpBuffers[len] = new byte[len];
- }
-
- Streams.readFully(defIn, buf);
-
- return buf;
+ return defIn.toByteArray();
}
- else
+
+ byte[] buf = tmpBuffers[len];
+ if (buf == null)
{
- return defIn.toByteArray();
+ buf = tmpBuffers[len] = new byte[len];
}
+
+ defIn.readAllIntoByteArray(buf);
+
+ return buf;
}
private static char[] getBMPCharBuffer(DefiniteLengthInputStream defIn)
throws IOException
{
- int len = defIn.getRemaining() / 2;
- char[] buf = new char[len];
- int totalRead = 0;
- while (totalRead < len)
+ int remainingBytes = defIn.getRemaining();
+ if (0 != (remainingBytes & 1))
{
- int ch1 = defIn.read();
- if (ch1 < 0)
+ throw new IOException("malformed BMPString encoding encountered");
+ }
+
+ char[] string = new char[remainingBytes / 2];
+ int stringPos = 0;
+
+ byte[] buf = new byte[8];
+ while (remainingBytes >= 8)
+ {
+ if (Streams.readFully(defIn, buf, 0, 8) != 8)
{
- break;
+ throw new EOFException("EOF encountered in middle of BMPString");
}
- int ch2 = defIn.read();
- if (ch2 < 0)
+
+ string[stringPos ] = (char)((buf[0] << 8) | (buf[1] & 0xFF));
+ string[stringPos + 1] = (char)((buf[2] << 8) | (buf[3] & 0xFF));
+ string[stringPos + 2] = (char)((buf[4] << 8) | (buf[5] & 0xFF));
+ string[stringPos + 3] = (char)((buf[6] << 8) | (buf[7] & 0xFF));
+ stringPos += 4;
+ remainingBytes -= 8;
+ }
+ if (remainingBytes > 0)
+ {
+ if (Streams.readFully(defIn, buf, 0, remainingBytes) != remainingBytes)
+ {
+ throw new EOFException("EOF encountered in middle of BMPString");
+ }
+
+ int bufPos = 0;
+ do
{
- break;
+ int b1 = buf[bufPos++] << 8;
+ int b2 = buf[bufPos++] & 0xFF;
+ string[stringPos++] = (char)(b1 | b2);
}
- buf[totalRead++] = (char)((ch1 << 8) | (ch2 & 0xff));
+ while (bufPos < remainingBytes);
}
- return buf;
+ if (0 != defIn.getRemaining() || string.length != stringPos)
+ {
+ throw new IllegalStateException();
+ }
+
+ return string;
}
static ASN1Primitive createPrimitiveDERObject(
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java
index 39ada8b5..baad01c2 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java
@@ -12,7 +12,11 @@ import org.bouncycastle.util.Properties;
public class ASN1Integer
extends ASN1Primitive
{
+ static final int SIGN_EXT_SIGNED = 0xFFFFFFFF;
+ static final int SIGN_EXT_UNSIGNED = 0xFF;
+
private final byte[] bytes;
+ private final int start;
/**
* Return an integer from the passed in object.
@@ -75,10 +79,10 @@ public class ASN1Integer
*
* @param value the long representing the value desired.
*/
- public ASN1Integer(
- long value)
+ public ASN1Integer(long value)
{
- bytes = BigInteger.valueOf(value).toByteArray();
+ this.bytes = BigInteger.valueOf(value).toByteArray();
+ this.start = 0;
}
/**
@@ -86,10 +90,10 @@ public class ASN1Integer
*
* @param value the BigInteger representing the value desired.
*/
- public ASN1Integer(
- BigInteger value)
+ public ASN1Integer(BigInteger value)
{
- bytes = value.toByteArray();
+ this.bytes = value.toByteArray();
+ this.start = 0;
}
/**
@@ -114,62 +118,77 @@ public class ASN1Integer
*
* @param bytes the byte array representing a 2's complement encoding of a BigInteger.
*/
- public ASN1Integer(
- byte[] bytes)
+ public ASN1Integer(byte[] bytes)
{
this(bytes, true);
}
ASN1Integer(byte[] bytes, boolean clone)
{
- // Apply loose validation, see note in public constructor ANS1Integer(byte[])
- if (!Properties.isOverrideSet("org.bouncycastle.asn1.allow_unsafe_integer"))
- {
- if (isMalformed(bytes))
- {
- throw new IllegalArgumentException("malformed integer");
- }
+ if (isMalformed(bytes))
+ {
+ throw new IllegalArgumentException("malformed integer");
}
- this.bytes = (clone) ? Arrays.clone(bytes) : bytes;
+
+ this.bytes = clone ? Arrays.clone(bytes) : bytes;
+ this.start = signBytesToSkip(bytes);
}
/**
- * Apply the correct validation for an INTEGER primitive following the BER rules.
+ * in some cases positive values get crammed into a space,
+ * that's not quite big enough...
*
- * @param bytes The raw encoding of the integer.
- * @return true if the (in)put fails this validation.
+ * @return the BigInteger that results from treating this ASN.1 INTEGER as unsigned.
*/
- static boolean isMalformed(byte[] bytes)
+ public BigInteger getPositiveValue()
+ {
+ return new BigInteger(1, bytes);
+ }
+
+ public BigInteger getValue()
{
- if (bytes.length > 1)
+ return new BigInteger(bytes);
+ }
+
+ public boolean hasValue(BigInteger x)
+ {
+ return null != x
+ // Fast check to avoid allocation
+ && intValue(bytes, start, SIGN_EXT_SIGNED) == x.intValue()
+ && getValue().equals(x);
+ }
+
+ public int intPositiveValueExact()
+ {
+ int count = bytes.length - start;
+ if (count > 4 || (count == 4 && 0 != (bytes[start] & 0x80)))
{
- if (bytes[0] == 0 && (bytes[1] & 0x80) == 0)
- {
- return true;
- }
- if (bytes[0] == (byte)0xff && (bytes[1] & 0x80) != 0)
- {
- return true;
- }
+ throw new ArithmeticException("ASN.1 Integer out of positive int range");
}
- return false;
+ return intValue(bytes, start, SIGN_EXT_UNSIGNED);
}
- public BigInteger getValue()
+ public int intValueExact()
{
- return new BigInteger(bytes);
+ int count = bytes.length - start;
+ if (count > 4)
+ {
+ throw new ArithmeticException("ASN.1 Integer out of int range");
+ }
+
+ return intValue(bytes, start, SIGN_EXT_SIGNED);
}
- /**
- * in some cases positive values get crammed into a space,
- * that's not quite big enough...
- *
- * @return the BigInteger that results from treating this ASN.1 INTEGER as unsigned.
- */
- public BigInteger getPositiveValue()
+ public long longValueExact()
{
- return new BigInteger(1, bytes);
+ int count = bytes.length - start;
+ if (count > 8)
+ {
+ throw new ArithmeticException("ASN.1 Integer out of long range");
+ }
+
+ return longValue(bytes, start, SIGN_EXT_SIGNED);
}
boolean isConstructed()
@@ -182,27 +201,17 @@ public class ASN1Integer
return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.INTEGER, bytes);
+ out.writeEncoded(withTag, BERTags.INTEGER, bytes);
}
public int hashCode()
{
- int value = 0;
-
- for (int i = 0; i != bytes.length; i++)
- {
- value ^= (bytes[i] & 0xff) << (i % 4);
- }
-
- return value;
+ return Arrays.hashCode(bytes);
}
- boolean asn1Equals(
- ASN1Primitive o)
+ boolean asn1Equals(ASN1Primitive o)
{
if (!(o instanceof ASN1Integer))
{
@@ -211,7 +220,7 @@ public class ASN1Integer
ASN1Integer other = (ASN1Integer)o;
- return Arrays.areEqual(bytes, other.bytes);
+ return Arrays.areEqual(this.bytes, other.bytes);
}
public String toString()
@@ -219,4 +228,61 @@ public class ASN1Integer
return getValue().toString();
}
+ static int intValue(byte[] bytes, int start, int signExt)
+ {
+ int length = bytes.length;
+ int pos = Math.max(start, length - 4);
+
+ int val = bytes[pos] & signExt;
+ while (++pos < length)
+ {
+ val = (val << 8) | (bytes[pos] & SIGN_EXT_UNSIGNED);
+ }
+ return val;
+ }
+
+ static long longValue(byte[] bytes, int start, int signExt)
+ {
+ int length = bytes.length;
+ int pos = Math.max(start, length - 8);
+
+ long val = bytes[pos] & signExt;
+ while (++pos < length)
+ {
+ val = (val << 8) | (bytes[pos] & SIGN_EXT_UNSIGNED);
+ }
+ return val;
+ }
+
+ /**
+ * Apply the correct validation for an INTEGER primitive following the BER rules.
+ *
+ * @param bytes The raw encoding of the integer.
+ * @return true if the (in)put fails this validation.
+ */
+ static boolean isMalformed(byte[] bytes)
+ {
+ switch (bytes.length)
+ {
+ case 0:
+ return true;
+ case 1:
+ return false;
+ default:
+ return bytes[0] == (bytes[1] >> 7)
+ // Apply loose validation, see note in public constructor ASN1Integer(byte[])
+ && !Properties.isOverrideSet("org.bouncycastle.asn1.allow_unsafe_integer");
+ }
+ }
+
+ static int signBytesToSkip(byte[] bytes)
+ {
+ int pos = 0, last = bytes.length - 1;
+ while (pos < last
+ && bytes[pos] == (bytes[pos + 1] >> 7))
+ {
+ ++pos;
+ }
+ return pos;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Null.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Null.java
index 7cf07657..c1815278 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Null.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Null.java
@@ -73,8 +73,7 @@ public abstract class ASN1Null
return true;
}
- abstract void encode(ASN1OutputStream out)
- throws IOException;
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
public String toString()
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Object.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Object.java
index 304866f7..0af2cdd6 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Object.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Object.java
@@ -2,6 +2,7 @@ package org.bouncycastle.asn1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import org.bouncycastle.util.Encodable;
@@ -11,20 +12,26 @@ import org.bouncycastle.util.Encodable;
public abstract class ASN1Object
implements ASN1Encodable, Encodable
{
+ public void encodeTo(OutputStream output) throws IOException
+ {
+ ASN1OutputStream.create(output).writeObject(this);
+ }
+
+ public void encodeTo(OutputStream output, String encoding) throws IOException
+ {
+ ASN1OutputStream.create(output, encoding).writeObject(this);
+ }
+
/**
* Return the default BER or DER encoding for this object.
*
* @return BER/DER byte encoded object.
* @throws java.io.IOException on encoding error.
*/
- public byte[] getEncoded()
- throws IOException
+ public byte[] getEncoded() throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
- aOut.writeObject(this);
-
+ encodeTo(bOut);
return bOut.toByteArray();
}
@@ -35,30 +42,11 @@ public abstract class ASN1Object
* @return byte encoded object.
* @throws IOException on encoding error.
*/
- public byte[] getEncoded(
- String encoding)
- throws IOException
+ public byte[] getEncoded(String encoding) throws IOException
{
- if (encoding.equals(ASN1Encoding.DER))
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- DEROutputStream dOut = new DEROutputStream(bOut);
-
- dOut.writeObject(this);
-
- return bOut.toByteArray();
- }
- else if (encoding.equals(ASN1Encoding.DL))
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- DLOutputStream dOut = new DLOutputStream(bOut);
-
- dOut.writeObject(this);
-
- return bOut.toByteArray();
- }
-
- return this.getEncoded();
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ encodeTo(bOut, encoding);
+ return bOut.toByteArray();
}
public int hashCode()
@@ -84,6 +72,8 @@ public abstract class ASN1Object
return this.toASN1Primitive().equals(other.toASN1Primitive());
}
+ // BEGIN Android-changed: Was removed in upstream.
+ // Used by https://source.corp.google.com/android/cts/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
/**
* @deprecated use toASN1Primitive()
* @return the underlying primitive type.
@@ -92,6 +82,7 @@ public abstract class ASN1Object
{
return this.toASN1Primitive();
}
+ // END Android-changed
/**
* Return true if obj is a byte array and represents an object with the given tag value.
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
index b5288a2b..8373dcaf 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
@@ -175,7 +175,7 @@ public class ASN1ObjectIdentifier
{
if (identifier == null)
{
- throw new IllegalArgumentException("'identifier' cannot be null");
+ throw new NullPointerException("'identifier' cannot be null");
}
if (!isValidIdentifier(identifier))
{
@@ -329,15 +329,9 @@ public class ASN1ObjectIdentifier
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- byte[] enc = getBody();
-
- out.write(BERTags.OBJECT_IDENTIFIER);
- out.writeLength(enc.length);
- out.write(enc);
+ out.writeEncoded(withTag, BERTags.OBJECT_IDENTIFIER, getBody());
}
public int hashCode()
@@ -369,35 +363,40 @@ public class ASN1ObjectIdentifier
private static boolean isValidBranchID(
String branchID, int start)
{
- boolean periodAllowed = false;
+ int digitCount = 0;
int pos = branchID.length();
while (--pos >= start)
{
char ch = branchID.charAt(pos);
- // TODO Leading zeroes?
- if ('0' <= ch && ch <= '9')
- {
- periodAllowed = true;
- continue;
- }
-
if (ch == '.')
{
- if (!periodAllowed)
+ if (0 == digitCount
+ || (digitCount > 1 && branchID.charAt(pos + 1) == '0'))
{
return false;
}
- periodAllowed = false;
- continue;
+ digitCount = 0;
+ }
+ else if ('0' <= ch && ch <= '9')
+ {
+ ++digitCount;
+ }
+ else
+ {
+ return false;
}
+ }
+ if (0 == digitCount
+ || (digitCount > 1 && branchID.charAt(pos + 1) == '0'))
+ {
return false;
}
- return periodAllowed;
+ return true;
}
private static boolean isValidIdentifier(
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java
index 2df802bc..59c6f340 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java
@@ -105,28 +105,78 @@ public abstract class ASN1OctetString
/**
* return an Octet String from a tagged object.
*
- * @param obj the tagged object holding the object we want.
+ * @param taggedObject the tagged object holding the object we want.
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
*/
public static ASN1OctetString getInstance(
- ASN1TaggedObject obj,
+ ASN1TaggedObject taggedObject,
boolean explicit)
{
- ASN1Primitive o = obj.getObject();
+ if (explicit)
+ {
+ if (!taggedObject.isExplicit())
+ {
+ throw new IllegalArgumentException("object implicit - explicit expected.");
+ }
+
+ return getInstance(taggedObject.getObject());
+ }
+
+ ASN1Primitive o = taggedObject.getObject();
+
+ /*
+ * constructed object which appears to be explicitly tagged and it's really implicit means
+ * we have to add the surrounding octet string.
+ */
+ if (taggedObject.isExplicit())
+ {
+ ASN1OctetString singleSegment = getInstance(o);
+
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return new BEROctetString(new ASN1OctetString[]{ singleSegment });
+ }
+
+ // TODO Should really be similar to the BERTaggedObject case above:
+// return new DLOctetString(new ASN1OctetString[]{ singleSegment });
+ return (ASN1OctetString)new BEROctetString(new ASN1OctetString[]{ singleSegment }).toDLObject();
+ }
- if (explicit || o instanceof ASN1OctetString)
+ if (o instanceof ASN1OctetString)
{
- return getInstance(o);
+ ASN1OctetString s = (ASN1OctetString)o;
+
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return s;
+ }
+
+ return (ASN1OctetString)s.toDLObject();
}
- else
+
+ /*
+ * in this case the parser returns a sequence, convert it into an octet string.
+ */
+ if (o instanceof ASN1Sequence)
{
- return BEROctetString.fromSequence(ASN1Sequence.getInstance(o));
+ ASN1Sequence s = (ASN1Sequence)o;
+
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return BEROctetString.fromSequence(s);
+ }
+
+ // TODO Should really be similar to the BERTaggedObject case above:
+// return DLOctetString.fromSequence(s);
+ return (ASN1OctetString)BEROctetString.fromSequence(s).toDLObject();
}
+
+ throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
}
-
+
/**
* return an Octet String from the given object.
*
@@ -144,7 +194,7 @@ public abstract class ASN1OctetString
{
try
{
- return ASN1OctetString.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
+ return getInstance(fromByteArray((byte[])obj));
}
catch (IOException e)
{
@@ -174,7 +224,7 @@ public abstract class ASN1OctetString
{
if (string == null)
{
- throw new NullPointerException("string cannot be null");
+ throw new NullPointerException("'string' cannot be null");
}
this.string = string;
}
@@ -242,8 +292,7 @@ public abstract class ASN1OctetString
return new DEROctetString(string);
}
- abstract void encode(ASN1OutputStream out)
- throws IOException;
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
public String toString()
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OutputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OutputStream.java
index 9a46a78b..e6ae93fb 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OutputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OutputStream.java
@@ -2,21 +2,45 @@ package org.bouncycastle.asn1;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.Enumeration;
/**
* Stream that produces output based on the default encoding for the passed in objects.
*/
public class ASN1OutputStream
{
+ public static ASN1OutputStream create(OutputStream out)
+ {
+ return new ASN1OutputStream(out);
+ }
+
+ public static ASN1OutputStream create(OutputStream out, String encoding)
+ {
+ if (encoding.equals(ASN1Encoding.DER))
+ {
+ return new DEROutputStream(out);
+ }
+ else if (encoding.equals(ASN1Encoding.DL))
+ {
+ return new DLOutputStream(out);
+ }
+ else
+ {
+ return new ASN1OutputStream(out);
+ }
+ }
+
private OutputStream os;
- public ASN1OutputStream(
- OutputStream os)
+ /**
+ * @deprecated Use {@link ASN1OutputStream#create(OutputStream)} instead.
+ */
+ public ASN1OutputStream(OutputStream os)
{
this.os = os;
}
- void writeLength(
+ final void writeLength(
int length)
throws IOException
{
@@ -43,37 +67,173 @@ public class ASN1OutputStream
}
}
- void write(int b)
+ final void write(int b)
throws IOException
{
os.write(b);
}
- void write(byte[] bytes)
+ final void write(byte[] bytes, int off, int len)
throws IOException
{
- os.write(bytes);
+ os.write(bytes, off, len);
}
- void write(byte[] bytes, int off, int len)
+ final void writeElements(ASN1Encodable[] elements)
throws IOException
{
- os.write(bytes, off, len);
+ int count = elements.length;
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive primitive = elements[i].toASN1Primitive();
+
+ writePrimitive(primitive, true);
+ }
+ }
+
+ final void writeElements(Enumeration elements)
+ throws IOException
+ {
+ while (elements.hasMoreElements())
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)elements.nextElement()).toASN1Primitive();
+
+ writePrimitive(primitive, true);
+ }
+ }
+
+ final void writeEncoded(
+ boolean withTag,
+ int tag,
+ byte contents)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(1);
+ write(contents);
}
- void writeEncoded(
+ final void writeEncoded(
+ boolean withTag,
int tag,
- byte[] bytes)
+ byte[] contents)
throws IOException
{
- write(tag);
- writeLength(bytes.length);
- write(bytes);
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(contents.length);
+ write(contents, 0, contents.length);
}
- void writeTag(int flags, int tagNo)
+ final void writeEncoded(
+ boolean withTag,
+ int tag,
+ byte[] contents,
+ int contentsOff,
+ int contentsLen)
throws IOException
{
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(contentsLen);
+ write(contents, contentsOff, contentsLen);
+ }
+
+ final void writeEncoded(
+ boolean withTag,
+ int tag,
+ byte headByte,
+ byte[] tailBytes)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(1 + tailBytes.length);
+ write(headByte);
+ write(tailBytes, 0, tailBytes.length);
+ }
+
+ final void writeEncoded(
+ boolean withTag,
+ int tag,
+ byte headByte,
+ byte[] body,
+ int bodyOff,
+ int bodyLen,
+ byte tailByte)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(2 + bodyLen);
+ write(headByte);
+ write(body, bodyOff, bodyLen);
+ write(tailByte);
+ }
+
+ final void writeEncoded(boolean withTag, int flags, int tagNo, byte[] contents)
+ throws IOException
+ {
+ writeTag(withTag, flags, tagNo);
+ writeLength(contents.length);
+ write(contents, 0, contents.length);
+ }
+
+ final void writeEncodedIndef(boolean withTag, int flags, int tagNo, byte[] contents)
+ throws IOException
+ {
+ writeTag(withTag, flags, tagNo);
+ write(0x80);
+ write(contents, 0, contents.length);
+ write(0x00);
+ write(0x00);
+ }
+
+ final void writeEncodedIndef(boolean withTag, int tag, ASN1Encodable[] elements)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ write(0x80);
+ writeElements(elements);
+ write(0x00);
+ write(0x00);
+ }
+
+ final void writeEncodedIndef(boolean withTag, int tag, Enumeration elements)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ write(0x80);
+ writeElements(elements);
+ write(0x00);
+ write(0x00);
+ }
+
+ final void writeTag(boolean withTag, int flags, int tagNo)
+ throws IOException
+ {
+ if (!withTag)
+ {
+ return;
+ }
+
if (tagNo < 31)
{
write(flags | tagNo);
@@ -104,46 +264,31 @@ public class ASN1OutputStream
}
}
- void writeEncoded(int flags, int tagNo, byte[] bytes)
- throws IOException
+ public void writeObject(ASN1Encodable obj) throws IOException
{
- writeTag(flags, tagNo);
- writeLength(bytes.length);
- write(bytes);
- }
+ if (null == obj)
+ {
+ throw new IOException("null object detected");
+ }
- protected void writeNull()
- throws IOException
- {
- os.write(BERTags.NULL);
- os.write(0x00);
+ writePrimitive(obj.toASN1Primitive(), true);
+ flushInternal();
}
- public void writeObject(
- ASN1Encodable obj)
- throws IOException
+ public void writeObject(ASN1Primitive primitive) throws IOException
{
- if (obj != null)
- {
- obj.toASN1Primitive().encode(this);
- }
- else
+ if (null == primitive)
{
throw new IOException("null object detected");
}
+
+ writePrimitive(primitive, true);
+ flushInternal();
}
- void writeImplicitObject(ASN1Primitive obj)
- throws IOException
+ void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
{
- if (obj != null)
- {
- obj.encode(new ImplicitOutputStream(os));
- }
- else
- {
- throw new IOException("null object detected");
- }
+ primitive.encode(this, withTag);
}
public void close()
@@ -158,37 +303,19 @@ public class ASN1OutputStream
os.flush();
}
- ASN1OutputStream getDERSubStream()
+ void flushInternal()
+ throws IOException
{
- return new DEROutputStream(os);
+ // Placeholder to support future internal buffering
}
- ASN1OutputStream getDLSubStream()
+ DEROutputStream getDERSubStream()
{
- return new DLOutputStream(os);
+ return new DEROutputStream(os);
}
- private class ImplicitOutputStream
- extends ASN1OutputStream
+ ASN1OutputStream getDLSubStream()
{
- private boolean first = true;
-
- public ImplicitOutputStream(OutputStream os)
- {
- super(os);
- }
-
- public void write(int b)
- throws IOException
- {
- if (first)
- {
- first = false;
- }
- else
- {
- super.write(b);
- }
- }
+ return new DLOutputStream(os);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java
index 94b0b3d5..b562b061 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java
@@ -1,6 +1,7 @@
package org.bouncycastle.asn1;
import java.io.IOException;
+import java.io.OutputStream;
/**
* Base class for ASN.1 primitive objects. These are the actual objects used to generate byte encodings.
@@ -10,7 +11,16 @@ public abstract class ASN1Primitive
{
ASN1Primitive()
{
+ }
+
+ public void encodeTo(OutputStream output) throws IOException
+ {
+ ASN1OutputStream.create(output).writeObject(this);
+ }
+ public void encodeTo(OutputStream output, String encoding) throws IOException
+ {
+ ASN1OutputStream.create(output, encoding).writeObject(this);
}
/**
@@ -52,7 +62,17 @@ public abstract class ASN1Primitive
return (o instanceof ASN1Encodable) && asn1Equals(((ASN1Encodable)o).toASN1Primitive());
}
- public ASN1Primitive toASN1Primitive()
+ public final boolean equals(ASN1Encodable other)
+ {
+ return this == other || (null != other && asn1Equals(other.toASN1Primitive()));
+ }
+
+ public final boolean equals(ASN1Primitive other)
+ {
+ return this == other || asn1Equals(other);
+ }
+
+ public final ASN1Primitive toASN1Primitive()
{
return this;
}
@@ -92,7 +112,7 @@ public abstract class ASN1Primitive
*/
abstract int encodedLength() throws IOException;
- abstract void encode(ASN1OutputStream out) throws IOException;
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
/**
* Equality (similarity) comparison for two ASN1Primitive objects.
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java
index ea6f3d87..b64127ad 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java
@@ -3,7 +3,7 @@ package org.bouncycastle.asn1;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
-import java.util.Vector;
+import java.util.NoSuchElementException;
import org.bouncycastle.util.Arrays;
@@ -60,7 +60,8 @@ public abstract class ASN1Sequence
extends ASN1Primitive
implements org.bouncycastle.util.Iterable<ASN1Encodable>
{
- protected Vector seq = new Vector();
+ // NOTE: Only non-final to support LazyEncodedSequence
+ ASN1Encodable[] elements;
/**
* Return an ASN1Sequence from the given object.
@@ -114,7 +115,7 @@ public abstract class ASN1Sequence
* dealing with implicitly tagged sequences you really <b>should</b>
* be using this method.
*
- * @param obj the tagged object.
+ * @param taggedObject the tagged object.
* @param explicit true if the object is meant to be explicitly tagged,
* false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
@@ -122,48 +123,48 @@ public abstract class ASN1Sequence
* @return an ASN1Sequence instance.
*/
public static ASN1Sequence getInstance(
- ASN1TaggedObject obj,
+ ASN1TaggedObject taggedObject,
boolean explicit)
{
if (explicit)
{
- if (!obj.isExplicit())
+ if (!taggedObject.isExplicit())
{
throw new IllegalArgumentException("object implicit - explicit expected.");
}
- return ASN1Sequence.getInstance(obj.getObject().toASN1Primitive());
+ return getInstance(taggedObject.getObject());
}
- else
+
+ ASN1Primitive o = taggedObject.getObject();
+
+ /*
+ * constructed object which appears to be explicitly tagged when it should be implicit means
+ * we have to add the surrounding sequence.
+ */
+ if (taggedObject.isExplicit())
{
- ASN1Primitive o = obj.getObject();
-
- //
- // constructed object which appears to be explicitly tagged
- // when it should be implicit means we have to add the
- // surrounding sequence.
- //
- if (obj.isExplicit())
+ if (taggedObject instanceof BERTaggedObject)
{
- if (obj instanceof BERTaggedObject)
- {
- return new BERSequence(o);
- }
- else
- {
- return new DLSequence(o);
- }
+ return new BERSequence(o);
}
- else
+
+ return new DLSequence(o);
+ }
+
+ if (o instanceof ASN1Sequence)
+ {
+ ASN1Sequence s = (ASN1Sequence)o;
+
+ if (taggedObject instanceof BERTaggedObject)
{
- if (o instanceof ASN1Sequence)
- {
- return (ASN1Sequence)o;
- }
+ return s;
}
+
+ return (ASN1Sequence)s.toDLObject();
}
- throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
+ throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
}
/**
@@ -171,79 +172,105 @@ public abstract class ASN1Sequence
*/
protected ASN1Sequence()
{
+ this.elements = ASN1EncodableVector.EMPTY_ELEMENTS;
}
/**
* Create a SEQUENCE containing one object.
- * @param obj the object to be put in the SEQUENCE.
+ * @param element the object to be put in the SEQUENCE.
*/
- protected ASN1Sequence(
- ASN1Encodable obj)
+ protected ASN1Sequence(ASN1Encodable element)
{
- seq.addElement(obj);
+ if (null == element)
+ {
+ throw new NullPointerException("'element' cannot be null");
+ }
+
+ this.elements = new ASN1Encodable[]{ element };
}
/**
* Create a SEQUENCE containing a vector of objects.
- * @param v the vector of objects to be put in the SEQUENCE.
+ * @param elementVector the vector of objects to be put in the SEQUENCE.
*/
- protected ASN1Sequence(
- ASN1EncodableVector v)
+ protected ASN1Sequence(ASN1EncodableVector elementVector)
{
- for (int i = 0; i != v.size(); i++)
+ if (null == elementVector)
{
- seq.addElement(v.get(i));
+ throw new NullPointerException("'elementVector' cannot be null");
}
+
+ this.elements = elementVector.takeElements();
}
/**
* Create a SEQUENCE containing an array of objects.
- * @param array the array of objects to be put in the SEQUENCE.
+ * @param elements the array of objects to be put in the SEQUENCE.
*/
- protected ASN1Sequence(
- ASN1Encodable[] array)
+ protected ASN1Sequence(ASN1Encodable[] elements)
{
- for (int i = 0; i != array.length; i++)
+ if (Arrays.isNullOrContainsNull(elements))
{
- seq.addElement(array[i]);
+ throw new NullPointerException("'elements' cannot be null, or contain null");
}
+
+ this.elements = ASN1EncodableVector.cloneElements(elements);
}
- public ASN1Encodable[] toArray()
+ ASN1Sequence(ASN1Encodable[] elements, boolean clone)
{
- ASN1Encodable[] values = new ASN1Encodable[this.size()];
+ this.elements = clone ? ASN1EncodableVector.cloneElements(elements) : elements;
+ }
- for (int i = 0; i != this.size(); i++)
- {
- values[i] = this.getObjectAt(i);
- }
+ public ASN1Encodable[] toArray()
+ {
+ return ASN1EncodableVector.cloneElements(elements);
+ }
- return values;
+ ASN1Encodable[] toArrayInternal()
+ {
+ return elements;
}
public Enumeration getObjects()
{
- return seq.elements();
+ return new Enumeration()
+ {
+ private int pos = 0;
+
+ public boolean hasMoreElements()
+ {
+ return pos < elements.length;
+ }
+
+ public Object nextElement()
+ {
+ if (pos < elements.length)
+ {
+ return elements[pos++];
+ }
+ throw new NoSuchElementException();
+ }
+ };
}
public ASN1SequenceParser parser()
{
- final ASN1Sequence outer = this;
+ // NOTE: Call size() here to 'force' a LazyEncodedSequence
+ final int count = size();
return new ASN1SequenceParser()
{
- private final int max = size();
-
- private int index;
+ private int pos = 0;
public ASN1Encodable readObject() throws IOException
{
- if (index == max)
+ if (count == pos)
{
return null;
}
-
- ASN1Encodable obj = getObjectAt(index++);
+
+ ASN1Encodable obj = elements[pos++];
if (obj instanceof ASN1Sequence)
{
return ((ASN1Sequence)obj).parser();
@@ -258,12 +285,12 @@ public abstract class ASN1Sequence
public ASN1Primitive getLoadedObject()
{
- return outer;
+ return ASN1Sequence.this;
}
-
+
public ASN1Primitive toASN1Primitive()
{
- return outer;
+ return ASN1Sequence.this;
}
};
}
@@ -274,10 +301,9 @@ public abstract class ASN1Sequence
* @param index the sequence number (starting at zero) of the object
* @return the object at the sequence position indicated by index.
*/
- public ASN1Encodable getObjectAt(
- int index)
+ public ASN1Encodable getObjectAt(int index)
{
- return (ASN1Encodable)seq.elementAt(index);
+ return elements[index];
}
/**
@@ -287,80 +313,60 @@ public abstract class ASN1Sequence
*/
public int size()
{
- return seq.size();
+ return elements.length;
}
public int hashCode()
{
- Enumeration e = this.getObjects();
- int hashCode = size();
+// return Arrays.hashCode(elements);
+ int i = elements.length;
+ int hc = i + 1;
- while (e.hasMoreElements())
+ while (--i >= 0)
{
- Object o = getNext(e);
- hashCode *= 17;
-
- hashCode ^= o.hashCode();
+ hc *= 257;
+ hc ^= elements[i].toASN1Primitive().hashCode();
}
- return hashCode;
+ return hc;
}
- boolean asn1Equals(
- ASN1Primitive o)
+ boolean asn1Equals(ASN1Primitive other)
{
- if (!(o instanceof ASN1Sequence))
+ if (!(other instanceof ASN1Sequence))
{
return false;
}
-
- ASN1Sequence other = (ASN1Sequence)o;
- if (this.size() != other.size())
+ ASN1Sequence that = (ASN1Sequence)other;
+
+ int count = this.size();
+ if (that.size() != count)
{
return false;
}
- Enumeration s1 = this.getObjects();
- Enumeration s2 = other.getObjects();
-
- while (s1.hasMoreElements())
+ for (int i = 0; i < count; ++i)
{
- ASN1Encodable obj1 = getNext(s1);
- ASN1Encodable obj2 = getNext(s2);
-
- ASN1Primitive o1 = obj1.toASN1Primitive();
- ASN1Primitive o2 = obj2.toASN1Primitive();
+ ASN1Primitive p1 = this.elements[i].toASN1Primitive();
+ ASN1Primitive p2 = that.elements[i].toASN1Primitive();
- if (o1 == o2 || o1.equals(o2))
+ if (p1 != p2 && !p1.asn1Equals(p2))
{
- continue;
+ return false;
}
-
- return false;
}
return true;
}
- private ASN1Encodable getNext(Enumeration e)
- {
- ASN1Encodable encObj = (ASN1Encodable)e.nextElement();
-
- return encObj;
- }
-
/**
* Change current SEQUENCE object to be encoded as {@link DERSequence}.
* This is part of Distinguished Encoding Rules form serialization.
*/
ASN1Primitive toDERObject()
{
- ASN1Sequence derSeq = new DERSequence();
-
- derSeq.seq = this.seq;
-
- return derSeq;
+ return new DERSequence(elements, false);
}
/**
@@ -369,11 +375,7 @@ public abstract class ASN1Sequence
*/
ASN1Primitive toDLObject()
{
- ASN1Sequence dlSeq = new DLSequence();
-
- dlSeq.seq = this.seq;
-
- return dlSeq;
+ return new DLSequence(elements, false);
}
boolean isConstructed()
@@ -381,16 +383,34 @@ public abstract class ASN1Sequence
return true;
}
- abstract void encode(ASN1OutputStream out)
- throws IOException;
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
public String toString()
{
- return seq.toString();
+ // NOTE: Call size() here to 'force' a LazyEncodedSequence
+ int count = size();
+ if (0 == count)
+ {
+ return "[]";
+ }
+
+ StringBuffer sb = new StringBuffer();
+ sb.append('[');
+ for (int i = 0;;)
+ {
+ sb.append(elements[i]);
+ if (++i >= count)
+ {
+ break;
+ }
+ sb.append(", ");
+ }
+ sb.append(']');
+ return sb.toString();
}
public Iterator<ASN1Encodable> iterator()
{
- return new Arrays.Iterator<ASN1Encodable>(toArray());
+ return new Arrays.Iterator<ASN1Encodable>(elements);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java
index 9865533c..fd676d77 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java
@@ -3,7 +3,7 @@ package org.bouncycastle.asn1;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
-import java.util.Vector;
+import java.util.NoSuchElementException;
import org.bouncycastle.util.Arrays;
@@ -98,8 +98,8 @@ public abstract class ASN1Set
extends ASN1Primitive
implements org.bouncycastle.util.Iterable<ASN1Encodable>
{
- private Vector set = new Vector();
- private boolean isSorted = false;
+ protected final ASN1Encodable[] elements;
+ protected final boolean isSorted;
/**
* return an ASN1Set from the given object.
@@ -153,7 +153,7 @@ public abstract class ASN1Set
* dealing with implicitly tagged sets you really <b>should</b>
* be using this method.
*
- * @param obj the tagged object.
+ * @param taggedObject the tagged object.
* @param explicit true if the object is meant to be explicitly tagged
* false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
@@ -161,125 +161,164 @@ public abstract class ASN1Set
* @return an ASN1Set instance.
*/
public static ASN1Set getInstance(
- ASN1TaggedObject obj,
+ ASN1TaggedObject taggedObject,
boolean explicit)
{
if (explicit)
{
- if (!obj.isExplicit())
+ if (!taggedObject.isExplicit())
{
throw new IllegalArgumentException("object implicit - explicit expected.");
}
- return (ASN1Set)obj.getObject();
+ return getInstance(taggedObject.getObject());
}
- else
+
+ ASN1Primitive o = taggedObject.getObject();
+
+ /*
+ * constructed object which appears to be explicitly tagged and it's really implicit means
+ * we have to add the surrounding set.
+ */
+ if (taggedObject.isExplicit())
{
- ASN1Primitive o = obj.getObject();
-
- //
- // constructed object which appears to be explicitly tagged
- // and it's really implicit means we have to add the
- // surrounding set.
- //
- if (obj.isExplicit())
+ if (taggedObject instanceof BERTaggedObject)
{
- if (obj instanceof BERTaggedObject)
- {
- return new BERSet(o);
- }
- else
- {
- return new DLSet(o);
- }
+ return new BERSet(o);
}
- else
+
+ return new DLSet(o);
+ }
+
+ if (o instanceof ASN1Set)
+ {
+ ASN1Set s = (ASN1Set)o;
+
+ if (taggedObject instanceof BERTaggedObject)
{
- if (o instanceof ASN1Set)
- {
- return (ASN1Set)o;
- }
+ return s;
+ }
- //
- // in this case the parser returns a sequence, convert it
- // into a set.
- //
- if (o instanceof ASN1Sequence)
- {
- ASN1Sequence s = (ASN1Sequence)o;
-
- if (obj instanceof BERTaggedObject)
- {
- return new BERSet(s.toArray());
- }
- else
- {
- return new DLSet(s.toArray());
- }
- }
+ return (ASN1Set)s.toDLObject();
+ }
+
+ /*
+ * in this case the parser returns a sequence, convert it into a set.
+ */
+ if (o instanceof ASN1Sequence)
+ {
+ ASN1Sequence s = (ASN1Sequence)o;
+
+ // NOTE: Will force() a LazyEncodedSequence
+ ASN1Encodable[] elements = s.toArrayInternal();
+
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return new BERSet(false, elements);
}
+
+ return new DLSet(false, elements);
}
- throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
+ throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
}
protected ASN1Set()
{
+ this.elements = ASN1EncodableVector.EMPTY_ELEMENTS;
+ this.isSorted = true;
}
/**
* Create a SET containing one object
- * @param obj object to be added to the SET.
+ * @param element object to be added to the SET.
*/
- protected ASN1Set(
- ASN1Encodable obj)
+ protected ASN1Set(ASN1Encodable element)
{
- set.addElement(obj);
+ if (null == element)
+ {
+ throw new NullPointerException("'element' cannot be null");
+ }
+
+ this.elements = new ASN1Encodable[]{ element };
+ this.isSorted = true;
}
/**
* Create a SET containing a vector of objects.
- * @param v a vector of objects to make up the SET.
+ * @param elementVector a vector of objects to make up the SET.
* @param doSort true if should be sorted DER style, false otherwise.
*/
- protected ASN1Set(
- ASN1EncodableVector v,
- boolean doSort)
+ protected ASN1Set(ASN1EncodableVector elementVector, boolean doSort)
{
- for (int i = 0; i != v.size(); i++)
+ if (null == elementVector)
{
- set.addElement(v.get(i));
+ throw new NullPointerException("'elementVector' cannot be null");
}
- if (doSort)
+ ASN1Encodable[] tmp;
+ if (doSort && elementVector.size() >= 2)
{
- this.sort();
+ tmp = elementVector.copyElements();
+ sort(tmp);
}
+ else
+ {
+ tmp = elementVector.takeElements();
+ }
+
+ this.elements = tmp;
+ this.isSorted = doSort || tmp.length < 2;
}
/**
* Create a SET containing an array of objects.
- * @param array an array of objects to make up the SET.
+ * @param elements an array of objects to make up the SET.
* @param doSort true if should be sorted DER style, false otherwise.
*/
- protected ASN1Set(
- ASN1Encodable[] array,
- boolean doSort)
+ protected ASN1Set(ASN1Encodable[] elements, boolean doSort)
{
- for (int i = 0; i != array.length; i++)
+ if (Arrays.isNullOrContainsNull(elements))
{
- set.addElement(array[i]);
+ throw new NullPointerException("'elements' cannot be null, or contain null");
}
- if (doSort)
+ ASN1Encodable[] tmp = ASN1EncodableVector.cloneElements(elements);
+ if (doSort && tmp.length >= 2)
{
- this.sort();
+ sort(tmp);
}
+
+ this.elements = tmp;
+ this.isSorted = doSort || tmp.length < 2;
+ }
+
+ ASN1Set(boolean isSorted, ASN1Encodable[] elements)
+ {
+ this.elements = elements;
+ this.isSorted = isSorted || elements.length < 2;
}
public Enumeration getObjects()
{
- return set.elements();
+ return new Enumeration()
+ {
+ private int pos = 0;
+
+ public boolean hasMoreElements()
+ {
+ return pos < elements.length;
+ }
+
+ public Object nextElement()
+ {
+ if (pos < elements.length)
+ {
+ return elements[pos++];
+ }
+ throw new NoSuchElementException();
+ }
+ };
}
/**
@@ -288,10 +327,9 @@ public abstract class ASN1Set
* @param index the set number (starting at zero) of the object
* @return the object at the set position indicated by index.
*/
- public ASN1Encodable getObjectAt(
- int index)
+ public ASN1Encodable getObjectAt(int index)
{
- return (ASN1Encodable)set.elementAt(index);
+ return elements[index];
}
/**
@@ -301,39 +339,30 @@ public abstract class ASN1Set
*/
public int size()
{
- return set.size();
+ return elements.length;
}
public ASN1Encodable[] toArray()
{
- ASN1Encodable[] values = new ASN1Encodable[this.size()];
-
- for (int i = 0; i != this.size(); i++)
- {
- values[i] = this.getObjectAt(i);
- }
-
- return values;
+ return ASN1EncodableVector.cloneElements(elements);
}
public ASN1SetParser parser()
{
- final ASN1Set outer = this;
+ final int count = size();
return new ASN1SetParser()
{
- private final int max = size();
-
- private int index;
+ private int pos = 0;
public ASN1Encodable readObject() throws IOException
{
- if (index == max)
+ if (count == pos)
{
return null;
}
- ASN1Encodable obj = getObjectAt(index++);
+ ASN1Encodable obj = elements[pos++];
if (obj instanceof ASN1Sequence)
{
return ((ASN1Sequence)obj).parser();
@@ -348,30 +377,29 @@ public abstract class ASN1Set
public ASN1Primitive getLoadedObject()
{
- return outer;
+ return ASN1Set.this;
}
public ASN1Primitive toASN1Primitive()
{
- return outer;
+ return ASN1Set.this;
}
};
}
public int hashCode()
{
- Enumeration e = this.getObjects();
- int hashCode = size();
+// return Arrays.hashCode(elements);
+ int i = elements.length;
+ int hc = i + 1;
- while (e.hasMoreElements())
+ // NOTE: Order-independent contribution of elements to avoid sorting
+ while (--i >= 0)
{
- Object o = getNext(e);
- hashCode *= 17;
-
- hashCode ^= o.hashCode();
+ hc += elements[i].toASN1Primitive().hashCode();
}
- return hashCode;
+ return hc;
}
/**
@@ -380,31 +408,18 @@ public abstract class ASN1Set
*/
ASN1Primitive toDERObject()
{
+ ASN1Encodable[] tmp;
if (isSorted)
{
- ASN1Set derSet = new DERSet();
-
- derSet.set = this.set;
-
- return derSet;
+ tmp = elements;
}
else
{
- Vector v = new Vector();
-
- for (int i = 0; i != set.size(); i++)
- {
- v.addElement(set.elementAt(i));
- }
-
- ASN1Set derSet = new DERSet();
-
- derSet.set = v;
-
- derSet.sort();
-
- return derSet;
+ tmp = (ASN1Encodable[])elements.clone();
+ sort(tmp);
}
+
+ return new DERSet(true, tmp);
}
/**
@@ -413,83 +428,77 @@ public abstract class ASN1Set
*/
ASN1Primitive toDLObject()
{
- ASN1Set derSet = new DLSet();
-
- derSet.set = this.set;
-
- return derSet;
+ return new DLSet(isSorted, elements);
}
- boolean asn1Equals(
- ASN1Primitive o)
+ boolean asn1Equals(ASN1Primitive other)
{
- if (!(o instanceof ASN1Set))
+ if (!(other instanceof ASN1Set))
{
return false;
}
- ASN1Set other = (ASN1Set)o;
+ ASN1Set that = (ASN1Set)other;
- if (this.size() != other.size())
+ int count = this.size();
+ if (that.size() != count)
{
return false;
}
- Enumeration s1 = this.getObjects();
- Enumeration s2 = other.getObjects();
+ DERSet dis = (DERSet)this.toDERObject();
+ DERSet dat = (DERSet)that.toDERObject();
- while (s1.hasMoreElements())
+ for (int i = 0; i < count; ++i)
{
- ASN1Encodable obj1 = getNext(s1);
- ASN1Encodable obj2 = getNext(s2);
+ ASN1Primitive p1 = dis.elements[i].toASN1Primitive();
+ ASN1Primitive p2 = dat.elements[i].toASN1Primitive();
- ASN1Primitive o1 = obj1.toASN1Primitive();
- ASN1Primitive o2 = obj2.toASN1Primitive();
-
- if (o1 == o2 || o1.equals(o2))
+ if (p1 != p2 && !p1.asn1Equals(p2))
{
- continue;
+ return false;
}
-
- return false;
}
return true;
}
- private ASN1Encodable getNext(Enumeration e)
+ boolean isConstructed()
{
- ASN1Encodable encObj = (ASN1Encodable)e.nextElement();
+ return true;
+ }
+
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
- // unfortunately null was allowed as a substitute for DER null
- if (encObj == null)
+ public String toString()
+ {
+ int count = size();
+ if (0 == count)
{
- return DERNull.INSTANCE;
+ return "[]";
}
- return encObj;
- }
-
- /**
- * return true if a <= b (arrays are assumed padded with zeros).
- */
- private boolean lessThanOrEqual(
- byte[] a,
- byte[] b)
- {
- int len = Math.min(a.length, b.length);
- for (int i = 0; i != len; ++i)
+ StringBuffer sb = new StringBuffer();
+ sb.append('[');
+ for (int i = 0;;)
{
- if (a[i] != b[i])
+ sb.append(elements[i]);
+ if (++i >= count)
{
- return (a[i] & 0xff) < (b[i] & 0xff);
+ break;
}
+ sb.append(", ");
}
- return len == a.length;
+ sb.append(']');
+ return sb.toString();
+ }
+
+ public Iterator<ASN1Encodable> iterator()
+ {
+ return new Arrays.Iterator<ASN1Encodable>(toArray());
}
- private byte[] getDEREncoded(
- ASN1Encodable obj)
+ private static byte[] getDEREncoded(ASN1Encodable obj)
{
try
{
@@ -501,67 +510,98 @@ public abstract class ASN1Set
}
}
- protected void sort()
+ /**
+ * return true if a <= b (arrays are assumed padded with zeros).
+ */
+ private static boolean lessThanOrEqual(byte[] a, byte[] b)
{
- if (!isSorted)
+// assert a.length >= 2 && b.length >= 2;
+
+ /*
+ * NOTE: Set elements in DER encodings are ordered first according to their tags (class and
+ * number); the CONSTRUCTED bit is not part of the tag.
+ *
+ * For SET-OF, this is unimportant. All elements have the same tag and DER requires them to
+ * either all be in constructed form or all in primitive form, according to that tag. The
+ * elements are effectively ordered according to their content octets.
+ *
+ * For SET, the elements will have distinct tags, and each will be in constructed or
+ * primitive form accordingly. Failing to ignore the CONSTRUCTED bit could therefore lead to
+ * ordering inversions.
+ */
+ int a0 = a[0] & ~BERTags.CONSTRUCTED;
+ int b0 = b[0] & ~BERTags.CONSTRUCTED;
+ if (a0 != b0)
+ {
+ return a0 < b0;
+ }
+
+ int last = Math.min(a.length, b.length) - 1;
+ for (int i = 1; i < last; ++i)
{
- isSorted = true;
- if (set.size() > 1)
+ if (a[i] != b[i])
{
- boolean swapped = true;
- int lastSwap = set.size() - 1;
+ return (a[i] & 0xFF) < (b[i] & 0xFF);
+ }
+ }
+ return (a[last] & 0xFF) <= (b[last] & 0xFF);
+ }
- while (swapped)
- {
- int index = 0;
- int swapIndex = 0;
- byte[] a = getDEREncoded((ASN1Encodable)set.elementAt(0));
+ private static void sort(ASN1Encodable[] t)
+ {
+ int count = t.length;
+ if (count < 2)
+ {
+ return;
+ }
- swapped = false;
+ ASN1Encodable eh = t[0], ei = t[1];
+ byte[] bh = getDEREncoded(eh), bi = getDEREncoded(ei);;
- while (index != lastSwap)
- {
- byte[] b = getDEREncoded((ASN1Encodable)set.elementAt(index + 1));
+ if (lessThanOrEqual(bi, bh))
+ {
+ ASN1Encodable et = ei; ei = eh; eh = et;
+ byte[] bt = bi; bi = bh; bh = bt;
+ }
- if (lessThanOrEqual(a, b))
- {
- a = b;
- }
- else
- {
- Object o = set.elementAt(index);
+ for (int i = 2; i < count; ++i)
+ {
+ ASN1Encodable e2 = t[i];
+ byte[] b2 = getDEREncoded(e2);
- set.setElementAt(set.elementAt(index + 1), index);
- set.setElementAt(o, index + 1);
+ if (lessThanOrEqual(bi, b2))
+ {
+ t[i - 2] = eh;
+ eh = ei; bh = bi;
+ ei = e2; bi = b2;
+ continue;
+ }
- swapped = true;
- swapIndex = index;
- }
+ if (lessThanOrEqual(bh, b2))
+ {
+ t[i - 2] = eh;
+ eh = e2; bh = b2;
+ continue;
+ }
- index++;
- }
+ int j = i - 1;
+ while (--j > 0)
+ {
+ ASN1Encodable e1 = t[j - 1];
+ byte[] b1 = getDEREncoded(e1);
- lastSwap = swapIndex;
+ if (lessThanOrEqual(b1, b2))
+ {
+ break;
}
- }
- }
- }
-
- boolean isConstructed()
- {
- return true;
- }
- abstract void encode(ASN1OutputStream out)
- throws IOException;
+ t[j] = e1;
+ }
- public String toString()
- {
- return set.toString();
- }
+ t[j] = e2;
+ }
- public Iterator<ASN1Encodable> iterator()
- {
- return new Arrays.Iterator<ASN1Encodable>(toArray());
+ t[count - 2] = eh;
+ t[count - 1] = ei;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java
index a1034292..95bc6113 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java
@@ -72,9 +72,9 @@ public class ASN1StreamParser
switch (tag)
{
case BERTags.SET:
- return new DERSetParser(this);
+ return new DLSetParser(this);
case BERTags.SEQUENCE:
- return new DERSequenceParser(this);
+ return new DLSequenceParser(this);
case BERTags.OCTET_STRING:
return new BEROctetStringParser(this);
}
@@ -101,7 +101,7 @@ public class ASN1StreamParser
{
// Note: !CONSTRUCTED => IMPLICIT
DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in;
- return new DERTaggedObject(false, tag, new DEROctetString(defIn.toByteArray()));
+ return new DLTaggedObject(false, tag, new DEROctetString(defIn.toByteArray()));
}
ASN1EncodableVector v = readVector();
@@ -114,8 +114,8 @@ public class ASN1StreamParser
}
return v.size() == 1
- ? new DERTaggedObject(true, tag, v.get(0))
- : new DERTaggedObject(false, tag, DERFactory.createSequence(v));
+ ? new DLTaggedObject(true, tag, v.get(0))
+ : new DLTaggedObject(false, tag, DLFactory.createSequence(v));
}
public ASN1Encodable readObject()
@@ -142,7 +142,8 @@ public class ASN1StreamParser
//
// calculate length
//
- int length = ASN1InputStream.readLength(_in, _limit);
+ int length = ASN1InputStream.readLength(_in, _limit,
+ tagNo == BERTags.OCTET_STRING || tagNo == BERTags.SEQUENCE || tagNo == BERTags.SET || tagNo == BERTags.EXTERNAL);
if (length < 0) // indefinite-length method
{
@@ -168,7 +169,7 @@ public class ASN1StreamParser
}
else
{
- DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length);
+ DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length, _limit);
if ((tag & BERTags.APPLICATION) != 0)
{
@@ -191,9 +192,9 @@ public class ASN1StreamParser
//
return new BEROctetStringParser(new ASN1StreamParser(defIn));
case BERTags.SEQUENCE:
- return new DERSequenceParser(new ASN1StreamParser(defIn));
+ return new DLSequenceParser(new ASN1StreamParser(defIn));
case BERTags.SET:
- return new DERSetParser(new ASN1StreamParser(defIn));
+ return new DLSetParser(new ASN1StreamParser(defIn));
case BERTags.EXTERNAL:
return new DERExternalParser(new ASN1StreamParser(defIn));
default:
@@ -229,10 +230,14 @@ public class ASN1StreamParser
ASN1EncodableVector readVector() throws IOException
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1Encodable obj = readObject();
+ if (null == obj)
+ {
+ return new ASN1EncodableVector(0);
+ }
- ASN1Encodable obj;
- while ((obj = readObject()) != null)
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ do
{
if (obj instanceof InMemoryRepresentable)
{
@@ -243,7 +248,7 @@ public class ASN1StreamParser
v.add(obj.toASN1Primitive());
}
}
-
+ while ((obj = readObject()) != null);
return v;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java
index 66ac4aaa..00aac911 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java
@@ -11,10 +11,9 @@ public abstract class ASN1TaggedObject
extends ASN1Primitive
implements ASN1TaggedObjectParser
{
- int tagNo;
- boolean empty = false;
- boolean explicit = true;
- ASN1Encodable obj = null;
+ final int tagNo;
+ final boolean explicit;
+ final ASN1Encodable obj;
static public ASN1TaggedObject getInstance(
ASN1TaggedObject obj,
@@ -22,7 +21,7 @@ public abstract class ASN1TaggedObject
{
if (explicit)
{
- return (ASN1TaggedObject)obj.getObject();
+ return getInstance(obj.getObject());
}
throw new IllegalArgumentException("implicitly tagged tagged object");
@@ -33,7 +32,7 @@ public abstract class ASN1TaggedObject
{
if (obj == null || obj instanceof ASN1TaggedObject)
{
- return (ASN1TaggedObject)obj;
+ return (ASN1TaggedObject)obj;
}
else if (obj instanceof byte[])
{
@@ -65,82 +64,39 @@ public abstract class ASN1TaggedObject
int tagNo,
ASN1Encodable obj)
{
- if (obj instanceof ASN1Choice)
+ if (null == obj)
{
- this.explicit = true;
+ throw new NullPointerException("'obj' cannot be null");
}
- else
- {
- this.explicit = explicit;
- }
-
- this.tagNo = tagNo;
-
- if (this.explicit)
- {
- this.obj = obj;
- }
- else
- {
- ASN1Primitive prim = obj.toASN1Primitive();
-
- if (prim instanceof ASN1Set)
- {
- ASN1Set s = null;
- }
- this.obj = obj;
- }
+ this.tagNo = tagNo;
+ this.explicit = explicit || (obj instanceof ASN1Choice);
+ this.obj = obj;
}
-
- boolean asn1Equals(
- ASN1Primitive o)
+
+ boolean asn1Equals(ASN1Primitive other)
{
- if (!(o instanceof ASN1TaggedObject))
+ if (!(other instanceof ASN1TaggedObject))
{
return false;
}
-
- ASN1TaggedObject other = (ASN1TaggedObject)o;
-
- if (tagNo != other.tagNo || empty != other.empty || explicit != other.explicit)
+
+ ASN1TaggedObject that = (ASN1TaggedObject)other;
+
+ if (this.tagNo != that.tagNo || this.explicit != that.explicit)
{
return false;
}
-
- if(obj == null)
- {
- if (other.obj != null)
- {
- return false;
- }
- }
- else
- {
- if (!(obj.toASN1Primitive().equals(other.obj.toASN1Primitive())))
- {
- return false;
- }
- }
-
- return true;
+
+ ASN1Primitive p1 = this.obj.toASN1Primitive();
+ ASN1Primitive p2 = that.obj.toASN1Primitive();
+
+ return p1 == p2 || p1.asn1Equals(p2);
}
-
+
public int hashCode()
{
- int code = tagNo;
-
- // TODO: actually this is wrong - the problem is that a re-encoded
- // object may end up with a different hashCode due to implicit
- // tagging. As implicit tagging is ambiguous if a sequence is involved
- // it seems the only correct method for both equals and hashCode is to
- // compare the encodings...
- if (obj != null)
- {
- code ^= obj.hashCode();
- }
-
- return code;
+ return tagNo ^ (explicit ? 0x0F : 0xF0) ^ obj.toASN1Primitive().hashCode();
}
/**
@@ -167,11 +123,6 @@ public abstract class ASN1TaggedObject
return explicit;
}
- public boolean isEmpty()
- {
- return empty;
- }
-
/**
* Return whatever was following the tag.
* <p>
@@ -181,12 +132,7 @@ public abstract class ASN1TaggedObject
*/
public ASN1Primitive getObject()
{
- if (obj != null)
- {
- return obj.toASN1Primitive();
- }
-
- return null;
+ return obj.toASN1Primitive();
}
/**
@@ -232,8 +178,7 @@ public abstract class ASN1TaggedObject
return new DLTaggedObject(explicit, tagNo, obj);
}
- abstract void encode(ASN1OutputStream out)
- throws IOException;
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
public String toString()
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UTCTime.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UTCTime.java
index d2909370..d9a26291 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UTCTime.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1UTCTime.java
@@ -90,7 +90,7 @@ public class ASN1UTCTime
}
else
{
- return new ASN1UTCTime(((ASN1OctetString)o).getOctets());
+ return new ASN1UTCTime(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -159,7 +159,15 @@ public class ASN1UTCTime
ASN1UTCTime(
byte[] time)
{
+ if (time.length < 2)
+ {
+ throw new IllegalArgumentException("UTCTime string too short");
+ }
this.time = time;
+ if (!(isDigit(0) && isDigit(1)))
+ {
+ throw new IllegalArgumentException("illegal characters in UTCTime string");
+ }
}
/**
@@ -275,6 +283,11 @@ public class ASN1UTCTime
}
}
+ private boolean isDigit(int pos)
+ {
+ return time.length > pos && time[pos] >= '0' && time[pos] <= '9';
+ }
+
boolean isConstructed()
{
return false;
@@ -287,20 +300,9 @@ public class ASN1UTCTime
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.write(BERTags.UTC_TIME);
-
- int length = time.length;
-
- out.writeLength(length);
-
- for (int i = 0; i != length; i++)
- {
- out.write((byte)time[i]);
- }
+ out.writeEncoded(withTag, BERTags.UTC_TIME, time);
}
boolean asn1Equals(
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java
index 3608668d..a0e36004 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java
@@ -97,18 +97,14 @@ public class BERApplicationSpecific
/* (non-Javadoc)
* @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
*/
- void encode(ASN1OutputStream out) throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- int classBits = BERTags.APPLICATION;
+ int flags = BERTags.APPLICATION;
if (isConstructed)
{
- classBits |= BERTags.CONSTRUCTED;
+ flags |= BERTags.CONSTRUCTED;
}
- out.writeTag(classBits, tag);
- out.write(0x80);
- out.write(octets);
- out.write(0x00);
- out.write(0x00);
+ out.writeEncodedIndef(withTag, flags, tag, octets);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERFactory.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERFactory.java
index 023be0b6..c8885a5f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERFactory.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERFactory.java
@@ -7,11 +7,21 @@ class BERFactory
static BERSequence createSequence(ASN1EncodableVector v)
{
- return v.size() < 1 ? EMPTY_SEQUENCE : new BERSequence(v);
+ if (v.size() < 1)
+ {
+ return EMPTY_SEQUENCE;
+ }
+
+ return new BERSequence(v);
}
static BERSet createSet(ASN1EncodableVector v)
{
- return v.size() < 1 ? EMPTY_SET : new BERSet(v);
+ if (v.size() < 1)
+ {
+ return EMPTY_SET;
+ }
+
+ return new BERSet(v);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERGenerator.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERGenerator.java
index c855110f..b4921577 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERGenerator.java
@@ -9,23 +9,20 @@ import java.io.OutputStream;
public class BERGenerator
extends ASN1Generator
{
- private boolean _tagged = false;
- private boolean _isExplicit;
- private int _tagNo;
+ private boolean _tagged = false;
+ private boolean _isExplicit;
+ private int _tagNo;
- protected BERGenerator(
- OutputStream out)
+ protected BERGenerator(OutputStream out)
{
super(out);
}
- protected BERGenerator(
- OutputStream out,
- int tagNo,
- boolean isExplicit)
+ protected BERGenerator(OutputStream out, int tagNo, boolean isExplicit)
{
super(out);
-
+
+ // TODO Check proper handling of implicit tagging
_tagged = true;
_isExplicit = isExplicit;
_tagNo = tagNo;
@@ -35,18 +32,14 @@ public class BERGenerator
{
return _out;
}
-
- private void writeHdr(
- int tag)
- throws IOException
+
+ private void writeHdr(int tag) throws IOException
{
_out.write(tag);
_out.write(0x80);
}
-
- protected void writeBERHeader(
- int tag)
- throws IOException
+
+ protected void writeBERHeader(int tag) throws IOException
{
if (_tagged)
{
@@ -58,7 +51,7 @@ public class BERGenerator
writeHdr(tag);
}
else
- {
+ {
if ((tag & BERTags.CONSTRUCTED) != 0)
{
writeHdr(tagNum | BERTags.CONSTRUCTED);
@@ -75,12 +68,11 @@ public class BERGenerator
}
}
- protected void writeBEREnd()
- throws IOException
+ protected void writeBEREnd() throws IOException
{
_out.write(0x00);
_out.write(0x00);
-
+
if (_tagged && _isExplicit) // write extra end for tag header
{
_out.write(0x00);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetString.java b/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetString.java
index 63349340..3544c564 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetString.java
@@ -3,7 +3,7 @@ package org.bouncycastle.asn1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Enumeration;
-import java.util.Vector;
+import java.util.NoSuchElementException;
/**
* ASN.1 OctetStrings, with indefinite length rules, and <i>constructed form</i> support.
@@ -22,7 +22,7 @@ import java.util.Vector;
public class BEROctetString
extends ASN1OctetString
{
- private static final int DEFAULT_LENGTH = 1000;
+ private static final int DEFAULT_CHUNK_SIZE = 1000;
private final int chunkSize;
private final ASN1OctetString[] octs;
@@ -39,13 +39,7 @@ public class BEROctetString
{
try
{
- DEROctetString o = (DEROctetString)octs[i];
-
- bOut.write(o.getOctets());
- }
- catch (ClassCastException e)
- {
- throw new IllegalArgumentException(octs[i].getClass().getName() + " found in input should only contain DEROctetString");
+ bOut.write(octs[i].getOctets());
}
catch (IOException e)
{
@@ -63,7 +57,7 @@ public class BEROctetString
public BEROctetString(
byte[] string)
{
- this(string, DEFAULT_LENGTH);
+ this(string, DEFAULT_CHUNK_SIZE);
}
/**
@@ -75,7 +69,7 @@ public class BEROctetString
public BEROctetString(
ASN1OctetString[] octs)
{
- this(octs, DEFAULT_LENGTH);
+ this(octs, DEFAULT_CHUNK_SIZE);
}
/**
@@ -112,15 +106,6 @@ public class BEROctetString
}
/**
- * Return a concatenated byte array of all the octets making up the constructed OCTET STRING
- * @return the full OCTET STRING.
- */
- public byte[] getOctets()
- {
- return string;
- }
-
- /**
* Return the OCTET STRINGs that make up this string.
*
* @return an Enumeration of the component OCTET STRINGs.
@@ -129,7 +114,28 @@ public class BEROctetString
{
if (octs == null)
{
- return generateOcts().elements();
+ return new Enumeration()
+ {
+ int pos = 0;
+
+ public boolean hasMoreElements()
+ {
+ return pos < string.length;
+ }
+
+ public Object nextElement()
+ {
+ if (pos < string.length)
+ {
+ int length = Math.min(string.length - pos, chunkSize);
+ byte[] chunk = new byte[length];
+ System.arraycopy(string, pos, chunk, 0, length);
+ pos += length;
+ return new DEROctetString(chunk);
+ }
+ throw new NoSuchElementException();
+ }
+ };
}
return new Enumeration()
@@ -143,37 +149,15 @@ public class BEROctetString
public Object nextElement()
{
- return octs[counter++];
+ if (counter < octs.length)
+ {
+ return octs[counter++];
+ }
+ throw new NoSuchElementException();
}
};
}
- private Vector generateOcts()
- {
- Vector vec = new Vector();
- for (int i = 0; i < string.length; i += chunkSize)
- {
- int end;
-
- if (i + chunkSize > string.length)
- {
- end = string.length;
- }
- else
- {
- end = i + chunkSize;
- }
-
- byte[] nStr = new byte[end - i];
-
- System.arraycopy(string, i, nStr, 0, nStr.length);
-
- vec.addElement(new DEROctetString(nStr));
- }
-
- return vec;
- }
-
boolean isConstructed()
{
return true;
@@ -191,37 +175,19 @@ public class BEROctetString
return 2 + length + 2;
}
- public void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.write(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
-
- out.write(0x80);
-
- //
- // write out the octet array
- //
- for (Enumeration e = getObjects(); e.hasMoreElements();)
- {
- out.writeObject((ASN1Encodable)e.nextElement());
- }
-
- out.write(0x00);
- out.write(0x00);
+ out.writeEncodedIndef(withTag, BERTags.CONSTRUCTED | BERTags.OCTET_STRING, getObjects());
}
static BEROctetString fromSequence(ASN1Sequence seq)
{
- ASN1OctetString[] v = new ASN1OctetString[seq.size()];
- Enumeration e = seq.getObjects();
- int index = 0;
-
- while (e.hasMoreElements())
+ int count = seq.size();
+ ASN1OctetString[] v = new ASN1OctetString[count];
+ for (int i = 0; i < count; ++i)
{
- v[index++] = (ASN1OctetString)e.nextElement();
+ v[i] = ASN1OctetString.getInstance(seq.getObjectAt(i));
}
-
return new BEROctetString(v);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java b/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java
index 55e695c7..68bf8015 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java
@@ -20,7 +20,7 @@ public class BEROctetStringGenerator
throws IOException
{
super(out);
-
+
writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
}
@@ -40,7 +40,7 @@ public class BEROctetStringGenerator
throws IOException
{
super(out, tagNo, isExplicit);
-
+
writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
}
@@ -65,7 +65,7 @@ public class BEROctetStringGenerator
{
return new BufferedBEROctetStream(buf);
}
-
+
private class BufferedBEROctetStream
extends OutputStream
{
@@ -80,7 +80,7 @@ public class BEROctetStringGenerator
_off = 0;
_derOut = new DEROutputStream(_out);
}
-
+
public void write(
int b)
throws IOException
@@ -89,7 +89,7 @@ public class BEROctetStringGenerator
if (_off == _buf.length)
{
- DEROctetString.encode(_derOut, _buf);
+ DEROctetString.encode(_derOut, true, _buf, 0, _buf.length);
_off = 0;
}
}
@@ -107,7 +107,7 @@ public class BEROctetStringGenerator
break;
}
- DEROctetString.encode(_derOut, _buf);
+ DEROctetString.encode(_derOut, true, _buf, 0, _buf.length);
_off = 0;
off += numToCopy;
@@ -115,17 +115,16 @@ public class BEROctetStringGenerator
}
}
- public void close()
+ public void close()
throws IOException
{
if (_off != 0)
{
- byte[] bytes = new byte[_off];
- System.arraycopy(_buf, 0, bytes, 0, _off);
-
- DEROctetString.encode(_derOut, bytes);
+ DEROctetString.encode(_derOut, true, _buf, 0, _off);
}
-
+
+ _derOut.flushInternal();
+
writeBEREnd();
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BEROutputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/BEROutputStream.java
index 22a37ed4..6bced5e4 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BEROutputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BEROutputStream.java
@@ -1,51 +1,22 @@
package org.bouncycastle.asn1;
-import java.io.IOException;
import java.io.OutputStream;
/**
- * A class which writes indefinite and definite length objects. Objects which specify DER will be encoded accordingly, but DL or BER
- * objects will be encoded as defined.
+ * A class which writes indefinite and definite length objects. Objects which specify DER will be
+ * encoded accordingly, but DL or BER objects will be encoded as defined.
*/
-public class BEROutputStream
- extends DEROutputStream
+class BEROutputStream
+ extends ASN1OutputStream
{
/**
* Base constructor.
*
- * @param os target output stream.
+ * @param os
+ * target output stream.
*/
- public BEROutputStream(
- OutputStream os)
+ BEROutputStream(OutputStream os)
{
super(os);
}
-
- /**
- * Write out an ASN.1 object.
- *
- * @param obj the object to be encoded.
- * @throws IOException if there is an issue on encoding or output of the object.
- */
- public void writeObject(
- Object obj)
- throws IOException
- {
- if (obj == null)
- {
- writeNull();
- }
- else if (obj instanceof ASN1Primitive)
- {
- ((ASN1Primitive)obj).encode(this);
- }
- else if (obj instanceof ASN1Encodable)
- {
- ((ASN1Encodable)obj).toASN1Primitive().encode(this);
- }
- else
- {
- throw new IOException("object not BEREncodable");
- }
- }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERSequence.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERSequence.java
index 3ecb1461..269c6d43 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERSequence.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERSequence.java
@@ -1,7 +1,6 @@
package org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* Indefinite length SEQUENCE of objects.
@@ -24,56 +23,43 @@ public class BERSequence
/**
* Create a sequence containing one object
*/
- public BERSequence(
- ASN1Encodable obj)
+ public BERSequence(ASN1Encodable element)
{
- super(obj);
+ super(element);
}
/**
* Create a sequence containing a vector of objects.
*/
- public BERSequence(
- ASN1EncodableVector v)
+ public BERSequence(ASN1EncodableVector elementVector)
{
- super(v);
+ super(elementVector);
}
/**
* Create a sequence containing an array of objects.
*/
- public BERSequence(
- ASN1Encodable[] array)
+ public BERSequence(ASN1Encodable[] elements)
{
- super(array);
+ super(elements);
}
- int encodedLength()
- throws IOException
+ int encodedLength() throws IOException
{
- int length = 0;
- for (Enumeration e = getObjects(); e.hasMoreElements();)
+ int count = elements.length;
+ int totalLength = 0;
+
+ for (int i = 0; i < count; ++i)
{
- length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
+ ASN1Primitive p = elements[i].toASN1Primitive();
+ totalLength += p.encodedLength();
}
- return 2 + length + 2;
+ return 2 + totalLength + 2;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
- out.write(0x80);
-
- Enumeration e = getObjects();
- while (e.hasMoreElements())
- {
- out.writeObject((ASN1Encodable)e.nextElement());
- }
-
- out.write(0x00);
- out.write(0x00);
+ out.writeEncodedIndef(withTag, BERTags.SEQUENCE | BERTags.CONSTRUCTED, elements);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERSet.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERSet.java
index 29ae7fd7..905b4e72 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERSet.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERSet.java
@@ -1,7 +1,6 @@
package org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* Indefinite length <code>SET</code> and <code>SET OF</code> constructs.
@@ -30,60 +29,52 @@ public class BERSet
/**
* Create a SET containing one object.
*
- * @param obj - a single object that makes up the set.
+ * @param element - a single object that makes up the set.
*/
- public BERSet(
- ASN1Encodable obj)
+ public BERSet(ASN1Encodable element)
{
- super(obj);
+ super(element);
}
/**
* Create a SET containing multiple objects.
- * @param v a vector of objects making up the set.
+ * @param elementVector a vector of objects making up the set.
*/
- public BERSet(
- ASN1EncodableVector v)
+ public BERSet(ASN1EncodableVector elementVector)
{
- super(v, false);
+ super(elementVector, false);
}
/**
* Create a SET from an array of objects.
- * @param a an array of ASN.1 objects.
+ * @param elements an array of ASN.1 objects.
*/
- public BERSet(
- ASN1Encodable[] a)
+ public BERSet(ASN1Encodable[] elements)
{
- super(a, false);
+ super(elements, false);
}
- int encodedLength()
- throws IOException
+ BERSet(boolean isSorted, ASN1Encodable[] elements)
{
- int length = 0;
- for (Enumeration e = getObjects(); e.hasMoreElements();)
- {
- length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
- }
-
- return 2 + length + 2;
+ super(isSorted, elements);
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ int encodedLength() throws IOException
{
- out.write(BERTags.SET | BERTags.CONSTRUCTED);
- out.write(0x80);
+ int count = elements.length;
+ int totalLength = 0;
- Enumeration e = getObjects();
- while (e.hasMoreElements())
+ for (int i = 0; i < count; ++i)
{
- out.writeObject((ASN1Encodable)e.nextElement());
+ ASN1Primitive p = elements[i].toASN1Primitive();
+ totalLength += p.encodedLength();
}
- out.write(0x00);
- out.write(0x00);
+ return 2 + totalLength + 2;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodedIndef(withTag, BERTags.SET | BERTags.CONSTRUCTED, elements);
}
-} \ No newline at end of file
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java
index 37599fbe..51036f67 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java
@@ -47,101 +47,92 @@ public class BERTaggedObject
boolean isConstructed()
{
- if (!empty)
- {
- if (explicit)
- {
- return true;
- }
- else
- {
- ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
-
- return primitive.isConstructed();
- }
- }
- else
- {
- return true;
- }
+ return explicit || obj.toASN1Primitive().isConstructed();
}
int encodedLength()
throws IOException
{
- if (!empty)
- {
- ASN1Primitive primitive = obj.toASN1Primitive();
- int length = primitive.encodedLength();
+ ASN1Primitive primitive = obj.toASN1Primitive();
+ int length = primitive.encodedLength();
- if (explicit)
- {
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
- }
- else
- {
- // header length already in calculation
- length = length - 1;
-
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ if (explicit)
+ {
+ return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
}
else
{
- return StreamUtil.calculateTagLength(tagNo) + 1;
+ // header length already in calculation
+ length = length - 1;
+
+ return StreamUtil.calculateTagLength(tagNo) + length;
}
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
+ out.writeTag(withTag, BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
out.write(0x80);
- if (!empty)
+ if (!explicit)
{
- if (!explicit)
+ Enumeration e;
+ if (obj instanceof ASN1OctetString)
{
- Enumeration e;
- if (obj instanceof ASN1OctetString)
+ if (obj instanceof BEROctetString)
{
- if (obj instanceof BEROctetString)
- {
- e = ((BEROctetString)obj).getObjects();
- }
- else
- {
- ASN1OctetString octs = (ASN1OctetString)obj;
- BEROctetString berO = new BEROctetString(octs.getOctets());
- e = berO.getObjects();
- }
- }
- else if (obj instanceof ASN1Sequence)
- {
- e = ((ASN1Sequence)obj).getObjects();
- }
- else if (obj instanceof ASN1Set)
- {
- e = ((ASN1Set)obj).getObjects();
+ e = ((BEROctetString)obj).getObjects();
}
else
{
- throw new ASN1Exception("not implemented: " + obj.getClass().getName());
- }
-
- while (e.hasMoreElements())
- {
- out.writeObject((ASN1Encodable)e.nextElement());
+ ASN1OctetString octs = (ASN1OctetString)obj;
+ BEROctetString berO = new BEROctetString(octs.getOctets());
+ e = berO.getObjects();
}
}
+ else if (obj instanceof ASN1Sequence)
+ {
+ e = ((ASN1Sequence)obj).getObjects();
+ }
+ else if (obj instanceof ASN1Set)
+ {
+ e = ((ASN1Set)obj).getObjects();
+ }
else
{
- out.writeObject(obj);
+ throw new ASN1Exception("not implemented: " + obj.getClass().getName());
}
+
+ out.writeElements(e);
+ }
+ else
+ {
+ out.writePrimitive(obj.toASN1Primitive(), true);
}
out.write(0x00);
out.write(0x00);
+
+// ASN1Primitive primitive = obj.toASN1Primitive();
+//
+// int flags = BERTags.TAGGED;
+// if (explicit || primitive.isConstructed())
+// {
+// flags |= BERTags.CONSTRUCTED;
+// }
+//
+// out.writeTag(withTag, flags, tagNo);
+//
+// if (explicit)
+// {
+// out.write(0x80);
+// out.writePrimitive(obj.toASN1Primitive(), true);
+// out.write(0x00);
+// out.write(0x00);
+// }
+// else
+// {
+// out.writePrimitive(obj.toASN1Primitive(), false);
+// }
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ConstructedOctetStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/ConstructedOctetStream.java
index f247b11f..fd261787 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ConstructedOctetStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ConstructedOctetStream.java
@@ -26,15 +26,14 @@ class ConstructedOctetStream
return -1;
}
- ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
-
- if (s == null)
+ ASN1OctetStringParser next = getNextParser();
+ if (next == null)
{
return -1;
}
_first = false;
- _currentStream = s.getOctetStream();
+ _currentStream = next.getOctetStream();
}
int totalRead = 0;
@@ -54,15 +53,14 @@ class ConstructedOctetStream
}
else
{
- ASN1OctetStringParser aos = (ASN1OctetStringParser)_parser.readObject();
-
- if (aos == null)
+ ASN1OctetStringParser next = getNextParser();
+ if (next == null)
{
_currentStream = null;
return totalRead < 1 ? -1 : totalRead;
}
- _currentStream = aos.getOctetStream();
+ _currentStream = next.getOctetStream();
}
}
}
@@ -77,15 +75,14 @@ class ConstructedOctetStream
return -1;
}
- ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
-
- if (s == null)
+ ASN1OctetStringParser next = getNextParser();
+ if (next == null)
{
return -1;
}
-
+
_first = false;
- _currentStream = s.getOctetStream();
+ _currentStream = next.getOctetStream();
}
for (;;)
@@ -97,15 +94,30 @@ class ConstructedOctetStream
return b;
}
- ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
-
- if (s == null)
+ ASN1OctetStringParser next = getNextParser();
+ if (next == null)
{
_currentStream = null;
return -1;
}
- _currentStream = s.getOctetStream();
+ _currentStream = next.getOctetStream();
}
}
+
+ private ASN1OctetStringParser getNextParser() throws IOException
+ {
+ ASN1Encodable asn1Obj = _parser.readObject();
+ if (asn1Obj == null)
+ {
+ return null;
+ }
+
+ if (asn1Obj instanceof ASN1OctetStringParser)
+ {
+ return (ASN1OctetStringParser)asn1Obj;
+ }
+
+ throw new IOException("unknown object encountered: " + asn1Obj.getClass());
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java
index a5999c09..eb54b203 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java
@@ -111,14 +111,14 @@ public class DERApplicationSpecific
/* (non-Javadoc)
* @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
*/
- void encode(ASN1OutputStream out) throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- int classBits = BERTags.APPLICATION;
+ int flags = BERTags.APPLICATION;
if (isConstructed)
{
- classBits |= BERTags.CONSTRUCTED;
+ flags |= BERTags.CONSTRUCTED;
}
- out.writeEncoded(classBits, tag, octets);
+ out.writeEncoded(withTag, flags, tag, octets);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java
index c64802c9..8daf8422 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java
@@ -81,9 +81,21 @@ public class DERBMPString
DERBMPString(
byte[] string)
{
- char[] cs = new char[string.length / 2];
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
+ int byteLen = string.length;
+ if (0 != (byteLen & 1))
+ {
+ throw new IllegalArgumentException("malformed BMPString encoding encountered");
+ }
- for (int i = 0; i != cs.length; i++)
+ int charLen = byteLen / 2;
+ char[] cs = new char[charLen];
+
+ for (int i = 0; i != charLen; i++)
{
cs[i] = (char)((string[2 * i] << 8) | (string[2 * i + 1] & 0xff));
}
@@ -93,6 +105,11 @@ public class DERBMPString
DERBMPString(char[] string)
{
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
this.string = string;
}
@@ -103,6 +120,11 @@ public class DERBMPString
public DERBMPString(
String string)
{
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
this.string = string.toCharArray();
}
@@ -145,18 +167,49 @@ public class DERBMPString
}
void encode(
- ASN1OutputStream out)
+ ASN1OutputStream out, boolean withTag)
throws IOException
{
- out.write(BERTags.BMP_STRING);
- out.writeLength(string.length * 2);
+ int count = string.length;
+ if (withTag)
+ {
+ out.write(BERTags.BMP_STRING);
+ }
+ out.writeLength(count * 2);
+
+ byte[] buf = new byte[8];
- for (int i = 0; i != string.length; i++)
+ int i = 0, limit = count & -4;
+ while (i < limit)
{
- char c = string[i];
+ char c0 = string[i], c1 = string[i + 1], c2 = string[i + 2], c3 = string[i + 3];
+ i += 4;
+
+ buf[0] = (byte)(c0 >> 8);
+ buf[1] = (byte)c0;
+ buf[2] = (byte)(c1 >> 8);
+ buf[3] = (byte)c1;
+ buf[4] = (byte)(c2 >> 8);
+ buf[5] = (byte)c2;
+ buf[6] = (byte)(c3 >> 8);
+ buf[7] = (byte)c3;
+
+ out.write(buf, 0, 8);
+ }
+ if (i < count)
+ {
+ int bufPos = 0;
+ do
+ {
+ char c0 = string[i];
+ i += 1;
+
+ buf[bufPos++] = (byte)(c0 >> 8);
+ buf[bufPos++] = (byte)c0;
+ }
+ while (i < count);
- out.write((byte)(c >> 8));
- out.write((byte)c);
+ out.write(buf, 0, bufPos);
}
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java
index 8efcaf7a..0807aaff 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java
@@ -63,24 +63,13 @@ public class DERBitString
}
else
{
- return fromOctetString(((ASN1OctetString)o).getOctets());
+ return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
}
}
-
- protected DERBitString(
- byte data,
- int padBits)
- {
- this(toByteArray(data), padBits);
- }
- private static byte[] toByteArray(byte data)
+ protected DERBitString(byte data, int padBits)
{
- byte[] rv = new byte[1];
-
- rv[0] = data;
-
- return rv;
+ super(data, padBits);
}
/**
@@ -123,17 +112,30 @@ public class DERBitString
return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- byte[] string = derForm(data, padBits);
- byte[] bytes = new byte[string.length + 1];
+ int len = data.length;
+ if (0 == len
+ || 0 == padBits
+ || (data[len - 1] == (byte)(data[len - 1] & (0xFF << padBits))))
+ {
+ out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
+ }
+ else
+ {
+ byte der = (byte)(data[len - 1] & (0xFF << padBits));
+ out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data, 0, len - 1, der);
+ }
+ }
- bytes[0] = (byte)getPadBits();
- System.arraycopy(string, 0, bytes, 1, bytes.length - 1);
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
- out.writeEncoded(BERTags.BIT_STRING, bytes);
+ ASN1Primitive toDLObject()
+ {
+ return this;
}
static DERBitString fromOctetString(byte[] bytes)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERBoolean.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERBoolean.java
deleted file mode 100644
index 378ea359..00000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERBoolean.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.bouncycastle.asn1;
-
-/**
- * @deprecated use ASN1Boolean
- */
-public class DERBoolean
- extends ASN1Boolean
-{
- /**
- * @deprecated use getInstance(boolean) method.
- * @param value
- */
- public DERBoolean(boolean value)
- {
- super(value);
- }
-
- DERBoolean(byte[] value)
- {
- super(value);
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERExternal.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERExternal.java
index 480a3942..02b0e763 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERExternal.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERExternal.java
@@ -53,6 +53,16 @@ public class DERExternal
super(directReference, indirectReference, dataValueDescriptor, encoding, externalData);
}
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
int encodedLength()
throws IOException
{
@@ -62,8 +72,7 @@ public class DERExternal
/* (non-Javadoc)
* @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
*/
- void encode(ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (directReference != null)
@@ -80,6 +89,7 @@ public class DERExternal
}
DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent);
baos.write(obj.getEncoded(ASN1Encoding.DER));
- out.writeEncoded(BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
+
+ out.writeEncoded(withTag, BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERFactory.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERFactory.java
index b829e3bc..d7c7d866 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERFactory.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERFactory.java
@@ -7,11 +7,21 @@ class DERFactory
static ASN1Sequence createSequence(ASN1EncodableVector v)
{
- return v.size() < 1 ? EMPTY_SEQUENCE : new DLSequence(v);
+ if (v.size() < 1)
+ {
+ return EMPTY_SEQUENCE;
+ }
+
+ return new DERSequence(v);
}
static ASN1Set createSet(ASN1EncodableVector v)
{
- return v.size() < 1 ? EMPTY_SET : new DLSet(v);
+ if (v.size() < 1)
+ {
+ return EMPTY_SET;
+ }
+
+ return new DERSet(v);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java
index 52a580fa..bac214f0 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java
@@ -71,7 +71,7 @@ public class DERGeneralString
}
else
{
- return new DERGeneralString(((ASN1OctetString)o).getOctets());
+ return new DERGeneralString(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -125,12 +125,11 @@ public class DERGeneralString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.GENERAL_STRING, string);
+ out.writeEncoded(withTag, BERTags.GENERAL_STRING, string);
}
-
+
public int hashCode()
{
return Arrays.hashCode(string);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralizedTime.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralizedTime.java
index 1270e85c..33b9abf5 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralizedTime.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralizedTime.java
@@ -107,10 +107,18 @@ public class DERGeneralizedTime
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.GENERALIZED_TIME, getDERTime());
+ out.writeEncoded(withTag, BERTags.GENERALIZED_TIME, getDERTime());
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERGraphicString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERGraphicString.java
index 01baf0f9..2beb4351 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERGraphicString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERGraphicString.java
@@ -63,7 +63,7 @@ public class DERGraphicString
}
else
{
- return new DERGraphicString(((ASN1OctetString)o).getOctets());
+ return new DERGraphicString(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -92,11 +92,9 @@ public class DERGraphicString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.GRAPHIC_STRING, string);
+ out.writeEncoded(withTag, BERTags.GRAPHIC_STRING, string);
}
public int hashCode()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java
index d2f7a8d1..d238741a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java
@@ -69,7 +69,7 @@ public class DERIA5String
}
else
{
- return new DERIA5String(((ASN1OctetString)o).getOctets());
+ return new DERIA5String(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -107,11 +107,11 @@ public class DERIA5String
{
if (string == null)
{
- throw new NullPointerException("string cannot be null");
+ throw new NullPointerException("'string' cannot be null");
}
if (validate && !isIA5String(string))
{
- throw new IllegalArgumentException("string contains illegal characters");
+ throw new IllegalArgumentException("'string' contains illegal characters");
}
this.string = Strings.toByteArray(string);
@@ -142,11 +142,9 @@ public class DERIA5String
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.IA5_STRING, string);
+ out.writeEncoded(withTag, BERTags.IA5_STRING, string);
}
public int hashCode()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERNull.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERNull.java
index 1981fef7..38960a41 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERNull.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERNull.java
@@ -14,11 +14,7 @@ public class DERNull
private static final byte[] zeroBytes = new byte[0];
- /**
- * @deprecated use DERNull.INSTANCE
- */
- // Android-changed: Reduce visibility to protected.
- protected DERNull()
+ private DERNull()
{
}
@@ -32,10 +28,8 @@ public class DERNull
return 2;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.NULL, zeroBytes);
+ out.writeEncoded(withTag, BERTags.NULL, zeroBytes);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java
index 1f82be17..9a4a968d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java
@@ -140,11 +140,9 @@ public class DERNumericString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.NUMERIC_STRING, string);
+ out.writeEncoded(withTag, BERTags.NUMERIC_STRING, string);
}
public int hashCode()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetString.java
index 1201c74e..2b535e89 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetString.java
@@ -41,18 +41,23 @@ public class DEROctetString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.OCTET_STRING, string);
+ out.writeEncoded(withTag, BERTags.OCTET_STRING, string);
}
- static void encode(
- DEROutputStream derOut,
- byte[] bytes)
- throws IOException
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
+ static void encode(ASN1OutputStream derOut, boolean withTag, byte[] buf, int off, int len) throws IOException
{
- derOut.writeEncoded(BERTags.OCTET_STRING, bytes);
+ derOut.writeEncoded(withTag, BERTags.OCTET_STRING, buf, off, len);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DEROutputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/DEROutputStream.java
index 8b18c3d7..caa97660 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DEROutputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DEROutputStream.java
@@ -6,30 +6,22 @@ import java.io.OutputStream;
/**
* Stream that outputs encoding based on distinguished encoding rules.
*/
+// BEGIN Android-changed: Class is package-private in upstream.
+// Leaving as public as it's used by build/make/tools/signapk/src/com/android/signapk/SignApk.java
public class DEROutputStream
extends ASN1OutputStream
{
- public DEROutputStream(
- OutputStream os)
+ public DEROutputStream(OutputStream os)
{
super(os);
}
- public void writeObject(
- ASN1Encodable obj)
- throws IOException
+ void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
{
- if (obj != null)
- {
- obj.toASN1Primitive().toDERObject().encode(this);
- }
- else
- {
- throw new IOException("null object detected");
- }
+ primitive.toDERObject().encode(this, withTag);
}
- ASN1OutputStream getDERSubStream()
+ DEROutputStream getDERSubStream()
{
return this;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java
index a234eea4..f7721c28 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java
@@ -151,11 +151,9 @@ public class DERPrintableString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.PRINTABLE_STRING, string);
+ out.writeEncoded(withTag, BERTags.PRINTABLE_STRING, string);
}
public int hashCode()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERSequence.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERSequence.java
index 8efbbab5..e5474714 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERSequence.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERSequence.java
@@ -1,7 +1,6 @@
package org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* Definite length SEQUENCE, encoding tells explicit number of bytes
@@ -12,6 +11,11 @@ import java.util.Enumeration;
public class DERSequence
extends ASN1Sequence
{
+ public static DERSequence convert(ASN1Sequence seq)
+ {
+ return (DERSequence)seq.toDERObject();
+ }
+
private int bodyLength = -1;
/**
@@ -23,56 +27,56 @@ public class DERSequence
/**
* Create a sequence containing one object
- * @param obj the object to go in the sequence.
+ * @param element the object to go in the sequence.
*/
- public DERSequence(
- ASN1Encodable obj)
+ public DERSequence(ASN1Encodable element)
{
- super(obj);
+ super(element);
}
/**
* Create a sequence containing a vector of objects.
- * @param v the vector of objects to make up the sequence.
+ * @param elementVector the vector of objects to make up the sequence.
*/
- public DERSequence(
- ASN1EncodableVector v)
+ public DERSequence(ASN1EncodableVector elementVector)
{
- super(v);
+ super(elementVector);
}
/**
* Create a sequence containing an array of objects.
- * @param array the array of objects to make up the sequence.
+ * @param elements the array of objects to make up the sequence.
*/
- public DERSequence(
- ASN1Encodable[] array)
+ public DERSequence(ASN1Encodable[] elements)
{
- super(array);
+ super(elements);
}
- private int getBodyLength()
- throws IOException
+ DERSequence(ASN1Encodable[] elements, boolean clone)
+ {
+ super(elements, clone);
+ }
+
+ private int getBodyLength() throws IOException
{
if (bodyLength < 0)
{
- int length = 0;
+ int count = elements.length;
+ int totalLength = 0;
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ for (int i = 0; i < count; ++i)
{
- Object obj = e.nextElement();
-
- length += ((ASN1Encodable)obj).toASN1Primitive().toDERObject().encodedLength();
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ totalLength += derObject.encodedLength();
}
- bodyLength = length;
+ this.bodyLength = totalLength;
}
return bodyLength;
}
- int encodedLength()
- throws IOException
+ int encodedLength() throws IOException
{
int length = getBodyLength();
@@ -87,21 +91,55 @@ public class DERSequence
* ASN.1 descriptions given. Rather than just outputting SEQUENCE,
* we also have to specify CONSTRUCTED, and the objects length.
*/
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- ASN1OutputStream dOut = out.getDERSubStream();
- int length = getBodyLength();
+ if (withTag)
+ {
+ out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
+ }
+
+ DEROutputStream derOut = out.getDERSubStream();
- out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
- out.writeLength(length);
+ int count = elements.length;
+ if (bodyLength >= 0 || count > 16)
+ {
+ out.writeLength(getBodyLength());
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ derObject.encode(derOut, true);
+ }
+ }
+ else
{
- Object obj = e.nextElement();
+ int totalLength = 0;
+
+ ASN1Primitive[] derObjects = new ASN1Primitive[count];
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ derObjects[i] = derObject;
+ totalLength += derObject.encodedLength();
+ }
- dOut.writeObject((ASN1Encodable)obj);
+ this.bodyLength = totalLength;
+ out.writeLength(totalLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ derObjects[i].encode(derOut, true);
+ }
}
}
+
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERSequenceParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERSequenceParser.java
index 5503feb8..aed121aa 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERSequenceParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERSequenceParser.java
@@ -3,7 +3,7 @@ package org.bouncycastle.asn1;
import java.io.IOException;
/**
- * Parser class for DER SEQUENCEs.
+ * @deprecated Use DLSequenceParser instead
*/
public class DERSequenceParser
implements ASN1SequenceParser
@@ -36,7 +36,7 @@ public class DERSequenceParser
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new DERSequence(_parser.readVector());
+ return new DLSequence(_parser.readVector());
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java
index 99d10d8e..bc55bcb9 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java
@@ -1,7 +1,6 @@
package org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* A DER encoded SET object
@@ -16,6 +15,11 @@ import java.util.Enumeration;
public class DERSet
extends ASN1Set
{
+ public static DERSet convert(ASN1Set set)
+ {
+ return (DERSet)set.toDERObject();
+ }
+
private int bodyLength = -1;
/**
@@ -27,63 +31,56 @@ public class DERSet
/**
* create a set containing one object
- * @param obj the object to go in the set
+ * @param element the object to go in the set
*/
- public DERSet(
- ASN1Encodable obj)
+ public DERSet(ASN1Encodable element)
{
- super(obj);
+ super(element);
}
/**
* create a set containing a vector of objects.
- * @param v the vector of objects to make up the set.
+ * @param elementVector the vector of objects to make up the set.
*/
- public DERSet(
- ASN1EncodableVector v)
+ public DERSet(ASN1EncodableVector elementVector)
{
- super(v, true);
+ super(elementVector, true);
}
-
+
/**
* create a set containing an array of objects.
- * @param a the array of objects to make up the set.
+ * @param elements the array of objects to make up the set.
*/
- public DERSet(
- ASN1Encodable[] a)
+ public DERSet(ASN1Encodable[] elements)
{
- super(a, true);
+ super(elements, true);
}
- DERSet(
- ASN1EncodableVector v,
- boolean doSort)
+ DERSet(boolean isSorted, ASN1Encodable[] elements)
{
- super(v, doSort);
+ super(checkSorted(isSorted), elements);
}
- private int getBodyLength()
- throws IOException
+ private int getBodyLength() throws IOException
{
if (bodyLength < 0)
{
- int length = 0;
+ int count = elements.length;
+ int totalLength = 0;
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ for (int i = 0; i < count; ++i)
{
- Object obj = e.nextElement();
-
- length += ((ASN1Encodable)obj).toASN1Primitive().toDERObject().encodedLength();
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ totalLength += derObject.encodedLength();
}
- bodyLength = length;
+ this.bodyLength = totalLength;
}
return bodyLength;
}
- int encodedLength()
- throws IOException
+ int encodedLength() throws IOException
{
int length = getBodyLength();
@@ -98,21 +95,64 @@ public class DERSet
* ASN.1 descriptions given. Rather than just outputting SET,
* we also have to specify CONSTRUCTED, and the objects length.
*/
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- ASN1OutputStream dOut = out.getDERSubStream();
- int length = getBodyLength();
+ if (withTag)
+ {
+ out.write(BERTags.SET | BERTags.CONSTRUCTED);
+ }
- out.write(BERTags.SET | BERTags.CONSTRUCTED);
- out.writeLength(length);
+ DEROutputStream derOut = out.getDERSubStream();
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ int count = elements.length;
+ if (bodyLength >= 0 || count > 16)
{
- Object obj = e.nextElement();
+ out.writeLength(getBodyLength());
+
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ derObject.encode(derOut, true);
+ }
+ }
+ else
+ {
+ int totalLength = 0;
+
+ ASN1Primitive[] derObjects = new ASN1Primitive[count];
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ derObjects[i] = derObject;
+ totalLength += derObject.encodedLength();
+ }
- dOut.writeObject((ASN1Encodable)obj);
+ this.bodyLength = totalLength;
+ out.writeLength(totalLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ derObjects[i].encode(derOut, true);
+ }
+ }
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return isSorted ? this : super.toDERObject();
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
+ private static boolean checkSorted(boolean isSorted)
+ {
+ if (!isSorted)
+ {
+ throw new IllegalStateException("DERSet elements should always be in sorted order");
}
+ return isSorted;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERSetParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERSetParser.java
index d16cb157..492f4a44 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERSetParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERSetParser.java
@@ -3,7 +3,7 @@ package org.bouncycastle.asn1;
import java.io.IOException;
/**
- * Parser class for DER SETs.
+ * @deprecated Use DLSetParser instead
*/
public class DERSetParser
implements ASN1SetParser
@@ -36,7 +36,7 @@ public class DERSetParser
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new DERSet(_parser.readVector(), false);
+ return new DLSet(_parser.readVector());
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java
index 289bfc8c..018f636a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java
@@ -117,11 +117,9 @@ public class DERT61String
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.T61_STRING, string);
+ out.writeEncoded(withTag, BERTags.T61_STRING, string);
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERTaggedObject.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERTaggedObject.java
index a87a0dc9..dfdfcd2a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERTaggedObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERTaggedObject.java
@@ -10,8 +10,6 @@ import java.io.IOException;
public class DERTaggedObject
extends ASN1TaggedObject
{
- private static final byte[] ZERO_BYTES = new byte[0];
-
/**
* @param explicit true if an explicitly tagged object.
* @param tagNo the tag number for this object.
@@ -32,87 +30,55 @@ public class DERTaggedObject
boolean isConstructed()
{
- if (!empty)
- {
- if (explicit)
- {
- return true;
- }
- else
- {
- ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
-
- return primitive.isConstructed();
- }
- }
- else
- {
- return true;
- }
+ return explicit || obj.toASN1Primitive().toDERObject().isConstructed();
}
int encodedLength()
throws IOException
{
- if (!empty)
- {
- ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
- int length = primitive.encodedLength();
-
- if (explicit)
- {
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
- }
- else
- {
- // header length already in calculation
- length = length - 1;
+ ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
+ int length = primitive.encodedLength();
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ if (explicit)
+ {
+ return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
}
else
{
- return StreamUtil.calculateTagLength(tagNo) + 1;
+ // header length already in calculation
+ length = length - 1;
+
+ return StreamUtil.calculateTagLength(tagNo) + length;
}
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (!empty)
+ ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
+
+ int flags = BERTags.TAGGED;
+ if (explicit || primitive.isConstructed())
{
- ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
+ flags |= BERTags.CONSTRUCTED;
+ }
- if (explicit)
- {
- out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
- out.writeLength(primitive.encodedLength());
- out.writeObject(primitive);
- }
- else
- {
- //
- // need to mark constructed types...
- //
- int flags;
- if (primitive.isConstructed())
- {
- flags = BERTags.CONSTRUCTED | BERTags.TAGGED;
- }
- else
- {
- flags = BERTags.TAGGED;
- }
+ out.writeTag(withTag, flags, tagNo);
- out.writeTag(flags, tagNo);
- out.writeImplicitObject(primitive);
- }
- }
- else
+ if (explicit)
{
- out.writeEncoded(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo, ZERO_BYTES);
+ out.writeLength(primitive.encodedLength());
}
+
+ primitive.encode(out.getDERSubStream(), explicit);
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java
index d1fffa67..ceb1409f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java
@@ -129,9 +129,8 @@ public class DERUTF8String
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.UTF8_STRING, string);
+ out.writeEncoded(withTag, BERTags.UTF8_STRING, string);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java
index 487f86d9..474584b4 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java
@@ -1,6 +1,5 @@
package org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.bouncycastle.util.Arrays;
@@ -68,7 +67,7 @@ public class DERUniversalString
}
else
{
- return new DERUniversalString(((ASN1OctetString)o).getOctets());
+ return new DERUniversalString(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -85,21 +84,18 @@ public class DERUniversalString
public String getString()
{
- StringBuffer buf = new StringBuffer("#");
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
+ StringBuffer buf = new StringBuffer("#");
+
+ byte[] string;
try
{
- aOut.writeObject(this);
+ string = getEncoded();
}
catch (IOException e)
{
throw new ASN1ParsingException("internal error encoding UniversalString");
}
-
- byte[] string = bOut.toByteArray();
-
+
for (int i = 0; i != string.length; i++)
{
buf.append(table[(string[i] >>> 4) & 0xf]);
@@ -129,13 +125,11 @@ public class DERUniversalString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.UNIVERSAL_STRING, this.getOctets());
+ out.writeEncoded(withTag, BERTags.UNIVERSAL_STRING, string);
}
-
+
boolean asn1Equals(
ASN1Primitive o)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERVideotexString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERVideotexString.java
index da231e15..35458a8e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERVideotexString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERVideotexString.java
@@ -63,7 +63,7 @@ public class DERVideotexString
}
else
{
- return new DERVideotexString(((ASN1OctetString)o).getOctets());
+ return new DERVideotexString(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -92,11 +92,9 @@ public class DERVideotexString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.VIDEOTEX_STRING, string);
+ out.writeEncoded(withTag, BERTags.VIDEOTEX_STRING, string);
}
public int hashCode()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java
index 5932c977..ddb692a9 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java
@@ -118,13 +118,11 @@ public class DERVisibleString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.VISIBLE_STRING, this.string);
+ out.writeEncoded(withTag, BERTags.VISIBLE_STRING, this.string);
}
-
+
boolean asn1Equals(
ASN1Primitive o)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLApplicationSpecific.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLApplicationSpecific.java
index 8369492a..88059a71 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLApplicationSpecific.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLApplicationSpecific.java
@@ -111,14 +111,14 @@ public class DLApplicationSpecific
/* (non-Javadoc)
* @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
*/
- void encode(ASN1OutputStream out) throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- int classBits = BERTags.APPLICATION;
+ int flags = BERTags.APPLICATION;
if (isConstructed)
{
- classBits |= BERTags.CONSTRUCTED;
+ flags |= BERTags.CONSTRUCTED;
}
- out.writeEncoded(classBits, tag, octets);
+ out.writeEncoded(withTag, flags, tag, octets);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java
index a5d9cbb6..176dc8e5 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java
@@ -63,24 +63,13 @@ public class DLBitString
}
else
{
- return fromOctetString(((ASN1OctetString)o).getOctets());
+ return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
}
}
- protected DLBitString(
- byte data,
- int padBits)
- {
- this(toByteArray(data), padBits);
- }
-
- private static byte[] toByteArray(byte data)
+ protected DLBitString(byte data, int padBits)
{
- byte[] rv = new byte[1];
-
- rv[0] = data;
-
- return rv;
+ super(data, padBits);
}
/**
@@ -123,17 +112,14 @@ public class DLBitString
return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- byte[] string = data;
- byte[] bytes = new byte[string.length + 1];
-
- bytes[0] = (byte)getPadBits();
- System.arraycopy(string, 0, bytes, 1, bytes.length - 1);
+ out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
+ }
- out.writeEncoded(BERTags.BIT_STRING, bytes);
+ ASN1Primitive toDLObject()
+ {
+ return this;
}
static DLBitString fromOctetString(byte[] bytes)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLExternal.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLExternal.java
index e3df2506..833c60ef 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLExternal.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLExternal.java
@@ -53,6 +53,11 @@ public class DLExternal
super(directReference, indirectReference, dataValueDescriptor, encoding, externalData);
}
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
int encodedLength()
throws IOException
{
@@ -62,8 +67,7 @@ public class DLExternal
/* (non-Javadoc)
* @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
*/
- void encode(ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (directReference != null)
@@ -78,8 +82,9 @@ public class DLExternal
{
baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DL));
}
- DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent);
+ ASN1TaggedObject obj = new DLTaggedObject(true, encoding, externalContent);
baos.write(obj.getEncoded(ASN1Encoding.DL));
- out.writeEncoded(BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
+
+ out.writeEncoded(withTag, BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLFactory.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLFactory.java
new file mode 100644
index 00000000..0ce21ca8
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLFactory.java
@@ -0,0 +1,27 @@
+package org.bouncycastle.asn1;
+
+class DLFactory
+{
+ static final ASN1Sequence EMPTY_SEQUENCE = new DLSequence();
+ static final ASN1Set EMPTY_SET = new DLSet();
+
+ static ASN1Sequence createSequence(ASN1EncodableVector v)
+ {
+ if (v.size() < 1)
+ {
+ return EMPTY_SEQUENCE;
+ }
+
+ return new DLSequence(v);
+ }
+
+ static ASN1Set createSet(ASN1EncodableVector v)
+ {
+ if (v.size() < 1)
+ {
+ return EMPTY_SET;
+ }
+
+ return new DLSet(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLOutputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLOutputStream.java
index 68c0ed62..9c2a88c4 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLOutputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLOutputStream.java
@@ -6,26 +6,21 @@ import java.io.OutputStream;
/**
* Stream that outputs encoding based on definite length.
*/
-public class DLOutputStream
+class DLOutputStream
extends ASN1OutputStream
{
- public DLOutputStream(
- OutputStream os)
+ DLOutputStream(OutputStream os)
{
super(os);
}
- public void writeObject(
- ASN1Encodable obj)
- throws IOException
+ void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
{
- if (obj != null)
- {
- obj.toASN1Primitive().toDLObject().encode(this);
- }
- else
- {
- throw new IOException("null object detected");
- }
+ primitive.toDLObject().encode(this, withTag);
+ }
+
+ ASN1OutputStream getDLSubStream()
+ {
+ return this;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLSequence.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLSequence.java
index 65acd274..b040ded8 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLSequence.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLSequence.java
@@ -1,7 +1,6 @@
package org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* The DLSequence encodes a SEQUENCE using definite length form.
@@ -20,56 +19,56 @@ public class DLSequence
/**
* create a sequence containing one object
- * @param obj the object to go in the sequence.
+ * @param element the object to go in the sequence.
*/
- public DLSequence(
- ASN1Encodable obj)
+ public DLSequence(ASN1Encodable element)
{
- super(obj);
+ super(element);
}
/**
* create a sequence containing a vector of objects.
- * @param v the vector of objects to make up the sequence.
+ * @param elementVector the vector of objects to make up the sequence.
*/
- public DLSequence(
- ASN1EncodableVector v)
+ public DLSequence(ASN1EncodableVector elementVector)
{
- super(v);
+ super(elementVector);
}
/**
* create a sequence containing an array of objects.
- * @param array the array of objects to make up the sequence.
+ * @param elements the array of objects to make up the sequence.
*/
- public DLSequence(
- ASN1Encodable[] array)
+ public DLSequence(ASN1Encodable[] elements)
{
- super(array);
+ super(elements);
}
- private int getBodyLength()
- throws IOException
+ DLSequence(ASN1Encodable[] elements, boolean clone)
+ {
+ super(elements, clone);
+ }
+
+ private int getBodyLength() throws IOException
{
if (bodyLength < 0)
{
- int length = 0;
+ int count = elements.length;
+ int totalLength = 0;
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ for (int i = 0; i < count; ++i)
{
- Object obj = e.nextElement();
-
- length += ((ASN1Encodable)obj).toASN1Primitive().toDLObject().encodedLength();
+ ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
+ totalLength += dlObject.encodedLength();
}
- bodyLength = length;
+ this.bodyLength = totalLength;
}
return bodyLength;
}
- int encodedLength()
- throws IOException
+ int encodedLength() throws IOException
{
int length = getBodyLength();
@@ -84,21 +83,49 @@ public class DLSequence
* ASN.1 descriptions given. Rather than just outputting SEQUENCE,
* we also have to specify CONSTRUCTED, and the objects length.
*/
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- ASN1OutputStream dOut = out.getDLSubStream();
- int length = getBodyLength();
+ if (withTag)
+ {
+ out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
+ }
- out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
- out.writeLength(length);
+ ASN1OutputStream dlOut = out.getDLSubStream();
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ int count = elements.length;
+ if (bodyLength >= 0 || count > 16)
{
- Object obj = e.nextElement();
+ out.writeLength(getBodyLength());
- dOut.writeObject((ASN1Encodable)obj);
+ for (int i = 0; i < count; ++i)
+ {
+ dlOut.writePrimitive(elements[i].toASN1Primitive(), true);
+ }
}
+ else
+ {
+ int totalLength = 0;
+
+ ASN1Primitive[] dlObjects = new ASN1Primitive[count];
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
+ dlObjects[i] = dlObject;
+ totalLength += dlObject.encodedLength();
+ }
+
+ this.bodyLength = totalLength;
+ out.writeLength(totalLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ dlOut.writePrimitive(dlObjects[i], true);
+ }
+ }
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
}
} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLSequenceParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLSequenceParser.java
new file mode 100644
index 00000000..290a46ec
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLSequenceParser.java
@@ -0,0 +1,60 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Parser class for DL SEQUENCEs.
+ *
+ * TODO The class is only publicly visible to support 'instanceof' checks; provide an alternative
+ */
+public class DLSequenceParser
+ implements ASN1SequenceParser
+{
+ private ASN1StreamParser _parser;
+
+ DLSequenceParser(ASN1StreamParser parser)
+ {
+ this._parser = parser;
+ }
+
+ /**
+ * Return the next object in the SEQUENCE.
+ *
+ * @return next object in SEQUENCE.
+ * @throws IOException if there is an issue loading the object.
+ */
+ public ASN1Encodable readObject()
+ throws IOException
+ {
+ return _parser.readObject();
+ }
+
+ /**
+ * Return an in memory, encodable, representation of the SEQUENCE.
+ *
+ * @return a DLSequence.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return new DLSequence(_parser.readVector());
+ }
+
+ /**
+ * Return a DLSequence representing this parser and its contents.
+ *
+ * @return a DLSequence.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException(e.getMessage());
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLSet.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLSet.java
index e3042c25..576197aa 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLSet.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLSet.java
@@ -1,7 +1,6 @@
package org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* The DLSet encodes ASN.1 SET value without element ordering,
@@ -64,54 +63,54 @@ public class DLSet
}
/**
- * @param obj - a single object that makes up the set.
+ * @param element - a single object that makes up the set.
*/
- public DLSet(
- ASN1Encodable obj)
+ public DLSet(ASN1Encodable element)
{
- super(obj);
+ super(element);
}
/**
- * @param v - a vector of objects making up the set.
+ * @param elementVector - a vector of objects making up the set.
*/
- public DLSet(
- ASN1EncodableVector v)
+ public DLSet(ASN1EncodableVector elementVector)
{
- super(v, false);
+ super(elementVector, false);
}
/**
* create a set from an array of objects.
*/
- public DLSet(
- ASN1Encodable[] a)
+ public DLSet(ASN1Encodable[] elements)
{
- super(a, false);
+ super(elements, false);
}
- private int getBodyLength()
- throws IOException
+ DLSet(boolean isSorted, ASN1Encodable[] elements)
+ {
+ super(isSorted, elements);
+ }
+
+ private int getBodyLength() throws IOException
{
if (bodyLength < 0)
{
- int length = 0;
+ int count = elements.length;
+ int totalLength = 0;
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ for (int i = 0; i < count; ++i)
{
- Object obj = e.nextElement();
-
- length += ((ASN1Encodable)obj).toASN1Primitive().toDLObject().encodedLength();
+ ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
+ totalLength += dlObject.encodedLength();
}
- bodyLength = length;
+ this.bodyLength = totalLength;
}
return bodyLength;
}
- int encodedLength()
- throws IOException
+ int encodedLength() throws IOException
{
int length = getBodyLength();
@@ -126,21 +125,49 @@ public class DLSet
* ASN.1 descriptions given. Rather than just outputting SET,
* we also have to specify CONSTRUCTED, and the objects length.
*/
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- ASN1OutputStream dOut = out.getDLSubStream();
- int length = getBodyLength();
+ if (withTag)
+ {
+ out.write(BERTags.SET | BERTags.CONSTRUCTED);
+ }
- out.write(BERTags.SET | BERTags.CONSTRUCTED);
- out.writeLength(length);
+ ASN1OutputStream dlOut = out.getDLSubStream();
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ int count = elements.length;
+ if (bodyLength >= 0 || count > 16)
{
- Object obj = e.nextElement();
+ out.writeLength(getBodyLength());
- dOut.writeObject((ASN1Encodable)obj);
+ for (int i = 0; i < count; ++i)
+ {
+ dlOut.writePrimitive(elements[i].toASN1Primitive(), true);
+ }
}
+ else
+ {
+ int totalLength = 0;
+
+ ASN1Primitive[] dlObjects = new ASN1Primitive[count];
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
+ dlObjects[i] = dlObject;
+ totalLength += dlObject.encodedLength();
+ }
+
+ this.bodyLength = totalLength;
+ out.writeLength(totalLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ dlOut.writePrimitive(dlObjects[i], true);
+ }
+ }
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
}
} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLSetParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLSetParser.java
new file mode 100644
index 00000000..9f4421df
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLSetParser.java
@@ -0,0 +1,60 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Parser class for DL SETs.
+ *
+ * TODO The class is only publicly visible to support 'instanceof' checks; provide an alternative
+ */
+public class DLSetParser
+ implements ASN1SetParser
+{
+ private ASN1StreamParser _parser;
+
+ DLSetParser(ASN1StreamParser parser)
+ {
+ this._parser = parser;
+ }
+
+ /**
+ * Return the next object in the SET.
+ *
+ * @return next object in SET.
+ * @throws IOException if there is an issue loading the object.
+ */
+ public ASN1Encodable readObject()
+ throws IOException
+ {
+ return _parser.readObject();
+ }
+
+ /**
+ * Return an in memory, encodable, representation of the SET.
+ *
+ * @return a DLSet.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return new DLSet(_parser.readVector());
+ }
+
+ /**
+ * Return a DLSet representing this parser and its contents.
+ *
+ * @return a DLSet
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException(e.getMessage(), e);
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLTaggedObject.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLTaggedObject.java
index 4a245dff..50a3a267 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLTaggedObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLTaggedObject.java
@@ -10,8 +10,6 @@ import java.io.IOException;
public class DLTaggedObject
extends ASN1TaggedObject
{
- private static final byte[] ZERO_BYTES = new byte[0];
-
/**
* @param explicit true if an explicitly tagged object.
* @param tagNo the tag number for this object.
@@ -27,86 +25,49 @@ public class DLTaggedObject
boolean isConstructed()
{
- if (!empty)
- {
- if (explicit)
- {
- return true;
- }
- else
- {
- ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
-
- return primitive.isConstructed();
- }
- }
- else
- {
- return true;
- }
+ return explicit || obj.toASN1Primitive().toDLObject().isConstructed();
}
int encodedLength()
throws IOException
{
- if (!empty)
- {
- int length = obj.toASN1Primitive().toDLObject().encodedLength();
+ int length = obj.toASN1Primitive().toDLObject().encodedLength();
- if (explicit)
- {
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
- }
- else
- {
- // header length already in calculation
- length = length - 1;
-
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ if (explicit)
+ {
+ return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
}
else
{
- return StreamUtil.calculateTagLength(tagNo) + 1;
+ // header length already in calculation
+ length = length - 1;
+
+ return StreamUtil.calculateTagLength(tagNo) + length;
}
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (!empty)
+ ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
+
+ int flags = BERTags.TAGGED;
+ if (explicit || primitive.isConstructed())
{
- ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
+ flags |= BERTags.CONSTRUCTED;
+ }
- if (explicit)
- {
- out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
- out.writeLength(primitive.encodedLength());
- out.writeObject(primitive);
- }
- else
- {
- //
- // need to mark constructed types...
- //
- int flags;
- if (primitive.isConstructed())
- {
- flags = BERTags.CONSTRUCTED | BERTags.TAGGED;
- }
- else
- {
- flags = BERTags.TAGGED;
- }
+ out.writeTag(withTag, flags, tagNo);
- out.writeTag(flags, tagNo);
- out.writeImplicitObject(primitive);
- }
- }
- else
+ if (explicit)
{
- out.writeEncoded(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo, ZERO_BYTES);
+ out.writeLength(primitive.encodedLength());
}
+
+ out.getDLSubStream().writePrimitive(primitive, explicit);
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java
index d7b51ded..359bcc25 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java
@@ -15,13 +15,15 @@ class DefiniteLengthInputStream
private static final byte[] EMPTY_BYTES = new byte[0];
private final int _originalLength;
+
private int _remaining;
DefiniteLengthInputStream(
InputStream in,
- int length)
+ int length,
+ int limit)
{
- super(in, length);
+ super(in, limit);
if (length < 0)
{
@@ -89,6 +91,33 @@ class DefiniteLengthInputStream
return numRead;
}
+ void readAllIntoByteArray(byte[] buf)
+ throws IOException
+ {
+ if (_remaining != buf.length)
+ {
+ throw new IllegalArgumentException("buffer length not right for data");
+ }
+
+ if (_remaining == 0)
+ {
+ return;
+ }
+
+ // make sure it's safe to do this!
+ int limit = getLimit();
+ if (_remaining >= limit)
+ {
+ throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit);
+ }
+
+ if ((_remaining -= Streams.readFully(_in, buf)) != 0)
+ {
+ throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
+ }
+ setParentEofDetect(true);
+ }
+
byte[] toByteArray()
throws IOException
{
@@ -97,6 +126,13 @@ class DefiniteLengthInputStream
return EMPTY_BYTES;
}
+ // make sure it's safe to do this!
+ int limit = getLimit();
+ if (_remaining >= limit)
+ {
+ throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit);
+ }
+
byte[] bytes = new byte[_remaining];
if ((_remaining -= Streams.readFully(_in, bytes)) != 0)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/LazyConstructionEnumeration.java b/bcprov/src/main/java/org/bouncycastle/asn1/LazyConstructionEnumeration.java
index 31d988d4..c671e5b3 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/LazyConstructionEnumeration.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/LazyConstructionEnumeration.java
@@ -2,6 +2,7 @@ package org.bouncycastle.asn1;
import java.io.IOException;
import java.util.Enumeration;
+import java.util.NoSuchElementException;
class LazyConstructionEnumeration
implements Enumeration
@@ -22,11 +23,13 @@ class LazyConstructionEnumeration
public Object nextElement()
{
- Object o = nextObj;
-
- nextObj = readObject();
-
- return o;
+ if (nextObj != null)
+ {
+ Object o = nextObj;
+ nextObj = readObject();
+ return o;
+ }
+ throw new NoSuchElementException();
}
private Object readObject()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/LazyEncodedSequence.java b/bcprov/src/main/java/org/bouncycastle/asn1/LazyEncodedSequence.java
index c7342adf..23c72f89 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/LazyEncodedSequence.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/LazyEncodedSequence.java
@@ -2,6 +2,7 @@ package org.bouncycastle.asn1;
import java.io.IOException;
import java.util.Enumeration;
+import java.util.Iterator;
/**
* Note: this class is for processing DER/DL encoded sequences only.
@@ -11,99 +12,117 @@ class LazyEncodedSequence
{
private byte[] encoded;
- LazyEncodedSequence(
- byte[] encoded)
- throws IOException
+ LazyEncodedSequence(byte[] encoded) throws IOException
{
+ // NOTE: Initially, the actual 'elements' will be empty
+ super();
+
this.encoded = encoded;
}
- private void parse()
+ public synchronized ASN1Encodable getObjectAt(int index)
{
- Enumeration en = new LazyConstructionEnumeration(encoded);
+ force();
+
+ return super.getObjectAt(index);
+ }
- while (en.hasMoreElements())
+ public synchronized Enumeration getObjects()
+ {
+ if (null != encoded)
{
- seq.addElement(en.nextElement());
+ return new LazyConstructionEnumeration(encoded);
}
- encoded = null;
+ return super.getObjects();
}
- public synchronized ASN1Encodable getObjectAt(int index)
+ public synchronized int hashCode()
{
- if (encoded != null)
- {
- parse();
- }
+ force();
- return super.getObjectAt(index);
+ return super.hashCode();
}
- public synchronized Enumeration getObjects()
+ public synchronized Iterator<ASN1Encodable> iterator()
{
- if (encoded == null)
- {
- return super.getObjects();
- }
+ force();
- return new LazyConstructionEnumeration(encoded);
+ return super.iterator();
}
public synchronized int size()
{
- if (encoded != null)
- {
- parse();
- }
+ force();
return super.size();
}
- ASN1Primitive toDERObject()
+ public synchronized ASN1Encodable[] toArray()
{
- if (encoded != null)
- {
- parse();
- }
+ force();
- return super.toDERObject();
+ return super.toArray();
}
- ASN1Primitive toDLObject()
+ ASN1Encodable[] toArrayInternal()
{
- if (encoded != null)
- {
- parse();
- }
+ force();
- return super.toDLObject();
+ return super.toArrayInternal();
}
- int encodedLength()
+ synchronized int encodedLength()
throws IOException
{
- if (encoded != null)
+ if (null != encoded)
{
return 1 + StreamUtil.calculateBodyLength(encoded.length) + encoded.length;
}
- else
- {
- return super.toDLObject().encodedLength();
- }
+
+ return super.toDLObject().encodedLength();
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ synchronized void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (encoded != null)
+ if (null != encoded)
{
- out.writeEncoded(BERTags.SEQUENCE | BERTags.CONSTRUCTED, encoded);
+ out.writeEncoded(withTag, BERTags.SEQUENCE | BERTags.CONSTRUCTED, encoded);
}
else
{
- super.toDLObject().encode(out);
+ super.toDLObject().encode(out, withTag);
+ }
+ }
+
+ synchronized ASN1Primitive toDERObject()
+ {
+ force();
+
+ return super.toDERObject();
+ }
+
+ synchronized ASN1Primitive toDLObject()
+ {
+ force();
+
+ return super.toDLObject();
+ }
+
+ private void force()
+ {
+ if (null != encoded)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ Enumeration en = new LazyConstructionEnumeration(encoded);
+ while (en.hasMoreElements())
+ {
+ v.add((ASN1Primitive)en.nextElement());
+ }
+
+ this.elements = v.takeElements();
+ this.encoded = null;
}
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/LimitedInputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/LimitedInputStream.java
index ab8470f8..b18a65b0 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/LimitedInputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/LimitedInputStream.java
@@ -19,12 +19,11 @@ abstract class LimitedInputStream
this._limit = limit;
}
- int getRemaining()
+ int getLimit()
{
- // TODO: maybe one day this can become more accurate
return _limit;
}
-
+
protected void setParentEofDetect(boolean on)
{
if (_in instanceof IndefiniteLengthInputStream)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/StreamUtil.java b/bcprov/src/main/java/org/bouncycastle/asn1/StreamUtil.java
index 1fc8ab09..4d454c8d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/StreamUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/StreamUtil.java
@@ -12,7 +12,7 @@ class StreamUtil
// private static final long MAX_MEMORY = Runtime.getRuntime().maxMemory();
/**
- * Find out possible longest length...
+ * Find out possible longest length, capped by available memory.
*
* @param in input stream of interest
* @return length calculation or MAX_VALUE.
@@ -21,7 +21,7 @@ class StreamUtil
{
if (in instanceof LimitedInputStream)
{
- return ((LimitedInputStream)in).getRemaining();
+ return ((LimitedInputStream)in).getLimit();
}
else if (in instanceof ASN1InputStream)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
index dae0dacc..31b14f23 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
@@ -147,11 +147,16 @@ public interface BCObjectIdentifiers
* qTESLA
*/
public static final ASN1ObjectIdentifier qTESLA = bc_sig.branch("4");
- public static final ASN1ObjectIdentifier qTESLA_I = qTESLA.branch("1");
- public static final ASN1ObjectIdentifier qTESLA_III_size = qTESLA.branch("2");
- public static final ASN1ObjectIdentifier qTESLA_III_speed = qTESLA.branch("3");
- public static final ASN1ObjectIdentifier qTESLA_p_I = qTESLA.branch("4");
- public static final ASN1ObjectIdentifier qTESLA_p_III = qTESLA.branch("5");
+
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_I = qTESLA.branch("1");
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_III_size = qTESLA.branch("2");
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_III_speed = qTESLA.branch("3");
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_p_I = qTESLA.branch("4");
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_p_III = qTESLA.branch("5");
+
+
+ public static final ASN1ObjectIdentifier qTESLA_p_I = qTESLA.branch("11");
+ public static final ASN1ObjectIdentifier qTESLA_p_III = qTESLA.branch("12");
/**
* key_exchange(3) algorithms
@@ -164,4 +169,13 @@ public interface BCObjectIdentifiers
public static final ASN1ObjectIdentifier newHope = bc_exch.branch("1");
*/
// END Android-removed: Unsupported algorithms
+
+ /**
+ * X.509 extension(4) values
+ * <p>
+ * 1.3.6.1.4.1.22554.4
+ */
+ public static final ASN1ObjectIdentifier bc_ext = bc.branch("4");
+
+ public static final ASN1ObjectIdentifier linkedCertificate = bc_ext.branch("1");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/Attribute.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/Attribute.java
index 8c487433..f5995b07 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/Attribute.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/Attribute.java
@@ -10,7 +10,7 @@ import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.DERSequence;
/**
- * <a href="http://tools.ietf.org/html/rfc5652#page-14">RFC 5652</a>:
+ * <a href="https://tools.ietf.org/html/rfc5652#page-14">RFC 5652</a>:
* Attribute is a pair of OID (as type identifier) + set of values.
* <p>
* <pre>
@@ -100,7 +100,7 @@ public class Attribute
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(attrType);
v.add(attrValues);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/Attributes.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/Attributes.java
index 4ffe5ea5..420372a0 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/Attributes.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/Attributes.java
@@ -8,7 +8,7 @@ import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DLSet;
/**
- * <a href="http://tools.ietf.org/html/rfc5652">RFC 5652</a> defines
+ * <a href="https://tools.ietf.org/html/rfc5652">RFC 5652</a> defines
* 5 "SET OF Attribute" entities with 5 different names.
* This is common implementation for them all:
* <pre>
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java
index d18fe4bc..b7835382 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java
@@ -119,7 +119,7 @@ public class CMSAlgorithmProtection
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(digestAlgorithm);
if (signatureAlgorithm != null)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAttributes.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAttributes.java
index d452ef8a..0801078d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAttributes.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAttributes.java
@@ -5,8 +5,8 @@ import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
/**
- * <a href="http://tools.ietf.org/html/rfc5652">RFC 5652</a> CMS attribute OID constants.
- * and <a href="http://tools.ietf.org/html/rfc6211">RFC 6211</a> Algorithm Identifier Protection Attribute.
+ * <a href="https://tools.ietf.org/html/rfc5652">RFC 5652</a> CMS attribute OID constants.
+ * and <a href="https://tools.ietf.org/html/rfc6211">RFC 6211</a> Algorithm Identifier Protection Attribute.
* <pre>
* contentType ::= 1.2.840.113549.1.9.3
* messageDigest ::= 1.2.840.113549.1.9.4
@@ -28,7 +28,7 @@ public interface CMSAttributes
ASN1ObjectIdentifier signingTime = PKCSObjectIdentifiers.pkcs_9_at_signingTime;
/** PKCS#9: 1.2.840.113549.1.9.6 */
ASN1ObjectIdentifier counterSignature = PKCSObjectIdentifiers.pkcs_9_at_counterSignature;
- /** PKCS#9: 1.2.840.113549.1.9.16.6.2.4 - See <a href="http://tools.ietf.org/html/rfc2634">RFC 2634</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.6.2.4 - See <a href="https://tools.ietf.org/html/rfc2634">RFC 2634</a> */
ASN1ObjectIdentifier contentHint = PKCSObjectIdentifiers.id_aa_contentHint;
ASN1ObjectIdentifier cmsAlgorithmProtect = PKCSObjectIdentifiers.id_aa_cmsAlgorithmProtect;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java
index 2e8e0392..be197d26 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java
@@ -11,8 +11,8 @@ import org.bouncycastle.asn1.BERSequence;
import org.bouncycastle.asn1.BERTaggedObject;
/**
- * <a href="http://tools.ietf.org/html/rfc5652#section-3">RFC 5652</a> ContentInfo, and
- * <a href="http://tools.ietf.org/html/rfc5652#section-5.2">RFC 5652</a> EncapsulatedContentInfo objects.
+ * <a href="https://tools.ietf.org/html/rfc5652#section-3">RFC 5652</a> ContentInfo, and
+ * <a href="https://tools.ietf.org/html/rfc5652#section-5.2">RFC 5652</a> EncapsulatedContentInfo objects.
*
* <pre>
* ContentInfo ::= SEQUENCE {
@@ -116,7 +116,7 @@ public class ContentInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(contentType);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/GCMParameters.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/GCMParameters.java
index 0f03c879..76a98dc6 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/GCMParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/GCMParameters.java
@@ -11,7 +11,7 @@ import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.util.Arrays;
/**
- * <a href="http://tools.ietf.org/html/rfc5084">RFC 5084</a>: GCMParameters object.
+ * <a href="https://tools.ietf.org/html/rfc5084">RFC 5084</a>: GCMParameters object.
* <p>
* <pre>
GCMParameters ::= SEQUENCE {
@@ -60,7 +60,7 @@ public class GCMParameters
if (seq.size() == 2)
{
- this.icvLen = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue().intValue();
+ this.icvLen = ASN1Integer.getInstance(seq.getObjectAt(1)).intValueExact();
}
else
{
@@ -88,7 +88,7 @@ public class GCMParameters
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(new DEROctetString(nonce));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java
index d46cbfb2..960ee7a6 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java
@@ -14,7 +14,7 @@ import org.bouncycastle.asn1.x509.X509CertificateStructure;
import org.bouncycastle.asn1.x509.X509Name;
/**
- * <a href="http://tools.ietf.org/html/rfc5652#section-10.2.4">RFC 5652</a>: IssuerAndSerialNumber object.
+ * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.4">RFC 5652</a>: IssuerAndSerialNumber object.
* <p>
* <pre>
* IssuerAndSerialNumber ::= SEQUENCE {
@@ -128,7 +128,7 @@ public class IssuerAndSerialNumber
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(name);
v.add(serialNumber);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignedData.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignedData.java
index 70278970..a30b7642 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignedData.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignedData.java
@@ -16,7 +16,7 @@ import org.bouncycastle.asn1.BERTaggedObject;
import org.bouncycastle.asn1.DERTaggedObject;
/**
- * <a href="http://tools.ietf.org/html/rfc5652#section-5.1">RFC 5652</a>:
+ * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">RFC 5652</a>:
* <p>
* A signed data object containing multitude of {@link SignerInfo}s.
* <pre>
@@ -206,7 +206,7 @@ public class SignedData
{
SignerInfo s = SignerInfo.getInstance(e.nextElement());
- if (s.getVersion().getValue().intValue() == 3)
+ if (s.getVersion().intValueExact() == 3)
{
return true;
}
@@ -293,7 +293,7 @@ public class SignedData
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(6);
v.add(version);
v.add(digestAlgorithms);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignerIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignerIdentifier.java
index 2543eb1c..d5681483 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignerIdentifier.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignerIdentifier.java
@@ -9,7 +9,7 @@ import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERTaggedObject;
/**
- * <a href="http://tools.ietf.org/html/rfc5652#section-5.3">RFC 5652</a>:
+ * <a href="https://tools.ietf.org/html/rfc5652#section-5.3">RFC 5652</a>:
* Identify who signed the containing {@link SignerInfo} object.
* <p>
* The certificates referred to by this are at containing {@link SignedData} structure.
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignerInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignerInfo.java
index 486eae2d..d9640de1 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignerInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignerInfo.java
@@ -16,7 +16,7 @@ import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
/**
- * <a href="http://tools.ietf.org/html/rfc5652#section-5.3">RFC 5652</a>:
+ * <a href="https://tools.ietf.org/html/rfc5652#section-5.3">RFC 5652</a>:
* Signature container per Signer, see {@link SignerIdentifier}.
* <pre>
* PKCS#7:
@@ -258,7 +258,7 @@ public class SignerInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(7);
v.add(version);
v.add(sid);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/Time.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/Time.java
index a6f8d8fe..07455a15 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/Time.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/Time.java
@@ -18,7 +18,7 @@ import org.bouncycastle.asn1.DERGeneralizedTime;
import org.bouncycastle.asn1.DERUTCTime;
/**
- * <a href="http://tools.ietf.org/html/rfc5652#section-11.3">RFC 5652</a>:
+ * <a href="https://tools.ietf.org/html/rfc5652#section-11.3">RFC 5652</a>:
* Dual-mode timestamp format producing either UTCTIme or GeneralizedTime.
* <p>
* <pre>
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java
index 805a5064..35e65f50 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java
@@ -5,7 +5,7 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier;
/**
* German Federal Office for Information Security
* (Bundesamt f&uuml;r Sicherheit in der Informationstechnik)
- * <a href="http://www.bsi.bund.de/">http://www.bsi.bund.de/</a>
+ * <a href="https://www.bsi.bund.de/">https://www.bsi.bund.de/</a>
* <p>
* <a href="https://www.bsi.bund.de/EN/Publications/TechnicalGuidelines/TR03110/BSITR03110.html">BSI TR-03110</a>
* Technical Guideline Advanced Security Mechanisms for Machine Readable Travel Documents
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java
index 73575f1c..a4611333 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java
@@ -6,10 +6,10 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier;
* Korea Information Security Agency (KISA)
* ({iso(1) member-body(2) kr(410) kisa(200004)})
* <p>
- * See <a href="http://tools.ietf.org/html/rfc4010">RFC 4010</a>
+ * See <a href="https://tools.ietf.org/html/rfc4010">RFC 4010</a>
* Use of the SEED Encryption Algorithm
* in Cryptographic Message Syntax (CMS),
- * and <a href="http://tools.ietf.org/html/rfc4269">RFC 4269</a>
+ * and <a href="https://tools.ietf.org/html/rfc4269">RFC 4269</a>
* The SEED Encryption Algorithm
*/
public interface KISAObjectIdentifiers
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
index 0f0b10d5..89b91d0a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
@@ -102,6 +102,12 @@ public interface MiscObjectIdentifiers
ASN1ObjectIdentifier cast5CBC = entrust.branch("66.10");
//
+ // HMAC-SHA1 hMAC-SHA1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
+ // dod(6) internet(1) security(5) mechanisms(5) 8 1 2 }
+ //
+ ASN1ObjectIdentifier hMAC_SHA1 = new ASN1ObjectIdentifier("1.3.6.1.5.5.8.1.2");
+
+ //
// Ascom
//
ASN1ObjectIdentifier as_sys_sec_alg_ideaCBC = new ASN1ObjectIdentifier("1.3.6.1.4.1.188.7.1.1.2");
@@ -135,4 +141,11 @@ public interface MiscObjectIdentifiers
//
// Scrypt
ASN1ObjectIdentifier id_scrypt = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.4.11");
+
+ // Composite key/signature oid - prototyping
+ //
+ // id-alg-composite OBJECT IDENTIFIER ::= {
+ // iso(1) identified-organization(3) dod(6) internet(1) private(4)
+ // enterprise(1) OpenCA(18227) Algorithms(2) id-alg-composite(1) }
+ ASN1ObjectIdentifier id_alg_composite = new ASN1ObjectIdentifier("1.3.6.1.4.1.18227.2.1");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
index 49c0e6d7..8de357a8 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
@@ -51,6 +51,14 @@ public interface NISTObjectIdentifiers
static final ASN1ObjectIdentifier id_hmacWithSHA3_384 = hashAlgs.branch("15");
/** 2.16.840.1.101.3.4.2.16 */
static final ASN1ObjectIdentifier id_hmacWithSHA3_512 = hashAlgs.branch("16");
+ /** 2.16.840.1.101.3.4.2.17 */
+ static final ASN1ObjectIdentifier id_shake128_len = hashAlgs.branch("17");
+ /** 2.16.840.1.101.3.4.2.18 */
+ static final ASN1ObjectIdentifier id_shake256_len = hashAlgs.branch("18");
+ /** 2.16.840.1.101.3.4.2.19 */
+ static final ASN1ObjectIdentifier id_KmacWithSHAKE128 = hashAlgs.branch("19");
+ /** 2.16.840.1.101.3.4.2.20 */
+ static final ASN1ObjectIdentifier id_KmacWithSHAKE256 = hashAlgs.branch("20");
/** 2.16.840.1.101.3.4.1 */
static final ASN1ObjectIdentifier aes = nistAlgorithm.branch("1");
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java
index fa32068e..e6630c56 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java
@@ -3,7 +3,7 @@ package org.bouncycastle.asn1.ntt;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
/**
- * From <a href="http://tools.ietf.org/html/rfc3657">RFC 3657</a>
+ * From <a href="https://tools.ietf.org/html/rfc3657">RFC 3657</a>
* Use of the Camellia Encryption Algorithm
* in Cryptographic Message Syntax (CMS)
*/
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/BasicOCSPResponse.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/BasicOCSPResponse.java
index 1b2e7f53..f2cf3a0e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/BasicOCSPResponse.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/BasicOCSPResponse.java
@@ -10,6 +10,16 @@ import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * BasicOCSPResponse ::= SEQUENCE {
+ * tbsResponseData ResponseData,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING,
+ * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ * </pre>
+ */
public class BasicOCSPResponse
extends ASN1Object
{
@@ -97,7 +107,7 @@ public class BasicOCSPResponse
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(tbsResponseData);
v.add(signatureAlgorithm);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CertID.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CertID.java
index 9d3496ef..001b6e36 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CertID.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CertID.java
@@ -93,7 +93,7 @@ public class CertID
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(hashAlgorithm);
v.add(issuerNameHash);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CrlID.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CrlID.java
index f5a35811..b9f5d7c8 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CrlID.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CrlID.java
@@ -88,7 +88,7 @@ public class CrlID
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
if (crlUrl != null)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPObjectIdentifiers.java
index 577e413a..d52cfcc1 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPObjectIdentifiers.java
@@ -3,7 +3,7 @@ package org.bouncycastle.asn1.ocsp;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
/**
- * OIDs for <a href="http://tools.ietf.org/html/rfc2560">RFC 2560</a> and <a href="http://tools.ietf.org/html/rfc6960">RFC 6960</a>
+ * OIDs for <a href="https://tools.ietf.org/html/rfc2560">RFC 2560</a> and <a href="https://tools.ietf.org/html/rfc6960">RFC 6960</a>
* Online Certificate Status Protocol - OCSP.
*/
public interface OCSPObjectIdentifiers
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPRequest.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPRequest.java
index 559cf4ce..93c39296 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPRequest.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPRequest.java
@@ -76,7 +76,7 @@ public class OCSPRequest
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(tbsRequest);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPResponse.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPResponse.java
index 31602daf..46a7c380 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPResponse.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPResponse.java
@@ -8,6 +8,17 @@ import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * OCSPResponse ::= SEQUENCE {
+ * responseStatus OCSPResponseStatus,
+ * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
+ * </pre>
+ * @see OCSPResponseStatus
+ * @see ResponseBytes
+ */
+
public class OCSPResponse
extends ASN1Object
{
@@ -76,7 +87,7 @@ public class OCSPResponse
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(responseStatus);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPResponseStatus.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPResponseStatus.java
index aa225f93..e44bd9b1 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPResponseStatus.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/OCSPResponseStatus.java
@@ -6,6 +6,23 @@ import org.bouncycastle.asn1.ASN1Enumerated;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <p>
+ * The OCSPResponseStatus enumeration.
+ * <pre>
+ * OCSPResponseStatus ::= ENUMERATED {
+ * successful (0), --Response has valid confirmations
+ * malformedRequest (1), --Illegal confirmation request
+ * internalError (2), --Internal error in issuer
+ * tryLater (3), --Try again later
+ * --(4) is not used
+ * sigRequired (5), --Must sign the request
+ * unauthorized (6) --Request unauthorized
+ * }
+ * </pre>
+ */
public class OCSPResponseStatus
extends ASN1Object
{
@@ -19,6 +36,8 @@ public class OCSPResponseStatus
private ASN1Enumerated value;
/**
+ * RFC 2560, RFC 6960
+ * <p>
* The OCSPResponseStatus enumeration.
* <pre>
* OCSPResponseStatus ::= ENUMERATED {
@@ -59,6 +78,11 @@ public class OCSPResponseStatus
return null;
}
+ public int getIntValue()
+ {
+ return value.intValueExact();
+ }
+
public BigInteger getValue()
{
return value.getValue();
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/Request.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/Request.java
index 236bc72f..c9437cdf 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/Request.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/Request.java
@@ -77,7 +77,7 @@ public class Request
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(reqCert);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponseBytes.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponseBytes.java
index 01167b57..ec6d926f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponseBytes.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponseBytes.java
@@ -9,6 +9,14 @@ import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSequence;
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * ResponseBytes ::= SEQUENCE {
+ * responseType OBJECT IDENTIFIER,
+ * response OCTET STRING }
+ * </pre>
+ */
public class ResponseBytes
extends ASN1Object
{
@@ -75,7 +83,7 @@ public class ResponseBytes
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(responseType);
v.add(response);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponseData.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponseData.java
index 6874b227..9de94728 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponseData.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/ResponseData.java
@@ -12,6 +12,17 @@ import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.X509Extensions;
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * ResponseData ::= SEQUENCE {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * responderID ResponderID,
+ * producedAt GeneralizedTime,
+ * responses SEQUENCE OF SingleResponse,
+ * responseExtensions [1] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ */
public class ResponseData
extends ASN1Object
{
@@ -161,7 +172,7 @@ public class ResponseData
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
if (versionPresent || !version.equals(V1))
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/RevokedInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/RevokedInfo.java
index 67700500..2976d4bf 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/RevokedInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/RevokedInfo.java
@@ -79,7 +79,7 @@ public class RevokedInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(revocationTime);
if (revocationReason != null)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/Signature.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/Signature.java
index 80bd740a..67a52c57 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/Signature.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/Signature.java
@@ -96,7 +96,7 @@ public class Signature
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(signatureAlgorithm);
v.add(signature);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/SingleResponse.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/SingleResponse.java
index 0dc2a91c..5e533ca5 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/SingleResponse.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/SingleResponse.java
@@ -141,7 +141,7 @@ public class SingleResponse
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
v.add(certID);
v.add(certStatus);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/TBSRequest.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/TBSRequest.java
index 2a05705b..28c64290 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/TBSRequest.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/TBSRequest.java
@@ -144,7 +144,7 @@ public class TBSRequest
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
//
// if default don't include - unless explicitly provided. Not strictly correct
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/Attribute.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/Attribute.java
index 6374c980..1cc67fac 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/Attribute.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/Attribute.java
@@ -78,7 +78,7 @@ public class Attribute
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(attrType);
v.add(attrValues);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java
index b7cae332..5022ef4d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java
@@ -64,20 +64,13 @@ public class AuthenticatedSafe
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
-
- for (int i = 0; i != info.length; i++)
- {
- v.add(info[i]);
- }
-
if (isBer)
{
- return new BERSequence(v);
+ return new BERSequence(info);
}
else
{
- return new DLSequence(v);
+ return new DLSequence(info);
}
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java
index 49b2652c..47e1a541 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java
@@ -76,7 +76,7 @@ public class CRLBag
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(crlId);
v.add(new DERTaggedObject(0, crlValue));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java
index 4a730286..f43f472b 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertBag.java
@@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
@@ -18,8 +19,8 @@ public class CertBag
private CertBag(
ASN1Sequence seq)
{
- this.certId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
- this.certValue = ((DERTaggedObject)seq.getObjectAt(1)).getObject();
+ this.certId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+ this.certValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getObject();
}
public static CertBag getInstance(Object o)
@@ -56,7 +57,7 @@ public class CertBag
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(certId);
v.add(new DERTaggedObject(0, certValue));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequest.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequest.java
index e089cbc4..13587f8b 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequest.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequest.java
@@ -83,7 +83,7 @@ public class CertificationRequest
public ASN1Primitive toASN1Primitive()
{
// Construct the CertificateRequest
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(reqInfo);
v.add(sigAlgId);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
index 25e62863..11fdf6ce 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
@@ -148,7 +148,7 @@ public class CertificationRequestInfo
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(version);
v.add(subject);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java
index 1ee920fd..a7b2bc74 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/ContentInfo.java
@@ -81,7 +81,7 @@ public class ContentInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(contentType);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/DHParameter.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/DHParameter.java
index fa22f792..aeb8f01e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/DHParameter.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/DHParameter.java
@@ -89,7 +89,7 @@ public class DHParameter
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(p);
v.add(g);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java
index 7a250eaa..e4d449be 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java
@@ -55,7 +55,7 @@ public class EncryptedData
private EncryptedData(
ASN1Sequence seq)
{
- int version = ((ASN1Integer)seq.getObjectAt(0)).getValue().intValue();
+ int version = ((ASN1Integer)seq.getObjectAt(0)).intValueExact();
if (version != 0)
{
@@ -70,7 +70,7 @@ public class EncryptedData
AlgorithmIdentifier encryptionAlgorithm,
ASN1Encodable content)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(contentType);
v.add(encryptionAlgorithm.toASN1Primitive());
@@ -103,7 +103,7 @@ public class EncryptedData
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(new ASN1Integer(0));
v.add(data);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
index acbe04a9..82645ae8 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
@@ -76,7 +76,7 @@ public class EncryptedPrivateKeyInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(algId);
v.add(data);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java
index 6cbf907a..aa06263b 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java
@@ -75,7 +75,7 @@ public class IssuerAndSerialNumber
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(name);
v.add(certSerialNumber);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/MacData.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/MacData.java
index 593373f5..36c462b1 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/MacData.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/MacData.java
@@ -92,7 +92,7 @@ public class MacData
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(digInfo);
v.add(new DEROctetString(salt));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBEParameter.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBEParameter.java
index 06180dfe..fa4dacd3 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBEParameter.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBEParameter.java
@@ -63,7 +63,7 @@ public class PBEParameter
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(salt);
v.add(iterations);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Parameters.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Parameters.java
index b47e9cdd..fdea9b14 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Parameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Parameters.java
@@ -67,7 +67,7 @@ public class PBES2Parameters
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(func);
v.add(scheme);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
index 6a6ad559..58fa82ba 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
@@ -243,7 +243,7 @@ public class PBKDF2Params
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(octStr);
v.add(iterationCount);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java
index 0ddf5c34..1587a596 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java
@@ -59,7 +59,7 @@ public class PKCS12PBEParams
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(iv);
v.add(iterations);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
index d245b9bb..7cf720fd 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
@@ -261,6 +261,49 @@ public interface PKCSObjectIdentifiers
*/
ASN1ObjectIdentifier id_rsa_KEM = id_alg.branch("14");
+
+ /**
+ * id-alg-hss-lms-hashsig OBJECT IDENTIFIER ::= { iso(1)
+ * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
+ * smime(16) alg(3) 17 }
+ */
+ public static final ASN1ObjectIdentifier id_alg_hss_lms_hashsig = id_alg.branch("17");
+
+ /**
+ * <pre>
+ * id-alg-AEADChaCha20Poly1305 OBJECT IDENTIFIER ::=
+ * { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+ * pkcs9(9) smime(16) alg(3) 18 }
+ *
+ * AEADChaCha20Poly1305Nonce ::= OCTET STRING (SIZE(12))
+ * </pre>
+ */
+ ASN1ObjectIdentifier id_alg_AEADChaCha20Poly1305 = id_alg.branch("18");
+
+ /**
+ * <pre>
+ * id-alg-hkdf-with-sha256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ * us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 28 }
+ * </pre>
+ */
+ ASN1ObjectIdentifier id_alg_hkdf_with_sha256 = id_alg.branch("28");
+
+ /**
+ * <pre>
+ * id-alg-hkdf-with-sha384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ * us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 29 }
+ * </pre>
+ */
+ ASN1ObjectIdentifier id_alg_hkdf_with_sha384 = id_alg.branch("29");
+
+ /**
+ * <pre>
+ * id-alg-hkdf-with-sha512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ * us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 30 }
+ * </pre>
+ */
+ ASN1ObjectIdentifier id_alg_hkdf_with_sha512 = id_alg.branch("30");
+
//
// id-cti OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
// rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) cti(6)}
@@ -292,7 +335,7 @@ public interface PKCSObjectIdentifiers
/** PKCS#9: 1.2.840.113549.1.9.16.2.1 -- smime attribute receiptRequest */
ASN1ObjectIdentifier id_aa_receiptRequest = id_aa.branch("1");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.4 - See <a href="http://tools.ietf.org/html/rfc2634">RFC 2634</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.4 - See <a href="https://tools.ietf.org/html/rfc2634">RFC 2634</a> */
ASN1ObjectIdentifier id_aa_contentHint = id_aa.branch("4"); // See RFC 2634
/** PKCS#9: 1.2.840.113549.1.9.16.2.5 */
ASN1ObjectIdentifier id_aa_msgSigDigest = id_aa.branch("5");
@@ -309,40 +352,40 @@ public interface PKCSObjectIdentifiers
/** PKCS#9: 1.2.840.113549.1.9.16.2.47 */
ASN1ObjectIdentifier id_aa_signingCertificateV2 = id_aa.branch("47");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.7 - See <a href="http://tools.ietf.org/html/rfc2634">RFC 2634</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.7 - See <a href="https://tools.ietf.org/html/rfc2634">RFC 2634</a> */
ASN1ObjectIdentifier id_aa_contentIdentifier = id_aa.branch("7"); // See RFC 2634
/*
* RFC 3126
*/
- /** PKCS#9: 1.2.840.113549.1.9.16.2.14 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.14 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_signatureTimeStampToken = id_aa.branch("14");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.15 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.15 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_sigPolicyId = id_aa.branch("15");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.16 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.16 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_commitmentType = id_aa.branch("16");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.17 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.17 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_signerLocation = id_aa.branch("17");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.18 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.18 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_signerAttr = id_aa.branch("18");
- /** PKCS#9: 1.2.840.113549.1.9.16.6.2.19 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.6.2.19 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_otherSigCert = id_aa.branch("19");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.20 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.20 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_contentTimestamp = id_aa.branch("20");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.21 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.21 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_certificateRefs = id_aa.branch("21");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.22 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.22 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_revocationRefs = id_aa.branch("22");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.23 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.23 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_certValues = id_aa.branch("23");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.24 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.24 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_revocationValues = id_aa.branch("24");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.25 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.25 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_escTimeStamp = id_aa.branch("25");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.26 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.26 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_certCRLTimestamp = id_aa.branch("26");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.27 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.27 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_archiveTimestamp = id_aa.branch("27");
/** PKCS#9: 1.2.840.113549.1.9.16.2.37 - <a href="https://tools.ietf.org/html/rfc4108#section-2.2.5">RFC 4108</a> */
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java
index ce7e0758..5954313e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java
@@ -1,7 +1,5 @@
package org.bouncycastle.asn1.pkcs;
-import java.math.BigInteger;
-
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
@@ -22,8 +20,8 @@ public class Pfx
private Pfx(
ASN1Sequence seq)
{
- BigInteger version = ASN1Integer.getInstance(seq.getObjectAt(0)).getValue();
- if (version.intValue() != 3)
+ ASN1Integer version = ASN1Integer.getInstance(seq.getObjectAt(0));
+ if (version.intValueExact() != 3)
{
throw new IllegalArgumentException("wrong version for PFX PDU");
}
@@ -72,7 +70,7 @@ public class Pfx
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(new ASN1Integer(3));
v.add(contentInfo);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
index 85700b6a..9ac8c5eb 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
@@ -1,7 +1,6 @@
package org.bouncycastle.asn1.pkcs;
import java.io.IOException;
-import java.math.BigInteger;
import java.util.Enumeration;
import org.bouncycastle.asn1.ASN1BitString;
@@ -88,12 +87,12 @@ public class PrivateKeyInfo
private static int getVersionValue(ASN1Integer version)
{
- BigInteger bigValue = version.getValue();
- if (bigValue.compareTo(BigIntegers.ZERO) < 0 || bigValue.compareTo(BigIntegers.ONE) > 0)
+ int versionValue = version.intValueExact();
+ if (versionValue < 0 || versionValue > 1)
{
throw new IllegalArgumentException("invalid version for private key info");
}
- return bigValue.intValue();
+ return versionValue;
}
public PrivateKeyInfo(
@@ -176,6 +175,11 @@ public class PrivateKeyInfo
}
}
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
public ASN1Set getAttributes()
{
return attributes;
@@ -186,6 +190,11 @@ public class PrivateKeyInfo
return privateKeyAlgorithm;
}
+ public ASN1OctetString getPrivateKey()
+ {
+ return new DEROctetString(privateKey.getOctets());
+ }
+
public ASN1Encodable parsePrivateKey()
throws IOException
{
@@ -228,7 +237,7 @@ public class PrivateKeyInfo
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
v.add(version);
v.add(privateKeyAlgorithm);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
index e707fd10..9e5c364e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
@@ -133,7 +133,7 @@ public class RSAESOAEPparams
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
if (!hashAlgorithm.equals(DEFAULT_HASH_ALGORITHM))
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java
index 36992cf5..be914ec0 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java
@@ -74,13 +74,14 @@ public class RSAPrivateKey
{
Enumeration e = seq.getObjects();
- BigInteger v = ((ASN1Integer)e.nextElement()).getValue();
- if (v.intValue() != 0 && v.intValue() != 1)
+ ASN1Integer v = (ASN1Integer)e.nextElement();
+ int versionValue = v.intValueExact();
+ if (versionValue < 0 || versionValue > 1)
{
throw new IllegalArgumentException("wrong version for RSA private key");
}
- version = v;
+ version = v.getValue();
modulus = ((ASN1Integer)e.nextElement()).getValue();
publicExponent = ((ASN1Integer)e.nextElement()).getValue();
privateExponent = ((ASN1Integer)e.nextElement()).getValue();
@@ -165,7 +166,7 @@ public class RSAPrivateKey
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(10);
v.add(new ASN1Integer(version)); // version
v.add(new ASN1Integer(getModulus()));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java
index 5912d5ea..8e654cc0 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java
@@ -76,13 +76,14 @@ public class RSAPrivateKeyStructure
{
Enumeration e = seq.getObjects();
- BigInteger v = ((ASN1Integer)e.nextElement()).getValue();
- if (v.intValue() != 0 && v.intValue() != 1)
+ ASN1Integer v = (ASN1Integer)e.nextElement();
+ int versionValue = v.intValueExact();
+ if (versionValue < 0 || versionValue > 1)
{
throw new IllegalArgumentException("wrong version for RSA private key");
}
- version = v.intValue();
+ version = versionValue;
modulus = ((ASN1Integer)e.nextElement()).getValue();
publicExponent = ((ASN1Integer)e.nextElement()).getValue();
privateExponent = ((ASN1Integer)e.nextElement()).getValue();
@@ -167,7 +168,7 @@ public class RSAPrivateKeyStructure
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(10);
v.add(new ASN1Integer(version)); // version
v.add(new ASN1Integer(getModulus()));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPublicKey.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPublicKey.java
index 6c432985..f07819be 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSAPublicKey.java
@@ -85,7 +85,7 @@ public class RSAPublicKey
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(new ASN1Integer(getModulus()));
v.add(new ASN1Integer(getPublicExponent()));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java
index dc91c9c1..fb89370c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java
@@ -145,7 +145,7 @@ public class RSASSAPSSparams
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
if (!hashAlgorithm.equals(DEFAULT_HASH_ALGORITHM))
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java
index 00ca0a20..1d39416f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SafeBag.java
@@ -81,7 +81,7 @@ public class SafeBag
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(bagId);
v.add(new DLTaggedObject(true, 0, bagValue));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SignedData.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SignedData.java
index 3d3089bc..e5d4a897 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SignedData.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/SignedData.java
@@ -144,7 +144,7 @@ public class SignedData
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(6);
v.add(version);
v.add(digestAlgorithms);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java
index 269466dc..d6e9d470 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java
@@ -68,7 +68,7 @@ public class ECPrivateKey
{
byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key);
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(new ASN1Integer(1));
v.add(new DEROctetString(bytes));
@@ -113,7 +113,7 @@ public class ECPrivateKey
{
byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key);
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(new ASN1Integer(1));
v.add(new DEROctetString(bytes));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java b/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
index 3b1bcc38..d1639878 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
@@ -37,7 +37,7 @@ public class ECPrivateKeyStructure
{
byte[] bytes = BigIntegers.asUnsignedByteArray(key);
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(new ASN1Integer(1));
v.add(new DEROctetString(bytes));
@@ -59,7 +59,7 @@ public class ECPrivateKeyStructure
{
byte[] bytes = BigIntegers.asUnsignedByteArray(key);
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(new ASN1Integer(1));
v.add(new DEROctetString(bytes));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java b/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java
index 1d2c78cb..03c09c4e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java
@@ -10,13 +10,22 @@ import org.bouncycastle.asn1.x9.X9ECParametersHolder;
import org.bouncycastle.asn1.x9.X9ECPoint;
import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.WNafUtil;
import org.bouncycastle.math.ec.endo.GLVTypeBEndomorphism;
import org.bouncycastle.math.ec.endo.GLVTypeBParameters;
+import org.bouncycastle.math.ec.endo.ScalarSplitParameters;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
public class SECNamedCurves
{
+ private static X9ECPoint configureBasepoint(ECCurve curve, String encoding)
+ {
+ X9ECPoint G = new X9ECPoint(curve, Hex.decodeStrict(encoding));
+ WNafUtil.configureBasepoint(G.getPoint());
+ return G;
+ }
+
private static ECCurve configureCurve(ECCurve curve)
{
return curve;
@@ -27,10 +36,9 @@ public class SECNamedCurves
return c.configure().setEndomorphism(new GLVTypeBEndomorphism(c, p)).create();
}
- private static BigInteger fromHex(
- String hex)
+ private static BigInteger fromHex(String hex)
{
- return new BigInteger(1, Hex.decode(hex));
+ return new BigInteger(1, Hex.decodeStrict(hex));
}
/*
@@ -44,16 +52,14 @@ public class SECNamedCurves
BigInteger p = fromHex("DB7C2ABF62E35E668076BEAD208B");
BigInteger a = fromHex("DB7C2ABF62E35E668076BEAD2088");
BigInteger b = fromHex("659EF8BA043916EEDE8911702B22");
- byte[] S = Hex.decode("00F50B028E4D696E676875615175290472783FB1");
+ byte[] S = Hex.decodeStrict("00F50B028E4D696E676875615175290472783FB1");
BigInteger n = fromHex("DB7C2ABF62E35E7628DFAC6561C5");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "09487239995A5EE76B55F9C2F098"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "09487239995A5EE76B55F9C2F098"
- + "A89CE5AF8724C0A23E0E0FF77500"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0FF77500");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -70,16 +76,14 @@ public class SECNamedCurves
BigInteger p = fromHex("DB7C2ABF62E35E668076BEAD208B");
BigInteger a = fromHex("6127C24C05F38A0AAAF65C0EF02C");
BigInteger b = fromHex("51DEF1815DB5ED74FCC34C85D709");
- byte[] S = Hex.decode("002757A1114D696E6768756151755316C05E0BD4");
+ byte[] S = Hex.decodeStrict("002757A1114D696E6768756151755316C05E0BD4");
BigInteger n = fromHex("36DF0AAFD8B8D7597CA10520D04B");
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "4BA30AB5E892B4E1649DD0928643"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "4BA30AB5E892B4E1649DD0928643"
- + "ADCD46F5882E3747DEF36E956E97"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -96,16 +100,14 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("E87579C11079F43DD824993C2CEE5ED3");
- byte[] S = Hex.decode("000E0D4D696E6768756151750CC03A4473D03679");
+ byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
BigInteger n = fromHex("FFFFFFFE0000000075A30D1B9038A115");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "161FF7528B899B2D0C28607CA52C5B86"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "161FF7528B899B2D0C28607CA52C5B86"
- + "CF5AC8395BAFEB13C02DA292DDED7A83"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -122,16 +124,14 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("D6031998D1B3BBFEBF59CC9BBFF9AEE1");
BigInteger b = fromHex("5EEEFCA380D02919DC2C6558BB6D8A5D");
- byte[] S = Hex.decode("004D696E67687561517512D8F03431FCE63B88F4");
+ byte[] S = Hex.decodeStrict("004D696E67687561517512D8F03431FCE63B88F4");
BigInteger n = fromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3");
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "7B6AA5D85E572983E6FB32A7CDEBC140"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "7B6AA5D85E572983E6FB32A7CDEBC140"
- + "27B6916A894D3AEE7106FE805FC34B44"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "047B6AA5D85E572983E6FB32A7CDEBC14027B6916A894D3AEE7106FE805FC34B44");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -155,22 +155,21 @@ public class SECNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16),
new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16),
- new BigInteger[]{
- new BigInteger("9162fbe73984472a0a9e", 16),
- new BigInteger("-96341f1138933bc2f505", 16) },
- new BigInteger[]{
- new BigInteger("127971af8721782ecffa3", 16),
- new BigInteger("9162fbe73984472a0a9e", 16) },
- new BigInteger("9162fbe73984472a0a9d0590", 16),
- new BigInteger("96341f1138933bc2f503fd44", 16),
- 176);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("9162fbe73984472a0a9e", 16),
+ new BigInteger("-96341f1138933bc2f505", 16) },
+ new BigInteger[]{
+ new BigInteger("127971af8721782ecffa3", 16),
+ new BigInteger("9162fbe73984472a0a9e", 16) },
+ new BigInteger("9162fbe73984472a0a9d0590", 16),
+ new BigInteger("96341f1138933bc2f503fd44", 16),
+ 176));
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
-// ECPoint G = curve.decodePoint(Hex.decode("02"
-// + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"
- + "938CF935318FDCED6BC28286531733C3F03C4FEE"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -187,16 +186,14 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC");
BigInteger b = fromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45");
- byte[] S = Hex.decode("1053CDE42C14D696E67687561517533BF3F83345");
+ byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
BigInteger n = fromHex("0100000000000000000001F4C8F927AED3CA752257");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "4A96B5688EF573284664698968C38BB913CBFC82"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "4A96B5688EF573284664698968C38BB913CBFC82"
- + "23A628553168947D59DCC912042351377AC5FB32"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -213,16 +210,14 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70");
BigInteger b = fromHex("B4E134D3FB59EB8BAB57274904664D5AF50388BA");
- byte[] S = Hex.decode("B99B99B099B323E02709A4D696E6768756151751");
+ byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
BigInteger n = fromHex("0100000000000000000000351EE786A818F3A1A16B");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "52DCB034293A117E1F4FF11B30F7199D3144CE6D"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "52DCB034293A117E1F4FF11B30F7199D3144CE6D"
- + "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -246,22 +241,21 @@ public class SECNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16),
new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16),
- new BigInteger[]{
- new BigInteger("71169be7330b3038edb025f1", 16),
- new BigInteger("-b3fb3400dec5c4adceb8655c", 16) },
- new BigInteger[]{
- new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
- new BigInteger("71169be7330b3038edb025f1", 16) },
- new BigInteger("71169be7330b3038edb025f1d0f9", 16),
- new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
- 208);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("71169be7330b3038edb025f1", 16),
+ new BigInteger("-b3fb3400dec5c4adceb8655c", 16) },
+ new BigInteger[]{
+ new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
+ new BigInteger("71169be7330b3038edb025f1", 16) },
+ new BigInteger("71169be7330b3038edb025f1d0f9", 16),
+ new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
+ 208));
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"
- + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -278,16 +272,14 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1");
- byte[] S = Hex.decode("3045AE6FC8422F64ED579528D38120EAE12196D5");
+ byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"
- + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -311,22 +303,21 @@ public class SECNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16),
new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16),
- new BigInteger[]{
- new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
- new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) },
- new BigInteger[]{
- new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
- new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) },
- new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
- new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
- 240);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
+ new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) },
+ new BigInteger[]{
+ new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) },
+ new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
+ new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
+ 240));
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"
- + "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -343,16 +334,14 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE");
BigInteger b = fromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4");
- byte[] S = Hex.decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
+ byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"
- + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -376,22 +365,21 @@ public class SECNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16),
new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16),
- new BigInteger[]{
- new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
- new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) },
- new BigInteger[]{
- new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
- new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) },
- new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
- new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
- 272);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
+ new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) },
+ new BigInteger[]{
+ new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) },
+ new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
+ new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
+ 272));
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
- + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -408,16 +396,14 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B");
- byte[] S = Hex.decode("C49D360886E704936A6678E1139D26B7819F7E90");
+ byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
BigInteger n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
- + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -434,16 +420,15 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC");
BigInteger b = fromHex("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF");
- byte[] S = Hex.decode("A335926AA319A27A1D00896A6773A4827ACDAC73");
+ byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
- + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"));
+ + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -460,17 +445,15 @@ public class SECNamedCurves
BigInteger p = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00");
- byte[] S = Hex.decode("D09E8800291CB85396CC6717393284AAA0DA64BA");
+ byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
- + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"));
+ + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -488,16 +471,14 @@ public class SECNamedCurves
BigInteger a = fromHex("003088250CA6E7C7FE649CE85820F7");
BigInteger b = fromHex("00E8BEE4D3E2260744188BE0E9C723");
- byte[] S = Hex.decode("10E723AB14D696E6768756151756FEBF8FCB49A9");
+ byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
BigInteger n = fromHex("0100000000000000D9CCEC8A39E56F");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "009D73616F35F4AB1407D73562C10F"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "009D73616F35F4AB1407D73562C10F"
- + "00A52830277958EE84D1315ED31886"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -515,16 +496,14 @@ public class SECNamedCurves
BigInteger a = fromHex("00689918DBEC7E5A0DD6DFC0AA55C7");
BigInteger b = fromHex("0095E9A9EC9B297BD4BF36E059184F");
- byte[] S = Hex.decode("10C0FB15760860DEF1EEF4D696E676875615175D");
+ byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
BigInteger n = fromHex("010000000000000108789B2496AF93");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "01A57A6A7B26CA5EF52FCDB8164797"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "01A57A6A7B26CA5EF52FCDB8164797"
- + "00B3ADC94ED1FE674C06E695BABA1D"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -544,16 +523,14 @@ public class SECNamedCurves
BigInteger a = fromHex("07A11B09A76B562144418FF3FF8C2570B8");
BigInteger b = fromHex("0217C05610884B63B9C6C7291678F9D341");
- byte[] S = Hex.decode("4D696E676875615175985BD3ADBADA21B43A97E2");
+ byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
BigInteger n = fromHex("0400000000000000023123953A9464B54D");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "0081BAF91FDF9833C40F9C181343638399"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "0081BAF91FDF9833C40F9C181343638399"
- + "078C6E7EA38C001F73C8134B1B4EF9E150"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -573,16 +550,14 @@ public class SECNamedCurves
BigInteger a = fromHex("03E5A88919D7CAFCBF415F07C2176573B2");
BigInteger b = fromHex("04B8266A46C55657AC734CE38F018F2192");
- byte[] S = Hex.decode("985BD3ADBAD4D696E676875615175A21B43A97E3");
+ byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
BigInteger n = fromHex("0400000000000000016954A233049BA98F");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "0356DCD8F2F95031AD652D23951BB366A8"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "0356DCD8F2F95031AD652D23951BB366A8"
- + "0648F06D867940A5366D9E265DE9EB240F"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -607,11 +582,9 @@ public class SECNamedCurves
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8"
- + "0289070FB05D38FF58321F2E800536D538CCDAA3D9"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -631,16 +604,14 @@ public class SECNamedCurves
BigInteger a = fromHex("07B6882CAAEFA84F9554FF8428BD88E246D2782AE2");
BigInteger b = fromHex("0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9");
- byte[] S = Hex.decode("24B7B137C8A14D696E6768756151756FD0DA2E5C");
+ byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "0369979697AB43897789566789567F787A7876A654"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "0369979697AB43897789566789567F787A7876A654"
- + "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -660,16 +631,14 @@ public class SECNamedCurves
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("020A601907B8C953CA1481EB10512F78744A3205FD");
- byte[] S = Hex.decode("85E25BFE5C86226CDB12016F7553F9D0E693A268");
+ byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
BigInteger n = fromHex("040000000000000000000292FE77E70C12A4234C33");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "03F0EBA16286A2D57EA0991168D4994637E8343E36"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "03F0EBA16286A2D57EA0991168D4994637E8343E36"
- + "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -687,16 +656,14 @@ public class SECNamedCurves
BigInteger a = fromHex("0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01");
BigInteger b = fromHex("00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814");
- byte[] S = Hex.decode("103FAEC74D696E676875615175777FC5B191EF30");
+ byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
BigInteger n = fromHex("01000000000000000000000000C7F34A778F443ACC920EBA49");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1"
- + "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -714,16 +681,14 @@ public class SECNamedCurves
BigInteger a = fromHex("0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B");
BigInteger b = fromHex("00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE");
- byte[] S = Hex.decode("10B7B4D696E676875615175137C8A16FD0DA2211");
+ byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
BigInteger n = fromHex("010000000000000000000000015AAB561B005413CCD4EE99D5");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F"
- + "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -746,11 +711,9 @@ public class SECNamedCurves
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126"
- + "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -768,16 +731,14 @@ public class SECNamedCurves
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD");
- byte[] S = Hex.decode("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
+ byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
BigInteger n = fromHex("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B"
- + "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -800,11 +761,9 @@ public class SECNamedCurves
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC"
- + "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -829,11 +788,10 @@ public class SECNamedCurves
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
- + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259"));
+ + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -853,16 +811,15 @@ public class SECNamedCurves
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5");
- byte[] S = Hex.decode("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
+ byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
- + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4"));
+ + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -885,11 +842,10 @@ public class SECNamedCurves
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
- + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B"));
+ + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -907,16 +863,15 @@ public class SECNamedCurves
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F");
- byte[] S = Hex.decode("4099B5A457F9D69F79213D094C4BCD4D4262210B");
+ byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
BigInteger n = fromHex("010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
- + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706"));
+ + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -941,11 +896,10 @@ public class SECNamedCurves
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
- + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3"));
+ + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -965,16 +919,15 @@ public class SECNamedCurves
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A");
- byte[] S = Hex.decode("2AA058F73A0E33AB486B0F610410C53A7F132310");
+ byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
- + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B"));
+ + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B");
return new X9ECParameters(curve, G, n, h, S);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java b/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java
index f251702e..a8e07fed 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java
@@ -127,16 +127,7 @@ public class ASN1Dump
buf.append(nl);
- if (o.isEmpty())
- {
- buf.append(tab);
- buf.append("EMPTY");
- buf.append(nl);
- }
- else
- {
- _dumpAsString(tab, verbose, o.getObject(), buf);
- }
+ _dumpAsString(tab, verbose, o.getObject(), buf);
}
else if (obj instanceof ASN1Set)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java
index b4b2bd43..44b5b9f4 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java
@@ -65,7 +65,7 @@ public class AttributeTypeAndValue
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(type);
v.add(value);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/RDN.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/RDN.java
index c84bd0e2..1475b4a4 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/RDN.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/RDN.java
@@ -44,7 +44,7 @@ public class RDN
*/
public RDN(ASN1ObjectIdentifier oid, ASN1Encodable value)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(oid);
v.add(value);
@@ -104,6 +104,31 @@ public class RDN
return tmp;
}
+ int collectAttributeTypes(ASN1ObjectIdentifier[] oids, int oidsOff)
+ {
+ int count = values.size();
+ for (int i = 0; i < count; ++i)
+ {
+ AttributeTypeAndValue attr = AttributeTypeAndValue.getInstance(values.getObjectAt(i));
+ oids[oidsOff + i] = attr.getType();
+ }
+ return count;
+ }
+
+ boolean containsAttributeType(ASN1ObjectIdentifier attributeType)
+ {
+ int count = values.size();
+ for (int i = 0; i < count; ++i)
+ {
+ AttributeTypeAndValue attr = AttributeTypeAndValue.getInstance(values.getObjectAt(i));
+ if (attr.getType().equals(attributeType))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* <pre>
* RelativeDistinguishedName ::=
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500Name.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500Name.java
index bcdfa334..50efe506 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500Name.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500Name.java
@@ -38,14 +38,16 @@ public class X500Name
private X500NameStyle style;
private RDN[] rdns;
+ private DERSequence rdnSeq;
/**
* @deprecated use the getInstance() method that takes a style.
*/
public X500Name(X500NameStyle style, X500Name name)
{
- this.rdns = name.rdns;
this.style = style;
+ this.rdns = name.rdns;
+ this.rdnSeq = name.rdnSeq;
}
/**
@@ -112,11 +114,24 @@ public class X500Name
this.style = style;
this.rdns = new RDN[seq.size()];
- int index = 0;
+ boolean inPlace = true;
+ int index = 0;
for (Enumeration e = seq.getObjects(); e.hasMoreElements();)
{
- rdns[index++] = RDN.getInstance(e.nextElement());
+ Object element = e.nextElement();
+ RDN rdn = RDN.getInstance(element);
+ inPlace &= (rdn == element);
+ rdns[index++] = rdn;
+ }
+
+ if (inPlace)
+ {
+ this.rdnSeq = DERSequence.convert(seq);
+ }
+ else
+ {
+ this.rdnSeq = new DERSequence(this.rdns);
}
}
@@ -130,8 +145,9 @@ public class X500Name
X500NameStyle style,
RDN[] rDNs)
{
- this.rdns = copy(rDNs);
this.style = style;
+ this.rdns = (RDN[])rDNs.clone();
+ this.rdnSeq = new DERSequence(this.rdns);
}
public X500Name(
@@ -156,11 +172,7 @@ public class X500Name
*/
public RDN[] getRDNs()
{
- RDN[] tmp = new RDN[this.rdns.length];
-
- System.arraycopy(rdns, 0, tmp, 0, tmp.length);
-
- return tmp;
+ return (RDN[])rdns.clone();
}
/**
@@ -170,38 +182,21 @@ public class X500Name
*/
public ASN1ObjectIdentifier[] getAttributeTypes()
{
- int count = 0;
-
- for (int i = 0; i != rdns.length; i++)
+ int count = rdns.length, totalSize = 0;
+ for (int i = 0; i < count; ++i)
{
RDN rdn = rdns[i];
-
- count += rdn.size();
+ totalSize += rdn.size();
}
- ASN1ObjectIdentifier[] res = new ASN1ObjectIdentifier[count];
-
- count = 0;
-
- for (int i = 0; i != rdns.length; i++)
+ ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[totalSize];
+ int oidsOff = 0;
+ for (int i = 0; i < count; ++i)
{
RDN rdn = rdns[i];
-
- if (rdn.isMultiValued())
- {
- AttributeTypeAndValue[] attr = rdn.getTypesAndValues();
- for (int j = 0; j != attr.length; j++)
- {
- res[count++] = attr[j].getType();
- }
- }
- else if (rdn.size() != 0)
- {
- res[count++] = rdn.getFirst().getType();
- }
+ oidsOff += rdn.collectAttributeTypes(oids, oidsOff);
}
-
- return res;
+ return oids;
}
/**
@@ -213,52 +208,30 @@ public class X500Name
public RDN[] getRDNs(ASN1ObjectIdentifier attributeType)
{
RDN[] res = new RDN[rdns.length];
- int count = 0;
+ int count = 0;
for (int i = 0; i != rdns.length; i++)
{
RDN rdn = rdns[i];
-
- if (rdn.isMultiValued())
- {
- AttributeTypeAndValue[] attr = rdn.getTypesAndValues();
- for (int j = 0; j != attr.length; j++)
- {
- if (attr[j].getType().equals(attributeType))
- {
- res[count++] = rdn;
- break;
- }
- }
- }
- else
+ if (rdn.containsAttributeType(attributeType))
{
- if (rdn.getFirst().getType().equals(attributeType))
- {
- res[count++] = rdn;
- }
+ res[count++] = rdn;
}
}
- RDN[] tmp = new RDN[count];
-
- System.arraycopy(res, 0, tmp, 0, tmp.length);
-
- return tmp;
- }
-
- private RDN[] copy(RDN[] rdns)
- {
- RDN[] tmp = new RDN[rdns.length];
-
- System.arraycopy(rdns, 0, tmp, 0, tmp.length);
+ if (count < res.length)
+ {
+ RDN[] tmp = new RDN[count];
+ System.arraycopy(res, 0, tmp, 0, tmp.length);
+ res = tmp;
+ }
- return tmp;
+ return res;
}
public ASN1Primitive toASN1Primitive()
{
- return new DERSequence(rdns);
+ return rdnSeq;
}
public int hashCode()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
index a97b17d2..8d801b3d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
@@ -44,8 +44,7 @@ public abstract class AbstractX500NameStyle
private int calcHashCode(ASN1Encodable enc)
{
- String value = IETFUtils.valueToString(enc);
- value = IETFUtils.canonicalize(value);
+ String value = IETFUtils.canonicalString(enc);
return value.hashCode();
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java
index 8d2129ae..a7be3eba 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java
@@ -43,6 +43,7 @@ public class BCStyle
/**
* device serial number name - StringType(SIZE(1..64))
+ * @deprecated use SERIALNUMBER or SURNAME
*/
public static final ASN1ObjectIdentifier SN = new ASN1ObjectIdentifier("2.5.4.5").intern();
@@ -54,7 +55,7 @@ public class BCStyle
/**
* device serial number name - StringType(SIZE(1..64))
*/
- public static final ASN1ObjectIdentifier SERIALNUMBER = SN;
+ public static final ASN1ObjectIdentifier SERIALNUMBER = new ASN1ObjectIdentifier("2.5.4.5").intern();
/**
* locality name - StringType(SIZE(1..64))
@@ -75,6 +76,8 @@ public class BCStyle
public static final ASN1ObjectIdentifier GENERATION = new ASN1ObjectIdentifier("2.5.4.44").intern();
public static final ASN1ObjectIdentifier UNIQUE_IDENTIFIER = new ASN1ObjectIdentifier("2.5.4.45").intern();
+ public static final ASN1ObjectIdentifier DESCRIPTION = new ASN1ObjectIdentifier("2.5.4.13").intern();
+
/**
* businessCategory - DirectoryString(SIZE(1..128)
*/
@@ -95,6 +98,7 @@ public class BCStyle
*/
public static final ASN1ObjectIdentifier PSEUDONYM = new ASN1ObjectIdentifier("2.5.4.65").intern();
+ public static final ASN1ObjectIdentifier ROLE = new ASN1ObjectIdentifier("2.5.4.72").intern();
/**
* RFC 3039 DateOfBirth - GeneralizedTime - YYYYMMDD000000Z
@@ -203,7 +207,7 @@ public class BCStyle
DefaultSymbols.put(CN, "CN");
DefaultSymbols.put(L, "L");
DefaultSymbols.put(ST, "ST");
- DefaultSymbols.put(SN, "SERIALNUMBER");
+ DefaultSymbols.put(SERIALNUMBER, "SERIALNUMBER");
DefaultSymbols.put(EmailAddress, "E");
DefaultSymbols.put(DC, "DC");
DefaultSymbols.put(UID, "UID");
@@ -212,6 +216,8 @@ public class BCStyle
DefaultSymbols.put(GIVENNAME, "GIVENNAME");
DefaultSymbols.put(INITIALS, "INITIALS");
DefaultSymbols.put(GENERATION, "GENERATION");
+ DefaultSymbols.put(DESCRIPTION, "DESCRIPTION");
+ DefaultSymbols.put(ROLE, "ROLE");
DefaultSymbols.put(UnstructuredAddress, "unstructuredAddress");
DefaultSymbols.put(UnstructuredName, "unstructuredName");
DefaultSymbols.put(UNIQUE_IDENTIFIER, "UniqueIdentifier");
@@ -237,8 +243,8 @@ public class BCStyle
DefaultLookUp.put("cn", CN);
DefaultLookUp.put("l", L);
DefaultLookUp.put("st", ST);
- DefaultLookUp.put("sn", SN);
- DefaultLookUp.put("serialnumber", SN);
+ DefaultLookUp.put("sn", SURNAME);
+ DefaultLookUp.put("serialnumber", SERIALNUMBER);
DefaultLookUp.put("street", STREET);
DefaultLookUp.put("emailaddress", E);
DefaultLookUp.put("dc", DC);
@@ -248,13 +254,15 @@ public class BCStyle
DefaultLookUp.put("givenname", GIVENNAME);
DefaultLookUp.put("initials", INITIALS);
DefaultLookUp.put("generation", GENERATION);
+ DefaultLookUp.put("description", DESCRIPTION);
+ DefaultLookUp.put("role", ROLE);
DefaultLookUp.put("unstructuredaddress", UnstructuredAddress);
DefaultLookUp.put("unstructuredname", UnstructuredName);
DefaultLookUp.put("uniqueidentifier", UNIQUE_IDENTIFIER);
DefaultLookUp.put("dn", DN_QUALIFIER);
DefaultLookUp.put("pseudonym", PSEUDONYM);
DefaultLookUp.put("postaladdress", POSTAL_ADDRESS);
- DefaultLookUp.put("nameofbirth", NAME_AT_BIRTH);
+ DefaultLookUp.put("nameatbirth", NAME_AT_BIRTH);
DefaultLookUp.put("countryofcitizenship", COUNTRY_OF_CITIZENSHIP);
DefaultLookUp.put("countryofresidence", COUNTRY_OF_RESIDENCE);
DefaultLookUp.put("gender", GENDER);
@@ -343,6 +351,4 @@ public class BCStyle
return buf.toString();
}
-
-
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java
index 9df924c8..5ddd3223 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java
@@ -359,18 +359,17 @@ public class IETFUtils
String v = ((ASN1String)value).getString();
if (v.length() > 0 && v.charAt(0) == '#')
{
- vBuf.append("\\" + v);
- }
- else
- {
- vBuf.append(v);
+ vBuf.append('\\');
}
+
+ vBuf.append(v);
}
else
{
try
{
- vBuf.append("#" + bytesToString(Hex.encode(value.toASN1Primitive().getEncoded(ASN1Encoding.DER))));
+ vBuf.append('#');
+ vBuf.append(Hex.toHexString(value.toASN1Primitive().getEncoded(ASN1Encoding.DER)));
}
catch (IOException e)
{
@@ -378,8 +377,8 @@ public class IETFUtils
}
}
- int end = vBuf.length();
- int index = 0;
+ int end = vBuf.length();
+ int index = 0;
if (vBuf.length() >= 2 && vBuf.charAt(0) == '\\' && vBuf.charAt(1) == '#')
{
@@ -388,21 +387,28 @@ public class IETFUtils
while (index != end)
{
- if ((vBuf.charAt(index) == ',')
- || (vBuf.charAt(index) == '"')
- || (vBuf.charAt(index) == '\\')
- || (vBuf.charAt(index) == '+')
- || (vBuf.charAt(index) == '=')
- || (vBuf.charAt(index) == '<')
- || (vBuf.charAt(index) == '>')
- || (vBuf.charAt(index) == ';'))
+ switch (vBuf.charAt(index))
{
- vBuf.insert(index, "\\");
- index++;
- end++;
+ case ',':
+ case '"':
+ case '\\':
+ case '+':
+ case '=':
+ case '<':
+ case '>':
+ case ';':
+ {
+ vBuf.insert(index, "\\");
+ index += 2;
+ ++end;
+ break;
+ }
+ default:
+ {
+ ++index;
+ break;
+ }
}
-
- index++;
}
int start = 0;
@@ -426,63 +432,55 @@ public class IETFUtils
return vBuf.toString();
}
- private static String bytesToString(
- byte[] data)
- {
- char[] cs = new char[data.length];
-
- for (int i = 0; i != cs.length; i++)
- {
- cs[i] = (char)(data[i] & 0xff);
- }
-
- return new String(cs);
- }
-
public static String canonicalize(String s)
{
- String value = Strings.toLowerCase(s);
-
- if (value.length() > 0 && value.charAt(0) == '#')
+ if (s.length() > 0 && s.charAt(0) == '#')
{
- ASN1Primitive obj = decodeObject(value);
-
+ ASN1Primitive obj = decodeObject(s);
if (obj instanceof ASN1String)
{
- value = Strings.toLowerCase(((ASN1String)obj).getString());
+ s = ((ASN1String)obj).getString();
}
}
- if (value.length() > 1)
+ s = Strings.toLowerCase(s);
+
+ int length = s.length();
+ if (length < 2)
{
- int start = 0;
- while (start + 1 < value.length() && value.charAt(start) == '\\' && value.charAt(start + 1) == ' ')
- {
- start += 2;
- }
+ return s;
+ }
- int end = value.length() - 1;
- while (end - 1 > 0 && value.charAt(end - 1) == '\\' && value.charAt(end) == ' ')
- {
- end -= 2;
- }
+ int start = 0, last = length - 1;
+ while (start < last && s.charAt(start) == '\\' && s.charAt(start + 1) == ' ')
+ {
+ start += 2;
+ }
- if (start > 0 || end < value.length() - 1)
- {
- value = value.substring(start, end + 1);
- }
+ int end = last, first = start + 1;
+ while (end > first && s.charAt(end - 1) == '\\' && s.charAt(end) == ' ')
+ {
+ end -= 2;
}
- value = stripInternalSpaces(value);
+ if (start > 0 || end < last)
+ {
+ s = s.substring(start, end + 1);
+ }
+
+ return stripInternalSpaces(s);
+ }
- return value;
+ public static String canonicalString(ASN1Encodable value)
+ {
+ return canonicalize(valueToString(value));
}
private static ASN1Primitive decodeObject(String oValue)
{
try
{
- return ASN1Primitive.fromByteArray(Hex.decode(oValue.substring(1)));
+ return ASN1Primitive.fromByteArray(Hex.decodeStrict(oValue, 1, oValue.length() - 1));
}
catch (IOException e)
{
@@ -493,21 +491,22 @@ public class IETFUtils
public static String stripInternalSpaces(
String str)
{
- StringBuffer res = new StringBuffer();
-
- if (str.length() != 0)
+ if (str.indexOf(" ") < 0)
{
- char c1 = str.charAt(0);
+ return str;
+ }
- res.append(c1);
+ StringBuffer res = new StringBuffer();
- for (int k = 1; k < str.length(); k++)
+ char c1 = str.charAt(0);
+ res.append(c1);
+
+ for (int k = 1; k < str.length(); k++)
+ {
+ char c2 = str.charAt(k);
+ if (!(c1 == ' ' && c2 == ' '))
{
- char c2 = str.charAt(k);
- if (!(c1 == ' ' && c2 == ' '))
- {
- res.append(c2);
- }
+ res.append(c2);
c1 = c2;
}
}
@@ -517,38 +516,22 @@ public class IETFUtils
public static boolean rDNAreEqual(RDN rdn1, RDN rdn2)
{
- if (rdn1.isMultiValued())
+ if (rdn1.size() != rdn2.size())
{
- if (rdn2.isMultiValued())
- {
- AttributeTypeAndValue[] atvs1 = rdn1.getTypesAndValues();
- AttributeTypeAndValue[] atvs2 = rdn2.getTypesAndValues();
+ return false;
+ }
- if (atvs1.length != atvs2.length)
- {
- return false;
- }
+ AttributeTypeAndValue[] atvs1 = rdn1.getTypesAndValues();
+ AttributeTypeAndValue[] atvs2 = rdn2.getTypesAndValues();
- for (int i = 0; i != atvs1.length; i++)
- {
- if (!atvAreEqual(atvs1[i], atvs2[i]))
- {
- return false;
- }
- }
- }
- else
- {
- return false;
- }
+ if (atvs1.length != atvs2.length)
+ {
+ return false;
}
- else
+
+ for (int i = 0; i != atvs1.length; i++)
{
- if (!rdn2.isMultiValued())
- {
- return atvAreEqual(rdn1.getFirst(), rdn2.getFirst());
- }
- else
+ if (!atvAreEqual(atvs1[i], atvs2[i]))
{
return false;
}
@@ -564,12 +547,7 @@ public class IETFUtils
return true;
}
- if (atv1 == null)
- {
- return false;
- }
-
- if (atv2 == null)
+ if (null == atv1 || null == atv2)
{
return false;
}
@@ -582,8 +560,8 @@ public class IETFUtils
return false;
}
- String v1 = IETFUtils.canonicalize(IETFUtils.valueToString(atv1.getValue()));
- String v2 = IETFUtils.canonicalize(IETFUtils.valueToString(atv2.getValue()));
+ String v1 = canonicalString(atv1.getValue());
+ String v2 = canonicalString(atv2.getValue());
if (!v1.equals(v2))
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java
index b55d9a9b..53333d95 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java
@@ -92,7 +92,7 @@ public class AlgorithmIdentifier
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(algorithm);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java
index 2f781564..dcda7f88 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java
@@ -74,7 +74,7 @@ public class AttCertValidityPeriod
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(notBeforeTime);
v.add(notAfterTime);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Attribute.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Attribute.java
index b8d4bde7..afe1d4ee 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Attribute.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Attribute.java
@@ -83,7 +83,7 @@ public class Attribute
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(attrType);
v.add(attrValues);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificate.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificate.java
index 73fe7b49..7042e1eb 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificate.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificate.java
@@ -86,7 +86,7 @@ public class AttributeCertificate
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(acinfo);
v.add(signatureAlgorithm);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
index ae539f42..431cb296 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
@@ -152,9 +152,9 @@ public class AttributeCertificateInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(9);
- if (version.getValue().intValue() != 0)
+ if (version.intValueExact() != 0)
{
v.add(version);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
index df4ad65f..356a2fe6 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
@@ -36,9 +36,9 @@ import org.bouncycastle.util.encoders.Hex;
public class AuthorityKeyIdentifier
extends ASN1Object
{
- ASN1OctetString keyidentifier=null;
- GeneralNames certissuer=null;
- ASN1Integer certserno=null;
+ ASN1OctetString keyidentifier = null;
+ GeneralNames certissuer = null;
+ ASN1Integer certserno = null;
public static AuthorityKeyIdentifier getInstance(
ASN1TaggedObject obj,
@@ -64,7 +64,7 @@ public class AuthorityKeyIdentifier
public static AuthorityKeyIdentifier fromExtensions(Extensions extensions)
{
- return AuthorityKeyIdentifier.getInstance(extensions.getExtensionParsedValue(Extension.authorityKeyIdentifier));
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.authorityKeyIdentifier));
}
protected AuthorityKeyIdentifier(
@@ -74,7 +74,7 @@ public class AuthorityKeyIdentifier
while (e.hasMoreElements())
{
- ASN1TaggedObject o = DERTaggedObject.getInstance(e.nextElement());
+ ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement());
switch (o.getTagNo())
{
@@ -140,8 +140,8 @@ public class AuthorityKeyIdentifier
digest.doFinal(resBuf, 0);
this.keyidentifier = new DEROctetString(resBuf);
- this.certissuer = GeneralNames.getInstance(name.toASN1Primitive());
- this.certserno = new ASN1Integer(serialNumber);
+ this.certissuer = name;
+ this.certserno = (serialNumber != null) ? new ASN1Integer(serialNumber) : null;
}
/**
@@ -208,7 +208,7 @@ public class AuthorityKeyIdentifier
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
if (keyidentifier != null)
{
@@ -225,12 +225,13 @@ public class AuthorityKeyIdentifier
v.add(new DERTaggedObject(false, 2, certserno));
}
-
return new DERSequence(v);
}
public String toString()
{
- return ("AuthorityKeyIdentifier: KeyID(" + ((keyidentifier != null) ? Hex.toHexString(this.keyidentifier.getOctets()) : "null") + ")");
+ String keyID = (keyidentifier != null) ? Hex.toHexString(keyidentifier.getOctets()) : "null";
+
+ return "AuthorityKeyIdentifier: KeyID(" + keyID + ")";
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java
index ba5ecf1f..fa4c53d7 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java
@@ -45,7 +45,7 @@ public class BasicConstraints
public static BasicConstraints fromExtensions(Extensions extensions)
{
- return BasicConstraints.getInstance(extensions.getExtensionParsedValue(Extension.basicConstraints));
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.basicConstraints));
}
private BasicConstraints(
@@ -133,7 +133,7 @@ public class BasicConstraints
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
if (cA != null)
{
@@ -152,10 +152,6 @@ public class BasicConstraints
{
if (pathLenConstraint == null)
{
- if (cA == null)
- {
- return "BasicConstraints: isCa(false)";
- }
return "BasicConstraints: isCa(" + this.isCA() + ")";
}
return "BasicConstraints: isCa(" + this.isCA() + "), pathLenConstraint = " + pathLenConstraint.getValue();
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLDistPoint.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLDistPoint.java
index 14bc2e23..1aa3f38d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLDistPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLDistPoint.java
@@ -1,6 +1,5 @@
package org.bouncycastle.asn1.x509;
-import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
@@ -20,11 +19,6 @@ public class CRLDistPoint
return getInstance(ASN1Sequence.getInstance(obj, explicit));
}
- public static CRLDistPoint fromExtensions(Extensions extensions)
- {
- return CRLDistPoint.getInstance(extensions.getExtensionParsedValue(Extension.cRLDistributionPoints));
- }
-
public static CRLDistPoint getInstance(
Object obj)
{
@@ -40,6 +34,11 @@ public class CRLDistPoint
return null;
}
+ public static CRLDistPoint fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.cRLDistributionPoints));
+ }
+
private CRLDistPoint(
ASN1Sequence seq)
{
@@ -49,14 +48,7 @@ public class CRLDistPoint
public CRLDistPoint(
DistributionPoint[] points)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
-
- for (int i = 0; i != points.length; i++)
- {
- v.add(points[i]);
- }
-
- seq = new DERSequence(v);
+ seq = new DERSequence(points);
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLReason.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLReason.java
index ecc68721..a62122ee 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLReason.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLReason.java
@@ -100,7 +100,7 @@ public class CRLReason
}
else if (o != null)
{
- return lookup(ASN1Enumerated.getInstance(o).getValue().intValue());
+ return lookup(ASN1Enumerated.getInstance(o).intValueExact());
}
return null;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/CertificateList.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/CertificateList.java
index 61d7d4a5..b21e3cd9 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/CertificateList.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/CertificateList.java
@@ -122,7 +122,7 @@ public class CertificateList
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(tbsCertList);
v.add(sigAlgId);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DSAParameter.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DSAParameter.java
index 056798ca..6cb8a18c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DSAParameter.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DSAParameter.java
@@ -81,7 +81,7 @@ public class DSAParameter
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(p);
v.add(q);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DigestInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DigestInfo.java
index 4b040a72..245b0ddf 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DigestInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DigestInfo.java
@@ -77,7 +77,7 @@ public class DigestInfo
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(algId);
v.add(new DEROctetString(digest));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java
index 1a4c8dd2..f0017008 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java
@@ -100,7 +100,7 @@ public class DistributionPoint
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
if (distributionPoint != null)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java
index 84d21cac..82aea5af 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java
@@ -68,7 +68,7 @@ public class ExtendedKeyUsage
*/
public static ExtendedKeyUsage fromExtensions(Extensions extensions)
{
- return ExtendedKeyUsage.getInstance(extensions.getExtensionParsedValue(Extension.extendedKeyUsage));
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.extendedKeyUsage));
}
/**
@@ -110,7 +110,7 @@ public class ExtendedKeyUsage
public ExtendedKeyUsage(
KeyPurposeId[] usages)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(usages.length);
for (int i = 0; i != usages.length; i++)
{
@@ -127,12 +127,12 @@ public class ExtendedKeyUsage
public ExtendedKeyUsage(
Vector usages)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
- Enumeration e = usages.elements();
+ ASN1EncodableVector v = new ASN1EncodableVector(usages.size());
+ Enumeration e = usages.elements();
while (e.hasMoreElements())
{
- KeyPurposeId o = KeyPurposeId.getInstance(e.nextElement());
+ KeyPurposeId o = KeyPurposeId.getInstance(e.nextElement());
v.add(o);
this.usageTable.put(o, o);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java
index b8c0473a..50080282 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java
@@ -183,6 +183,13 @@ public class Extension
private boolean critical;
private ASN1OctetString value;
+ /**
+ * Constructor using an ASN1Boolean and an OCTET STRING for the value.
+ *
+ * @param extnId the OID associated with this extension.
+ * @param critical will evaluate to true if the extension is critical, false otherwise.
+ * @param value the extension's value wrapped in an OCTET STRING.
+ */
public Extension(
ASN1ObjectIdentifier extnId,
ASN1Boolean critical,
@@ -191,6 +198,13 @@ public class Extension
this(extnId, critical.isTrue(), value);
}
+ /**
+ * Constructor using a byte[] for the value.
+ *
+ * @param extnId the OID associated with this extension.
+ * @param critical true if the extension is critical, false otherwise.
+ * @param value the extension's value as a byte[] to be wrapped in an OCTET STRING.
+ */
public Extension(
ASN1ObjectIdentifier extnId,
boolean critical,
@@ -199,6 +213,13 @@ public class Extension
this(extnId, critical, new DEROctetString(value));
}
+ /**
+ * Constructor using an OCTET STRING for the value.
+ *
+ * @param extnId the OID associated with this extension.
+ * @param critical true if the extension is critical, false otherwise.
+ * @param value the extension's value wrapped in an OCTET STRING.
+ */
public Extension(
ASN1ObjectIdentifier extnId,
boolean critical,
@@ -209,6 +230,24 @@ public class Extension
this.value = value;
}
+ /**
+ * Helper method to create an extension from any ASN.1 encodable object.
+ *
+ * @param extnId the OID associated with this extension.
+ * @param critical true if the extension is critical, false otherwise.
+ * @param value the value to be encoded into the extension's OCTET STRING.
+ * @return a new Extension with the encoding of value in the bytes of the extension's OCTET STRING.
+ * @throws IOException if the value cannot be encoded into bytes.
+ */
+ public static Extension create(
+ ASN1ObjectIdentifier extnId,
+ boolean critical,
+ ASN1Encodable value)
+ throws IOException
+ {
+ return new Extension(extnId, critical, value.toASN1Primitive().getEncoded());
+ }
+
private Extension(ASN1Sequence seq)
{
if (seq.size() == 2)
@@ -290,7 +329,7 @@ public class Extension
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(extnId);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extensions.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extensions.java
index 30a16f3c..0795a08d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extensions.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extensions.java
@@ -13,12 +13,32 @@ import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSequence;
+/**
+ * <pre>
+ * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ *
+ * Extension ::= SEQUENCE {
+ * extnId EXTENSION.&amp;id ({ExtensionSet}),
+ * critical BOOLEAN DEFAULT FALSE,
+ * extnValue OCTET STRING }
+ * </pre>
+ */
public class Extensions
extends ASN1Object
{
private Hashtable extensions = new Hashtable();
private Vector ordering = new Vector();
+ public static Extension getExtension(Extensions extensions, ASN1ObjectIdentifier oid)
+ {
+ return null == extensions ? null : extensions.getExtension(oid);
+ }
+
+ public static ASN1Encodable getExtensionParsedValue(Extensions extensions, ASN1ObjectIdentifier oid)
+ {
+ return null == extensions ? null : extensions.getExtensionParsedValue(oid);
+ }
+
public static Extensions getInstance(
ASN1TaggedObject obj,
boolean explicit)
@@ -145,9 +165,9 @@ public class Extensions
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector vec = new ASN1EncodableVector();
- Enumeration e = ordering.elements();
+ ASN1EncodableVector vec = new ASN1EncodableVector(ordering.size());
+ Enumeration e = ordering.elements();
while (e.hasMoreElements())
{
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtensionsGenerator.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
index d20e62f5..e4e2ffe5 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
@@ -83,6 +83,94 @@ public class ExtensionsGenerator
}
/**
+ * Replace an extension with the given oid and the passed in value to be included
+ * in the OCTET STRING associated with the extension.
+ *
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the ASN.1 object to be included in the extension.
+ */
+ public void replaceExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ ASN1Encodable value)
+ throws IOException
+ {
+ this.replaceExtension(oid, critical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER));
+ }
+
+ /**
+ * Replace an extension with the given oid and the passed in byte array to be wrapped in the
+ * OCTET STRING associated with the extension.
+ *
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the byte array to be wrapped.
+ */
+ public void replaceExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ byte[] value)
+ {
+ this.replaceExtension(new Extension(oid, critical, value));
+ }
+
+ /**
+ * Replace a given extension.
+ *
+ * @param extension the full extension value.
+ */
+ public void replaceExtension(
+ Extension extension)
+ {
+ if (!extensions.containsKey(extension.getExtnId()))
+ {
+ throw new IllegalArgumentException("extension " + extension.getExtnId() + " not present");
+ }
+
+ extensions.put(extension.getExtnId(), extension);
+ }
+
+ /**
+ * Remove a given extension.
+ *
+ * @param oid OID for the extension to remove.
+ */
+ public void removeExtension(
+ ASN1ObjectIdentifier oid)
+ {
+ if (!extensions.containsKey(oid))
+ {
+ throw new IllegalArgumentException("extension " + oid + " not present");
+ }
+
+ extOrdering.removeElement(oid);
+ extensions.remove(oid);
+ }
+
+ /**
+ * 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 extensions.containsKey(oid);
+ }
+
+ /**
+ * 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 (Extension)extensions.get(oid);
+ }
+
+ /**
* Return true if there are no extension present in this generator.
*
* @return true if empty, false otherwise
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralName.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralName.java
index 1829ecd2..50b88d87 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralName.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralName.java
@@ -186,24 +186,25 @@ public class GeneralName
switch (tag)
{
+ case ediPartyName:
case otherName:
+ case x400Address:
return new GeneralName(tag, ASN1Sequence.getInstance(tagObj, false));
- case rfc822Name:
- return new GeneralName(tag, DERIA5String.getInstance(tagObj, false));
+
case dNSName:
+ case rfc822Name:
+ case uniformResourceIdentifier:
return new GeneralName(tag, DERIA5String.getInstance(tagObj, false));
- case x400Address:
- throw new IllegalArgumentException("unknown tag: " + tag);
+
case directoryName:
return new GeneralName(tag, X500Name.getInstance(tagObj, true));
- case ediPartyName:
- return new GeneralName(tag, ASN1Sequence.getInstance(tagObj, false));
- case uniformResourceIdentifier:
- return new GeneralName(tag, DERIA5String.getInstance(tagObj, false));
case iPAddress:
return new GeneralName(tag, ASN1OctetString.getInstance(tagObj, false));
case registeredID:
return new GeneralName(tag, ASN1ObjectIdentifier.getInstance(tagObj, false));
+
+ default:
+ throw new IllegalArgumentException("unknown tag: " + tag);
}
}
@@ -427,13 +428,9 @@ public class GeneralName
public ASN1Primitive toASN1Primitive()
{
- if (tag == directoryName) // directoryName is explicitly tagged as it is a CHOICE
- {
- return new DERTaggedObject(true, tag, obj);
- }
- else
- {
- return new DERTaggedObject(false, tag, obj);
- }
+ // directoryName is explicitly tagged as it is a CHOICE
+ boolean explicit = (tag == directoryName);
+
+ return new DERTaggedObject(explicit, tag, obj);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralNames.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralNames.java
index 52e0c36b..5ba472bf 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralNames.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralNames.java
@@ -13,6 +13,13 @@ public class GeneralNames
{
private final GeneralName[] names;
+ private static GeneralName[] copy(GeneralName[] names)
+ {
+ GeneralName[] result = new GeneralName[names.length];
+ System.arraycopy(names, 0, result, 0, names.length);
+ return result;
+ }
+
public static GeneralNames getInstance(
Object obj)
{
@@ -33,12 +40,12 @@ public class GeneralNames
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ return new GeneralNames(ASN1Sequence.getInstance(obj, explicit));
}
public static GeneralNames fromExtensions(Extensions extensions, ASN1ObjectIdentifier extOID)
{
- return GeneralNames.getInstance(extensions.getExtensionParsedValue(extOID));
+ return getInstance(Extensions.getExtensionParsedValue(extensions, extOID));
}
/**
@@ -75,15 +82,6 @@ public class GeneralNames
return copy(names);
}
- private GeneralName[] copy(GeneralName[] nms)
- {
- GeneralName[] tmp = new GeneralName[nms.length];
-
- System.arraycopy(nms, 0, tmp, 0, tmp.length);
-
- return tmp;
- }
-
/**
* Produce an object suitable for an ASN1OutputStream.
* <pre>
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralSubtree.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralSubtree.java
index bf72ce63..db06da4d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralSubtree.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralSubtree.java
@@ -199,11 +199,11 @@ public class GeneralSubtree
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(base);
- if (minimum != null && !minimum.getValue().equals(ZERO))
+ if (minimum != null && !minimum.hasValue(ZERO))
{
v.add(new DERTaggedObject(false, 0, minimum));
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Holder.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Holder.java
index e854681f..9a457b8c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Holder.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Holder.java
@@ -211,7 +211,7 @@ public class Holder
{
if (version == 1)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
if (baseCertificateID != null)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java
index fefc9396..4d8e323e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuerSerial.java
@@ -108,7 +108,7 @@ public class IssuerSerial
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(issuer);
v.add(serial);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
index c24b788e..687fc99f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
@@ -90,7 +90,7 @@ public class IssuingDistributionPoint
this.onlyContainsUserCerts = onlyContainsUserCerts;
this.onlySomeReasons = onlySomeReasons;
- ASN1EncodableVector vec = new ASN1EncodableVector();
+ ASN1EncodableVector vec = new ASN1EncodableVector(6);
if (distributionPoint != null)
{ // CHOICE item so explicitly tagged
vec.add(new DERTaggedObject(true, 0, distributionPoint));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java
index f545d0b6..18e056d3 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java
@@ -123,12 +123,12 @@ public class KeyPurposeId
/**
- * Microsoft Server Gated Crypto (msSGC) see http://www.alvestrand.no/objectid/1.3.6.1.4.1.311.10.3.3.html
+ * Microsoft Server Gated Crypto (msSGC) see https://www.alvestrand.no/objectid/1.3.6.1.4.1.311.10.3.3.html
*/
public static final KeyPurposeId id_kp_msSGC = new KeyPurposeId(new ASN1ObjectIdentifier("1.3.6.1.4.1.311.10.3.3"));
/**
- * Netscape Server Gated Crypto (nsSGC) see http://www.alvestrand.no/objectid/2.16.840.1.113730.4.1.html
+ * Netscape Server Gated Crypto (nsSGC) see https://www.alvestrand.no/objectid/2.16.840.1.113730.4.1.html
*/
public static final KeyPurposeId id_kp_nsSGC = new KeyPurposeId(new ASN1ObjectIdentifier("2.16.840.1.113730.4.1"));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyUsage.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyUsage.java
index d4456b74..8301013c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyUsage.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyUsage.java
@@ -52,7 +52,7 @@ public class KeyUsage
public static KeyUsage fromExtensions(Extensions extensions)
{
- return KeyUsage.getInstance(extensions.getExtensionParsedValue(Extension.keyUsage));
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.keyUsage));
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraints.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraints.java
index 88cfe3a9..971bd3f1 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraints.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraints.java
@@ -96,7 +96,7 @@ public class NameConstraints
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
if (permitted != null)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
index c4668b76..d0557059 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
@@ -173,7 +173,7 @@ public class ObjectDigestInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(digestedObjectType);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/OtherName.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/OtherName.java
index eb652f7f..93cbafc4 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/OtherName.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/OtherName.java
@@ -82,7 +82,7 @@ public class OtherName
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(typeID);
v.add(new DERTaggedObject(true, 0, value));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
index d360609e..22bf7cee 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
@@ -12,7 +12,10 @@ import java.util.Set;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERIA5String;
+import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x500.style.IETFUtils;
+import org.bouncycastle.asn1.x500.style.RFC4519Style;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Integers;
import org.bouncycastle.util.Strings;
@@ -64,27 +67,22 @@ public class PKIXNameConstraintValidator
checkPermittedOtherName(permittedSubtreesOtherName, OtherName.getInstance(name.getName()));
break;
case GeneralName.rfc822Name:
- checkPermittedEmail(permittedSubtreesEmail,
- extractNameAsString(name));
+ checkPermittedEmail(permittedSubtreesEmail, extractNameAsString(name));
break;
case GeneralName.dNSName:
- checkPermittedDNS(permittedSubtreesDNS, DERIA5String.getInstance(
- name.getName()).getString());
+ checkPermittedDNS(permittedSubtreesDNS, extractNameAsString(name));
break;
case GeneralName.directoryName:
checkPermittedDN(X500Name.getInstance(name.getName()));
break;
case GeneralName.uniformResourceIdentifier:
- checkPermittedURI(permittedSubtreesURI, DERIA5String.getInstance(
- name.getName()).getString());
+ checkPermittedURI(permittedSubtreesURI, extractNameAsString(name));
break;
case GeneralName.iPAddress:
- byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets();
-
- checkPermittedIP(permittedSubtreesIP, ip);
+ checkPermittedIP(permittedSubtreesIP, ASN1OctetString.getInstance(name.getName()).getOctets());
break;
default:
- throw new IllegalStateException("Unknown tag encountered: " + name.getTagNo());
+ // other tags to be ignored.
}
}
@@ -107,23 +105,19 @@ public class PKIXNameConstraintValidator
checkExcludedEmail(excludedSubtreesEmail, extractNameAsString(name));
break;
case GeneralName.dNSName:
- checkExcludedDNS(excludedSubtreesDNS, DERIA5String.getInstance(
- name.getName()).getString());
+ checkExcludedDNS(excludedSubtreesDNS, extractNameAsString(name));
break;
case GeneralName.directoryName:
checkExcludedDN(X500Name.getInstance(name.getName()));
break;
case GeneralName.uniformResourceIdentifier:
- checkExcludedURI(excludedSubtreesURI, DERIA5String.getInstance(
- name.getName()).getString());
+ checkExcludedURI(excludedSubtreesURI, extractNameAsString(name));
break;
case GeneralName.iPAddress:
- byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets();
-
- checkExcludedIP(excludedSubtreesIP, ip);
+ checkExcludedIP(excludedSubtreesIP, ASN1OctetString.getInstance(name.getName()).getOctets());
break;
default:
- throw new IllegalStateException("Unknown tag encountered: " + name.getTagNo());
+ // other tags to be ignored.
}
}
@@ -154,7 +148,7 @@ public class PKIXNameConstraintValidator
((Set)subtreesMap.get(tagNo)).add(subtree);
}
- for (Iterator it = subtreesMap.entrySet().iterator(); it.hasNext(); )
+ for (Iterator it = subtreesMap.entrySet().iterator(); it.hasNext();)
{
Map.Entry entry = (Map.Entry)it.next();
@@ -251,8 +245,8 @@ public class PKIXNameConstraintValidator
extractNameAsString(base));
break;
case GeneralName.iPAddress:
- excludedSubtreesIP = unionIP(excludedSubtreesIP, ASN1OctetString
- .getInstance(base.getName()).getOctets());
+ excludedSubtreesIP = unionIP(excludedSubtreesIP,
+ ASN1OctetString.getInstance(base.getName()).getOctets());
break;
default:
throw new IllegalStateException("Unknown tag encountered: " + base.getTagNo());
@@ -296,81 +290,13 @@ public class PKIXNameConstraintValidator
&& collectionsAreEqual(constraintValidator.permittedSubtreesOtherName, permittedSubtreesOtherName);
}
- public String toString()
- {
- String temp = "";
- temp += "permitted:\n";
- if (permittedSubtreesDN != null)
- {
- temp += "DN:\n";
- temp += permittedSubtreesDN.toString() + "\n";
- }
- if (permittedSubtreesDNS != null)
- {
- temp += "DNS:\n";
- temp += permittedSubtreesDNS.toString() + "\n";
- }
- if (permittedSubtreesEmail != null)
- {
- temp += "Email:\n";
- temp += permittedSubtreesEmail.toString() + "\n";
- }
- if (permittedSubtreesURI != null)
- {
- temp += "URI:\n";
- temp += permittedSubtreesURI.toString() + "\n";
- }
- if (permittedSubtreesIP != null)
- {
- temp += "IP:\n";
- temp += stringifyIPCollection(permittedSubtreesIP) + "\n";
- }
- if (permittedSubtreesOtherName != null)
- {
- temp += "OtherName:\n";
- temp += stringifyOtherNameCollection(permittedSubtreesOtherName) + "\n";
- }
- temp += "excluded:\n";
- if (!excludedSubtreesDN.isEmpty())
- {
- temp += "DN:\n";
- temp += excludedSubtreesDN.toString() + "\n";
- }
- if (!excludedSubtreesDNS.isEmpty())
- {
- temp += "DNS:\n";
- temp += excludedSubtreesDNS.toString() + "\n";
- }
- if (!excludedSubtreesEmail.isEmpty())
- {
- temp += "Email:\n";
- temp += excludedSubtreesEmail.toString() + "\n";
- }
- if (!excludedSubtreesURI.isEmpty())
- {
- temp += "URI:\n";
- temp += excludedSubtreesURI.toString() + "\n";
- }
- if (!excludedSubtreesIP.isEmpty())
- {
- temp += "IP:\n";
- temp += stringifyIPCollection(excludedSubtreesIP) + "\n";
- }
- if (!excludedSubtreesOtherName.isEmpty())
- {
- temp += "OtherName:\n";
- temp += stringifyOtherNameCollection(excludedSubtreesOtherName) + "\n";
- }
- return temp;
- }
-
- private void checkPermittedDN(X500Name dns)
+ public void checkPermittedDN(X500Name dns)
throws NameConstraintValidatorException
{
checkPermittedDN(permittedSubtreesDN, ASN1Sequence.getInstance(dns.toASN1Primitive()));
}
- private void checkExcludedDN(X500Name dns)
+ public void checkExcludedDN(X500Name dns)
throws NameConstraintValidatorException
{
checkExcludedDN(excludedSubtreesDN, ASN1Sequence.getInstance(dns));
@@ -390,9 +316,56 @@ public class PKIXNameConstraintValidator
return false;
}
- for (int j = subtree.size() - 1; j >= 0; j--)
+ int start = 0;
+ RDN subtreeRdnStart = RDN.getInstance(subtree.getObjectAt(0));
+ for (int j = 0; j < dns.size(); j++)
+ {
+ start = j;
+ RDN dnsRdn = RDN.getInstance(dns.getObjectAt(j));
+ if (IETFUtils.rDNAreEqual(subtreeRdnStart, dnsRdn))
+ {
+ break;
+ }
+ }
+
+ if (subtree.size() > dns.size() - start)
+ {
+ return false;
+ }
+
+ for (int j = 0; j < subtree.size(); j++)
{
- if (!subtree.getObjectAt(j).equals(dns.getObjectAt(j)))
+ // both subtree and dns are a ASN.1 Name and the elements are a RDN
+ RDN subtreeRdn = RDN.getInstance(subtree.getObjectAt(j));
+ RDN dnsRdn = RDN.getInstance(dns.getObjectAt(start + j));
+
+ // check if types and values of all naming attributes are matching, other types which are not restricted are allowed, see https://tools.ietf.org/html/rfc5280#section-7.1
+ if (subtreeRdn.size() == dnsRdn.size())
+ {
+ // Two relative distinguished names
+ // RDN1 and RDN2 match if they have the same number of naming attributes
+ // and for each naming attribute in RDN1 there is a matching naming attribute in RDN2.
+ // NOTE: this is checking the attributes in the same order, which might be not necessary, if this is a problem also IETFUtils.rDNAreEqual mus tbe changed.
+ // use new RFC 5280 comparison, NOTE: this is now different from with RFC 3280, where only binary comparison is used
+ // obey RFC 5280 7.1
+ // special treatment of serialNumber for GSMA SGP.22 RSP specification
+ if (!subtreeRdn.getFirst().getType().equals(dnsRdn.getFirst().getType()))
+ {
+ return false;
+ }
+ if (subtreeRdn.size() == 1 && subtreeRdn.getFirst().getType().equals(RFC4519Style.serialNumber))
+ {
+ if (!dnsRdn.getFirst().getValue().toString().startsWith(subtreeRdn.getFirst().getValue().toString()))
+ {
+ return false;
+ }
+ }
+ else if (!IETFUtils.rDNAreEqual(subtreeRdn, dnsRdn))
+ {
+ return false;
+ }
+ }
+ else
{
return false;
}
@@ -454,7 +427,7 @@ public class PKIXNameConstraintValidator
private Set intersectDN(Set permitted, Set dns)
{
Set intersect = new HashSet();
- for (Iterator it = dns.iterator(); it.hasNext(); )
+ for (Iterator it = dns.iterator(); it.hasNext();)
{
ASN1Sequence dn = ASN1Sequence.getInstance(((GeneralSubtree)it
.next()).getBase().getName().toASN1Primitive());
@@ -505,7 +478,7 @@ public class PKIXNameConstraintValidator
Iterator it = excluded.iterator();
while (it.hasNext())
{
- ASN1Sequence subtree = (ASN1Sequence)it.next();
+ ASN1Sequence subtree = ASN1Sequence.getInstance(it.next());
if (withinDNSubtree(dn, subtree))
{
@@ -528,17 +501,43 @@ public class PKIXNameConstraintValidator
private Set intersectOtherName(Set permitted, Set otherNames)
{
- Set intersect = new HashSet(permitted);
+ Set intersect = new HashSet();
+ for (Iterator it = otherNames.iterator(); it.hasNext();)
+ {
+ OtherName otName1 = OtherName.getInstance(((GeneralSubtree)it.next()).getBase().getName());
- intersect.retainAll(otherNames);
+ if (permitted == null)
+ {
+ if (otName1 != null)
+ {
+ intersect.add(otName1);
+ }
+ }
+ else
+ {
+ Iterator it2 = permitted.iterator();
+ while (it2.hasNext())
+ {
+ OtherName otName2 = OtherName.getInstance(it2.next());
+ intersectOtherName(otName1, otName2, intersect);
+ }
+ }
+ }
return intersect;
}
+ private void intersectOtherName(OtherName otName1, OtherName otName2, Set intersect)
+ {
+ if (otName1.equals(otName2))
+ {
+ intersect.add(otName1);
+ }
+ }
private Set unionOtherName(Set permitted, OtherName otherName)
{
- Set union = new HashSet(permitted);
+ Set union = permitted != null ? new HashSet(permitted) : new HashSet();
union.add(otherName);
@@ -548,7 +547,7 @@ public class PKIXNameConstraintValidator
private Set intersectEmail(Set permitted, Set emails)
{
Set intersect = new HashSet();
- for (Iterator it = emails.iterator(); it.hasNext(); )
+ for (Iterator it = emails.iterator(); it.hasNext();)
{
String email = extractNameAsString(((GeneralSubtree)it.next())
.getBase());
@@ -614,7 +613,7 @@ public class PKIXNameConstraintValidator
private Set intersectIP(Set permitted, Set ips)
{
Set intersect = new HashSet();
- for (Iterator it = ips.iterator(); it.hasNext(); )
+ for (Iterator it = ips.iterator(); it.hasNext();)
{
byte[] ip = ASN1OctetString.getInstance(
((GeneralSubtree)it.next()).getBase().getName()).getOctets();
@@ -700,7 +699,7 @@ public class PKIXNameConstraintValidator
}
/**
- * Calculates the interesction if two IP ranges.
+ * Calculates the intersection if two IP ranges.
*
* @param ipWithSubmask1 The first IP address with its subnet mask.
* @param ipWithSubmask2 The second IP address with its subnet mask.
@@ -857,7 +856,7 @@ public class PKIXNameConstraintValidator
while (it.hasNext())
{
- OtherName str = ((OtherName)it.next());
+ OtherName str = OtherName.getInstance(it.next());
if (otherNameIsConstrained(name, str))
{
@@ -1036,6 +1035,10 @@ public class PKIXNameConstraintValidator
{
return true;
}
+ if (sub.equalsIgnoreCase(constraint.substring(1)))
+ {
+ return true;
+ }
}
// on particular host
else if (!(constraint.charAt(0) == '.'))
@@ -1424,7 +1427,7 @@ public class PKIXNameConstraintValidator
private Set intersectDNS(Set permitted, Set dnss)
{
Set intersect = new HashSet();
- for (Iterator it = dnss.iterator(); it.hasNext(); )
+ for (Iterator it = dnss.iterator(); it.hasNext();)
{
String dns = extractNameAsString(((GeneralSubtree)it.next())
.getBase());
@@ -1623,7 +1626,7 @@ public class PKIXNameConstraintValidator
private Set intersectURI(Set permitted, Set uris)
{
Set intersect = new HashSet();
- for (Iterator it = uris.iterator(); it.hasNext(); )
+ for (Iterator it = uris.iterator(); it.hasNext();)
{
String uri = extractNameAsString(((GeneralSubtree)it.next())
.getBase());
@@ -2046,7 +2049,7 @@ public class PKIXNameConstraintValidator
{
StringBuilder temp = new StringBuilder();
temp.append("[");
- for (Iterator it = ips.iterator(); it.hasNext(); )
+ for (Iterator it = ips.iterator(); it.hasNext();)
{
if (temp.length() > 1)
{
@@ -2062,7 +2065,7 @@ public class PKIXNameConstraintValidator
{
StringBuilder temp = new StringBuilder();
temp.append("[");
- for (Iterator it = otherNames.iterator(); it.hasNext(); )
+ for (Iterator it = otherNames.iterator(); it.hasNext();)
{
if (temp.length() > 1)
{
@@ -2083,4 +2086,78 @@ public class PKIXNameConstraintValidator
temp.append("]");
return temp.toString();
}
+
+ private final void addLine(StringBuilder sb, String str)
+ {
+ sb.append(str).append(Strings.lineSeparator());
+ }
+
+ public String toString()
+ {
+ StringBuilder temp = new StringBuilder();
+
+ addLine(temp, "permitted:");
+ if (permittedSubtreesDN != null)
+ {
+ addLine(temp, "DN:");
+ addLine(temp, permittedSubtreesDN.toString());
+ }
+ if (permittedSubtreesDNS != null)
+ {
+ addLine(temp, "DNS:");
+ addLine(temp, permittedSubtreesDNS.toString());
+ }
+ if (permittedSubtreesEmail != null)
+ {
+ addLine(temp, "Email:");
+ addLine(temp, permittedSubtreesEmail.toString());
+ }
+ if (permittedSubtreesURI != null)
+ {
+ addLine(temp, "URI:");
+ addLine(temp, permittedSubtreesURI.toString());
+ }
+ if (permittedSubtreesIP != null)
+ {
+ addLine(temp, "IP:");
+ addLine(temp, stringifyIPCollection(permittedSubtreesIP));
+ }
+ if (permittedSubtreesOtherName != null)
+ {
+ addLine(temp, "OtherName:");
+ addLine(temp, stringifyOtherNameCollection(permittedSubtreesOtherName));
+ }
+ addLine(temp, "excluded:");
+ if (!excludedSubtreesDN.isEmpty())
+ {
+ addLine(temp, "DN:");
+ addLine(temp, excludedSubtreesDN.toString());
+ }
+ if (!excludedSubtreesDNS.isEmpty())
+ {
+ addLine(temp, "DNS:");
+ addLine(temp, excludedSubtreesDNS.toString());
+ }
+ if (!excludedSubtreesEmail.isEmpty())
+ {
+ addLine(temp, "Email:");
+ addLine(temp, excludedSubtreesEmail.toString());
+ }
+ if (!excludedSubtreesURI.isEmpty())
+ {
+ addLine(temp, "URI:");
+ addLine(temp, excludedSubtreesURI.toString());
+ }
+ if (!excludedSubtreesIP.isEmpty())
+ {
+ addLine(temp, "IP:");
+ addLine(temp, stringifyIPCollection(excludedSubtreesIP));
+ }
+ if (!excludedSubtreesOtherName.isEmpty())
+ {
+ addLine(temp, "OtherName:");
+ addLine(temp, stringifyOtherNameCollection(excludedSubtreesOtherName));
+ }
+ return temp.toString();
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyConstraints.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyConstraints.java
index e2d22a73..a6425ece 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyConstraints.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyConstraints.java
@@ -74,7 +74,7 @@ public class PolicyConstraints
public static PolicyConstraints fromExtensions(Extensions extensions)
{
- return PolicyConstraints.getInstance(extensions.getExtensionParsedValue(Extension.policyConstraints));
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.policyConstraints));
}
public BigInteger getRequireExplicitPolicyMapping()
@@ -89,7 +89,7 @@ public class PolicyConstraints
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
if (requireExplicitPolicyMapping != null)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyInformation.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyInformation.java
index 97f752ae..3b584a8b 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyInformation.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyInformation.java
@@ -75,7 +75,7 @@ public class PolicyInformation
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(policyIdentifier);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
index 2f79a963..6c6b89cb 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
@@ -108,7 +108,7 @@ public class PolicyQualifierInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector dev = new ASN1EncodableVector();
+ ASN1EncodableVector dev = new ASN1EncodableVector(2);
dev.add(policyQualifierId);
dev.add(qualifier);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java
index 91c87256..7ba9e3b0 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java
@@ -88,7 +88,7 @@ public class RSAPublicKeyStructure
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(new ASN1Integer(getModulus()));
v.add(new ASN1Integer(getPublicExponent()));
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java
index 52e35a15..84e13660 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java
@@ -42,7 +42,7 @@ public class SubjectKeyIdentifier
public static SubjectKeyIdentifier fromExtensions(Extensions extensions)
{
- return SubjectKeyIdentifier.getInstance(extensions.getExtensionParsedValue(Extension.subjectKeyIdentifier));
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.subjectKeyIdentifier));
}
public SubjectKeyIdentifier(
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
index 97c0f143..5ad2952c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
@@ -144,7 +144,7 @@ public class SubjectPublicKeyInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(algId);
v.add(keyData);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java
index c7682f1a..abaa9099 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java
@@ -217,7 +217,7 @@ public class TBSCertList
{
return 1;
}
- return version.getValue().intValue() + 1;
+ return version.intValueExact() + 1;
}
public ASN1Integer getVersion()
@@ -279,7 +279,7 @@ public class TBSCertList
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(7);
if (version != null)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java
index 3d5e1be1..6ae198a0 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java
@@ -2,13 +2,18 @@ package org.bouncycastle.asn1.x509;
import java.math.BigInteger;
+import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERBitString;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.util.BigIntegers;
+import org.bouncycastle.util.Properties;
/**
* The TBSCertificate object.
@@ -91,15 +96,15 @@ public class TBSCertificate
boolean isV1 = false;
boolean isV2 = false;
- if (version.getValue().equals(BigInteger.valueOf(0)))
+ if (version.hasValue(BigInteger.valueOf(0)))
{
isV1 = true;
}
- else if (version.getValue().equals(BigInteger.valueOf(1)))
+ else if (version.hasValue(BigInteger.valueOf(1)))
{
isV2 = true;
}
- else if (!version.getValue().equals(BigInteger.valueOf(2)))
+ else if (!version.hasValue(BigInteger.valueOf(2)))
{
throw new IllegalArgumentException("version number not recognised");
}
@@ -158,7 +163,7 @@ public class TBSCertificate
public int getVersionNumber()
{
- return version.getValue().intValue() + 1;
+ return version.intValueExact() + 1;
}
public ASN1Integer getVersion()
@@ -218,6 +223,69 @@ public class TBSCertificate
public ASN1Primitive toASN1Primitive()
{
- return seq;
+ if (Properties.getPropertyValue("org.bouncycastle.x509.allow_non-der_tbscert") != null)
+ {
+ if (Properties.isOverrideSet("org.bouncycastle.x509.allow_non-der_tbscert"))
+ {
+ return seq;
+ }
+ }
+ else
+ {
+ return seq;
+ }
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ // DEFAULT Zero
+ if (!version.hasValue(BigIntegers.ZERO))
+ {
+ v.add(new DERTaggedObject(true, 0, version));
+ }
+
+ v.add(serialNumber);
+ v.add(signature);
+ v.add(issuer);
+
+ //
+ // before and after dates
+ //
+ {
+ ASN1EncodableVector validity = new ASN1EncodableVector(2);
+ validity.add(startDate);
+ validity.add(endDate);
+
+ v.add(new DERSequence(validity));
+ }
+
+ if (subject != null)
+ {
+ v.add(subject);
+ }
+ else
+ {
+ v.add(new DERSequence());
+ }
+
+ v.add(subjectPublicKeyInfo);
+
+ // Note: implicit tag
+ if (issuerUniqueId != null)
+ {
+ v.add(new DERTaggedObject(false, 1, issuerUniqueId));
+ }
+
+ // Note: implicit tag
+ if (subjectUniqueId != null)
+ {
+ v.add(new DERTaggedObject(false, 2, subjectUniqueId));
+ }
+
+ if (extensions != null)
+ {
+ v.add(new DERTaggedObject(true, 3, extensions));
+ }
+
+ return new DERSequence(v);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificateStructure.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
index e7bdedc5..b635d597 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
@@ -6,7 +6,6 @@ import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERBitString;
-import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
@@ -80,7 +79,7 @@ public class TBSCertificateStructure
//
// some certficates don't include a version number - we assume v1
//
- if (seq.getObjectAt(0) instanceof DERTaggedObject)
+ if (seq.getObjectAt(0) instanceof ASN1TaggedObject)
{
version = ASN1Integer.getInstance((ASN1TaggedObject)seq.getObjectAt(0), true);
}
@@ -112,7 +111,7 @@ public class TBSCertificateStructure
for (int extras = seq.size() - (seqStart + 6) - 1; extras > 0; extras--)
{
- DERTaggedObject extra = (DERTaggedObject)seq.getObjectAt(seqStart + 6 + extras);
+ ASN1TaggedObject extra = ASN1TaggedObject.getInstance(seq.getObjectAt(seqStart + 6 + extras));
switch (extra.getTagNo())
{
@@ -130,7 +129,7 @@ public class TBSCertificateStructure
public int getVersion()
{
- return version.getValue().intValue() + 1;
+ return version.intValueExact() + 1;
}
public ASN1Integer getVersionNumber()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java
index fe4cb5eb..9df0b167 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java
@@ -118,7 +118,7 @@ public class V1TBSCertificateGenerator
throw new IllegalStateException("not all mandatory fields set in V1 TBScertificate generator");
}
- ASN1EncodableVector seq = new ASN1EncodableVector();
+ ASN1EncodableVector seq = new ASN1EncodableVector(6);
// seq.add(version); - not required as default value.
seq.add(serialNumber);
@@ -128,12 +128,13 @@ public class V1TBSCertificateGenerator
//
// before and after dates
//
- ASN1EncodableVector validity = new ASN1EncodableVector();
-
- validity.add(startDate);
- validity.add(endDate);
+ {
+ ASN1EncodableVector validity = new ASN1EncodableVector(2);
+ validity.add(startDate);
+ validity.add(endDate);
- seq.add(new DERSequence(validity));
+ seq.add(new DERSequence(validity));
+ }
seq.add(subject);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/V2Form.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/V2Form.java
index 5cee8471..bd4c59cb 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/V2Form.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/V2Form.java
@@ -135,7 +135,7 @@ public class V2Form
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
if (issuerName != null)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
index d778d7f5..c4ebdc1c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
@@ -164,7 +164,7 @@ public class V3TBSCertificateGenerator
throw new IllegalStateException("not all mandatory fields set in V3 TBScertificate generator");
}
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(10);
v.add(version);
v.add(serialNumber);
@@ -174,12 +174,13 @@ public class V3TBSCertificateGenerator
//
// before and after dates
//
- ASN1EncodableVector validity = new ASN1EncodableVector();
-
- validity.add(startDate);
- validity.add(endDate);
+ {
+ ASN1EncodableVector validity = new ASN1EncodableVector(2);
+ validity.add(startDate);
+ validity.add(endDate);
- v.add(new DERSequence(validity));
+ v.add(new DERSequence(validity));
+ }
if (subject != null)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java
index 5b9ea9e1..86e3b248 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java
@@ -15,7 +15,7 @@ import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSequence;
/**
- * @deprecated use Extensions
+ * @deprecated use {@link Extensions}
*/
public class X509Extensions
extends ASN1Object
@@ -385,14 +385,15 @@ public class X509Extensions
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector vec = new ASN1EncodableVector();
- Enumeration e = ordering.elements();
+ ASN1EncodableVector vec = new ASN1EncodableVector(ordering.size());
+ Enumeration e = ordering.elements();
while (e.hasMoreElements())
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
- X509Extension ext = (X509Extension)extensions.get(oid);
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ X509Extension ext = (X509Extension)extensions.get(oid);
v.add(oid);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Name.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Name.java
index fafb68ff..9f8d9b9d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Name.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509Name.java
@@ -376,7 +376,7 @@ public class X509Name
public static X509Name getInstance(
Object obj)
{
- if (obj == null || obj instanceof X509Name)
+ if (obj instanceof X509Name)
{
return (X509Name)obj;
}
@@ -928,7 +928,7 @@ public class X509Name
for (int i = 0; i != ordering.size(); i++)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)ordering.elementAt(i);
v.add(oid);
@@ -945,8 +945,8 @@ public class X509Name
else
{
vec.add(new DERSet(sVec));
+
sVec = new ASN1EncodableVector();
-
sVec.add(new DERSequence(v));
}
@@ -1188,7 +1188,7 @@ public class X509Name
{
try
{
- return ASN1Primitive.fromByteArray(Hex.decode(oValue.substring(1)));
+ return ASN1Primitive.fromByteArray(Hex.decodeStrict(oValue, 1, oValue.length() - 1));
}
catch (IOException e)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509NameEntryConverter.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
index 188af430..b5de2e05 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
@@ -2,11 +2,10 @@ package org.bouncycastle.asn1.x509;
import java.io.IOException;
-import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.DERPrintableString;
-import org.bouncycastle.util.Strings;
+import org.bouncycastle.util.encoders.Hex;
/**
* It turns out that the number of standard ways the fields in a DN should be
@@ -62,36 +61,9 @@ public abstract class X509NameEntryConverter
int off)
throws IOException
{
- str = Strings.toLowerCase(str);
- byte[] data = new byte[(str.length() - off) / 2];
- for (int index = 0; index != data.length; index++)
- {
- char left = str.charAt((index * 2) + off);
- char right = str.charAt((index * 2) + off + 1);
-
- if (left < 'a')
- {
- data[index] = (byte)((left - '0') << 4);
- }
- else
- {
- data[index] = (byte)((left - 'a' + 10) << 4);
- }
- if (right < 'a')
- {
- data[index] |= (byte)(right - '0');
- }
- else
- {
- data[index] |= (byte)(right - 'a' + 10);
- }
- }
-
- ASN1InputStream aIn = new ASN1InputStream(data);
-
- return aIn.readObject();
+ return ASN1Primitive.fromByteArray(Hex.decodeStrict(str, off, str.length() - off));
}
-
+
/**
* return true if the passed in String can be represented without
* loss as a PrintableString, false otherwise.
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
index af218bca..02857c7b 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
@@ -4,7 +4,6 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier;
public interface X509ObjectIdentifiers
{
-
/** Subject RDN components: commonName = 2.5.4.3 */
static final ASN1ObjectIdentifier commonName = new ASN1ObjectIdentifier("2.5.4.3").intern();
/** Subject RDN components: countryName = 2.5.4.6 */
@@ -58,6 +57,34 @@ public interface X509ObjectIdentifiers
static final ASN1ObjectIdentifier id_pkix = new ASN1ObjectIdentifier("1.3.6.1.5.5.7");
/**
+ * id-RSASSA-PSS-SHAKE128 OBJECT IDENTIFIER ::= { iso(1)
+ * identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) algorithms(6) 30 }
+ */
+ static final ASN1ObjectIdentifier id_rsassa_pss_shake128 = id_pkix.branch("6.30");
+
+ /**
+ * id-RSASSA-PSS-SHAKE256 OBJECT IDENTIFIER ::= { iso(1)
+ * identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) algorithms(6) 31 }
+ */
+ static final ASN1ObjectIdentifier id_rsassa_pss_shake256 = id_pkix.branch("6.31");
+
+ /**
+ * id-ecdsa-with-shake128 OBJECT IDENTIFIER ::= { iso(1)
+ * identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) algorithms(6) 32 }
+ */
+ static final ASN1ObjectIdentifier id_ecdsa_with_shake128 = id_pkix.branch("6.32");
+
+ /**
+ * id-ecdsa-with-shake256 OBJECT IDENTIFIER ::= { iso(1)
+ * identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) algorithms(6) 33 }
+ */
+ static final ASN1ObjectIdentifier id_ecdsa_with_shake256 = id_pkix.branch("6.33");
+
+ /**
* private internet extensions; OID = 1.3.6.1.5.5.7.1
*/
static final ASN1ObjectIdentifier id_pe = id_pkix.branch("1");
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHDomainParameters.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHDomainParameters.java
index abff3635..08aab85d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHDomainParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHDomainParameters.java
@@ -146,7 +146,7 @@ public class DHDomainParameters
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
v.add(this.p);
v.add(this.g);
v.add(this.q);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java
index db384590..8def60c1 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java
@@ -74,7 +74,7 @@ public class DHValidationParms extends ASN1Object
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(this.seed);
v.add(this.pgenCounter);
return new DERSequence(v);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/DomainParameters.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DomainParameters.java
index 0555190a..a0e0ae06 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/DomainParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DomainParameters.java
@@ -203,7 +203,7 @@ public class DomainParameters
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
v.add(this.p);
v.add(this.g);
v.add(this.q);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
index 41f12b1c..1d68df7e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
@@ -8,12 +8,12 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier;
// import org.bouncycastle.asn1.anssi.ANSSINamedCurves;
// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
// import org.bouncycastle.asn1.gm.GMNamedCurves;
+// import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTNamedCurves;
import org.bouncycastle.asn1.sec.SECNamedCurves;
// Android-removed: Unsupported curves
// import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
import org.bouncycastle.crypto.ec.CustomNamedCurves;
-import org.bouncycastle.crypto.params.ECDomainParameters;
/**
* A general class that reads all X9.62 style EC curve tables.
@@ -56,7 +56,7 @@ public class ECNamedCurveTable
if (ecP == null)
{
- ecP = fromDomainParameters(ECGOST3410NamedCurves.getByName(name));
+ ecP = ECGOST3410NamedCurves.getByNameX9(name);
}
if (ecP == null)
@@ -111,6 +111,11 @@ public class ECNamedCurveTable
{
oid = GMNamedCurves.getOID(name);
}
+
+ if (oid == null && name.equals("curve25519"))
+ {
+ oid = CryptlibObjectIdentifiers.curvey25519;
+ }
*/
// END Android-removed: Unsupported curves
@@ -204,7 +209,7 @@ public class ECNamedCurveTable
if (ecP == null)
{
- ecP = fromDomainParameters(ECGOST3410NamedCurves.getByOID(oid));
+ ecP = ECGOST3410NamedCurves.getByOIDX9(oid);
}
if (ecP == null)
@@ -248,9 +253,4 @@ public class ECNamedCurveTable
v.addElement(e.nextElement());
}
}
-
- private static X9ECParameters fromDomainParameters(ECDomainParameters dp)
- {
- return dp == null ? null : new X9ECParameters(dp.getCurve(), dp.getG(), dp.getN(), dp.getH(), dp.getSeed());
- }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java
index 855974d2..466e265c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java
@@ -94,7 +94,7 @@ public class ValidationParams
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(this.seed);
v.add(this.pgenCounter);
return new DERSequence(v);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java
index 02968345..3d1ddd5c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java
@@ -6,6 +6,7 @@ import java.util.Hashtable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.WNafUtil;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
@@ -15,25 +16,40 @@ import org.bouncycastle.util.encoders.Hex;
*/
public class X962NamedCurves
{
+ private static X9ECPoint configureBasepoint(ECCurve curve, String encoding)
+ {
+ X9ECPoint G = new X9ECPoint(curve, Hex.decodeStrict(encoding));
+ WNafUtil.configureBasepoint(G.getPoint());
+ return G;
+ }
+
+ private static ECCurve configureCurve(ECCurve curve)
+ {
+ return curve;
+ }
+
+ private static BigInteger fromHex(String hex)
+ {
+ return new BigInteger(1, Hex.decodeStrict(hex));
+ }
+
static X9ECParametersHolder prime192v1 = new X9ECParametersHolder()
{
protected X9ECParameters createParameters()
{
- BigInteger n = new BigInteger("ffffffffffffffffffffffff99def836146bc9b1b4d22831", 16);
+ BigInteger n = fromHex("ffffffffffffffffffffffff99def836146bc9b1b4d22831");
BigInteger h = BigInteger.valueOf(1);
- ECCurve cFp192v1 = new ECCurve.Fp(
- new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 16),
- new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16),
- new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16),
- n, h);
-
- return new X9ECParameters(
- cFp192v1,
- new X9ECPoint(cFp192v1,
- Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")),
- n, h,
- Hex.decode("3045AE6FC8422f64ED579528D38120EAE12196D5"));
+ ECCurve curve = configureCurve(new ECCurve.Fp(
+ fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
+ fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
+ fromHex("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("3045AE6FC8422f64ED579528D38120EAE12196D5"));
}
};
@@ -41,21 +57,19 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger n = new BigInteger("fffffffffffffffffffffffe5fb1a724dc80418648d8dd31", 16);
+ BigInteger n = fromHex("fffffffffffffffffffffffe5fb1a724dc80418648d8dd31");
BigInteger h = BigInteger.valueOf(1);
- ECCurve cFp192v2 = new ECCurve.Fp(
- new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 16),
- new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16),
- new BigInteger("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953", 16),
- n, h);
-
- return new X9ECParameters(
- cFp192v2,
- new X9ECPoint(cFp192v2,
- Hex.decode("03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a")),
- n, h,
- Hex.decode("31a92ee2029fd10d901b113e990710f0d21ac6b6"));
+ ECCurve curve = configureCurve(new ECCurve.Fp(
+ fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
+ fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
+ fromHex("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("31a92ee2029fd10d901b113e990710f0d21ac6b6"));
}
};
@@ -63,21 +77,19 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger n = new BigInteger("ffffffffffffffffffffffff7a62d031c83f4294f640ec13", 16);
+ BigInteger n = fromHex("ffffffffffffffffffffffff7a62d031c83f4294f640ec13");
BigInteger h = BigInteger.valueOf(1);
- ECCurve cFp192v3 = new ECCurve.Fp(
- new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 16),
- new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16),
- new BigInteger("22123dc2395a05caa7423daeccc94760a7d462256bd56916", 16),
- n, h);
-
- return new X9ECParameters(
- cFp192v3,
- new X9ECPoint(cFp192v3,
- Hex.decode("027d29778100c65a1da1783716588dce2b8b4aee8e228f1896")),
- n, h,
- Hex.decode("c469684435deb378c4b65ca9591e2a5763059a2e"));
+ ECCurve curve = configureCurve(new ECCurve.Fp(
+ fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
+ fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
+ fromHex("22123dc2395a05caa7423daeccc94760a7d462256bd56916"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "027d29778100c65a1da1783716588dce2b8b4aee8e228f1896");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("c469684435deb378c4b65ca9591e2a5763059a2e"));
}
};
@@ -85,21 +97,19 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger n = new BigInteger("7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b", 16);
+ BigInteger n = fromHex("7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b");
BigInteger h = BigInteger.valueOf(1);
- ECCurve cFp239v1 = new ECCurve.Fp(
+ ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
- new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16),
- new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16),
- n, h);
-
- return new X9ECParameters(
- cFp239v1,
- new X9ECPoint(cFp239v1,
- Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")),
- n, h,
- Hex.decode("e43bb460f0b80cc0c0b075798e948060f8321b7d"));
+ fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
+ fromHex("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("e43bb460f0b80cc0c0b075798e948060f8321b7d"));
}
};
@@ -107,21 +117,19 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger n = new BigInteger("7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063", 16);
+ BigInteger n = fromHex("7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063");
BigInteger h = BigInteger.valueOf(1);
- ECCurve cFp239v2 = new ECCurve.Fp(
+ ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
- new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16),
- new BigInteger("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c", 16),
- n, h);
-
- return new X9ECParameters(
- cFp239v2,
- new X9ECPoint(cFp239v2,
- Hex.decode("0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7")),
- n, h,
- Hex.decode("e8b4011604095303ca3b8099982be09fcb9ae616"));
+ fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
+ fromHex("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("e8b4011604095303ca3b8099982be09fcb9ae616"));
}
};
@@ -129,21 +137,19 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger n = new BigInteger("7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551", 16);
+ BigInteger n = fromHex("7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551");
BigInteger h = BigInteger.valueOf(1);
- ECCurve cFp239v3 = new ECCurve.Fp(
+ ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
- new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16),
- new BigInteger("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e", 16),
- n, h);
-
- return new X9ECParameters(
- cFp239v3,
- new X9ECPoint(cFp239v3,
- Hex.decode("036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a")),
- n, h,
- Hex.decode("7d7374168ffe3471b60a857686a19475d3bfa2ff"));
+ fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
+ fromHex("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("7d7374168ffe3471b60a857686a19475d3bfa2ff"));
}
};
@@ -151,21 +157,19 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger n = new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16);
+ BigInteger n = fromHex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551");
BigInteger h = BigInteger.valueOf(1);
- ECCurve cFp256v1 = new ECCurve.Fp(
+ ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951"),
- new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
- new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
- n, h);
-
- return new X9ECParameters(
- cFp256v1,
- new X9ECPoint(cFp256v1,
- Hex.decode("036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296")),
- n, h,
- Hex.decode("c49d360886e704936a6678e1139d26b7819f7e90"));
+ fromHex("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc"),
+ fromHex("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("c49d360886e704936a6678e1139d26b7819f7e90"));
}
};
@@ -176,22 +180,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m163v1n = new BigInteger("0400000000000000000001E60FC8821CC74DAEAFC1", 16);
- BigInteger c2m163v1h = BigInteger.valueOf(2);
+ BigInteger n = fromHex("0400000000000000000001E60FC8821CC74DAEAFC1");
+ BigInteger h = BigInteger.valueOf(2);
- ECCurve c2m163v1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
- new BigInteger("072546B5435234A422E0789675F432C89435DE5242", 16),
- new BigInteger("00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", 16),
- c2m163v1n, c2m163v1h);
-
- return new X9ECParameters(
- c2m163v1,
- new X9ECPoint(c2m163v1,
- Hex.decode("0307AF69989546103D79329FCC3D74880F33BBE803CB")),
- c2m163v1n, c2m163v1h,
- Hex.decode("D2C0FB15760860DEF1EEF4D696E6768756151754"));
+ fromHex("072546B5435234A422E0789675F432C89435DE5242"),
+ fromHex("00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0307AF69989546103D79329FCC3D74880F33BBE803CB");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("D2C0FB15760860DEF1EEF4D696E6768756151754"));
}
};
@@ -199,22 +201,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m163v2n = new BigInteger("03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 16);
- BigInteger c2m163v2h = BigInteger.valueOf(2);
+ BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7");
+ BigInteger h = BigInteger.valueOf(2);
- ECCurve c2m163v2 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
- new BigInteger("0108B39E77C4B108BED981ED0E890E117C511CF072", 16),
- new BigInteger("0667ACEB38AF4E488C407433FFAE4F1C811638DF20", 16),
- c2m163v2n, c2m163v2h);
-
- return new X9ECParameters(
- c2m163v2,
- new X9ECPoint(c2m163v2,
- Hex.decode("030024266E4EB5106D0A964D92C4860E2671DB9B6CC5")),
- c2m163v2n, c2m163v2h,
- null);
+ fromHex("0108B39E77C4B108BED981ED0E890E117C511CF072"),
+ fromHex("0667ACEB38AF4E488C407433FFAE4F1C811638DF20"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "030024266E4EB5106D0A964D92C4860E2671DB9B6CC5");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -222,22 +222,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m163v3n = new BigInteger("03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 16);
- BigInteger c2m163v3h = BigInteger.valueOf(2);
+ BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309");
+ BigInteger h = BigInteger.valueOf(2);
- ECCurve c2m163v3 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
- new BigInteger("07A526C63D3E25A256A007699F5447E32AE456B50E", 16),
- new BigInteger("03F7061798EB99E238FD6F1BF95B48FEEB4854252B", 16),
- c2m163v3n, c2m163v3h);
-
- return new X9ECParameters(
- c2m163v3,
- new X9ECPoint(c2m163v3,
- Hex.decode("0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB")),
- c2m163v3n, c2m163v3h,
- null);
+ fromHex("07A526C63D3E25A256A007699F5447E32AE456B50E"),
+ fromHex("03F7061798EB99E238FD6F1BF95B48FEEB4854252B"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -245,22 +243,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m176w1n = new BigInteger("010092537397ECA4F6145799D62B0A19CE06FE26AD", 16);
- BigInteger c2m176w1h = BigInteger.valueOf(0xFF6E);
+ BigInteger n = fromHex("010092537397ECA4F6145799D62B0A19CE06FE26AD");
+ BigInteger h = BigInteger.valueOf(0xFF6E);
- ECCurve c2m176w1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
176,
1, 2, 43,
- new BigInteger("00E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", 16),
- new BigInteger("005DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", 16),
- c2m176w1n, c2m176w1h);
-
- return new X9ECParameters(
- c2m176w1,
- new X9ECPoint(c2m176w1,
- Hex.decode("038D16C2866798B600F9F08BB4A8E860F3298CE04A5798")),
- c2m176w1n, c2m176w1h,
- null);
+ fromHex("E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B"),
+ fromHex("5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "038D16C2866798B600F9F08BB4A8E860F3298CE04A5798");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -268,22 +264,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m191v1n = new BigInteger("40000000000000000000000004A20E90C39067C893BBB9A5", 16);
- BigInteger c2m191v1h = BigInteger.valueOf(2);
+ BigInteger n = fromHex("40000000000000000000000004A20E90C39067C893BBB9A5");
+ BigInteger h = BigInteger.valueOf(2);
- ECCurve c2m191v1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
191,
9,
- new BigInteger("2866537B676752636A68F56554E12640276B649EF7526267", 16),
- new BigInteger("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", 16),
- c2m191v1n, c2m191v1h);
-
- return new X9ECParameters(
- c2m191v1,
- new X9ECPoint(c2m191v1,
- Hex.decode("0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D")),
- c2m191v1n, c2m191v1h,
- Hex.decode("4E13CA542744D696E67687561517552F279A8C84"));
+ fromHex("2866537B676752636A68F56554E12640276B649EF7526267"),
+ fromHex("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("4E13CA542744D696E67687561517552F279A8C84"));
}
};
@@ -291,22 +285,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m191v2n = new BigInteger("20000000000000000000000050508CB89F652824E06B8173", 16);
- BigInteger c2m191v2h = BigInteger.valueOf(4);
+ BigInteger n = fromHex("20000000000000000000000050508CB89F652824E06B8173");
+ BigInteger h = BigInteger.valueOf(4);
- ECCurve c2m191v2 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
191,
9,
- new BigInteger("401028774D7777C7B7666D1366EA432071274F89FF01E718", 16),
- new BigInteger("0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", 16),
- c2m191v2n, c2m191v2h);
-
- return new X9ECParameters(
- c2m191v2,
- new X9ECPoint(c2m191v2,
- Hex.decode("023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10")),
- c2m191v2n, c2m191v2h,
- null);
+ fromHex("401028774D7777C7B7666D1366EA432071274F89FF01E718"),
+ fromHex("0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -314,22 +306,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m191v3n = new BigInteger("155555555555555555555555610C0B196812BFB6288A3EA3", 16);
- BigInteger c2m191v3h = BigInteger.valueOf(6);
+ BigInteger n = fromHex("155555555555555555555555610C0B196812BFB6288A3EA3");
+ BigInteger h = BigInteger.valueOf(6);
- ECCurve c2m191v3 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
191,
9,
- new BigInteger("6C01074756099122221056911C77D77E77A777E7E7E77FCB", 16),
- new BigInteger("71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", 16),
- c2m191v3n, c2m191v3h);
-
- return new X9ECParameters(
- c2m191v3,
- new X9ECPoint(c2m191v3,
- Hex.decode("03375D4CE24FDE434489DE8746E71786015009E66E38A926DD")),
- c2m191v3n, c2m191v3h,
- null);
+ fromHex("6C01074756099122221056911C77D77E77A777E7E7E77FCB"),
+ fromHex("71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "03375D4CE24FDE434489DE8746E71786015009E66E38A926DD");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -337,22 +327,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m208w1n = new BigInteger("0101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 16);
- BigInteger c2m208w1h = BigInteger.valueOf(0xFE48);
+ BigInteger n = fromHex("0101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D");
+ BigInteger h = BigInteger.valueOf(0xFE48);
- ECCurve c2m208w1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
208,
1, 2, 83,
- new BigInteger("0", 16),
- new BigInteger("00C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", 16),
- c2m208w1n, c2m208w1h);
-
- return new X9ECParameters(
- c2m208w1,
- new X9ECPoint(c2m208w1,
- Hex.decode("0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A")),
- c2m208w1n, c2m208w1h,
- null);
+ BigInteger.valueOf(0),
+ fromHex("C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -360,22 +348,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m239v1n = new BigInteger("2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 16);
- BigInteger c2m239v1h = BigInteger.valueOf(4);
+ BigInteger n = fromHex("2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447");
+ BigInteger h = BigInteger.valueOf(4);
- ECCurve c2m239v1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
239,
36,
- new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16),
- new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16),
- c2m239v1n, c2m239v1h);
-
- return new X9ECParameters(
- c2m239v1,
- new X9ECPoint(c2m239v1,
- Hex.decode("0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D")),
- c2m239v1n, c2m239v1h,
- null);
+ fromHex("32010857077C5431123A46B808906756F543423E8D27877578125778AC76"),
+ fromHex("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -383,22 +369,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m239v2n = new BigInteger("1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 16);
- BigInteger c2m239v2h = BigInteger.valueOf(6);
+ BigInteger n = fromHex("1555555555555555555555555555553C6F2885259C31E3FCDF154624522D");
+ BigInteger h = BigInteger.valueOf(6);
- ECCurve c2m239v2 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
239,
36,
- new BigInteger("4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", 16),
- new BigInteger("5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", 16),
- c2m239v2n, c2m239v2h);
-
- return new X9ECParameters(
- c2m239v2,
- new X9ECPoint(c2m239v2,
- Hex.decode("0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205")),
- c2m239v2n, c2m239v2h,
- null);
+ fromHex("4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F"),
+ fromHex("5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -406,22 +390,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m239v3n = new BigInteger("0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 16);
- BigInteger c2m239v3h = BigInteger.valueOf(10);
+ BigInteger n = fromHex("0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF");
+ BigInteger h = BigInteger.valueOf(10);
- ECCurve c2m239v3 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
239,
36,
- new BigInteger("01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", 16),
- new BigInteger("6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", 16),
- c2m239v3n, c2m239v3h);
-
- return new X9ECParameters(
- c2m239v3,
- new X9ECPoint(c2m239v3,
- Hex.decode("0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92")),
- c2m239v3n, c2m239v3h,
- null);
+ fromHex("01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F"),
+ fromHex("6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -429,22 +411,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m272w1n = new BigInteger("0100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", 16);
- BigInteger c2m272w1h = BigInteger.valueOf(0xFF06);
+ BigInteger n = fromHex("0100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521");
+ BigInteger h = BigInteger.valueOf(0xFF06);
- ECCurve c2m272w1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
272,
1, 3, 56,
- new BigInteger("0091A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", 16),
- new BigInteger("7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", 16),
- c2m272w1n, c2m272w1h);
-
- return new X9ECParameters(
- c2m272w1,
- new X9ECPoint(c2m272w1,
- Hex.decode("026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D")),
- c2m272w1n, c2m272w1h,
- null);
+ fromHex("91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20"),
+ fromHex("7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -452,22 +432,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m304w1n = new BigInteger("0101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D", 16);
- BigInteger c2m304w1h = BigInteger.valueOf(0xFE2E);
+ BigInteger n = fromHex("0101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D");
+ BigInteger h = BigInteger.valueOf(0xFE2E);
- ECCurve c2m304w1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
304,
1, 2, 11,
- new BigInteger("00FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681", 16),
- new BigInteger("00BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE", 16),
- c2m304w1n, c2m304w1h);
-
- return new X9ECParameters(
- c2m304w1,
- new X9ECPoint(c2m304w1,
- Hex.decode("02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614")),
- c2m304w1n, c2m304w1h,
- null);
+ fromHex("FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681"),
+ fromHex("BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -475,22 +453,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m359v1n = new BigInteger("01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B", 16);
- BigInteger c2m359v1h = BigInteger.valueOf(0x4C);
+ BigInteger n = fromHex("01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B");
+ BigInteger h = BigInteger.valueOf(0x4C);
- ECCurve c2m359v1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
359,
68,
- new BigInteger("5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557", 16),
- new BigInteger("2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988", 16),
- c2m359v1n, c2m359v1h);
-
- return new X9ECParameters(
- c2m359v1,
- new X9ECPoint(c2m359v1,
- Hex.decode("033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097")),
- c2m359v1n, c2m359v1h,
- null);
+ fromHex("5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557"),
+ fromHex("2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -498,22 +474,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m368w1n = new BigInteger("010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967", 16);
- BigInteger c2m368w1h = BigInteger.valueOf(0xFF70);
+ BigInteger n = fromHex("010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967");
+ BigInteger h = BigInteger.valueOf(0xFF70);
- ECCurve c2m368w1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
368,
1, 2, 85,
- new BigInteger("00E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D", 16),
- new BigInteger("00FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A", 16),
- c2m368w1n, c2m368w1h);
-
- return new X9ECParameters(
- c2m368w1,
- new X9ECPoint(c2m368w1,
- Hex.decode("021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F")),
- c2m368w1n, c2m368w1h,
- null);
+ fromHex("E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D"),
+ fromHex("FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -521,25 +495,24 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m431r1n = new BigInteger("0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91", 16);
- BigInteger c2m431r1h = BigInteger.valueOf(0x2760);
+ BigInteger n = fromHex("0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91");
+ BigInteger h = BigInteger.valueOf(0x2760);
- ECCurve c2m431r1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
431,
120,
- new BigInteger("1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F", 16),
- new BigInteger("10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618", 16),
- c2m431r1n, c2m431r1h);
-
- return new X9ECParameters(
- c2m431r1,
- new X9ECPoint(c2m431r1,
- Hex.decode("02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7")),
- c2m431r1n, c2m431r1h,
- null);
+ fromHex("1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F"),
+ fromHex("10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
+
static final Hashtable objIds = new Hashtable();
static final Hashtable curves = new Hashtable();
static final Hashtable names = new Hashtable();
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java
index 2f26c66d..eb067e63 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java
@@ -1,7 +1,5 @@
package org.bouncycastle.asn1.x9;
-import java.io.IOException;
-
import org.bouncycastle.asn1.ASN1Choice;
import org.bouncycastle.asn1.ASN1Null;
import org.bouncycastle.asn1.ASN1Object;
@@ -71,11 +69,7 @@ public class X962Parameters
this.params = obj;
}
- /**
- * @deprecated use getInstance()
- */
- public X962Parameters(
- ASN1Primitive obj)
+ private X962Parameters(ASN1Primitive obj)
{
this.params = obj;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9Curve.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9Curve.java
index 3838a232..f0c7ffc0 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9Curve.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9Curve.java
@@ -60,10 +60,8 @@ public class X9Curve
{
// Characteristic two field
ASN1Sequence parameters = ASN1Sequence.getInstance(fieldID.getParameters());
- int m = ((ASN1Integer)parameters.getObjectAt(0)).getValue().
- intValue();
- ASN1ObjectIdentifier representation
- = (ASN1ObjectIdentifier)parameters.getObjectAt(1);
+ int m = ((ASN1Integer)parameters.getObjectAt(0)).intValueExact();
+ ASN1ObjectIdentifier representation = (ASN1ObjectIdentifier)parameters.getObjectAt(1);
int k1 = 0;
int k2 = 0;
@@ -72,15 +70,15 @@ public class X9Curve
if (representation.equals(tpBasis))
{
// Trinomial basis representation
- k1 = ASN1Integer.getInstance(parameters.getObjectAt(2)).getValue().intValue();
+ k1 = ASN1Integer.getInstance(parameters.getObjectAt(2)).intValueExact();
}
else if (representation.equals(ppBasis))
{
// Pentanomial basis representation
ASN1Sequence pentanomial = ASN1Sequence.getInstance(parameters.getObjectAt(2));
- k1 = ASN1Integer.getInstance(pentanomial.getObjectAt(0)).getValue().intValue();
- k2 = ASN1Integer.getInstance(pentanomial.getObjectAt(1)).getValue().intValue();
- k3 = ASN1Integer.getInstance(pentanomial.getObjectAt(2)).getValue().intValue();
+ k1 = ASN1Integer.getInstance(pentanomial.getObjectAt(0)).intValueExact();
+ k2 = ASN1Integer.getInstance(pentanomial.getObjectAt(1)).intValueExact();
+ k3 = ASN1Integer.getInstance(pentanomial.getObjectAt(2)).intValueExact();
}
else
{
@@ -97,7 +95,7 @@ public class X9Curve
if (seq.size() == 3)
{
- seed = Arrays.clone(((DERBitString)seq.getObjectAt(2)).getBytes());
+ seed = ((DERBitString)seq.getObjectAt(2)).getBytes();
}
}
@@ -139,7 +137,7 @@ public class X9Curve
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
if (fieldIdentifier.equals(prime_field))
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParameters.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParameters.java
index f02404a9..5a1c0be4 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParameters.java
@@ -36,7 +36,7 @@ public class X9ECParameters
ASN1Sequence seq)
{
if (!(seq.getObjectAt(0) instanceof ASN1Integer)
- || !((ASN1Integer)seq.getObjectAt(0)).getValue().equals(ONE))
+ || !((ASN1Integer)seq.getObjectAt(0)).hasValue(ONE))
{
throw new IllegalArgumentException("bad version in X9ECParameters");
}
@@ -84,7 +84,7 @@ public class X9ECParameters
public X9ECParameters(
ECCurve curve,
- ECPoint g,
+ X9ECPoint g,
BigInteger n)
{
this(curve, g, n, null, null);
@@ -92,16 +92,7 @@ public class X9ECParameters
public X9ECParameters(
ECCurve curve,
- X9ECPoint g,
- BigInteger n,
- BigInteger h)
- {
- this(curve, g, n, h, null);
- }
-
- public X9ECParameters(
- ECCurve curve,
- ECPoint g,
+ X9ECPoint g,
BigInteger n,
BigInteger h)
{
@@ -110,16 +101,6 @@ public class X9ECParameters
public X9ECParameters(
ECCurve curve,
- ECPoint g,
- BigInteger n,
- BigInteger h,
- byte[] seed)
- {
- this(curve, new X9ECPoint(g), n, h, seed);
- }
-
- public X9ECParameters(
- ECCurve curve,
X9ECPoint g,
BigInteger n,
BigInteger h,
@@ -183,6 +164,11 @@ public class X9ECParameters
return Arrays.clone(seed);
}
+ public boolean hasSeed()
+ {
+ return null != seed;
+ }
+
/**
* Return the ASN.1 entry representing the Curve.
*
@@ -228,7 +214,7 @@ public class X9ECParameters
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(6);
v.add(new ASN1Integer(ONE));
v.add(fieldID);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECPoint.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECPoint.java
index b5037849..3cba907c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECPoint.java
@@ -20,12 +20,6 @@ public class X9ECPoint
private ECPoint p;
public X9ECPoint(
- ECPoint p)
- {
- this(p, false);
- }
-
- public X9ECPoint(
ECPoint p,
boolean compressed)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9FieldID.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9FieldID.java
index cb74234e..7e9ffe47 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9FieldID.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9FieldID.java
@@ -64,7 +64,7 @@ public class X9FieldID
public X9FieldID(int m, int k1, int k2, int k3)
{
this.id = characteristic_two_field;
- ASN1EncodableVector fieldIdParams = new ASN1EncodableVector();
+ ASN1EncodableVector fieldIdParams = new ASN1EncodableVector(3);
fieldIdParams.add(new ASN1Integer(m));
if (k2 == 0)
@@ -85,7 +85,7 @@ public class X9FieldID
}
fieldIdParams.add(ppBasis);
- ASN1EncodableVector pentanomialParams = new ASN1EncodableVector();
+ ASN1EncodableVector pentanomialParams = new ASN1EncodableVector(3);
pentanomialParams.add(new ASN1Integer(k1));
pentanomialParams.add(new ASN1Integer(k2));
pentanomialParams.add(new ASN1Integer(k3));
@@ -138,7 +138,7 @@ public class X9FieldID
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(this.id);
v.add(this.parameters);
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesRegistrar.java b/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesRegistrar.java
index 4448be04..6b283941 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesRegistrar.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/CryptoServicesRegistrar.java
@@ -28,7 +28,8 @@ public final class CryptoServicesRegistrar
private static final ThreadLocal<Map<String, Object[]>> threadProperties = new ThreadLocal<Map<String, Object[]>>();
private static final Map<String, Object[]> globalProperties = Collections.synchronizedMap(new HashMap<String, Object[]>());
- private static volatile SecureRandom defaultSecureRandom;
+ private static final Object cacheLock = new Object();
+ private static SecureRandom defaultSecureRandom;
static
{
@@ -38,7 +39,7 @@ public final class CryptoServicesRegistrar
new BigInteger("fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e17", 16),
new BigInteger("962eddcc369cba8ebb260ee6b6a126d9346e38c5", 16),
new BigInteger("678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4", 16),
- new DSAValidationParameters(Hex.decode("b869c82b35d70e1b1ff91b28e37a62ecdc34409b"), 123));
+ new DSAValidationParameters(Hex.decodeStrict("b869c82b35d70e1b1ff91b28e37a62ecdc34409b"), 123));
DSAParameters def768Params = new DSAParameters(
new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5" +
@@ -50,7 +51,7 @@ public final class CryptoServicesRegistrar
"a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d366844577" +
"1f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a" +
"7064f316933a346d3f529252", 16),
- new DSAValidationParameters(Hex.decode("77d0f8c4dad15eb8c4f2f8d6726cefd96d5bb399"), 263));
+ new DSAValidationParameters(Hex.decodeStrict("77d0f8c4dad15eb8c4f2f8d6726cefd96d5bb399"), 263));
DSAParameters def1024Params = new DSAParameters(
new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80" +
@@ -64,7 +65,7 @@ public final class CryptoServicesRegistrar
"b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f" +
"0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06" +
"928b665e807b552564014c3bfecf492a", 16),
- new DSAValidationParameters(Hex.decode("8d5155894229d5e689ee01e6018a237e2cae64cd"), 92));
+ new DSAValidationParameters(Hex.decodeStrict("8d5155894229d5e689ee01e6018a237e2cae64cd"), 92));
DSAParameters def2048Params = new DSAParameters(
new BigInteger("95475cf5d93e596c3fcd1d902add02f427f5f3c7210313bb45fb4d5b" +
@@ -88,7 +89,7 @@ public final class CryptoServicesRegistrar
"ac819a26ca9b04cb0eb9b7b035988d15bbac65212a55239cfc7e58fa" +
"e38d7250ab9991ffbc97134025fe8ce04c4399ad96569be91a546f49" +
"78693c7a", 16),
- new DSAValidationParameters(Hex.decode("b0b4417601b59cbc9d8ac8f935cadaec4f5fbb2f23785609ae466748d9b5a536"), 497));
+ new DSAValidationParameters(Hex.decodeStrict("b0b4417601b59cbc9d8ac8f935cadaec4f5fbb2f23785609ae466748d9b5a536"), 497));
localSetGlobalProperty(Property.DSA_DEFAULT_PARAMS, def512Params, def768Params, def1024Params, def2048Params);
localSetGlobalProperty(Property.DH_DEFAULT_PARAMS, toDH(def512Params), toDH(def768Params), toDH(def1024Params), toDH(def2048Params));
@@ -103,16 +104,39 @@ public final class CryptoServicesRegistrar
* Return the default source of randomness.
*
* @return the default SecureRandom
- * @throws IllegalStateException if no source of randomness has been provided.
*/
public static SecureRandom getSecureRandom()
{
- if (defaultSecureRandom == null)
+ synchronized (cacheLock)
{
- return new SecureRandom();
+ if (null != defaultSecureRandom)
+ {
+ return defaultSecureRandom;
+ }
+ }
+
+ SecureRandom tmp = new SecureRandom();
+
+ synchronized (cacheLock)
+ {
+ if (null == defaultSecureRandom)
+ {
+ defaultSecureRandom = tmp;
+ }
+
+ return defaultSecureRandom;
}
-
- return defaultSecureRandom;
+ }
+
+ /**
+ * Return either the passed-in SecureRandom, or if it is null, then the default source of randomness.
+ *
+ * @param secureRandom the SecureRandom to use if it is not null.
+ * @return the SecureRandom parameter if it is not null, or else the default SecureRandom
+ */
+ public static SecureRandom getSecureRandom(SecureRandom secureRandom)
+ {
+ return null == secureRandom ? getSecureRandom() : secureRandom;
}
/**
@@ -124,7 +148,10 @@ public final class CryptoServicesRegistrar
{
checkPermission(CanSetDefaultRandom);
- defaultSecureRandom = secureRandom;
+ synchronized (cacheLock)
+ {
+ defaultSecureRandom = secureRandom;
+ }
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/KeyGenerationParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/KeyGenerationParameters.java
index 9a63522f..ac901231 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/KeyGenerationParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/KeyGenerationParameters.java
@@ -21,7 +21,7 @@ public class KeyGenerationParameters
SecureRandom random,
int strength)
{
- this.random = random;
+ this.random = CryptoServicesRegistrar.getSecureRandom(random);
this.strength = strength;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/StagedAgreement.java b/bcprov/src/main/java/org/bouncycastle/crypto/StagedAgreement.java
new file mode 100644
index 00000000..2ba20482
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/StagedAgreement.java
@@ -0,0 +1,9 @@
+package org.bouncycastle.crypto;
+
+import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+
+public interface StagedAgreement
+ extends BasicAgreement
+{
+ AsymmetricKeyParameter calculateStage(CipherParameters pubKey);
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java
index c6e3d283..0fb1050d 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java
@@ -271,42 +271,34 @@ public class SHA256Digest
}
/* SHA-256 functions */
- private int Ch(
- int x,
- int y,
- int z)
+ private static int Ch(int x, int y, int z)
{
return (x & y) ^ ((~x) & z);
+// return z ^ (x & (y ^ z));
}
- private int Maj(
- int x,
- int y,
- int z)
+ private static int Maj(int x, int y, int z)
{
- return (x & y) ^ (x & z) ^ (y & z);
+// return (x & y) ^ (x & z) ^ (y & z);
+ return (x & y) | (z & (x ^ y));
}
- private int Sum0(
- int x)
+ private static int Sum0(int x)
{
return ((x >>> 2) | (x << 30)) ^ ((x >>> 13) | (x << 19)) ^ ((x >>> 22) | (x << 10));
}
- private int Sum1(
- int x)
+ private static int Sum1(int x)
{
return ((x >>> 6) | (x << 26)) ^ ((x >>> 11) | (x << 21)) ^ ((x >>> 25) | (x << 7));
}
- private int Theta0(
- int x)
+ private static int Theta0(int x)
{
return ((x >>> 7) | (x << 25)) ^ ((x >>> 18) | (x << 14)) ^ (x >>> 3);
}
- private int Theta1(
- int x)
+ private static int Theta1(int x)
{
return ((x >>> 17) | (x << 15)) ^ ((x >>> 19) | (x << 13)) ^ (x >>> 10);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/XofUtils.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/XofUtils.java
new file mode 100644
index 00000000..6e06a47c
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/XofUtils.java
@@ -0,0 +1,48 @@
+package org.bouncycastle.crypto.digests;
+
+public class XofUtils
+{
+ public static byte[] leftEncode(long strLen)
+ {
+ byte n = 1;
+
+ long v = strLen;
+ while ((v >>= 8) != 0)
+ {
+ n++;
+ }
+
+ byte[] b = new byte[n + 1];
+
+ b[0] = n;
+
+ for (int i = 1; i <= n; i++)
+ {
+ b[i] = (byte)(strLen >> (8 * (n - i)));
+ }
+
+ return b;
+ }
+
+ public static byte[] rightEncode(long strLen)
+ {
+ byte n = 1;
+
+ long v = strLen;
+ while ((v >>= 8) != 0)
+ {
+ n++;
+ }
+
+ byte[] b = new byte[n + 1];
+
+ b[n] = n;
+
+ for (int i = 0; i < n; i++)
+ {
+ b[i] = (byte)(strLen >> (8 * (n - i - 1)));
+ }
+
+ return b;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java b/bcprov/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java
index 006047cc..43ea0a72 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java
@@ -22,6 +22,7 @@ import org.bouncycastle.math.ec.ECCurve;
// import org.bouncycastle.math.ec.custom.sec.SecP160R1Curve;
// import org.bouncycastle.math.ec.custom.sec.SecP160R2Curve;
// END android-removed
+import org.bouncycastle.math.ec.WNafUtil;
import org.bouncycastle.math.ec.custom.sec.SecP192K1Curve;
import org.bouncycastle.math.ec.custom.sec.SecP192R1Curve;
import org.bouncycastle.math.ec.custom.sec.SecP224K1Curve;
@@ -52,11 +53,19 @@ import org.bouncycastle.math.ec.custom.sec.SecP521R1Curve;
// END android-removed
import org.bouncycastle.math.ec.endo.GLVTypeBEndomorphism;
import org.bouncycastle.math.ec.endo.GLVTypeBParameters;
+import org.bouncycastle.math.ec.endo.ScalarSplitParameters;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
public class CustomNamedCurves
{
+ private static X9ECPoint configureBasepoint(ECCurve curve, String encoding)
+ {
+ X9ECPoint G = new X9ECPoint(curve, Hex.decodeStrict(encoding));
+ WNafUtil.configureBasepoint(G.getPoint());
+ return G;
+ }
+
private static ECCurve configureCurve(ECCurve curve)
{
return curve;
@@ -88,9 +97,8 @@ public class CustomNamedCurves
*
* (The other possible y value is 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14)
*
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A"
- + "20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9"));
+ X9ECPoint G = configureBasepoint(curve,
+ "042AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
@@ -103,11 +111,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("000E0D4D696E6768756151750CC03A4473D03679");
+ byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
ECCurve curve = configureCurve(new SecP128R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "161FF7528B899B2D0C28607CA52C5B86"
- + "CF5AC8395BAFEB13C02DA292DDED7A83"));
+ X9ECPoint G = configureBasepoint(curve,
+ "04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -123,19 +130,19 @@ public class CustomNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16),
new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16),
- new BigInteger[]{
- new BigInteger("9162fbe73984472a0a9e", 16),
- new BigInteger("-96341f1138933bc2f505", 16) },
- new BigInteger[]{
- new BigInteger("127971af8721782ecffa3", 16),
- new BigInteger("9162fbe73984472a0a9e", 16) },
- new BigInteger("9162fbe73984472a0a9d0590", 16),
- new BigInteger("96341f1138933bc2f503fd44", 16),
- 176);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("9162fbe73984472a0a9e", 16),
+ new BigInteger("-96341f1138933bc2f505", 16) },
+ new BigInteger[]{
+ new BigInteger("127971af8721782ecffa3", 16),
+ new BigInteger("9162fbe73984472a0a9e", 16) },
+ new BigInteger("9162fbe73984472a0a9d0590", 16),
+ new BigInteger("96341f1138933bc2f503fd44", 16),
+ 176));
ECCurve curve = configureCurveGLV(new SecP160K1Curve(), glv);
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"
- + "938CF935318FDCED6BC28286531733C3F03C4FEE"));
+ X9ECPoint G = configureBasepoint(curve,
+ "043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -147,11 +154,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("1053CDE42C14D696E67687561517533BF3F83345");
+ byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
ECCurve curve = configureCurve(new SecP160R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "4A96B5688EF573284664698968C38BB913CBFC82"
- + "23A628553168947D59DCC912042351377AC5FB32"));
+ X9ECPoint G = configureBasepoint(curve,
+ "044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -163,11 +169,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("B99B99B099B323E02709A4D696E6768756151751");
+ byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
ECCurve curve = configureCurve(new SecP160R2Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "52DCB034293A117E1F4FF11B30F7199D3144CE6D"
- + "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -185,19 +190,19 @@ public class CustomNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16),
new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16),
- new BigInteger[]{
- new BigInteger("71169be7330b3038edb025f1", 16),
- new BigInteger("-b3fb3400dec5c4adceb8655c", 16) },
- new BigInteger[]{
- new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
- new BigInteger("71169be7330b3038edb025f1", 16) },
- new BigInteger("71169be7330b3038edb025f1d0f9", 16),
- new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
- 208);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("71169be7330b3038edb025f1", 16),
+ new BigInteger("-b3fb3400dec5c4adceb8655c", 16) },
+ new BigInteger[]{
+ new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
+ new BigInteger("71169be7330b3038edb025f1", 16) },
+ new BigInteger("71169be7330b3038edb025f1d0f9", 16),
+ new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
+ 208));
ECCurve curve = configureCurveGLV(new SecP192K1Curve(), glv);
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"
- + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"));
+ X9ECPoint G = configureBasepoint(curve,
+ "04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -209,11 +214,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("3045AE6FC8422F64ED579528D38120EAE12196D5");
+ byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
ECCurve curve = configureCurve(new SecP192R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"
- + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"));
+ X9ECPoint G = configureBasepoint(curve,
+ "04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -229,19 +233,19 @@ public class CustomNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16),
new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16),
- new BigInteger[]{
- new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
- new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) },
- new BigInteger[]{
- new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
- new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) },
- new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
- new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
- 240);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
+ new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) },
+ new BigInteger[]{
+ new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) },
+ new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
+ new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
+ 240));
ECCurve curve = configureCurveGLV(new SecP224K1Curve(), glv);
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"
- + "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"));
+ X9ECPoint G = configureBasepoint(curve,
+ "04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -253,11 +257,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
+ byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
ECCurve curve = configureCurve(new SecP224R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"
- + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"));
+ X9ECPoint G = configureBasepoint(curve,
+ "04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -273,19 +276,19 @@ public class CustomNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16),
new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16),
- new BigInteger[]{
- new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
- new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) },
- new BigInteger[]{
- new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
- new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) },
- new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
- new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
- 272);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
+ new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) },
+ new BigInteger[]{
+ new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) },
+ new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
+ new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
+ 272));
ECCurve curve = configureCurveGLV(new SecP256K1Curve(), glv);
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
- + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -297,11 +300,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("C49D360886E704936A6678E1139D26B7819F7E90");
+ byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
ECCurve curve = configureCurve(new SecP256R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
- + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"));
+ X9ECPoint G = configureBasepoint(curve,
+ "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -313,11 +315,11 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("A335926AA319A27A1D00896A6773A4827ACDAC73");
+ byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
ECCurve curve = configureCurve(new SecP384R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
- + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"));
+ + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -329,11 +331,11 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("D09E8800291CB85396CC6717393284AAA0DA64BA");
+ byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
ECCurve curve = configureCurve(new SecP521R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
- + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"));
+ + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -347,11 +349,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("10E723AB14D696E6768756151756FEBF8FCB49A9");
+ byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
ECCurve curve = configureCurve(new SecT113R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "009D73616F35F4AB1407D73562C10F"
- + "00A52830277958EE84D1315ED31886"));
+ X9ECPoint G = configureBasepoint(curve,
+ "04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -363,11 +364,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("10C0FB15760860DEF1EEF4D696E676875615175D");
+ byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
ECCurve curve = configureCurve(new SecT113R2Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "01A57A6A7B26CA5EF52FCDB8164797"
- + "00B3ADC94ED1FE674C06E695BABA1D"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -379,11 +379,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("4D696E676875615175985BD3ADBADA21B43A97E2");
+ byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
ECCurve curve = configureCurve(new SecT131R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "0081BAF91FDF9833C40F9C181343638399"
- + "078C6E7EA38C001F73C8134B1B4EF9E150"));
+ X9ECPoint G = configureBasepoint(curve,
+ "040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -395,11 +394,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("985BD3ADBAD4D696E676875615175A21B43A97E3");
+ byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
ECCurve curve = configureCurve(new SecT131R2Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "0356DCD8F2F95031AD652D23951BB366A8"
- + "0648F06D867940A5366D9E265DE9EB240F"));
+ X9ECPoint G = configureBasepoint(curve,
+ "040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -413,9 +411,8 @@ public class CustomNamedCurves
{
byte[] S = null;
ECCurve curve = configureCurve(new SecT163K1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8"
- + "0289070FB05D38FF58321F2E800536D538CCDAA3D9"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -427,11 +424,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("24B7B137C8A14D696E6768756151756FD0DA2E5C");
+ byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
ECCurve curve = configureCurve(new SecT163R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "0369979697AB43897789566789567F787A7876A654"
- + "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883"));
+ X9ECPoint G = configureBasepoint(curve,
+ "040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -443,11 +439,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("85E25BFE5C86226CDB12016F7553F9D0E693A268");
+ byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
ECCurve curve = configureCurve(new SecT163R2Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "03F0EBA16286A2D57EA0991168D4994637E8343E36"
- + "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -459,11 +454,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("103FAEC74D696E676875615175777FC5B191EF30");
+ byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
ECCurve curve = configureCurve(new SecT193R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1"
- + "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -475,11 +469,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("10B7B4D696E676875615175137C8A16FD0DA2211");
+ byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
ECCurve curve = configureCurve(new SecT193R2Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F"
- + "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -493,9 +486,8 @@ public class CustomNamedCurves
{
byte[] S = null;
ECCurve curve = configureCurve(new SecT233K1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126"
- + "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3"));
+ X9ECPoint G = configureBasepoint(curve,
+ "04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -507,11 +499,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
+ byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
ECCurve curve = configureCurve(new SecT233R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B"
- + "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -525,9 +516,8 @@ public class CustomNamedCurves
{
byte[] S = null;
ECCurve curve = configureCurve(new SecT239K1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC"
- + "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -541,9 +531,9 @@ public class CustomNamedCurves
{
byte[] S = null;
ECCurve curve = configureCurve(new SecT283K1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
- + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259"));
+ + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -555,11 +545,11 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
+ byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
ECCurve curve = configureCurve(new SecT283R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
- + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4"));
+ + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -573,9 +563,9 @@ public class CustomNamedCurves
{
byte[] S = null;
ECCurve curve = configureCurve(new SecT409K1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
- + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B"));
+ + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -587,11 +577,11 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("4099B5A457F9D69F79213D094C4BCD4D4262210B");
+ byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
ECCurve curve = configureCurve(new SecT409R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
- + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706"));
+ + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -605,9 +595,9 @@ public class CustomNamedCurves
{
byte[] S = null;
ECCurve curve = configureCurve(new SecT571K1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
- + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3"));
+ + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -619,11 +609,11 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("2AA058F73A0E33AB486B0F610410C53A7F132310");
+ byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
ECCurve curve = configureCurve(new SecT571R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
- + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B"));
+ + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -637,15 +627,15 @@ public class CustomNamedCurves
{
byte[] S = null;
ECCurve curve = configureCurve(new SM2P256V1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7"
- + "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0432C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
*/
// END Android-removed: Unsupported curves
+
static final Hashtable nameToCurve = new Hashtable();
static final Hashtable nameToOID = new Hashtable();
static final Hashtable oidToCurve = new Hashtable();
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java
index 417161e4..a38da9aa 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java
@@ -301,6 +301,7 @@ public class OAEPEncoding
byte[] output = new byte[block.length - start];
System.arraycopy(block, start, output, 0, output.length);
+ Arrays.fill(block, (byte)0);
return output;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
index cfd6dcf9..02a1ff16 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
@@ -1,7 +1,5 @@
package org.bouncycastle.crypto.encodings;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.security.SecureRandom;
import org.bouncycastle.crypto.AsymmetricBlockCipher;
@@ -11,6 +9,7 @@ import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Properties;
/**
* this does your basic PKCS 1 v1.5 padding - whether or not you should be using this
@@ -95,28 +94,12 @@ public class PKCS1Encoding
//
private boolean useStrict()
{
- // required if security manager has been installed.
- String strict = (String)AccessController.doPrivileged(new PrivilegedAction()
+ if (Properties.isOverrideSetTo(NOT_STRICT_LENGTH_ENABLED_PROPERTY, true))
{
- public Object run()
- {
- return System.getProperty(STRICT_LENGTH_ENABLED_PROPERTY);
- }
- });
- String notStrict = (String)AccessController.doPrivileged(new PrivilegedAction()
- {
- public Object run()
- {
- return System.getProperty(NOT_STRICT_LENGTH_ENABLED_PROPERTY);
- }
- });
-
- if (notStrict != null)
- {
- return !notStrict.equals("true");
+ return false;
}
- return strict == null || strict.equals("true");
+ return !Properties.isOverrideSetTo(STRICT_LENGTH_ENABLED_PROPERTY, false);
}
public AsymmetricBlockCipher getUnderlyingCipher()
@@ -269,7 +252,7 @@ public class PKCS1Encoding
* Now the padding check, check for no 0 byte in the padding
*/
int plen = encoded.length - (
- pLen /* Lenght of the PMS */
+ pLen /* Length of the PMS */
+ 1 /* Final 0-byte before PMS */
);
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java
index 021b0f7d..0b491ab5 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java
@@ -11,7 +11,7 @@ import org.bouncycastle.util.Pack;
/**
* an implementation of the AES (Rijndael), from FIPS-197.
* <p>
- * For further details see: <a href="http://csrc.nist.gov/encryption/aes/">http://csrc.nist.gov/encryption/aes/</a>.
+ * For further details see: <a href="https://csrc.nist.gov/encryption/aes/">https://csrc.nist.gov/encryption/aes/</a>.
*
* This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at
* <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
@@ -296,98 +296,97 @@ private static final int[] Tinv0 =
{
case 4:
{
- int t0 = Pack.littleEndianToInt(key, 0); W[0][0] = t0;
- int t1 = Pack.littleEndianToInt(key, 4); W[0][1] = t1;
- int t2 = Pack.littleEndianToInt(key, 8); W[0][2] = t2;
- int t3 = Pack.littleEndianToInt(key, 12); W[0][3] = t3;
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
for (int i = 1; i <= 10; ++i)
{
- int u = subWord(shift(t3, 8)) ^ rcon[i - 1];
- t0 ^= u; W[i][0] = t0;
- t1 ^= t0; W[i][1] = t1;
- t2 ^= t1; W[i][2] = t2;
- t3 ^= t2; W[i][3] = t3;
+ int colx = subWord(shift(col3, 8)) ^ rcon[i - 1];
+ col0 ^= colx; W[i][0] = col0;
+ col1 ^= col0; W[i][1] = col1;
+ col2 ^= col1; W[i][2] = col2;
+ col3 ^= col2; W[i][3] = col3;
}
break;
}
case 6:
{
- int t0 = Pack.littleEndianToInt(key, 0); W[0][0] = t0;
- int t1 = Pack.littleEndianToInt(key, 4); W[0][1] = t1;
- int t2 = Pack.littleEndianToInt(key, 8); W[0][2] = t2;
- int t3 = Pack.littleEndianToInt(key, 12); W[0][3] = t3;
- int t4 = Pack.littleEndianToInt(key, 16); W[1][0] = t4;
- int t5 = Pack.littleEndianToInt(key, 20); W[1][1] = t5;
-
- int rcon = 1;
- int u = subWord(shift(t5, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[1][2] = t0;
- t1 ^= t0; W[1][3] = t1;
- t2 ^= t1; W[2][0] = t2;
- t3 ^= t2; W[2][1] = t3;
- t4 ^= t3; W[2][2] = t4;
- t5 ^= t4; W[2][3] = t5;
-
- for (int i = 3; i < 12; i += 3)
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
+
+ int col4 = Pack.littleEndianToInt(key, 16);
+ int col5 = Pack.littleEndianToInt(key, 20);
+
+ int i = 1, rcon = 1, colx;
+ for (;;)
{
- u = subWord(shift(t5, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[i ][0] = t0;
- t1 ^= t0; W[i ][1] = t1;
- t2 ^= t1; W[i ][2] = t2;
- t3 ^= t2; W[i ][3] = t3;
- t4 ^= t3; W[i + 1][0] = t4;
- t5 ^= t4; W[i + 1][1] = t5;
- u = subWord(shift(t5, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[i + 1][2] = t0;
- t1 ^= t0; W[i + 1][3] = t1;
- t2 ^= t1; W[i + 2][0] = t2;
- t3 ^= t2; W[i + 2][1] = t3;
- t4 ^= t3; W[i + 2][2] = t4;
- t5 ^= t4; W[i + 2][3] = t5;
- }
+ W[i ][0] = col4;
+ W[i ][1] = col5;
+ colx = subWord(shift(col5, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i ][2] = col0;
+ col1 ^= col0; W[i ][3] = col1;
+
+ col2 ^= col1; W[i + 1][0] = col2;
+ col3 ^= col2; W[i + 1][1] = col3;
+ col4 ^= col3; W[i + 1][2] = col4;
+ col5 ^= col4; W[i + 1][3] = col5;
+
+ colx = subWord(shift(col5, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i + 2][0] = col0;
+ col1 ^= col0; W[i + 2][1] = col1;
+ col2 ^= col1; W[i + 2][2] = col2;
+ col3 ^= col2; W[i + 2][3] = col3;
+
+ if ((i += 3) >= 13)
+ {
+ break;
+ }
- u = subWord(shift(t5, 8)) ^ rcon;
- t0 ^= u; W[12][0] = t0;
- t1 ^= t0; W[12][1] = t1;
- t2 ^= t1; W[12][2] = t2;
- t3 ^= t2; W[12][3] = t3;
+ col4 ^= col3;
+ col5 ^= col4;
+ }
break;
}
case 8:
{
- int t0 = Pack.littleEndianToInt(key, 0); W[0][0] = t0;
- int t1 = Pack.littleEndianToInt(key, 4); W[0][1] = t1;
- int t2 = Pack.littleEndianToInt(key, 8); W[0][2] = t2;
- int t3 = Pack.littleEndianToInt(key, 12); W[0][3] = t3;
- int t4 = Pack.littleEndianToInt(key, 16); W[1][0] = t4;
- int t5 = Pack.littleEndianToInt(key, 20); W[1][1] = t5;
- int t6 = Pack.littleEndianToInt(key, 24); W[1][2] = t6;
- int t7 = Pack.littleEndianToInt(key, 28); W[1][3] = t7;
-
- int u, rcon = 1;
-
- for (int i = 2; i < 14; i += 2)
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
+
+ int col4 = Pack.littleEndianToInt(key, 16); W[1][0] = col4;
+ int col5 = Pack.littleEndianToInt(key, 20); W[1][1] = col5;
+ int col6 = Pack.littleEndianToInt(key, 24); W[1][2] = col6;
+ int col7 = Pack.littleEndianToInt(key, 28); W[1][3] = col7;
+
+ int i = 2, rcon = 1, colx;
+ for (;;)
{
- u = subWord(shift(t7, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[i ][0] = t0;
- t1 ^= t0; W[i ][1] = t1;
- t2 ^= t1; W[i ][2] = t2;
- t3 ^= t2; W[i ][3] = t3;
- u = subWord(t3);
- t4 ^= u; W[i + 1][0] = t4;
- t5 ^= t4; W[i + 1][1] = t5;
- t6 ^= t5; W[i + 1][2] = t6;
- t7 ^= t6; W[i + 1][3] = t7;
- }
+ colx = subWord(shift(col7, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i][0] = col0;
+ col1 ^= col0; W[i][1] = col1;
+ col2 ^= col1; W[i][2] = col2;
+ col3 ^= col2; W[i][3] = col3;
+ ++i;
+
+ if (i >= 15)
+ {
+ break;
+ }
- u = subWord(shift(t7, 8)) ^ rcon;
- t0 ^= u; W[14][0] = t0;
- t1 ^= t0; W[14][1] = t1;
- t2 ^= t1; W[14][2] = t2;
- t3 ^= t2; W[14][3] = t3;
+ colx = subWord(col3);
+ col4 ^= colx; W[i][0] = col4;
+ col5 ^= col4; W[i][1] = col5;
+ col6 ^= col5; W[i][2] = col6;
+ col7 ^= col6; W[i][3] = col7;
+ ++i;
+ }
break;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java
index abb8ba8c..b73e0a54 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java
@@ -10,7 +10,7 @@ import org.bouncycastle.util.Pack;
/**
* an implementation of the AES (Rijndael), from FIPS-197.
* <p>
- * For further details see: <a href="http://csrc.nist.gov/encryption/aes/">http://csrc.nist.gov/encryption/aes/</a>.
+ * For further details see: <a href="https://csrc.nist.gov/encryption/aes/">https://csrc.nist.gov/encryption/aes/</a>.
*
* This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at
* <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
@@ -625,98 +625,97 @@ public class AESFastEngine
{
case 4:
{
- int t0 = Pack.littleEndianToInt(key, 0); W[0][0] = t0;
- int t1 = Pack.littleEndianToInt(key, 4); W[0][1] = t1;
- int t2 = Pack.littleEndianToInt(key, 8); W[0][2] = t2;
- int t3 = Pack.littleEndianToInt(key, 12); W[0][3] = t3;
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
for (int i = 1; i <= 10; ++i)
{
- int u = subWord(shift(t3, 8)) ^ rcon[i - 1];
- t0 ^= u; W[i][0] = t0;
- t1 ^= t0; W[i][1] = t1;
- t2 ^= t1; W[i][2] = t2;
- t3 ^= t2; W[i][3] = t3;
+ int colx = subWord(shift(col3, 8)) ^ rcon[i - 1];
+ col0 ^= colx; W[i][0] = col0;
+ col1 ^= col0; W[i][1] = col1;
+ col2 ^= col1; W[i][2] = col2;
+ col3 ^= col2; W[i][3] = col3;
}
break;
}
case 6:
{
- int t0 = Pack.littleEndianToInt(key, 0); W[0][0] = t0;
- int t1 = Pack.littleEndianToInt(key, 4); W[0][1] = t1;
- int t2 = Pack.littleEndianToInt(key, 8); W[0][2] = t2;
- int t3 = Pack.littleEndianToInt(key, 12); W[0][3] = t3;
- int t4 = Pack.littleEndianToInt(key, 16); W[1][0] = t4;
- int t5 = Pack.littleEndianToInt(key, 20); W[1][1] = t5;
-
- int rcon = 1;
- int u = subWord(shift(t5, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[1][2] = t0;
- t1 ^= t0; W[1][3] = t1;
- t2 ^= t1; W[2][0] = t2;
- t3 ^= t2; W[2][1] = t3;
- t4 ^= t3; W[2][2] = t4;
- t5 ^= t4; W[2][3] = t5;
-
- for (int i = 3; i < 12; i += 3)
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
+
+ int col4 = Pack.littleEndianToInt(key, 16);
+ int col5 = Pack.littleEndianToInt(key, 20);
+
+ int i = 1, rcon = 1, colx;
+ for (;;)
{
- u = subWord(shift(t5, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[i ][0] = t0;
- t1 ^= t0; W[i ][1] = t1;
- t2 ^= t1; W[i ][2] = t2;
- t3 ^= t2; W[i ][3] = t3;
- t4 ^= t3; W[i + 1][0] = t4;
- t5 ^= t4; W[i + 1][1] = t5;
- u = subWord(shift(t5, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[i + 1][2] = t0;
- t1 ^= t0; W[i + 1][3] = t1;
- t2 ^= t1; W[i + 2][0] = t2;
- t3 ^= t2; W[i + 2][1] = t3;
- t4 ^= t3; W[i + 2][2] = t4;
- t5 ^= t4; W[i + 2][3] = t5;
- }
+ W[i ][0] = col4;
+ W[i ][1] = col5;
+ colx = subWord(shift(col5, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i ][2] = col0;
+ col1 ^= col0; W[i ][3] = col1;
+
+ col2 ^= col1; W[i + 1][0] = col2;
+ col3 ^= col2; W[i + 1][1] = col3;
+ col4 ^= col3; W[i + 1][2] = col4;
+ col5 ^= col4; W[i + 1][3] = col5;
+
+ colx = subWord(shift(col5, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i + 2][0] = col0;
+ col1 ^= col0; W[i + 2][1] = col1;
+ col2 ^= col1; W[i + 2][2] = col2;
+ col3 ^= col2; W[i + 2][3] = col3;
+
+ if ((i += 3) >= 13)
+ {
+ break;
+ }
- u = subWord(shift(t5, 8)) ^ rcon;
- t0 ^= u; W[12][0] = t0;
- t1 ^= t0; W[12][1] = t1;
- t2 ^= t1; W[12][2] = t2;
- t3 ^= t2; W[12][3] = t3;
+ col4 ^= col3;
+ col5 ^= col4;
+ }
break;
}
case 8:
{
- int t0 = Pack.littleEndianToInt(key, 0); W[0][0] = t0;
- int t1 = Pack.littleEndianToInt(key, 4); W[0][1] = t1;
- int t2 = Pack.littleEndianToInt(key, 8); W[0][2] = t2;
- int t3 = Pack.littleEndianToInt(key, 12); W[0][3] = t3;
- int t4 = Pack.littleEndianToInt(key, 16); W[1][0] = t4;
- int t5 = Pack.littleEndianToInt(key, 20); W[1][1] = t5;
- int t6 = Pack.littleEndianToInt(key, 24); W[1][2] = t6;
- int t7 = Pack.littleEndianToInt(key, 28); W[1][3] = t7;
-
- int u, rcon = 1;
-
- for (int i = 2; i < 14; i += 2)
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
+
+ int col4 = Pack.littleEndianToInt(key, 16); W[1][0] = col4;
+ int col5 = Pack.littleEndianToInt(key, 20); W[1][1] = col5;
+ int col6 = Pack.littleEndianToInt(key, 24); W[1][2] = col6;
+ int col7 = Pack.littleEndianToInt(key, 28); W[1][3] = col7;
+
+ int i = 2, rcon = 1, colx;
+ for (;;)
{
- u = subWord(shift(t7, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[i ][0] = t0;
- t1 ^= t0; W[i ][1] = t1;
- t2 ^= t1; W[i ][2] = t2;
- t3 ^= t2; W[i ][3] = t3;
- u = subWord(t3);
- t4 ^= u; W[i + 1][0] = t4;
- t5 ^= t4; W[i + 1][1] = t5;
- t6 ^= t5; W[i + 1][2] = t6;
- t7 ^= t6; W[i + 1][3] = t7;
- }
+ colx = subWord(shift(col7, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i][0] = col0;
+ col1 ^= col0; W[i][1] = col1;
+ col2 ^= col1; W[i][2] = col2;
+ col3 ^= col2; W[i][3] = col3;
+ ++i;
+
+ if (i >= 15)
+ {
+ break;
+ }
- u = subWord(shift(t7, 8)) ^ rcon;
- t0 ^= u; W[14][0] = t0;
- t1 ^= t0; W[14][1] = t1;
- t2 ^= t1; W[14][2] = t2;
- t3 ^= t2; W[14][3] = t3;
+ colx = subWord(col3);
+ col4 ^= colx; W[i][0] = col4;
+ col5 ^= col4; W[i][1] = col5;
+ col6 ^= col5; W[i][2] = col6;
+ col7 ^= col6; W[i][3] = col7;
+ ++i;
+ }
break;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java
index 6d3e5ac2..b80d653f 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESWrapEngine.java
@@ -4,7 +4,7 @@ package org.bouncycastle.crypto.engines;
* an implementation of the AES Key Wrapper from the NIST Key Wrap
* Specification.
* <p>
- * For further details see: <a href="http://csrc.nist.gov/encryption/kms/key-wrap.pdf">http://csrc.nist.gov/encryption/kms/key-wrap.pdf</a>.
+ * For further details see: <a href="https://csrc.nist.gov/encryption/kms/key-wrap.pdf">https://csrc.nist.gov/encryption/kms/key-wrap.pdf</a>.
*/
public class AESWrapEngine
extends RFC3394WrapEngine
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/BlowfishEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/BlowfishEngine.java
index cfe7f1ff..33918c20 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/BlowfishEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/BlowfishEngine.java
@@ -420,8 +420,9 @@ implements BlockCipher
xr ^= P[ROUNDS + 1];
+ // suppress LGTM warnings index-out-of-bounds since the loop increments s by 2
table[s] = xr;
- table[s + 1] = xl;
+ table[s + 1] = xl; // lgtm [java/index-out-of-bounds]
xr = xl; // end of cycle swap
xl = table[s];
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
index 76f20bbc..9978d35b 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
@@ -309,7 +309,7 @@ public class DESedeWrapEngine
* - Compute the 20 octet SHA-1 hash on the key being wrapped.
* - Use the first 8 octets of this hash as the checksum value.
*
- * For details see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum.
+ * For details see https://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum.
*
* @param key the key to check,
* @return the CMS checksum.
@@ -329,7 +329,7 @@ public class DESedeWrapEngine
}
/**
- * For details see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum
+ * For details see https://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum
*
* @param key key to be validated.
* @param checksum the checksum.
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
index d2886e72..46e5cbe5 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
@@ -14,8 +14,8 @@ import org.bouncycastle.util.Arrays;
* an implementation of the AES Key Wrapper from the NIST Key Wrap
* Specification as described in RFC 3394.
* <p>
- * For further details see: <a href="http://www.ietf.org/rfc/rfc3394.txt">http://www.ietf.org/rfc/rfc3394.txt</a>
- * and <a href="http://csrc.nist.gov/encryption/kms/key-wrap.pdf">http://csrc.nist.gov/encryption/kms/key-wrap.pdf</a>.
+ * For further details see: <a href="https://www.ietf.org/rfc/rfc3394.txt">https://www.ietf.org/rfc/rfc3394.txt</a>
+ * and <a href="https://csrc.nist.gov/encryption/kms/key-wrap.pdf">https://csrc.nist.gov/encryption/kms/key-wrap.pdf</a>.
*/
public class RFC3394WrapEngine
implements Wrapper
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java
index 65ac67bd..cc428990 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java
@@ -38,15 +38,31 @@ public class RSABlindedEngine
if (param instanceof ParametersWithRandom)
{
- ParametersWithRandom rParam = (ParametersWithRandom)param;
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
- key = (RSAKeyParameters)rParam.getParameters();
- random = rParam.getRandom();
+ this.key = (RSAKeyParameters)rParam.getParameters();
+
+ if (key instanceof RSAPrivateCrtKeyParameters)
+ {
+ this.random = rParam.getRandom();
+ }
+ else
+ {
+ this.random = null;
+ }
}
else
{
- key = (RSAKeyParameters)param;
- random = CryptoServicesRegistrar.getSecureRandom();
+ this.key = (RSAKeyParameters)param;
+
+ if (key instanceof RSAPrivateCrtKeyParameters)
+ {
+ this.random = CryptoServicesRegistrar.getSecureRandom();
+ }
+ else
+ {
+ this.random = null;
+ }
}
}
@@ -109,7 +125,7 @@ public class RSABlindedEngine
BigInteger blindedInput = r.modPow(e, m).multiply(input).mod(m);
BigInteger blindedResult = core.processBlock(blindedInput);
- BigInteger rInv = r.modInverse(m);
+ BigInteger rInv = BigIntegers.modOddInverse(m, r);
result = blindedResult.multiply(rInv).mod(m);
// defence against Arjen Lenstra’s CRT attack
if (!input.equals(result.modPow(e, m)))
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
index cb09f73f..137e8b96 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
@@ -357,7 +357,7 @@ public class DSAParametersGenerator
{
// A.2.3 Verifiable Canonical Generation of the Generator g
BigInteger e = p.subtract(ONE).divide(q);
- byte[] ggen = Hex.decode("6767656E");
+ byte[] ggen = Hex.decodeStrict("6767656E");
// 7. U = domain_parameter_seed || "ggen" || index || count.
byte[] U = new byte[seed.length + ggen.length + 1 + 2];
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
index 502f8b3e..1712db77 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
@@ -5,7 +5,6 @@ import java.security.SecureRandom;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
-import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.KeyGenerationParameters;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
@@ -31,11 +30,6 @@ public class ECKeyPairGenerator
this.random = ecP.getRandom();
this.params = ecP.getDomainParameters();
-
- if (this.random == null)
- {
- this.random = CryptoServicesRegistrar.getSecureRandom();
- }
}
/**
@@ -53,7 +47,7 @@ public class ECKeyPairGenerator
{
d = BigIntegers.createRandomBigInteger(nBitLength, random);
- if (d.compareTo(TWO) < 0 || (d.compareTo(n) >= 0))
+ if (d.compareTo(ONE) < 0 || (d.compareTo(n) >= 0))
{
continue;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java
index d9b82c32..eb2756de 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java
@@ -11,7 +11,7 @@ import org.bouncycastle.crypto.params.ParametersWithIV;
* Generator for PBE derived keys and ivs as defined by PKCS 12 V1.0.
* <p>
* The document this implementation is based on can be found at
- * <a href=http://www.rsasecurity.com/rsalabs/pkcs/pkcs-12/index.html>
+ * <a href=https://www.rsasecurity.com/rsalabs/pkcs/pkcs-12/index.html>
* RSA's PKCS12 Page</a>
*/
public class PKCS12ParametersGenerator
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java
index 1c62eccc..758a3f9a 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java
@@ -12,7 +12,7 @@ import org.bouncycastle.crypto.params.ParametersWithIV;
* digest used to drive it.
* <p>
* The document this implementation is based on can be found at
- * <a href=http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html>
+ * <a href=https://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html>
* RSA's PKCS5 Page</a>
*/
public class PKCS5S1ParametersGenerator
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
index c45c84f1..6c0151e2 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
@@ -17,7 +17,7 @@ import org.bouncycastle.util.Arrays;
* This generator uses a SHA-1 HMac as the calculation function.
* <p>
* The document this implementation is based on can be found at
- * <a href=http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html>
+ * <a href=https://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html>
* RSA's PKCS5 Page</a>
*/
public class PKCS5S2ParametersGenerator
@@ -117,7 +117,7 @@ public class PKCS5S2ParametersGenerator
{
keySize = keySize / 8;
- byte[] dKey = Arrays.copyOfRange(generateDerivedKey(keySize), 0, keySize);
+ byte[] dKey = generateDerivedKey(keySize);
return new KeyParameter(dKey, 0, keySize);
}
@@ -138,7 +138,7 @@ public class PKCS5S2ParametersGenerator
keySize = keySize / 8;
ivSize = ivSize / 8;
- byte[] dKey = generateDerivedKey(keySize + ivSize);
+ byte[] dKey = generateDerivedKey(keySize + ivSize);
return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
index eadbaa6c..6d5fc97d 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
@@ -139,7 +139,7 @@ public class RSAKeyPairGenerator
dP = d.remainder(pSub1);
dQ = d.remainder(qSub1);
- qInv = q.modInverse(p);
+ qInv = BigIntegers.modOddInverse(p, q);
result = new AsymmetricCipherKeyPair(
new RSAKeyParameters(false, n, e),
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/AEADBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/AEADBlockCipher.java
index fe461196..b8c7ad51 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/AEADBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/AEADBlockCipher.java
@@ -1,146 +1,17 @@
package org.bouncycastle.crypto.modes;
import org.bouncycastle.crypto.BlockCipher;
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.DataLengthException;
-import org.bouncycastle.crypto.InvalidCipherTextException;
/**
- * A block cipher mode that includes authenticated encryption with a streaming mode and optional associated data.
- * <p>
- * Implementations of this interface may operate in a packet mode (where all input data is buffered and
- * processed dugin the call to {@link #doFinal(byte[], int)}), or in a streaming mode (where output data is
- * incrementally produced with each call to {@link #processByte(byte, byte[], int)} or
- * {@link #processBytes(byte[], int, int, byte[], int)}.
- * </p>
- * This is important to consider during decryption: in a streaming mode, unauthenticated plaintext data
- * may be output prior to the call to {@link #doFinal(byte[], int)} that results in an authentication
- * failure. The higher level protocol utilising this cipher must ensure the plaintext data is handled
- * appropriately until the end of data is reached and the entire ciphertext is authenticated.
- * @see org.bouncycastle.crypto.params.AEADParameters
+ * An {@link AEADCipher} based on a {@link BlockCipher}.
*/
public interface AEADBlockCipher
+ extends AEADCipher
{
/**
- * initialise the underlying cipher. Parameter can either be an AEADParameters or a ParametersWithIV object.
+ * return the {@link BlockCipher} this object wraps.
*
- * @param forEncryption true if we are setting up for encryption, false otherwise.
- * @param params the necessary parameters for the underlying cipher to be initialised.
- * @exception IllegalArgumentException if the params argument is inappropriate.
- */
- public void init(boolean forEncryption, CipherParameters params)
- throws IllegalArgumentException;
-
- /**
- * Return the name of the algorithm.
- *
- * @return the algorithm name.
- */
- public String getAlgorithmName();
-
- /**
- * return the cipher this object wraps.
- *
- * @return the cipher this object wraps.
+ * @return the {@link BlockCipher} this object wraps.
*/
public BlockCipher getUnderlyingCipher();
-
- /**
- * Add a single byte to the associated data check.
- * <br>If the implementation supports it, this will be an online operation and will not retain the associated data.
- *
- * @param in the byte to be processed.
- */
- public void processAADByte(byte in);
-
- /**
- * Add a sequence of bytes to the associated data check.
- * <br>If the implementation supports it, this will be an online operation and will not retain the associated data.
- *
- * @param in the input byte array.
- * @param inOff the offset into the in array where the data to be processed starts.
- * @param len the number of bytes to be processed.
- */
- public void processAADBytes(byte[] in, int inOff, int len);
-
- /**
- * encrypt/decrypt a single byte.
- *
- * @param in the byte to be processed.
- * @param out the output buffer the processed byte goes into.
- * @param outOff the offset into the output byte array the processed data starts at.
- * @return the number of bytes written to out.
- * @exception DataLengthException if the output buffer is too small.
- */
- public int processByte(byte in, byte[] out, int outOff)
- throws DataLengthException;
-
- /**
- * process a block of bytes from in putting the result into out.
- *
- * @param in the input byte array.
- * @param inOff the offset into the in array where the data to be processed starts.
- * @param len the number of bytes to be processed.
- * @param out the output buffer the processed bytes go into.
- * @param outOff the offset into the output byte array the processed data starts at.
- * @return the number of bytes written to out.
- * @exception DataLengthException if the output buffer is too small.
- */
- public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
- throws DataLengthException;
-
- /**
- * Finish the operation either appending or verifying the MAC at the end of the data.
- *
- * @param out space for any resulting output data.
- * @param outOff offset into out to start copying the data at.
- * @return number of bytes written into out.
- * @throws IllegalStateException if the cipher is in an inappropriate state.
- * @throws org.bouncycastle.crypto.InvalidCipherTextException if the MAC fails to match.
- */
- public int doFinal(byte[] out, int outOff)
- throws IllegalStateException, InvalidCipherTextException;
-
- /**
- * Return the value of the MAC associated with the last stream processed.
- *
- * @return MAC for plaintext data.
- */
- public byte[] getMac();
-
- /**
- * return the size of the output buffer required for a processBytes
- * an input of len bytes.
- * <p>
- * The returned size may be dependent on the initialisation of this cipher
- * and may not be accurate once subsequent input data is processed - this method
- * should be invoked immediately prior to input data being processed.
- * </p>
- *
- * @param len the length of the input.
- * @return the space required to accommodate a call to processBytes
- * with len bytes of input.
- */
- public int getUpdateOutputSize(int len);
-
- /**
- * return the size of the output buffer required for a processBytes plus a
- * doFinal with an input of len bytes.
- * <p>
- * The returned size may be dependent on the initialisation of this cipher
- * and may not be accurate once subsequent input data is processed - this method
- * should be invoked immediately prior to a call to final processing of input data
- * and a call to {@link #doFinal(byte[], int)}.
- * </p>
- * @param len the length of the input.
- * @return the space required to accommodate a call to processBytes and doFinal
- * with len bytes of input.
- */
- public int getOutputSize(int len);
-
- /**
- * Reset the cipher. After resetting the cipher is in the same state
- * as it was after the last init (if there was one).
- */
- public void reset();
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/AEADCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/AEADCipher.java
new file mode 100644
index 00000000..4e49a5a9
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/AEADCipher.java
@@ -0,0 +1,138 @@
+package org.bouncycastle.crypto.modes;
+
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.InvalidCipherTextException;
+
+/**
+ * A cipher mode that includes authenticated encryption with a streaming mode and optional associated data.
+ * <p>
+ * Implementations of this interface may operate in a packet mode (where all input data is buffered and
+ * processed during the call to {@link #doFinal(byte[], int)}), or in a streaming mode (where output data is
+ * incrementally produced with each call to {@link #processByte(byte, byte[], int)} or
+ * {@link #processBytes(byte[], int, int, byte[], int)}.
+ * </p>
+ * This is important to consider during decryption: in a streaming mode, unauthenticated plaintext data
+ * may be output prior to the call to {@link #doFinal(byte[], int)} that results in an authentication
+ * failure. The higher level protocol utilising this cipher must ensure the plaintext data is handled
+ * appropriately until the end of data is reached and the entire ciphertext is authenticated.
+ * @see org.bouncycastle.crypto.params.AEADParameters
+ */
+public interface AEADCipher
+{
+ /**
+ * initialise the underlying cipher. Parameter can either be an AEADParameters or a ParametersWithIV object.
+ *
+ * @param forEncryption true if we are setting up for encryption, false otherwise.
+ * @param params the necessary parameters for the underlying cipher to be initialised.
+ * @exception IllegalArgumentException if the params argument is inappropriate.
+ */
+ public void init(boolean forEncryption, CipherParameters params)
+ throws IllegalArgumentException;
+
+ /**
+ * Return the name of the algorithm.
+ *
+ * @return the algorithm name.
+ */
+ public String getAlgorithmName();
+
+ /**
+ * Add a single byte to the associated data check.
+ * <br>If the implementation supports it, this will be an online operation and will not retain the associated data.
+ *
+ * @param in the byte to be processed.
+ */
+ public void processAADByte(byte in);
+
+ /**
+ * Add a sequence of bytes to the associated data check.
+ * <br>If the implementation supports it, this will be an online operation and will not retain the associated data.
+ *
+ * @param in the input byte array.
+ * @param inOff the offset into the in array where the data to be processed starts.
+ * @param len the number of bytes to be processed.
+ */
+ public void processAADBytes(byte[] in, int inOff, int len);
+
+ /**
+ * encrypt/decrypt a single byte.
+ *
+ * @param in the byte to be processed.
+ * @param out the output buffer the processed byte goes into.
+ * @param outOff the offset into the output byte array the processed data starts at.
+ * @return the number of bytes written to out.
+ * @exception DataLengthException if the output buffer is too small.
+ */
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException;
+
+ /**
+ * process a block of bytes from in putting the result into out.
+ *
+ * @param in the input byte array.
+ * @param inOff the offset into the in array where the data to be processed starts.
+ * @param len the number of bytes to be processed.
+ * @param out the output buffer the processed bytes go into.
+ * @param outOff the offset into the output byte array the processed data starts at.
+ * @return the number of bytes written to out.
+ * @exception DataLengthException if the output buffer is too small.
+ */
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException;
+
+ /**
+ * Finish the operation either appending or verifying the MAC at the end of the data.
+ *
+ * @param out space for any resulting output data.
+ * @param outOff offset into out to start copying the data at.
+ * @return number of bytes written into out.
+ * @throws IllegalStateException if the cipher is in an inappropriate state.
+ * @throws org.bouncycastle.crypto.InvalidCipherTextException if the MAC fails to match.
+ */
+ public int doFinal(byte[] out, int outOff)
+ throws IllegalStateException, InvalidCipherTextException;
+
+ /**
+ * Return the value of the MAC associated with the last stream processed.
+ *
+ * @return MAC for plaintext data.
+ */
+ public byte[] getMac();
+
+ /**
+ * return the size of the output buffer required for a processBytes
+ * an input of len bytes.
+ * <p>
+ * The returned size may be dependent on the initialisation of this cipher
+ * and may not be accurate once subsequent input data is processed - this method
+ * should be invoked immediately prior to input data being processed.
+ * </p>
+ *
+ * @param len the length of the input.
+ * @return the space required to accommodate a call to processBytes
+ * with len bytes of input.
+ */
+ public int getUpdateOutputSize(int len);
+
+ /**
+ * return the size of the output buffer required for a processBytes plus a
+ * doFinal with an input of len bytes.
+ * <p>
+ * The returned size may be dependent on the initialisation of this cipher
+ * and may not be accurate once subsequent input data is processed - this method
+ * should be invoked immediately prior to a call to final processing of input data
+ * and a call to {@link #doFinal(byte[], int)}.
+ * </p>
+ * @param len the length of the input.
+ * @return the space required to accommodate a call to processBytes and doFinal
+ * with len bytes of input.
+ */
+ public int getOutputSize(int len);
+
+ /**
+ * Reset the cipher. After resetting the cipher is in the same state
+ * as it was after the last init (if there was one).
+ */
+ public void reset();
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java
index 088c7283..00e1a78b 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java
@@ -73,7 +73,7 @@ public class CCMBlockCipher
nonce = param.getNonce();
initialAssociatedText = param.getAssociatedText();
- macSize = param.getMacSize() / 8;
+ macSize = getMacSize(forEncryption, param.getMacSize());
cipherParameters = param.getKey();
}
else if (params instanceof ParametersWithIV)
@@ -82,7 +82,7 @@ public class CCMBlockCipher
nonce = param.getIV();
initialAssociatedText = null;
- macSize = macBlock.length / 2;
+ macSize = getMacSize(forEncryption, 64);
cipherParameters = param.getParameters();
}
else
@@ -434,6 +434,16 @@ public class CCMBlockCipher
return cMac.doFinal(macBlock, 0);
}
+ private int getMacSize(boolean forEncryption, int requestedMacBits)
+ {
+ if (forEncryption && (requestedMacBits < 32 || requestedMacBits > 128 || 0 != (requestedMacBits & 15)))
+ {
+ throw new IllegalArgumentException("tag length in octets must be one of {4,6,8,10,12,14,16}");
+ }
+
+ return requestedMacBits >>> 3;
+ }
+
private int getAssociatedTextLength()
{
return associatedText.size() + ((initialAssociatedText == null) ? 0 : initialAssociatedText.length);
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java
index 6167d256..b11716f4 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java
@@ -36,6 +36,11 @@ public class CFBBlockCipher
{
super(cipher);
+ if (bitBlockSize > (cipher.getBlockSize() * 8) || bitBlockSize < 8 || bitBlockSize % 8 != 0)
+ {
+ throw new IllegalArgumentException("CFB" + bitBlockSize + " not supported");
+ }
+
this.cipher = cipher;
this.blockSize = bitBlockSize / 8;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/OFBBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/OFBBlockCipher.java
index d9ff428f..3cebc014 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/OFBBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/OFBBlockCipher.java
@@ -25,16 +25,21 @@ public class OFBBlockCipher
*
* @param cipher the block cipher to be used as the basis of the
* feedback mode.
- * @param blockSize the block size in bits (note: a multiple of 8)
+ * @param bitBlockSize the block size in bits (note: a multiple of 8)
*/
public OFBBlockCipher(
BlockCipher cipher,
- int blockSize)
+ int bitBlockSize)
{
super(cipher);
+ if (bitBlockSize > (cipher.getBlockSize() * 8) || bitBlockSize < 8 || bitBlockSize % 8 != 0)
+ {
+ throw new IllegalArgumentException("0FB" + bitBlockSize + " not supported");
+ }
+
this.cipher = cipher;
- this.blockSize = blockSize / 8;
+ this.blockSize = bitBlockSize / 8;
this.IV = new byte[cipher.getBlockSize()];
this.ofbV = new byte[cipher.getBlockSize()];
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
index 3e24a15f..4d13820b 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
@@ -1,6 +1,7 @@
package org.bouncycastle.crypto.modes.gcm;
import org.bouncycastle.math.raw.Interleave;
+import org.bouncycastle.util.Longs;
import org.bouncycastle.util.Pack;
public abstract class GCMUtil
@@ -140,24 +141,58 @@ public abstract class GCMUtil
public static void multiply(long[] x, long[] y)
{
+// long x0 = x[0], x1 = x[1];
+// long y0 = y[0], y1 = y[1];
+// long z0 = 0, z1 = 0, z2 = 0;
+//
+// for (int j = 0; j < 64; ++j)
+// {
+// long m0 = x0 >> 63; x0 <<= 1;
+// z0 ^= (y0 & m0);
+// z1 ^= (y1 & m0);
+//
+// long m1 = x1 >> 63; x1 <<= 1;
+// z1 ^= (y0 & m1);
+// z2 ^= (y1 & m1);
+//
+// long c = (y1 << 63) >> 8;
+// y1 = (y1 >>> 1) | (y0 << 63);
+// y0 = (y0 >>> 1) ^ (c & E1L);
+// }
+//
+// z0 ^= z2 ^ (z2 >>> 1) ^ (z2 >>> 2) ^ (z2 >>> 7);
+// z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57);
+//
+// x[0] = z0;
+// x[1] = z1;
+
+ /*
+ * "Three-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein.
+ *
+ * Without access to the high part of a 64x64 product x * y, we use a bit reversal to calculate it:
+ * rev(x) * rev(y) == rev((x * y) << 1)
+ */
+
long x0 = x[0], x1 = x[1];
long y0 = y[0], y1 = y[1];
- long z0 = 0, z1 = 0, z2 = 0;
+ long x0r = Longs.reverse(x0), x1r = Longs.reverse(x1);
+ long y0r = Longs.reverse(y0), y1r = Longs.reverse(y1);
- for (int j = 0; j < 64; ++j)
- {
- long m0 = x0 >> 63; x0 <<= 1;
- z0 ^= (y0 & m0);
- z1 ^= (y1 & m0);
+ long h0 = Longs.reverse(implMul64(x0r, y0r));
+ long h1 = implMul64(x0, y0) << 1;
+ long h2 = Longs.reverse(implMul64(x1r, y1r));
+ long h3 = implMul64(x1, y1) << 1;
+ long h4 = Longs.reverse(implMul64(x0r ^ x1r, y0r ^ y1r));
+ long h5 = implMul64(x0 ^ x1, y0 ^ y1) << 1;
- long m1 = x1 >> 63; x1 <<= 1;
- z1 ^= (y0 & m1);
- z2 ^= (y1 & m1);
+ long z0 = h0;
+ long z1 = h1 ^ h0 ^ h2 ^ h4;
+ long z2 = h2 ^ h1 ^ h3 ^ h5;
+ long z3 = h3;
- long c = (y1 << 63) >> 8;
- y1 = (y1 >>> 1) | (y0 << 63);
- y0 = (y0 >>> 1) ^ (c & E1L);
- }
+ z1 ^= z3 ^ (z3 >>> 1) ^ (z3 >>> 2) ^ (z3 >>> 7);
+// z2 ^= (z3 << 63) ^ (z3 << 62) ^ (z3 << 57);
+ z2 ^= (z3 << 62) ^ (z3 << 57);
z0 ^= z2 ^ (z2 >>> 1) ^ (z2 >>> 2) ^ (z2 >>> 7);
z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57);
@@ -382,4 +417,29 @@ public abstract class GCMUtil
z[0] = x[0] ^ y[0];
z[1] = x[1] ^ y[1];
}
+
+ private static long implMul64(long x, long y)
+ {
+ long x0 = x & 0x1111111111111111L;
+ long x1 = x & 0x2222222222222222L;
+ long x2 = x & 0x4444444444444444L;
+ long x3 = x & 0x8888888888888888L;
+
+ long y0 = y & 0x1111111111111111L;
+ long y1 = y & 0x2222222222222222L;
+ long y2 = y & 0x4444444444444444L;
+ long y3 = y & 0x8888888888888888L;
+
+ long z0 = (x0 * y0) ^ (x1 * y3) ^ (x2 * y2) ^ (x3 * y1);
+ long z1 = (x0 * y1) ^ (x1 * y0) ^ (x2 * y3) ^ (x3 * y2);
+ long z2 = (x0 * y2) ^ (x1 * y1) ^ (x2 * y0) ^ (x3 * y3);
+ long z3 = (x0 * y3) ^ (x1 * y2) ^ (x2 * y1) ^ (x3 * y0);
+
+ z0 &= 0x1111111111111111L;
+ z1 &= 0x2222222222222222L;
+ z2 &= 0x4444444444444444L;
+ z3 &= 0x8888888888888888L;
+
+ return z0 | z1 | z2 | z3;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
index 076ad588..0ad1e385 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
@@ -21,14 +21,7 @@ public class ISO10126d2Padding
public void init(SecureRandom random)
throws IllegalArgumentException
{
- if (random != null)
- {
- this.random = random;
- }
- else
- {
- this.random = CryptoServicesRegistrar.getSecureRandom();
- }
+ this.random = CryptoServicesRegistrar.getSecureRandom(random);
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/DESParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/DESParameters.java
index 5bee3604..061d134f 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/DESParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/DESParameters.java
@@ -52,7 +52,7 @@ public class DESParameters
* if the given DES key material is weak or semi-weak.
* Key material that is too short is regarded as weak.
* <p>
- * See <a href="http://www.counterpane.com/applied.html">"Applied
+ * See <a href="https://www.counterpane.com/applied.html">"Applied
* Cryptography"</a> by Bruce Schneier for more information.
*
* @return true if the given DES key material is weak or semi-weak,
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/DHParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/DHParameters.java
index 5bdb10a1..0a66736c 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/DHParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/DHParameters.java
@@ -3,6 +3,7 @@ package org.bouncycastle.crypto.params;
import java.math.BigInteger;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.util.Properties;
public class DHParameters
implements CipherParameters
@@ -94,7 +95,7 @@ public class DHParameters
}
}
- if (m > p.bitLength())
+ if (m > p.bitLength() && !Properties.isOverrideSet("org.bouncycastle.dh.allow_unsafe_p_value"))
{
throw new IllegalArgumentException("unsafe p value so small specific l required");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/DHPublicKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/DHPublicKeyParameters.java
index ba392ab1..dce2dbdd 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/DHPublicKeyParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/DHPublicKeyParameters.java
@@ -2,6 +2,9 @@ package org.bouncycastle.crypto.params;
import java.math.BigInteger;
+import org.bouncycastle.math.raw.Nat;
+import org.bouncycastle.util.Integers;
+
public class DHPublicKeyParameters
extends DHKeyParameters
{
@@ -26,25 +29,39 @@ public class DHPublicKeyParameters
throw new NullPointerException("y value cannot be null");
}
+ BigInteger p = dhParams.getP();
+
// TLS check
- if (y.compareTo(TWO) < 0 || y.compareTo(dhParams.getP().subtract(TWO)) > 0)
+ if (y.compareTo(TWO) < 0 || y.compareTo(p.subtract(TWO)) > 0)
{
throw new IllegalArgumentException("invalid DH public key");
}
- if (dhParams.getQ() != null)
+ BigInteger q = dhParams.getQ();
+ if (q == null)
{
- if (ONE.equals(y.modPow(dhParams.getQ(), dhParams.getP())))
+ return y; // we can't validate without Q.
+ }
+
+ if (p.testBit(0)
+ && p.bitLength() - 1 == q.bitLength()
+ && p.shiftRight(1).equals(q))
+ {
+ // Safe prime case
+ if (1 == legendre(y, p))
{
return y;
}
-
- throw new IllegalArgumentException("Y value does not appear to be in correct group");
}
else
{
- return y; // we can't validate without Q.
+ if (ONE.equals(y.modPow(q, p)))
+ {
+ return y;
+ }
}
+
+ throw new IllegalArgumentException("Y value does not appear to be in correct group");
}
public BigInteger getY()
@@ -69,4 +86,79 @@ public class DHPublicKeyParameters
return other.getY().equals(y) && super.equals(obj);
}
+
+ private static int legendre(BigInteger a, BigInteger b)
+ {
+// int r = 0, bits = b.intValue();
+//
+// for (;;)
+// {
+// int lowestSetBit = a.getLowestSetBit();
+// a = a.shiftRight(lowestSetBit);
+// r ^= (bits ^ (bits >>> 1)) & (lowestSetBit << 1);
+//
+// int cmp = a.compareTo(b);
+// if (cmp == 0)
+// {
+// break;
+// }
+//
+// if (cmp < 0)
+// {
+// BigInteger t = a; a = b; b = t;
+//
+// int oldBits = bits;
+// bits = b.intValue();
+// r ^= oldBits & bits;
+// }
+//
+// a = a.subtract(b);
+// }
+//
+// return ONE.equals(b) ? (1 - (r & 2)) : 0;
+
+ int bitLength = b.bitLength();
+ int[] A = Nat.fromBigInteger(bitLength, a);
+ int[] B = Nat.fromBigInteger(bitLength, b);
+
+ int r = 0;
+
+ int len = B.length;
+ for (;;)
+ {
+ while (A[0] == 0)
+ {
+ Nat.shiftDownWord(len, A, 0);
+ }
+
+ int shift = Integers.numberOfTrailingZeros(A[0]);
+ if (shift > 0)
+ {
+ Nat.shiftDownBits(len, A, shift, 0);
+ int bits = B[0];
+ r ^= (bits ^ (bits >>> 1)) & (shift << 1);
+ }
+
+ int cmp = Nat.compare(len, A, B);
+ if (cmp == 0)
+ {
+ break;
+ }
+
+ if (cmp < 0)
+ {
+ r ^= A[0] & B[0];
+ int[] t = A; A = B; B = t;
+ }
+
+ while (A[len - 1] == 0)
+ {
+ len = len - 1;
+ }
+
+ Nat.sub(len, A, B, A);
+ }
+
+ return Nat.isOne(len, B) ? (1 - (r & 2)) : 0;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java
index 1cead6f3..6e844969 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java
@@ -2,22 +2,30 @@ package org.bouncycastle.crypto.params;
import java.math.BigInteger;
+import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.math.ec.ECAlgorithms;
import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.BigIntegers;
public class ECDomainParameters
implements ECConstants
{
- private ECCurve curve;
- private byte[] seed;
- private ECPoint G;
- private BigInteger n;
- private BigInteger h;
+ private final ECCurve curve;
+ private final byte[] seed;
+ private final ECPoint G;
+ private final BigInteger n;
+ private final BigInteger h;
+
private BigInteger hInv = null;
+ public ECDomainParameters(X9ECParameters x9)
+ {
+ this(x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
+ }
+
public ECDomainParameters(
ECCurve curve,
ECPoint G,
@@ -53,7 +61,7 @@ public class ECDomainParameters
// we can't check for h == null here as h is optional in X9.62 as it is not required for ECDSA
this.curve = curve;
- this.G = validate(curve, G);
+ this.G = validatePublicPoint(curve, G);
this.n = n;
this.h = h;
this.seed = Arrays.clone(seed);
@@ -83,7 +91,7 @@ public class ECDomainParameters
{
if (hInv == null)
{
- hInv = h.modInverse(n);
+ hInv = BigIntegers.modOddInverseVar(n, h);
}
return hInv;
}
@@ -101,33 +109,56 @@ public class ECDomainParameters
return true;
}
- if ((obj instanceof ECDomainParameters))
+ if (!(obj instanceof ECDomainParameters))
{
- ECDomainParameters other = (ECDomainParameters)obj;
-
- return this.curve.equals(other.curve) && this.G.equals(other.G) && this.n.equals(other.n) && this.h.equals(other.h);
+ return false;
}
- return false;
+ ECDomainParameters other = (ECDomainParameters)obj;
+
+ return this.curve.equals(other.curve)
+ && this.G.equals(other.G)
+ && this.n.equals(other.n);
}
public int hashCode()
{
- int hc = curve.hashCode();
- hc *= 37;
+// return Arrays.hashCode(new Object[]{ curve, G, n });
+ int hc = 4;
+ hc *= 257;
+ hc ^= curve.hashCode();
+ hc *= 257;
hc ^= G.hashCode();
- hc *= 37;
+ hc *= 257;
hc ^= n.hashCode();
- hc *= 37;
- hc ^= h.hashCode();
return hc;
}
- static ECPoint validate(ECCurve c, ECPoint q)
+ public BigInteger validatePrivateScalar(BigInteger d)
+ {
+ if (null == d)
+ {
+ throw new NullPointerException("Scalar cannot be null");
+ }
+
+ if (d.compareTo(ECConstants.ONE) < 0 || (d.compareTo(getN()) >= 0))
+ {
+ throw new IllegalArgumentException("Scalar is not in the interval [1, n - 1]");
+ }
+
+ return d;
+ }
+
+ public ECPoint validatePublicPoint(ECPoint q)
+ {
+ return validatePublicPoint(getCurve(), q);
+ }
+
+ static ECPoint validatePublicPoint(ECCurve c, ECPoint q)
{
- if (q == null)
+ if (null == q)
{
- throw new IllegalArgumentException("Point has null value");
+ throw new NullPointerException("Point cannot be null");
}
q = ECAlgorithms.importPoint(c, q).normalize();
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECKeyParameters.java
index 19825c5b..f3c0aeae 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECKeyParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECKeyParameters.java
@@ -3,19 +3,24 @@ package org.bouncycastle.crypto.params;
public class ECKeyParameters
extends AsymmetricKeyParameter
{
- ECDomainParameters params;
+ private final ECDomainParameters parameters;
protected ECKeyParameters(
boolean isPrivate,
- ECDomainParameters params)
+ ECDomainParameters parameters)
{
super(isPrivate);
- this.params = params;
+ if (null == parameters)
+ {
+ throw new NullPointerException("'parameters' cannot be null");
+ }
+
+ this.parameters = parameters;
}
public ECDomainParameters getParameters()
{
- return params;
+ return parameters;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java
index ed89589f..13948848 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java
@@ -3,6 +3,7 @@ package org.bouncycastle.crypto.params;
import java.math.BigInteger;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
@@ -35,6 +36,12 @@ public class ECNamedDomainParameters
this.name = name;
}
+ public ECNamedDomainParameters(ASN1ObjectIdentifier name, X9ECParameters x9)
+ {
+ super(x9);
+ this.name = name;
+ }
+
public ASN1ObjectIdentifier getName()
{
return name;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java
index 3e49983e..ea0228f8 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java
@@ -5,14 +5,15 @@ import java.math.BigInteger;
public class ECPrivateKeyParameters
extends ECKeyParameters
{
- BigInteger d;
+ private final BigInteger d;
public ECPrivateKeyParameters(
BigInteger d,
- ECDomainParameters params)
+ ECDomainParameters parameters)
{
- super(true, params);
- this.d = d;
+ super(true, parameters);
+
+ this.d = parameters.validatePrivateScalar(d);
}
public BigInteger getD()
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECPublicKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECPublicKeyParameters.java
index 6f097ad3..ea72bad8 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECPublicKeyParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECPublicKeyParameters.java
@@ -5,19 +5,19 @@ import org.bouncycastle.math.ec.ECPoint;
public class ECPublicKeyParameters
extends ECKeyParameters
{
- private final ECPoint Q;
+ private final ECPoint q;
public ECPublicKeyParameters(
- ECPoint Q,
- ECDomainParameters params)
+ ECPoint q,
+ ECDomainParameters parameters)
{
- super(false, params);
+ super(false, parameters);
- this.Q = ECDomainParameters.validate(params.getCurve(), Q);
+ this.q = parameters.validatePublicPoint(q);
}
public ECPoint getQ()
{
- return Q;
+ return q;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/ParametersWithRandom.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/ParametersWithRandom.java
index 9c6ed020..9492f5a3 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/ParametersWithRandom.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/ParametersWithRandom.java
@@ -15,14 +15,14 @@ public class ParametersWithRandom
CipherParameters parameters,
SecureRandom random)
{
- this.random = random;
+ this.random = CryptoServicesRegistrar.getSecureRandom(random);
this.parameters = parameters;
}
public ParametersWithRandom(
CipherParameters parameters)
{
- this(parameters, CryptoServicesRegistrar.getSecureRandom());
+ this(parameters, null);
}
public SecureRandom getRandom()
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java
index c357843e..911f2003 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java
@@ -2,9 +2,19 @@ package org.bouncycastle.crypto.params;
import java.math.BigInteger;
+import org.bouncycastle.util.Properties;
+
public class RSAKeyParameters
extends AsymmetricKeyParameter
{
+ // Hexadecimal value of the product of the 131 smallest odd primes from 3 to 743
+ private static final BigInteger SMALL_PRIMES_PRODUCT = new BigInteger(
+ "8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
+ + "73d893fa424cd2edc8636a6c3285e022b0e3866a565ae8108eed8591cd4fe8d2"
+ + "ce86165a978d719ebf647f362d33fca29cd179fb42401cbaf3df0c614056f9c8"
+ + "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f",
+ 16);
+
private static final BigInteger ONE = BigInteger.valueOf(1);
private BigInteger modulus;
@@ -36,12 +46,14 @@ public class RSAKeyParameters
throw new IllegalArgumentException("RSA modulus is even");
}
- // the value is the product of the 132 smallest primes from 3 to 751
- if (!modulus.gcd(new BigInteger("145188775577763990151158743208307020242261438098488931355057091965" +
- "931517706595657435907891265414916764399268423699130577757433083166" +
- "651158914570105971074227669275788291575622090199821297575654322355" +
- "049043101306108213104080801056529374892690144291505781966373045481" +
- "8359472391642885328171302299245556663073719855")).equals(ONE))
+ // If you need to set this you need to have a serious word to whoever is generating
+ // your keys.
+ if (Properties.isOverrideSet("org.bouncycastle.rsa.allow_unsafe_mod"))
+ {
+ return modulus;
+ }
+
+ if (!modulus.gcd(SMALL_PRIMES_PRODUCT).equals(ONE))
{
throw new IllegalArgumentException("RSA modulus has a small prime factor");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java
index 668ac276..314a0961 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java
@@ -105,7 +105,7 @@ public class DSASigner
// the randomizer is to conceal timing information related to k and x.
BigInteger r = params.getG().modPow(k.add(getRandomizer(q, random)), params.getP()).mod(q);
- k = k.modInverse(q).multiply(m.add(x.multiply(r)));
+ k = BigIntegers.modOddInverse(q, k).multiply(m.add(x.multiply(r)));
BigInteger s = k.mod(q);
@@ -137,7 +137,7 @@ public class DSASigner
return false;
}
- BigInteger w = s.modInverse(q);
+ BigInteger w = BigIntegers.modOddInverseVar(q, s);
BigInteger u1 = m.multiply(w).mod(q);
BigInteger u2 = r.multiply(w).mod(q);
@@ -169,7 +169,7 @@ public class DSASigner
protected SecureRandom initSecureRandom(boolean needed, SecureRandom provided)
{
- return !needed ? null : (provided != null) ? provided : CryptoServicesRegistrar.getSecureRandom();
+ return needed ? CryptoServicesRegistrar.getSecureRandom(provided) : null;
}
private BigInteger getRandomizer(BigInteger q, SecureRandom provided)
@@ -177,6 +177,6 @@ public class DSASigner
// Calculate a random multiple of q to add to k. Note that g^q = 1 (mod p), so adding multiple of q to k does not change r.
int randomBits = 7;
- return BigIntegers.createRandomBigInteger(randomBits, provided != null ? provided : CryptoServicesRegistrar.getSecureRandom()).add(BigInteger.valueOf(128)).multiply(q);
+ return BigIntegers.createRandomBigInteger(randomBits, CryptoServicesRegistrar.getSecureRandom(provided)).add(BigInteger.valueOf(128)).multiply(q);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
index 057beed7..c8f687b6 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
@@ -18,6 +18,7 @@ import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECMultiplier;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.math.ec.FixedPointCombMultiplier;
+import org.bouncycastle.util.BigIntegers;
/**
* EC-DSA as described in X9.62
@@ -125,7 +126,7 @@ public class ECDSASigner
}
while (r.equals(ZERO));
- s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);
+ s = BigIntegers.modOddInverse(n, k).multiply(e.add(d.multiply(r))).mod(n);
}
while (s.equals(ZERO));
@@ -159,7 +160,7 @@ public class ECDSASigner
return false;
}
- BigInteger c = s.modInverse(n);
+ BigInteger c = BigIntegers.modOddInverseVar(n, s);
BigInteger u1 = e.multiply(c).mod(n);
BigInteger u2 = r.multiply(c).mod(n);
@@ -253,6 +254,6 @@ public class ECDSASigner
protected SecureRandom initSecureRandom(boolean needed, SecureRandom provided)
{
- return !needed ? null : (provided != null) ? provided : CryptoServicesRegistrar.getSecureRandom();
+ return needed ? CryptoServicesRegistrar.getSecureRandom(provided) : null;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java
index 45c8b57d..14f2eaf2 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java
@@ -78,7 +78,15 @@ public class RSADigestSigner
ASN1ObjectIdentifier digestOid)
{
this.digest = digest;
- this.algId = new AlgorithmIdentifier(digestOid, DERNull.INSTANCE);
+ if (digestOid != null)
+ {
+ this.algId = new AlgorithmIdentifier(digestOid, DERNull.INSTANCE);
+ }
+ else
+ {
+ // NULL digester, match behaviour with DigestSignatureSpi
+ this.algId = null;
+ }
}
/**
@@ -90,7 +98,7 @@ public class RSADigestSigner
}
/**
- * initialise the signer for signing or verification.
+ * Initialize the signer for signing or verification.
*
* @param forSigning
* true if for signing, false otherwise
@@ -246,6 +254,20 @@ public class RSADigestSigner
byte[] hash)
throws IOException
{
+ if (algId == null)
+ {
+ try
+ {
+ // check hash is at least right format
+ DigestInfo.getInstance(hash);
+ return hash;
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new IOException("malformed DigestInfo for NONEwithRSA hash: " + e.getMessage());
+ }
+ }
+
DigestInfo dInfo = new DigestInfo(algId, hash);
return dInfo.getEncoded(ASN1Encoding.DER);
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/tls/CertificateType.java b/bcprov/src/main/java/org/bouncycastle/crypto/tls/CertificateType.java
index 5dc503eb..cd126cd6 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/tls/CertificateType.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/tls/CertificateType.java
@@ -2,6 +2,8 @@ package org.bouncycastle.crypto.tls;
/**
* RFC 6091
+ *
+ * @deprecated Migrate to the (D)TLS API in org.bouncycastle.tls (bctls jar).
*/
public class CertificateType
{
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsCloseable.java b/bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsCloseable.java
new file mode 100644
index 00000000..7030f988
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsCloseable.java
@@ -0,0 +1,11 @@
+package org.bouncycastle.crypto.tls;
+
+import java.io.IOException;
+
+/**
+ * @deprecated Migrate to the (D)TLS API in org.bouncycastle.tls (bctls jar).
+ */
+public interface TlsCloseable
+{
+ public void close() throws IOException;
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java b/bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java
index 997d9907..c1716b45 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java
@@ -8,6 +8,8 @@ import java.io.EOFException;
* protocol cannot rule out truncation of the connection data (potentially malicious). It may be
* possible to check for truncation via some property of a higher level protocol built upon TLS,
* e.g. the Content-Length header for HTTPS.
+ *
+ * @deprecated Migrate to the (D)TLS API in org.bouncycastle.tls (bctls jar).
*/
public class TlsNoCloseNotifyException
extends EOFException
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java b/bcprov/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java
index 58c7871c..900c6c37 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java
@@ -51,6 +51,7 @@ import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.params.X25519PrivateKeyParameters;
// import org.bouncycastle.crypto.params.X448PrivateKeyParameters;
+import org.bouncycastle.util.Arrays;
/**
* Factory for creating private key objects from PKCS8 PrivateKeyInfo objects.
@@ -149,7 +150,7 @@ public class PrivateKeyFactory
}
else if (algOID.equals(X9ObjectIdentifiers.id_ecPublicKey))
{
- X962Parameters params = new X962Parameters((ASN1Primitive)algId.getParameters());
+ X962Parameters params = X962Parameters.getInstance(algId.getParameters());
X9ECParameters x9;
ECDomainParameters dParams;
@@ -163,8 +164,7 @@ public class PrivateKeyFactory
{
x9 = ECNamedCurveTable.getByOID(oid);
}
- dParams = new ECNamedDomainParameters(
- oid, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
+ dParams = new ECNamedDomainParameters(oid, x9);
}
else
{
@@ -208,7 +208,7 @@ public class PrivateKeyFactory
if (p instanceof ASN1Sequence && (ASN1Sequence.getInstance(p).size() == 2 || ASN1Sequence.getInstance(p).size() == 3))
{
- ECDomainParameters ecP = ECGOST3410NamedCurves.getByOID(gostParams.getPublicKeyParamSet());
+ X9ECParameters ecP = ECGOST3410NamedCurves.getByOIDX9(gostParams.getPublicKeyParamSet());
ecSpec = new ECGOST3410Parameters(
new ECNamedDomainParameters(
@@ -216,25 +216,25 @@ public class PrivateKeyFactory
gostParams.getPublicKeyParamSet(),
gostParams.getDigestParamSet(),
gostParams.getEncryptionParamSet());
- ASN1Encodable privKey = keyInfo.parsePrivateKey();
- if (privKey instanceof ASN1Integer)
+ ASN1OctetString privEnc = keyInfo.getPrivateKey();
+
+ if (privEnc.getOctets().length == 32 || privEnc.getOctets().length == 64)
{
- d = ASN1Integer.getInstance(privKey).getPositiveValue();
+ d = new BigInteger(1, Arrays.reverse(privEnc.getOctets()));
}
else
{
- byte[] encVal = ASN1OctetString.getInstance(privKey).getOctets();
- byte[] dVal = new byte[encVal.length];
-
- for (int i = 0; i != encVal.length; i++)
+ ASN1Encodable privKey = keyInfo.parsePrivateKey();
+ if (privKey instanceof ASN1Integer)
{
- dVal[i] = encVal[encVal.length - 1 - i];
+ d = ASN1Integer.getInstance(privKey).getPositiveValue();
+ }
+ else
+ {
+ byte[] dVal = Arrays.reverse(ASN1OctetString.getInstance(privKey).getOctets());
+ d = new BigInteger(1, dVal);
}
-
- d = new BigInteger(1, dVal);
}
-
-
}
else
{
@@ -244,27 +244,10 @@ public class PrivateKeyFactory
{
ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters());
X9ECParameters ecP = ECNamedCurveTable.getByOID(oid);
- if (ecP == null)
- {
- ECDomainParameters gParam = ECGOST3410NamedCurves.getByOID(oid);
- ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(
- oid,
- gParam.getCurve(),
- gParam.getG(),
- gParam.getN(),
- gParam.getH(),
- gParam.getSeed()), gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(), gostParams.getEncryptionParamSet());
- }
- else
- {
- ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(
- oid,
- ecP.getCurve(),
- ecP.getG(),
- ecP.getN(),
- ecP.getH(),
- ecP.getSeed()), gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(), gostParams.getEncryptionParamSet());
- }
+
+ ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(oid, ecP),
+ gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(),
+ gostParams.getEncryptionParamSet());
}
else if (params.isImplicitlyCA())
{
@@ -273,13 +256,9 @@ public class PrivateKeyFactory
else
{
X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
- ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(
- algOID,
- ecP.getCurve(),
- ecP.getG(),
- ecP.getN(),
- ecP.getH(),
- ecP.getSeed()), gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(), gostParams.getEncryptionParamSet());
+ ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(algOID, ecP),
+ gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(),
+ gostParams.getEncryptionParamSet());
}
ASN1Encodable privKey = keyInfo.parsePrivateKey();
@@ -291,7 +270,7 @@ public class PrivateKeyFactory
}
else
{
- org.bouncycastle.asn1.sec.ECPrivateKey ec = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(privKey);
+ ECPrivateKey ec = ECPrivateKey.getInstance(privKey);
d = ec.getKey();
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java b/bcprov/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java
index b64c6a2a..1a42913b 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java
@@ -65,6 +65,8 @@ import org.bouncycastle.crypto.params.RSAKeyParameters;
// import org.bouncycastle.crypto.params.X25519PublicKeyParameters;
// import org.bouncycastle.crypto.params.X448PublicKeyParameters;
import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.util.Arrays;
/**
* Factory to create asymmetric public key parameters for asymmetric ciphers from range of
@@ -151,17 +153,15 @@ public class PublicKeyFactory
public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo, Object defaultParams)
throws IOException
{
- AlgorithmIdentifier algId = keyInfo.getAlgorithm();
- SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)converters.get(algId.getAlgorithm());
+ AlgorithmIdentifier algID = keyInfo.getAlgorithm();
- if (converter != null)
+ SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)converters.get(algID.getAlgorithm());
+ if (null == converter)
{
- return converter.getPublicKeyParameters(keyInfo, defaultParams);
- }
- else
- {
- throw new IOException("algorithm identifier in public key not recognised: " + algId.getAlgorithm());
+ throw new IOException("algorithm identifier in public key not recognised: " + algID.getAlgorithm());
}
+
+ return converter.getPublicKeyParameters(keyInfo, defaultParams);
}
private static abstract class SubjectPublicKeyInfoConverter
@@ -292,8 +292,7 @@ public class PublicKeyFactory
{
x9 = ECNamedCurveTable.getByOID(oid);
}
- dParams = new ECNamedDomainParameters(
- oid, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
+ dParams = new ECNamedDomainParameters(oid, x9);
}
else if (params.isImplicitlyCA())
{
@@ -302,8 +301,7 @@ public class PublicKeyFactory
else
{
X9ECParameters x9 = X9ECParameters.getInstance(params.getParameters());
- dParams = new ECDomainParameters(
- x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
+ dParams = new ECDomainParameters(x9);
}
DERBitString bits = keyInfo.getPublicKeyData();
@@ -344,40 +342,47 @@ public class PublicKeyFactory
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- DERBitString bits = keyInfo.getPublicKeyData();
- ASN1OctetString key;
+ AlgorithmIdentifier algID = keyInfo.getAlgorithm();
+// ASN1ObjectIdentifier algOid = algID.getAlgorithm();
+ GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(algID.getParameters());
+ ASN1ObjectIdentifier publicKeyParamSet = gostParams.getPublicKeyParamSet();
+ ECGOST3410Parameters ecDomainParameters = new ECGOST3410Parameters(
+ new ECNamedDomainParameters(publicKeyParamSet, ECGOST3410NamedCurves.getByOIDX9(publicKeyParamSet)),
+ publicKeyParamSet,
+ gostParams.getDigestParamSet(),
+ gostParams.getEncryptionParamSet());
+
+ ASN1OctetString key;
try
{
- key = (ASN1OctetString)ASN1Primitive.fromByteArray(bits.getBytes());
+ key = (ASN1OctetString)keyInfo.parsePublicKey();
}
catch (IOException ex)
{
- throw new IllegalArgumentException("error recovering public key");
+ throw new IllegalArgumentException("error recovering GOST3410_2001 public key");
}
+ int fieldSize = 32;
+ int keySize = 2 * fieldSize;
+
byte[] keyEnc = key.getOctets();
+ if (keyEnc.length != keySize)
+ {
+ throw new IllegalArgumentException("invalid length for GOST3410_2001 public key");
+ }
- byte[] x9Encoding = new byte[65];
+ byte[] x9Encoding = new byte[1 + keySize];
x9Encoding[0] = 0x04;
- for (int i = 1; i <= 32; ++i)
+ for (int i = 1; i <= fieldSize; ++i)
{
- x9Encoding[i] = keyEnc[32 - i];
- x9Encoding[i + 32] = keyEnc[64 - i];
+ x9Encoding[i] = keyEnc[fieldSize - i];
+ x9Encoding[i + fieldSize] = keyEnc[keySize - i];
}
- GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(keyInfo.getAlgorithm().getParameters());
-
- ECGOST3410Parameters ecDomainParameters =
- new ECGOST3410Parameters(
- new ECNamedDomainParameters(gostParams.getPublicKeyParamSet(), ECGOST3410NamedCurves.getByOID(gostParams.getPublicKeyParamSet())),
- gostParams.getPublicKeyParamSet(),
- gostParams.getDigestParamSet(),
- gostParams.getEncryptionParamSet());
-
-
- return new ECPublicKeyParameters(ecDomainParameters.getCurve().decodePoint(x9Encoding), ecDomainParameters);
+ ECPoint q = ecDomainParameters.getCurve().decodePoint(x9Encoding);
+ return new ECPublicKeyParameters(q, ecDomainParameters);
}
}
@@ -386,29 +391,40 @@ public class PublicKeyFactory
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm();
- DERBitString bits = keyInfo.getPublicKeyData();
- ASN1OctetString key;
+ AlgorithmIdentifier algID = keyInfo.getAlgorithm();
+ ASN1ObjectIdentifier algOid = algID.getAlgorithm();
+ GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(algID.getParameters());
+ ASN1ObjectIdentifier publicKeyParamSet = gostParams.getPublicKeyParamSet();
+
+ ECGOST3410Parameters ecDomainParameters = new ECGOST3410Parameters(
+ new ECNamedDomainParameters(publicKeyParamSet, ECGOST3410NamedCurves.getByOIDX9(publicKeyParamSet)),
+ publicKeyParamSet,
+ gostParams.getDigestParamSet(),
+ gostParams.getEncryptionParamSet());
+ ASN1OctetString key;
try
{
- key = (ASN1OctetString)ASN1Primitive.fromByteArray(bits.getBytes());
+ key = (ASN1OctetString)keyInfo.parsePublicKey();
}
catch (IOException ex)
{
- throw new IllegalArgumentException("error recovering public key");
+ throw new IllegalArgumentException("error recovering GOST3410_2012 public key");
}
- byte[] keyEnc = key.getOctets();
-
int fieldSize = 32;
if (algOid.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512))
{
fieldSize = 64;
}
-
int keySize = 2 * fieldSize;
+ byte[] keyEnc = key.getOctets();
+ if (keyEnc.length != keySize)
+ {
+ throw new IllegalArgumentException("invalid length for GOST3410_2012 public key");
+ }
+
byte[] x9Encoding = new byte[1 + keySize];
x9Encoding[0] = 0x04;
for (int i = 1; i <= fieldSize; ++i)
@@ -417,17 +433,9 @@ public class PublicKeyFactory
x9Encoding[i + fieldSize] = keyEnc[keySize - i];
}
- GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(keyInfo.getAlgorithm().getParameters());
+ ECPoint q = ecDomainParameters.getCurve().decodePoint(x9Encoding);
- ECGOST3410Parameters ecDomainParameters =
- new ECGOST3410Parameters(
- new ECNamedDomainParameters(gostParams.getPublicKeyParamSet(), ECGOST3410NamedCurves.getByOID(gostParams.getPublicKeyParamSet())),
- gostParams.getPublicKeyParamSet(),
- gostParams.getDigestParamSet(),
- gostParams.getEncryptionParamSet());
-
-
- return new ECPublicKeyParameters(ecDomainParameters.getCurve().decodePoint(x9Encoding), ecDomainParameters);
+ return new ECPublicKeyParameters(q, ecDomainParameters);
}
}
@@ -437,53 +445,55 @@ public class PublicKeyFactory
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
throws IOException
{
- DERBitString bits = keyInfo.getPublicKeyData();
- ASN1OctetString key;
+ AlgorithmIdentifier algID = keyInfo.getAlgorithm();
+ ASN1ObjectIdentifier algOid = algID.getAlgorithm();
+ DSTU4145Params dstuParams = DSTU4145Params.getInstance(algID.getParameters());
+ ASN1OctetString key;
try
{
- key = (ASN1OctetString)ASN1Primitive.fromByteArray(bits.getBytes());
+ key = (ASN1OctetString)keyInfo.parsePublicKey();
}
catch (IOException ex)
{
- throw new IllegalArgumentException("error recovering public key");
+ throw new IllegalArgumentException("error recovering DSTU public key");
}
- byte[] keyEnc = key.getOctets();
+ byte[] keyEnc = Arrays.clone(key.getOctets());
- if (keyInfo.getAlgorithm().getAlgorithm().equals(UAObjectIdentifiers.dstu4145le))
+ if (algOid.equals(UAObjectIdentifiers.dstu4145le))
{
reverseBytes(keyEnc);
}
- DSTU4145Params dstuParams = DSTU4145Params.getInstance(keyInfo.getAlgorithm().getParameters());
-
ECDomainParameters ecDomain;
if (dstuParams.isNamedCurve())
{
- ASN1ObjectIdentifier curveOid = dstuParams.getNamedCurve();
-
- ecDomain = DSTU4145NamedCurves.getByOID(curveOid);
+ ecDomain = DSTU4145NamedCurves.getByOID(dstuParams.getNamedCurve());
}
else
{
DSTU4145ECBinary binary = dstuParams.getECBinary();
byte[] b_bytes = binary.getB();
- if (keyInfo.getAlgorithm().getAlgorithm().equals(UAObjectIdentifiers.dstu4145le))
+ if (algOid.equals(UAObjectIdentifiers.dstu4145le))
{
reverseBytes(b_bytes);
}
+ BigInteger b = new BigInteger(1, b_bytes);
DSTU4145BinaryField field = binary.getField();
- ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), new BigInteger(1, b_bytes));
+ ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), b);
byte[] g_bytes = binary.getG();
- if (keyInfo.getAlgorithm().getAlgorithm().equals(UAObjectIdentifiers.dstu4145le))
+ if (algOid.equals(UAObjectIdentifiers.dstu4145le))
{
reverseBytes(g_bytes);
}
- ecDomain = new ECDomainParameters(curve, DSTU4145PointEncoder.decodePoint(curve, g_bytes), binary.getN());
+ ECPoint g = DSTU4145PointEncoder.decodePoint(curve, g_bytes);
+ ecDomain = new ECDomainParameters(curve, g, binary.getN());
}
- return new ECPublicKeyParameters(DSTU4145PointEncoder.decodePoint(ecDomain.getCurve(), keyEnc), ecDomain);
+ ECPoint q = DSTU4145PointEncoder.decodePoint(ecDomain.getCurve(), keyEnc);
+
+ return new ECPublicKeyParameters(q, ecDomain);
}
private void reverseBytes(byte[] bytes)
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/util/SSHNamedCurves.java b/bcprov/src/main/java/org/bouncycastle/crypto/util/SSHNamedCurves.java
new file mode 100644
index 00000000..25d0c6c2
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/util/SSHNamedCurves.java
@@ -0,0 +1,130 @@
+package org.bouncycastle.crypto.util;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.nist.NISTNamedCurves;
+import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
+import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.crypto.ec.CustomNamedCurves;
+import org.bouncycastle.crypto.params.ECDomainParameters;
+import org.bouncycastle.crypto.params.ECNamedDomainParameters;
+import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.util.Strings;
+
+public class SSHNamedCurves
+{
+ private static final Map<ASN1ObjectIdentifier, String> oidToName;
+ private static final Map<String, ASN1ObjectIdentifier> oidMap =
+ Collections.unmodifiableMap(new HashMap<String, ASN1ObjectIdentifier>()
+ {
+ {
+ put("nistp256", SECObjectIdentifiers.secp256r1);
+ put("nistp384", SECObjectIdentifiers.secp384r1);
+ put("nistp521", SECObjectIdentifiers.secp521r1);
+ put("nistk163", SECObjectIdentifiers.sect163k1);
+ put("nistp192", SECObjectIdentifiers.secp192r1);
+ put("nistp224", SECObjectIdentifiers.secp224r1);
+ put("nistk233", SECObjectIdentifiers.sect233k1);
+ put("nistb233", SECObjectIdentifiers.sect233r1);
+ put("nistk283", SECObjectIdentifiers.sect283k1);
+ put("nistk409", SECObjectIdentifiers.sect409k1);
+ put("nistb409", SECObjectIdentifiers.sect409r1);
+ put("nistt571", SECObjectIdentifiers.sect571k1);
+ }
+ });
+
+ private static final Map<String, String> curveNameToSSHName = Collections.unmodifiableMap(new HashMap<String, String>()
+ {
+ {
+ String[][] curves = {
+ {"secp256r1", "nistp256"},
+ {"secp384r1", "nistp384"},
+ {"secp521r1", "nistp521"},
+ {"sect163k1", "nistk163"},
+ {"secp192r1", "nistp192"},
+ {"secp224r1", "nistp224"},
+ {"sect233k1", "nistk233"},
+ {"sect233r1", "nistb233"},
+ {"sect283k1", "nistk283"},
+ {"sect409k1", "nistk409"},
+ {"sect409r1", "nistb409"},
+ {"sect571k1", "nistt571"}
+ };
+ for (int i = 0; i != curves.length; i++)
+ {
+ String[] item = curves[i];
+ put(item[0], item[1]);
+ }
+ }
+ });
+ private static HashMap<ECCurve, String> curveMap = new HashMap<ECCurve, String>()
+ {
+ {
+ Enumeration<Object> e = CustomNamedCurves.getNames();
+ while (e.hasMoreElements())
+ {
+ String name = (String)e.nextElement();
+ X9ECParameters parameters = CustomNamedCurves.getByName(name);
+ put(parameters.getCurve(), name);
+ }
+
+ }
+ };
+
+ static
+ {
+ oidToName = Collections.unmodifiableMap(new HashMap<ASN1ObjectIdentifier, String>()
+ {
+ {
+ for (Iterator it = oidMap.keySet().iterator(); it.hasNext();)
+ {
+ String key = (String)it.next();
+ put(oidMap.get(key), key);
+ }
+ }
+ });
+
+
+ }
+
+ public static ASN1ObjectIdentifier getByName(String sshName)
+ {
+ return (ASN1ObjectIdentifier)oidMap.get(sshName);
+ }
+
+ public static X9ECParameters getParameters(String sshName)
+ {
+ return NISTNamedCurves.getByOID((ASN1ObjectIdentifier)oidMap.get(Strings.toLowerCase(sshName)));
+ }
+
+ public static X9ECParameters getParameters(ASN1ObjectIdentifier oid)
+ {
+ return NISTNamedCurves.getByOID(oid);
+ }
+
+ public static String getName(ASN1ObjectIdentifier oid)
+ {
+ return (String)oidToName.get(oid);
+ }
+
+ public static String getNameForParameters(ECDomainParameters parameters)
+ {
+ if (parameters instanceof ECNamedDomainParameters)
+ {
+ return getName(((ECNamedDomainParameters)parameters).getName());
+ }
+
+
+ return getNameForParameters(parameters.getCurve());
+ }
+
+ public static String getNameForParameters(ECCurve curve)
+ {
+ return (String)curveNameToSSHName.get(curveMap.get(curve));
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/AesCcmCiphertext.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/AesCcmCiphertext.java
new file mode 100644
index 00000000..3831c038
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/AesCcmCiphertext.java
@@ -0,0 +1,59 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * AesCcmCiphertext ::= SEQUENCE {
+ * nonce OCTET STRING (SIZE (12))
+ * ccmCiphertext Opaque -- 16 bytes longer than plaintext
+ * }
+ * </pre>
+ */
+public class AesCcmCiphertext
+ extends ASN1Object
+{
+ private final byte[] nonce;
+ private final SequenceOfOctetString opaque;
+
+ private AesCcmCiphertext(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("sequence not length 2");
+ }
+
+ nonce = Utils.octetStringFixed(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets(), 12);
+ opaque = SequenceOfOctetString.getInstance(seq.getObjectAt(1));
+ }
+
+ public static AesCcmCiphertext getInstance(Object o)
+ {
+ if (o instanceof AesCcmCiphertext)
+ {
+ return (AesCcmCiphertext)o;
+ }
+ else if (o != null)
+ {
+ return new AesCcmCiphertext(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(new DEROctetString(nonce));
+ v.add(opaque);
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/BitmapSspRange.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/BitmapSspRange.java
new file mode 100644
index 00000000..f3ae9c8d
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/BitmapSspRange.java
@@ -0,0 +1,72 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * BitmapSspRange ::= SEQUENCE {
+ * sspValue OCTET STRING (SIZE(1..32)),
+ * sspBitmask OCTET STRING (SIZE(1..32))
+ * }
+ * </pre>
+ */
+public class BitmapSspRange
+ extends ASN1Object
+{
+ private final byte[] sspValue;
+ private final byte[] sspBitmask;
+
+ private BitmapSspRange(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("expected sequence with sspValue and sspBitmask");
+ }
+
+ sspValue = Utils.octetStringFixed(
+ ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets());
+ sspBitmask = Utils.octetStringFixed(
+ ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets());
+ }
+
+ public static BitmapSspRange getInstance(Object o)
+ {
+ if (o instanceof BitmapSspRange)
+ {
+ return (BitmapSspRange)o;
+ }
+ else if (o != null)
+ {
+ return new BitmapSspRange(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public byte[] getSspValue()
+ {
+ return Arrays.clone(sspValue);
+ }
+
+ public byte[] getSspBitmask()
+ {
+ return Arrays.clone(sspBitmask);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector avec = new ASN1EncodableVector();
+
+ avec.add(new DEROctetString(sspValue));
+ avec.add(new DEROctetString(sspBitmask));
+
+ return new DERSequence(avec);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/CertificateBase.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/CertificateBase.java
new file mode 100644
index 00000000..54bad31c
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/CertificateBase.java
@@ -0,0 +1,66 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * CertificateBase ::= SEQUENCE {
+ * version Uint8(3),
+ * type CertificateType,
+ * issuer IssuerIdentifier,
+ * toBeSigned ToBeSignedCertificate,
+ * signature Signature OPTIONAL
+ * }
+ * </pre>
+ */
+public class CertificateBase
+ extends ASN1Object
+{
+ private CertificateType type;
+ private byte[] version;
+
+ protected CertificateBase(ASN1Sequence seq)
+ {
+
+ }
+
+ public static CertificateBase getInstance(Object o)
+ {
+ if (o instanceof ImplicitCertificate)
+ {
+ return (ImplicitCertificate)o;
+ }
+ if (o instanceof ExplicitCertificate)
+ {
+ return (ExplicitCertificate)o;
+ }
+
+ if (o != null)
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(o);
+
+ if (seq.getObjectAt(1).equals(CertificateType.Implicit))
+ {
+ return ImplicitCertificate.getInstance(seq);
+ }
+ if (seq.getObjectAt(1).equals(CertificateType.Explicit))
+ {
+ return ExplicitCertificate.getInstance(seq);
+ }
+ throw new IllegalArgumentException("unknown certificate type");
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/CertificateType.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/CertificateType.java
new file mode 100644
index 00000000..0d7416fa
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/CertificateType.java
@@ -0,0 +1,50 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Enumerated;
+import org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * CertificateType ::= ENUMERATED {
+ * explicit,
+ * implicit,
+ * ...
+ * }
+ */
+public class CertificateType
+{
+
+ public static final CertificateType Explicit = new CertificateType(0);
+ public static final CertificateType Implicit = new CertificateType(1);
+ private final ASN1Enumerated enumerated;
+
+ protected CertificateType(int ordinal)
+ {
+ enumerated = new ASN1Enumerated(ordinal);
+ }
+
+ private CertificateType(ASN1Enumerated enumerated)
+ {
+ this.enumerated = enumerated;
+ }
+
+ public CertificateType getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+ else if (src instanceof CertificateType)
+ {
+ return (CertificateType)src;
+ }
+ else
+ {
+ return new CertificateType(ASN1Enumerated.getInstance(src));
+ }
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return enumerated;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/CircularRegion.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/CircularRegion.java
new file mode 100644
index 00000000..e5f1890d
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/CircularRegion.java
@@ -0,0 +1,41 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * CircularRegion ::= SEQUENCE {
+ * center TwoDLocation,
+ * radius Uint16
+ * }
+ * </pre>
+ */
+public class CircularRegion
+ extends ASN1Object
+{
+ private CircularRegion(ASN1Sequence seq)
+ {
+
+ }
+
+ public static CircularRegion getInstance(Object o)
+ {
+ if (o instanceof CircularRegion)
+ {
+ return (CircularRegion)o;
+ }
+ else if (o != null)
+ {
+ return new CircularRegion(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/Duration.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/Duration.java
new file mode 100644
index 00000000..e29736e7
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/Duration.java
@@ -0,0 +1,28 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Choice;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * Duration ::= CHOICE {
+ * microseconds Uint16,
+ * milliseconds Uint16,
+ * seconds Uint16,
+ * minutes Uint16,
+ * hours Uint16,
+ * sixtyHours Uint16,
+ * years Uint16
+ * }
+ * </pre>
+ */
+public class Duration
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/EncryptedData.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/EncryptedData.java
new file mode 100644
index 00000000..d739e610
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/EncryptedData.java
@@ -0,0 +1,33 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * EncryptedData ::= SEQUENCE {
+ * recipients SequenceOfRecipientInfo,
+ * ciphertext SymmetricCiphertext
+ * }
+ * </pre>
+ */
+public class EncryptedData
+{
+ private EncryptedData(ASN1Sequence seq)
+ {
+
+ }
+
+ public static EncryptedData getInstance(Object o)
+ {
+ if (o instanceof EncryptedData)
+ {
+ return (EncryptedData)o;
+ }
+ else if (o != null)
+ {
+ return new EncryptedData(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/EndEntityType.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/EndEntityType.java
new file mode 100644
index 00000000..622f75e9
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/EndEntityType.java
@@ -0,0 +1,54 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1BitString;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DERBitString;
+
+/**
+ * <pre>
+ * EndEntityType ::= BIT STRING { app(0), enrol(1) } (SIZE (8)) (ALL EXCEPT ())
+ * </pre>
+ */
+public class EndEntityType
+ extends ASN1Object
+{
+ public static final int app = (1 << 7);
+ public static final int enrol = (1 << 6);
+
+ private final ASN1BitString type;
+
+ public EndEntityType(int type)
+ {
+ if (type != app && type != enrol)
+ {
+ throw new IllegalArgumentException("value out of range");
+ }
+
+ this.type = new DERBitString(type);
+ }
+
+ private EndEntityType(DERBitString str)
+ {
+ this.type = str;
+ }
+
+ public static EndEntityType getInstance(Object src)
+ {
+ if (src instanceof EndEntityType)
+ {
+ return (EndEntityType)src;
+ }
+ else if (src != null)
+ {
+ return new EndEntityType(DERBitString.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return type;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/EtsiTs103097Module.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/EtsiTs103097Module.java
new file mode 100644
index 00000000..892afca6
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/EtsiTs103097Module.java
@@ -0,0 +1,6 @@
+package org.bouncycastle.its.asn1;
+
+public class EtsiTs103097Module
+{
+
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/ExplicitCertificate.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/ExplicitCertificate.java
new file mode 100644
index 00000000..9cd6b30b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/ExplicitCertificate.java
@@ -0,0 +1,12 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Sequence;
+
+public class ExplicitCertificate
+ extends CertificateBase
+{
+ private ExplicitCertificate(ASN1Sequence seq)
+ {
+ super(seq);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/GeographicRegion.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/GeographicRegion.java
new file mode 100644
index 00000000..67eb0f12
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/GeographicRegion.java
@@ -0,0 +1,26 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Choice;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * GeographicRegion ::= CHOICE {
+ * circularRegion CircularRegion,
+ * rectangularRegion SequenceOfRectangularRegion,
+ * polygonalRegion PolygonalRegion,
+ * identifiedRegion SequenceOfIdentifiedRegion,
+ * ...
+ * }
+ * </pre>
+ */
+public class GeographicRegion
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/GroupLinkageValue.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/GroupLinkageValue.java
new file mode 100644
index 00000000..0abbe758
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/GroupLinkageValue.java
@@ -0,0 +1,67 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * GroupLinkageValue ::= SEQUENCE {
+ * jValue OCTET STRING (SIZE(4))
+ * value OCTET STRING (SIZE(9))
+ * }
+ * </pre>
+ */
+public class GroupLinkageValue
+ extends ASN1Object
+{
+ private byte[] jValue;
+ private byte[] value;
+
+ private GroupLinkageValue(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("sequence not length 2");
+ }
+
+ jValue = Utils.octetStringFixed(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets(), 4);
+ value = Utils.octetStringFixed(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets(), 9);
+ }
+
+ public static GroupLinkageValue getInstance(Object src)
+ {
+ if (src instanceof GroupLinkageValue)
+ {
+ return (GroupLinkageValue)src;
+ }
+ else if (src != null)
+ {
+ return new GroupLinkageValue(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public byte[] getJValue()
+ {
+ return jValue;
+ }
+
+ public byte[] getValue()
+ {
+ return value;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector avec = new ASN1EncodableVector();
+ avec.add(new DEROctetString(jValue));
+ avec.add(new DEROctetString(value));
+ return new DERSequence(avec);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/HashAlgorithm.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/HashAlgorithm.java
new file mode 100644
index 00000000..666f6068
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/HashAlgorithm.java
@@ -0,0 +1,50 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Enumerated;
+import org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * CertificateType ::= ENUMERATED {
+ * explicit,
+ * implicit,
+ * ...
+ * }
+ */
+public class HashAlgorithm
+{
+
+ public static final HashAlgorithm sha256 = new HashAlgorithm(0);
+ public static final HashAlgorithm sha384 = new HashAlgorithm(1);
+ private final ASN1Enumerated enumerated;
+
+ protected HashAlgorithm(int ordinal)
+ {
+ enumerated = new ASN1Enumerated(ordinal);
+ }
+
+ private HashAlgorithm(ASN1Enumerated enumerated)
+ {
+ this.enumerated = enumerated;
+ }
+
+ public HashAlgorithm getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+ else if (src instanceof HashAlgorithm)
+ {
+ return (HashAlgorithm)src;
+ }
+ else
+ {
+ return new HashAlgorithm(ASN1Enumerated.getInstance(src));
+ }
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return enumerated;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/HashedData.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/HashedData.java
new file mode 100644
index 00000000..52bf3d61
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/HashedData.java
@@ -0,0 +1,46 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Choice;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DEROctetString;
+
+/**
+ * <pre>
+ * HashedData ::= CHOICE {
+ * sha256HashedData OCTET STRING (SIZE(32))
+ * }
+ * </pre>
+ */
+public class HashedData
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private ASN1OctetString hashData;
+
+ public HashedData(byte[] digest)
+ {
+ this.hashData = new DEROctetString(digest);
+ }
+
+ private HashedData(ASN1OctetString hashData)
+ {
+ this.hashData = hashData;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return hashData;
+ }
+
+ public ASN1OctetString getHashData()
+ {
+ return hashData;
+ }
+
+ public void setHashData(ASN1OctetString hashData)
+ {
+ this.hashData = hashData;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/HeaderInfo.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/HeaderInfo.java
new file mode 100644
index 00000000..28dd7436
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/HeaderInfo.java
@@ -0,0 +1,52 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * HeaderInfo ::= SEQUENCE {
+ * psid Psid,
+ * generationTime Time64 OPTIONAL,
+ * expiryTime Time64 OPTIONAL,
+ * generationLocation ThreeDLocation OPTIONAL,
+ * p2pcdLearningRequest HashedId3 OPTIONAL,
+ * missingCrlIdentifier MissingCrlIdentifier OPTIONAL,
+ * ...,
+ * inlineP2pcdRequest SequenceOfHashedId3 OPTIONAL,
+ * requestedCertificate Certificate OPTIONAL
+ * }
+ * </pre>
+ */
+public class HeaderInfo
+ extends ASN1Object
+{
+ private HeaderInfo(ASN1Sequence seq)
+ {
+
+ }
+
+ public static HeaderInfo getInstance(Object o)
+ {
+ if (o instanceof HeaderInfo)
+ {
+ return (HeaderInfo)o;
+ }
+ else if (o != null)
+ {
+ return new HeaderInfo(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/IValue.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/IValue.java
new file mode 100644
index 00000000..22897de5
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/IValue.java
@@ -0,0 +1,52 @@
+package org.bouncycastle.its.asn1;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.util.BigIntegers;
+
+/**
+ * <pre>
+ * Uint16 ::= INTEGER (0..65535)
+ *
+ * IValue ::= Uint16
+ * </pre>
+ */
+public class IValue
+ extends ASN1Object
+{
+ private final BigInteger value;
+
+ private IValue(ASN1Integer value)
+ {
+ int i = BigIntegers.intValueExact(value.getValue());
+
+ if (i < 0 || i > 65535)
+ {
+ throw new IllegalArgumentException("value out of range");
+ }
+
+ this.value = value.getValue();
+ }
+
+ public static IValue getInstance(Object src)
+ {
+ if (src instanceof IValue)
+ {
+ return (IValue)src;
+ }
+ else if (src != null)
+ {
+ return new IValue(ASN1Integer.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new ASN1Integer(value);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/Ieee1609Dot2Content.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/Ieee1609Dot2Content.java
new file mode 100644
index 00000000..0e88f183
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/Ieee1609Dot2Content.java
@@ -0,0 +1,46 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Choice;
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * Ieee1609Dot2Content ::= CHOICE {
+ * unsecuredData Opaque,
+ * signedData SignedData,
+ * encryptedData EncryptedData,
+ * signedCertificateRequest Opaque,
+ * ...
+ * }
+ * </pre>
+ */
+public class Ieee1609Dot2Content
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public static Ieee1609Dot2Content getInstance(Object src)
+ {
+ if (src instanceof Ieee1609Dot2Content)
+ {
+ return (Ieee1609Dot2Content)src;
+ }
+ else if (src != null)
+ {
+ // TODO: need choice processing here
+ return getInstance(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/Ieee1609Dot2Data.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/Ieee1609Dot2Data.java
new file mode 100644
index 00000000..89ed1c5c
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/Ieee1609Dot2Data.java
@@ -0,0 +1,57 @@
+package org.bouncycastle.its.asn1;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * Ieee1609Dot2Data ::= SEQUENCE {
+ * protocolVersion Uint8(3),
+ * content Ieee1609Dot2Content
+ * }
+ * </pre>
+ */
+public class Ieee1609Dot2Data
+ extends ASN1Object
+{
+ private final BigInteger protcolVersion;
+ private final Ieee1609Dot2Content content;
+
+ private Ieee1609Dot2Data(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("sequence not length 2");
+ }
+
+ protcolVersion = ASN1Integer.getInstance(seq.getObjectAt(0)).getValue();
+ content = Ieee1609Dot2Content.getInstance(seq.getObjectAt(1));
+ }
+
+ public static Ieee1609Dot2Data getInstance(Object src)
+ {
+ if (src instanceof Ieee1609Dot2Data)
+ {
+ return (Ieee1609Dot2Data)src;
+ }
+ else if (src != null)
+ {
+ return new Ieee1609Dot2Data(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/ImplicitCertificate.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/ImplicitCertificate.java
new file mode 100644
index 00000000..dfdbad1b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/ImplicitCertificate.java
@@ -0,0 +1,12 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Sequence;
+
+public class ImplicitCertificate
+ extends CertificateBase
+{
+ private ImplicitCertificate(ASN1Sequence seq)
+ {
+ super(seq);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/IssuerIdentifier.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/IssuerIdentifier.java
new file mode 100644
index 00000000..915cadc2
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/IssuerIdentifier.java
@@ -0,0 +1,26 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Choice;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * IssuerIdentifier ::= CHOICE {
+ * sha256AndDigest HashedId8,
+ * self HashAlgorithm,
+ * ...,
+ * sha384AndDigest HashedId8
+ * }
+ * </pre>
+ */
+public class IssuerIdentifier
+ extends ASN1Object
+ implements ASN1Choice
+{
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/Latitude.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/Latitude.java
new file mode 100644
index 00000000..ad4a8e42
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/Latitude.java
@@ -0,0 +1,24 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * Latitude ::= NinetyDegreeInt
+ *
+ * NinetyDegreeInt ::= INTEGER {
+ * min (-900000000),
+ * max (900000000),
+ * unknown (900000001)
+ * }
+ * </pre>
+ */
+public class Latitude
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/LinkageData.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/LinkageData.java
new file mode 100644
index 00000000..e193c9d2
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/LinkageData.java
@@ -0,0 +1,58 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * LinkageData ::= SEQUENCE {
+ * iCert IValue,
+ * linkage-value LinkageValue,
+ * group-linkage-value GroupLinkageValue OPTIONAL
+ * }
+ * </pre>
+ */
+public class LinkageData
+ extends ASN1Object
+{
+ private final IValue iCert;
+ private final LinkageValue linkageValue;
+ private final GroupLinkageValue groupLinkageValue;
+
+ private LinkageData(ASN1Sequence seq)
+ {
+ if (seq.size() != 2 && seq.size() != 3)
+ {
+ throw new IllegalArgumentException("sequence must be size 2 or 3");
+ }
+
+ this.iCert = IValue.getInstance(seq.getObjectAt(2));
+ this.linkageValue = LinkageValue.getInstance(seq.getObjectAt(2));
+ this.groupLinkageValue = GroupLinkageValue.getInstance(seq.getObjectAt(2));
+ }
+
+ public static LinkageData getInstance(Object src)
+ {
+ if (src instanceof LinkageData)
+ {
+ return (LinkageData)src;
+ }
+ else if (src != null)
+ {
+ // TODO: need choice processing here
+ return new LinkageData(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/LinkageValue.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/LinkageValue.java
new file mode 100644
index 00000000..dffe6a21
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/LinkageValue.java
@@ -0,0 +1,42 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * LinkageValue ::= OCTET STRING (SIZE(9))
+ * </pre>
+ */
+public class LinkageValue
+ extends ASN1Object
+{
+ private final byte[] value;
+
+ private LinkageValue(ASN1OctetString octs)
+ {
+ this.value = Arrays.clone(Utils.octetStringFixed(octs.getOctets(), 9));
+ }
+
+ public static LinkageValue getInstance(Object src)
+ {
+ if (src instanceof LinkageValue)
+ {
+ return (LinkageValue)src;
+ }
+ else if (src != null)
+ {
+ return new LinkageValue(ASN1OctetString.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new DEROctetString(Arrays.clone(value));
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/Longitude.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/Longitude.java
new file mode 100644
index 00000000..686f83c1
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/Longitude.java
@@ -0,0 +1,24 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * Latitude ::= OneEightyDegreeInt
+ *
+ * NinetyDegreeInt ::= INTEGER {
+ * min (-17999999999),
+ * max (1800000000),
+ * unknown (1800000001)
+ * }
+ * </pre>
+ */
+public class Longitude
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/PKRecipientInfo.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/PKRecipientInfo.java
new file mode 100644
index 00000000..54ffca1b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/PKRecipientInfo.java
@@ -0,0 +1,25 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * PKRecipientInfo ::= SEQUENCE {
+ * recipientId HashedId8,
+ * encKey EncryptedDataEncryptionKey
+ * }
+ * </pre>
+ */
+public class PKRecipientInfo
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/PolygonalRegion.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/PolygonalRegion.java
new file mode 100644
index 00000000..8b95b155
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/PolygonalRegion.java
@@ -0,0 +1,18 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * SEQUENCE SIZE(3..MAX) OF TwoDLocation
+ * </pre>
+ */
+public class PolygonalRegion
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/PsidGroupPermissions.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/PsidGroupPermissions.java
new file mode 100644
index 00000000..25196142
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/PsidGroupPermissions.java
@@ -0,0 +1,59 @@
+package org.bouncycastle.its.asn1;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * PsidGroupPermissions ::= SEQUENCE {
+ * subjectPermissions SubjectPermissions,
+ * minChainLength INTEGER DEFAULT 1,
+ * chainLengthRange INTEGER DEFAULT 0,
+ * eeType EndEntityType DEFAULT (app)
+ * }
+ * </pre>
+ */
+public class PsidGroupPermissions
+ extends ASN1Object
+{
+ private final SubjectPermissions subjectPermissions;
+ private final BigInteger minChainLength;
+ private final BigInteger chainLengthRange;
+ private final Object eeType;
+
+ private PsidGroupPermissions(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("sequence not length 2");
+ }
+
+ this.subjectPermissions = SubjectPermissions.getInstance(seq.getObjectAt(0));
+ this.minChainLength = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue();
+ this.chainLengthRange = ASN1Integer.getInstance(seq.getObjectAt(2)).getValue();
+ this.eeType = EndEntityType.getInstance(seq.getObjectAt(3));
+ }
+
+ public static PsidGroupPermissions getInstance(Object src)
+ {
+ if (src instanceof PsidGroupPermissions)
+ {
+ return (PsidGroupPermissions)src;
+ }
+ else if (src != null)
+ {
+ return new PsidGroupPermissions(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/PsidSspRange.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/PsidSspRange.java
new file mode 100644
index 00000000..d48c4099
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/PsidSspRange.java
@@ -0,0 +1,89 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * PsidSspRange ::= SEQUENCE {
+ * psid Psid,
+ * sspRange SspRange OPTIONAL
+ * }
+ */
+public class PsidSspRange
+ extends ASN1Object
+{
+ private ASN1Integer psid;
+ private SspRange sspRange;
+
+ public PsidSspRange()
+ {
+
+ }
+
+ public static PsidSspRange getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+ else if (src instanceof PsidSspRange)
+ {
+ return (PsidSspRange)src;
+ }
+ else
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(src);
+ PsidSspRange psidSspRange = new PsidSspRange();
+ if (seq.size() < 1 || seq.size() > 2)
+ {
+ throw new IllegalStateException("expected sequences with one or optionally two items");
+ }
+
+ if (seq.size() == 1)
+ {
+ psidSspRange.psid = (ASN1Integer)seq.getObjectAt(0);
+ }
+ if (seq.size() == 2)
+ {
+ psidSspRange.sspRange = SspRange.getInstance(seq.getObjectAt(1));
+ }
+ return psidSspRange;
+ }
+ }
+
+
+ public ASN1Integer getPsid()
+ {
+ return psid;
+ }
+
+ public void setPsid(ASN1Integer psid)
+ {
+ this.psid = psid;
+ }
+
+ public SspRange getSspRange()
+ {
+ return sspRange;
+ }
+
+ public void setSspRange(SspRange sspRange)
+ {
+ this.sspRange = sspRange;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector avec = new ASN1EncodableVector();
+ avec.add(psid);
+ if (sspRange != null)
+ {
+ avec.add(sspRange);
+ }
+ return new DERSequence(avec);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/RecipientInfo.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/RecipientInfo.java
new file mode 100644
index 00000000..60062c95
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/RecipientInfo.java
@@ -0,0 +1,16 @@
+package org.bouncycastle.its.asn1;
+
+/**
+ * <pre>
+ * RecipientInfo ::= CHOICE {
+ * pskRecipInfo PreSharedKeyReicpientInfo,
+ * symmRecipInfo SymmRecipientInfo,
+ * certRecipInfo PKRecipientInfo,
+ * signedDataRecipInfo PKRecipientInfo,
+ * rekRecipInfo PKRecipientInfo
+ * }
+ * </pre>
+ */
+public class RecipientInfo
+{
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/RectangularRegion.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/RectangularRegion.java
new file mode 100644
index 00000000..40949b74
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/RectangularRegion.java
@@ -0,0 +1,41 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * RectangularRegion ::= SEQUENCE {
+ * northWest TwoDLocation,
+ * southEast TwoDLocation
+ * }
+ * </pre>
+ */
+public class RectangularRegion
+ extends ASN1Object
+{
+ private RectangularRegion(ASN1Sequence seq)
+ {
+
+ }
+
+ public static RectangularRegion getInstance(Object o)
+ {
+ if (o instanceof RectangularRegion)
+ {
+ return (RectangularRegion)o;
+ }
+ else if (o != null)
+ {
+ return new RectangularRegion(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfCertificate.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfCertificate.java
new file mode 100644
index 00000000..ed7ed8f1
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfCertificate.java
@@ -0,0 +1,22 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SequenceOfCertificate ::= SEQUENCE OF Certificate
+ * </pre>
+ */
+public class SequenceOfCertificate
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfOctetString.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfOctetString.java
new file mode 100644
index 00000000..3ade2e38
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfOctetString.java
@@ -0,0 +1,68 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * SequenceOfOctetString ::= SEQUENCE (SIZE(0..MAX)) OF OCTET STRING (SIZE(0..MAX))
+ * </pre>
+ */
+public class SequenceOfOctetString
+ extends ASN1Object
+{
+ private byte[][] octetStrings;
+
+ private SequenceOfOctetString(ASN1Sequence seq)
+ {
+ this.octetStrings = toByteArrays(seq);
+ }
+
+ public static SequenceOfOctetString getInstance(Object o)
+ {
+ if (o instanceof SequenceOfOctetString)
+ {
+ return (SequenceOfOctetString)o;
+ }
+ else if (o != null)
+ {
+ return new SequenceOfOctetString(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public int size()
+ {
+ return octetStrings.length;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (int i = 0; i != octetStrings.length; i++)
+ {
+ v.add(new DEROctetString(Arrays.clone(octetStrings[i])));
+ }
+
+ return new DERSequence(v);
+ }
+
+ static byte[][] toByteArrays(ASN1Sequence seq)
+ {
+ byte[][] octetStrings = new byte[seq.size()][];
+ for (int i = 0; i != seq.size(); i++)
+ {
+ octetStrings[i] = ASN1OctetString.getInstance(seq.getObjectAt(i)).getOctets();
+ }
+
+ return octetStrings;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfPsidGroupPermissions.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfPsidGroupPermissions.java
new file mode 100644
index 00000000..3412058f
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfPsidGroupPermissions.java
@@ -0,0 +1,22 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SEQUENCE OF PsidGroupPermissions
+ * </pre>
+ */
+public class SequenceOfPsidGroupPermissions
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfRecipientInfo.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfRecipientInfo.java
new file mode 100644
index 00000000..24e67a9f
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfRecipientInfo.java
@@ -0,0 +1,22 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SequenceOfRecipientInfo ::= SEQUENCE OF RecipientInfo
+ * </pre>
+ */
+public class SequenceOfRecipientInfo
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfRectangularRegion.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfRectangularRegion.java
new file mode 100644
index 00000000..387b819b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/SequenceOfRectangularRegion.java
@@ -0,0 +1,32 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SequenceOfRectangularRegion ::= SEQUENCE OF RectangularRegion
+ * </pre>
+ */
+public class SequenceOfRectangularRegion
+ extends ASN1Object
+{
+ private final RectangularRegion[] sequence;
+
+ private SequenceOfRectangularRegion(ASN1Sequence seq)
+ {
+ this.sequence = new RectangularRegion[seq.size()];
+
+ for (int i = 0; i != seq.size(); i++)
+ {
+ sequence[i] = RectangularRegion.getInstance(seq.getObjectAt(i));
+ }
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new DERSequence(sequence);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/ServiceSpecificPermissions.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/ServiceSpecificPermissions.java
new file mode 100644
index 00000000..ec459c12
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/ServiceSpecificPermissions.java
@@ -0,0 +1,6 @@
+package org.bouncycastle.its.asn1;
+
+public class ServiceSpecificPermissions
+{
+
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/Signature.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/Signature.java
new file mode 100644
index 00000000..b03ae50d
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/Signature.java
@@ -0,0 +1,25 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Choice;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * Signature ::= CHOICE {
+ * ecdsaNistP256Signature EcdsaP256Signature,
+ * ecdsaBrainpoolP256r1Signature EcdsaP256Signature,
+ * ...
+ * ecdsaBrainpoolP384r1Signature EcdsaP384Signature
+ * }
+ * </pre>
+ */
+public class Signature
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/SignedData.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/SignedData.java
new file mode 100644
index 00000000..69fd9869
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/SignedData.java
@@ -0,0 +1,27 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SignedData ::= SEQUENCE {
+ * hashId HashAlgorithm,
+ * tbsData ToBeSignedData,
+ * signer SignerIdentifier,
+ * signature Signature
+ * }
+ * </pre>
+ */
+public class SignedData
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/SignedDataPayload.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/SignedDataPayload.java
new file mode 100644
index 00000000..6cbd9e23
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/SignedDataPayload.java
@@ -0,0 +1,26 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SignedDataPayload ::= SEQUENCE {
+ * data Ieee1609Dot2Data OPTIONAL,
+ * extDataHash HashedData OPTIONAL,
+ * ...
+ * }
+ * </pre>
+ */
+public class SignedDataPayload
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/SignerIdentifier.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/SignerIdentifier.java
new file mode 100644
index 00000000..fc598123
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/SignerIdentifier.java
@@ -0,0 +1,29 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Choice;
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SignerIdentifier ::= CHOICE {
+ * digest HashedId8,
+ * certificate SequenceOfCertificate,
+ * self NULL,
+ * ...
+ * }
+ * </pre>
+ */
+public class SignerIdentifier
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/SspRange.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/SspRange.java
new file mode 100644
index 00000000..74c13cef
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/SspRange.java
@@ -0,0 +1,140 @@
+package org.bouncycastle.its.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.asn1.ASN1Null;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERNull;
+
+/**
+ * <pre>
+ * SspRange ::= CHOICE {
+ * opaque SequenceOfOctetString,
+ * all NULL,
+ * ...
+ * bitmapSspRange BitmapSspRange
+ * }
+ * </pre>
+ */
+public class SspRange
+ extends ASN1Object
+{
+ private final boolean isAll;
+ private final SequenceOfOctetString opaque;
+ private final BitmapSspRange bitmapSspRange;
+
+ private SspRange()
+ {
+ isAll = true;
+ opaque = null;
+ bitmapSspRange = null;
+ }
+
+ private SspRange(SequenceOfOctetString seq)
+ {
+ this.isAll = false;
+ if (seq.size() != 2)
+ {
+ opaque = seq;
+ bitmapSspRange = null;
+ }
+ else
+ {
+ // ambiguous
+ opaque = SequenceOfOctetString.getInstance(seq);
+
+ BitmapSspRange bitMapRange;
+ try
+ {
+ bitMapRange = BitmapSspRange.getInstance(seq);
+ }
+ catch (IllegalArgumentException e)
+ {
+ bitMapRange = null;
+ }
+
+ bitmapSspRange = bitMapRange;
+ }
+ }
+
+ public SspRange(BitmapSspRange range)
+ {
+ this.isAll = false;
+ this.bitmapSspRange = range;
+ this.opaque = null;
+ }
+
+ public static SspRange getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+
+ if (src instanceof SspRange)
+ {
+ return (SspRange)src;
+ }
+
+ if (src instanceof ASN1Null)
+ {
+ return new SspRange();
+ }
+
+ if (src instanceof ASN1Sequence)
+ {
+ return new SspRange(SequenceOfOctetString.getInstance(src));
+ }
+
+ if (src instanceof byte[])
+ {
+ try
+ {
+ return getInstance(ASN1Primitive.fromByteArray((byte[])src));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to parse encoded general name");
+ }
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance: " + src.getClass().getName());
+ }
+
+ public boolean isAll()
+ {
+ return isAll;
+ }
+
+ public boolean maybeOpaque()
+ {
+ return opaque != null;
+ }
+
+ public BitmapSspRange getBitmapSspRange()
+ {
+ return bitmapSspRange;
+ }
+
+ public SequenceOfOctetString getOpaque()
+ {
+ return opaque;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ if (isAll)
+ {
+ return DERNull.INSTANCE;
+ }
+
+ if (bitmapSspRange != null)
+ {
+ return bitmapSspRange.toASN1Primitive();
+ }
+
+ return opaque.toASN1Primitive();
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/SubjectPermissions.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/SubjectPermissions.java
new file mode 100644
index 00000000..d5256123
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/SubjectPermissions.java
@@ -0,0 +1,39 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Choice;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * SubjectPermissions ::= CHOICE {
+ * explicit SequenceOfPsidSspRange,
+ * all NULL,
+ * ...
+ * }
+ * </pre>
+ */
+public class SubjectPermissions
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public static SubjectPermissions getInstance(Object src)
+ {
+ if (src instanceof SubjectPermissions)
+ {
+ return (SubjectPermissions)src;
+ }
+ else if (src != null)
+ {
+ // TODO: ....
+ return null;
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/SymmAlgorithm.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/SymmAlgorithm.java
new file mode 100644
index 00000000..782610e9
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/SymmAlgorithm.java
@@ -0,0 +1,53 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Enumerated;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+
+public class SymmAlgorithm
+ extends ASN1Object
+{
+ public static SymmAlgorithm aes128Ccm = new SymmAlgorithm(new ASN1Enumerated(0));
+ private ASN1Enumerated symmAlgorithm;
+
+ private SymmAlgorithm(ASN1Enumerated symmAlgorithm)
+ {
+ this.symmAlgorithm = symmAlgorithm;
+ }
+
+ public SymmAlgorithm(int ordinal)
+ {
+ this.symmAlgorithm = new ASN1Enumerated(ordinal);
+ }
+
+ public SymmAlgorithm getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+ else if (src instanceof SymmAlgorithm)
+ {
+ return (SymmAlgorithm)src;
+ }
+ else
+ {
+ return new SymmAlgorithm(ASN1Enumerated.getInstance(src));
+ }
+ }
+
+ public ASN1Enumerated getSymmAlgorithm()
+ {
+ return symmAlgorithm;
+ }
+
+ public void setSymmAlgorithm(ASN1Enumerated symmAlgorithm)
+ {
+ this.symmAlgorithm = symmAlgorithm;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return symmAlgorithm.toASN1Primitive();
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/SymmRecipientInfo.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/SymmRecipientInfo.java
new file mode 100644
index 00000000..db5e4786
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/SymmRecipientInfo.java
@@ -0,0 +1,25 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SymmRecipientInfo ::= SEQUENCE {
+ * recipientId HashedId8,
+ * encKey SymmetricCiphertext
+ * }
+ * </pre>
+ */
+public class SymmRecipientInfo
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/ToBeSignedCertificate.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/ToBeSignedCertificate.java
new file mode 100644
index 00000000..8f7c4abb
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/ToBeSignedCertificate.java
@@ -0,0 +1,54 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * ToBeSignedCertificate ::= SEQUENCE {
+ * id CertificateId,
+ * cracaId HashedId3,
+ * crlSeries CrlSeries,
+ * validityPeriod ValidityPeriod,
+ * region GeographicRegion OPTIONAL,
+ * assuranceLevel SubjectAssurance OPTIONAL,
+ * appPermissions SequenceOfPsidSep OPTIONAL,
+ * certIssuePermissions SequenceOfPsidGroupPermissions OPTIONAL,
+ * certRequestPermissions NULL OPTIONAL,
+ * encryptionKey PublicEncryptionKey OPTIONAL,
+ * verifyKeyIndicator VerificationKeyIndicator,
+ * ...
+ * }
+ * </pre>
+ */
+public class ToBeSignedCertificate
+ extends ASN1Object
+{
+// private final CertificateId certificateId;
+
+ private ToBeSignedCertificate(ASN1Sequence seq)
+ {
+ //TODO: this.certificateId = CertificateId.
+ }
+
+ public static ToBeSignedCertificate getInstance(Object src)
+ {
+ if (src instanceof ToBeSignedCertificate)
+ {
+ return (ToBeSignedCertificate)src;
+ }
+ else if (src != null)
+ {
+ // TODO: need choice processing here
+ return new ToBeSignedCertificate(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/ToBeSignedData.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/ToBeSignedData.java
new file mode 100644
index 00000000..ee178947
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/ToBeSignedData.java
@@ -0,0 +1,25 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * ToBeSignedData ::= SEQUENCE {
+ * payload SignedDataPayload,
+ * headerInfo HeaderInfo
+ * }
+ * </pre>
+ */
+public class ToBeSignedData
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/TwoDLocation.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/TwoDLocation.java
new file mode 100644
index 00000000..07fa3afc
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/TwoDLocation.java
@@ -0,0 +1,21 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * TwoDLocation ::= SEQUENCE {
+ * latitude Latitude,
+ * longitude Longitude
+ * }
+ * </pre>
+ */
+public class TwoDLocation
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/Utils.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/Utils.java
new file mode 100644
index 00000000..94aacc03
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/Utils.java
@@ -0,0 +1,36 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.util.Arrays;
+
+class Utils
+{
+ /**
+ * <pre>
+ * OCTET STRING (SIZE(n))
+ * </pre>
+ */
+ static byte[] octetStringFixed(byte[] octets, int n)
+ {
+ if (octets.length != n)
+ {
+ throw new IllegalArgumentException("octet string out of range");
+ }
+
+ return octets;
+ }
+
+ /**
+ * <pre>
+ * OCTET STRING (SIZE(1..32))
+ * </pre>
+ */
+ static byte[] octetStringFixed(byte[] octets)
+ {
+ if (octets.length < 1 || octets.length > 32)
+ {
+ throw new IllegalArgumentException("octet string out of range");
+ }
+
+ return Arrays.clone(octets);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/ValidityPeriod.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/ValidityPeriod.java
new file mode 100644
index 00000000..3401f4db
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/ValidityPeriod.java
@@ -0,0 +1,25 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * ValidityPeriod ::= SEQUENCE {
+ * start Time32,
+ * duration Duration
+ * }
+ * </pre>
+ */
+public class ValidityPeriod
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/its/asn1/VerificationKeyIndicator.java b/bcprov/src/main/java/org/bouncycastle/its/asn1/VerificationKeyIndicator.java
new file mode 100644
index 00000000..140c6a09
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/its/asn1/VerificationKeyIndicator.java
@@ -0,0 +1,24 @@
+package org.bouncycastle.its.asn1;
+
+import org.bouncycastle.asn1.ASN1Choice;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * VerificationKeyIndicator ::= CHOICE {
+ * verificationKey PublicVerificationKey,
+ * reconstructionValue EccP256CurvePoint,
+ * ...
+ * }
+ * </pre>
+ */
+public class VerificationKeyIndicator
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java
new file mode 100644
index 00000000..e30881f5
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java
@@ -0,0 +1,103 @@
+package org.bouncycastle.jcajce;
+
+import java.io.IOException;
+import java.security.PrivateKey;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * A composite private key class.
+ */
+public class CompositePrivateKey
+ implements PrivateKey
+{
+ private final List<PrivateKey> keys;
+
+ /**
+ * Create a composite key containing a single private key.
+ *
+ * @param keys the private keys the composite private key wraps.
+ */
+ public CompositePrivateKey(PrivateKey... keys)
+ {
+ if (keys == null || keys.length == 0)
+ {
+ throw new IllegalArgumentException("at least one public key must be provided");
+ }
+
+ List<PrivateKey> keyList = new ArrayList<PrivateKey>(keys.length);
+ for (int i = 0; i != keys.length; i++)
+ {
+ keyList.add(keys[i]);
+ }
+ this.keys = Collections.unmodifiableList(keyList);
+ }
+
+ /**
+ * Return a list of the component private keys making up this composite.
+ *
+ * @return an immutable list of private keys.
+ */
+ public List<PrivateKey> getPrivateKeys()
+ {
+ return keys;
+ }
+
+ public String getAlgorithm()
+ {
+ return "Composite";
+ }
+
+ public String getFormat()
+ {
+ return "PKCS#8";
+ }
+
+ public byte[] getEncoded()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (int i = 0; i != keys.size(); i++)
+ {
+ v.add(PrivateKeyInfo.getInstance(keys.get(i).getEncoded()));
+ }
+
+ try
+ {
+ return new PrivateKeyInfo(
+ new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to encode composite key: " + e.getMessage());
+ }
+ }
+
+ public int hashCode()
+ {
+ return keys.hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (o instanceof CompositePrivateKey)
+ {
+ return keys.equals(((CompositePrivateKey)o).keys);
+ }
+
+ return false;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java
new file mode 100644
index 00000000..6a1ed2c5
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java
@@ -0,0 +1,103 @@
+package org.bouncycastle.jcajce;
+
+import java.io.IOException;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+
+/**
+ * A composite key class.
+ */
+public class CompositePublicKey
+ implements PublicKey
+{
+ private final List<PublicKey> keys;
+
+ /**
+ * Create a composite key containing a single public key.
+ *
+ * @param keys the public keys the composite key wraps.
+ */
+ public CompositePublicKey(PublicKey... keys)
+ {
+ if (keys == null || keys.length == 0)
+ {
+ throw new IllegalArgumentException("at least one public key must be provided");
+ }
+
+ List<PublicKey> keyList = new ArrayList<PublicKey>(keys.length);
+ for (int i = 0; i != keys.length; i++)
+ {
+ keyList.add(keys[i]);
+ }
+ this.keys = Collections.unmodifiableList(keyList);
+ }
+
+ /**
+ * Return a list of the component private keys making up this composite.
+ *
+ * @return an immutable list of private keys.
+ */
+ public List<PublicKey> getPublicKeys()
+ {
+ return keys;
+ }
+
+ public String getAlgorithm()
+ {
+ return "Composite";
+ }
+
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ public byte[] getEncoded()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (int i = 0; i != keys.size(); i++)
+ {
+ v.add(SubjectPublicKeyInfo.getInstance(keys.get(i).getEncoded()));
+ }
+
+ try
+ {
+ return new SubjectPublicKeyInfo(
+ new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to encode composite key: " + e.getMessage());
+ }
+ }
+
+ public int hashCode()
+ {
+ return keys.hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (o instanceof CompositePublicKey)
+ {
+ return keys.equals(((CompositePublicKey)o).keys);
+ }
+
+ return false;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertRevocationChecker.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertRevocationChecker.java
new file mode 100644
index 00000000..8414a9d3
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertRevocationChecker.java
@@ -0,0 +1,15 @@
+package org.bouncycastle.jcajce;
+
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.Certificate;
+
+public interface PKIXCertRevocationChecker
+{
+ void setParameter(String name, Object value);
+
+ void initialize(PKIXCertRevocationCheckerParameters params)
+ throws CertPathValidatorException;
+
+ void check(Certificate cert)
+ throws CertPathValidatorException;
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertRevocationCheckerParameters.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertRevocationCheckerParameters.java
new file mode 100644
index 00000000..be71c126
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertRevocationCheckerParameters.java
@@ -0,0 +1,56 @@
+package org.bouncycastle.jcajce;
+
+import java.security.PublicKey;
+import java.security.cert.CertPath;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+public class PKIXCertRevocationCheckerParameters
+{
+ private final PKIXExtendedParameters paramsPKIX;
+ private final Date validDate;
+ private final CertPath certPath;
+ private final int index;
+ private final X509Certificate signingCert;
+ private final PublicKey workingPublicKey;
+
+ public PKIXCertRevocationCheckerParameters(PKIXExtendedParameters paramsPKIX, Date validDate, CertPath certPath, int index, X509Certificate signingCert, PublicKey workingPublicKey)
+ {
+ this.paramsPKIX = paramsPKIX;
+ this.validDate = validDate;
+ this.certPath = certPath;
+ this.index = index;
+ this.signingCert = signingCert;
+ this.workingPublicKey = workingPublicKey;
+ }
+
+ public PKIXExtendedParameters getParamsPKIX()
+ {
+ return paramsPKIX;
+ }
+
+ public Date getValidDate()
+ {
+ return new Date(validDate.getTime());
+ }
+
+ public CertPath getCertPath()
+ {
+ return certPath;
+ }
+
+ public int getIndex()
+ {
+ return index;
+ }
+
+ public X509Certificate getSigningCert()
+ {
+ return signingCert;
+ }
+
+ public PublicKey getWorkingPublicKey()
+ {
+ return workingPublicKey;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStoreSelector.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStoreSelector.java
index faf25d1a..acad41c7 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStoreSelector.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStoreSelector.java
@@ -53,6 +53,21 @@ public class PKIXCertStoreSelector<T extends Certificate>
this.baseSelector = baseSelector;
}
+ /**
+ * Return the specific certificate this selector is designed to match.
+ *
+ * @return a specific certificate where the selector has been configured explicitly.
+ */
+ public Certificate getCertificate()
+ {
+ if (baseSelector instanceof X509CertSelector)
+ {
+ return ((X509CertSelector)baseSelector).getCertificate();
+ }
+
+ return null;
+ }
+
public boolean match(Certificate cert)
{
return baseSelector.match(cert);
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedParameters.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedParameters.java
index 34ac2b0a..e0316f0b 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedParameters.java
@@ -22,26 +22,22 @@ public class PKIXExtendedParameters
implements CertPathParameters
{
/**
- * This is the default PKIX validity model. Actually there are two variants
- * of this: The PKIX model and the modified PKIX model. The PKIX model
- * verifies that all involved certificates must have been valid at the
- * current time. The modified PKIX model verifies that all involved
- * certificates were valid at the signing time. Both are indirectly choosen
- * with the {@link PKIXParameters#setDate(Date)} method, so this
- * methods sets the Date when <em>all</em> certificates must have been
- * valid.
+ * This is the default PKIX validity model. Actually there are two variants of this: The PKIX
+ * model and the modified PKIX model. The PKIX model verifies that all involved certificates
+ * must have been valid at the current time. The modified PKIX model verifies that all involved
+ * certificates were valid at the signing time. Both are indirectly chosen with the
+ * {@link PKIXParameters#setDate(Date)} method, so this methods sets the Date when <em>all</em>
+ * certificates must have been valid.
*/
public static final int PKIX_VALIDITY_MODEL = 0;
/**
- * This model uses the following validity model. Each certificate must have
- * been valid at the moment where is was used. That means the end
- * certificate must have been valid at the time the signature was done. The
- * CA certificate which signed the end certificate must have been valid,
- * when the end certificate was signed. The CA (or Root CA) certificate must
- * have been valid, when the CA certificate was signed and so on. So the
- * {@link PKIXParameters#setDate(Date)} method sets the time, when
- * the <em>end certificate</em> must have been valid. It is used e.g.
+ * This model uses the following validity model. Each certificate must have been valid at the
+ * moment when it was used. That means the end certificate must have been valid at the time the
+ * signature was done. The CA certificate which signed the end certificate must have been valid,
+ * when the end certificate was signed. The CA (or Root CA) certificate must have been valid
+ * when the CA certificate was signed, and so on. So the {@link PKIXParameters#setDate(Date)}
+ * method sets the time, when the <em>end certificate</em> must have been valid. It is used e.g.
* in the German signature law.
*/
public static final int CHAIN_VALIDITY_MODEL = 1;
@@ -52,6 +48,7 @@ public class PKIXExtendedParameters
public static class Builder
{
private final PKIXParameters baseParameters;
+ private final Date validityDate;
private final Date date;
private PKIXCertStoreSelector targetConstraints;
@@ -72,8 +69,8 @@ public class PKIXExtendedParameters
{
this.targetConstraints = new PKIXCertStoreSelector.Builder(constraints).build();
}
- Date checkDate = baseParameters.getDate();
- this.date = (checkDate == null) ? new Date() : checkDate;
+ this.validityDate = baseParameters.getDate();
+ this.date = (validityDate == null) ? new Date() : validityDate;
this.revocationEnabled = baseParameters.isRevocationEnabled();
this.trustAnchors = baseParameters.getTrustAnchors();
}
@@ -81,6 +78,7 @@ public class PKIXExtendedParameters
public Builder(PKIXExtendedParameters baseParameters)
{
this.baseParameters = baseParameters.baseParameters;
+ this.validityDate = baseParameters.validityDate;
this.date = baseParameters.date;
this.targetConstraints = baseParameters.targetConstraints;
this.extraCertStores = new ArrayList<PKIXCertStore>(baseParameters.extraCertStores);
@@ -196,6 +194,7 @@ public class PKIXExtendedParameters
private final PKIXParameters baseParameters;
private final PKIXCertStoreSelector targetConstraints;
+ private final Date validityDate;
private final Date date;
private final List<PKIXCertStore> extraCertStores;
private final Map<GeneralName, PKIXCertStore> namedCertificateStoreMap;
@@ -209,6 +208,7 @@ public class PKIXExtendedParameters
private PKIXExtendedParameters(Builder builder)
{
this.baseParameters = builder.baseParameters;
+ this.validityDate = builder.validityDate;
this.date = builder.date;
this.extraCertStores = Collections.unmodifiableList(builder.extraCertStores);
this.namedCertificateStoreMap = Collections.unmodifiableMap(new HashMap<GeneralName, PKIXCertStore>(builder.namedCertificateStoreMap));
@@ -242,14 +242,25 @@ public class PKIXExtendedParameters
return namedCRLStoreMap;
}
+ /**
+ * Returns the time at which to check the validity of the certification path. If {@code null},
+ * the current time is used.
+ *
+ * @return the {@code Date}, or {@code null} if not set
+ */
+ public Date getValidityDate()
+ {
+ return null == validityDate ? null : new Date(validityDate.getTime());
+ }
+
+ /**
+ * @deprecated Use 'getValidityDate' instead (which can return null).
+ */
public Date getDate()
{
return new Date(date.getTime());
}
-
-
-
/**
* Defaults to <code>false</code>.
*
@@ -260,8 +271,6 @@ public class PKIXExtendedParameters
return useDeltas;
}
-
-
/**
* @return Returns the validity model.
* @see #CHAIN_VALIDITY_MODEL
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/interfaces/BCX509Certificate.java b/bcprov/src/main/java/org/bouncycastle/jcajce/interfaces/BCX509Certificate.java
new file mode 100644
index 00000000..5cb63d6c
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/interfaces/BCX509Certificate.java
@@ -0,0 +1,31 @@
+package org.bouncycastle.jcajce.interfaces;
+
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.TBSCertificate;
+
+/**
+ * Interface exposing some additional methods on a BC native certificate object.
+ */
+public interface BCX509Certificate
+{
+ /**
+ * Return the certificate issuer as an X500Name.
+ *
+ * @return the issuer.
+ */
+ X500Name getIssuerX500Name();
+
+ /**
+ * Return the ASN.1 class representing the TBSCertificate for this certificate.
+ *
+ * @return the issuer.
+ */
+ TBSCertificate getTBSCertificateNative();
+
+ /**
+ * Return the certificate subject as an X500Name.
+ *
+ * @return the issuer.
+ */
+ X500Name getSubjectX500Name();
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java
index b79b0c51..f900e90a 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java
@@ -39,12 +39,12 @@ public class EC
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("AlgorithmParameters.EC", PREFIX + "AlgorithmParametersSpi");
provider.addAttributes("KeyAgreement.ECDH", generalEcAttributes);
provider.addAlgorithm("KeyAgreement.ECDH", PREFIX + "KeyAgreementSpi$DH");
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAttributes("KeyAgreement.ECDHC", generalEcAttributes);
provider.addAlgorithm("KeyAgreement.ECDHC", PREFIX + "KeyAgreementSpi$DHC");
provider.addAttributes("KeyAgreement.ECCDH", generalEcAttributes);
@@ -114,13 +114,9 @@ public class EC
provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_RIPEMD160, PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF");
provider.addAlgorithm("KeyAgreement.ECKAEGWITHRIPEMD160KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF");
- */
- // END Android-removed: Unsupported algorithms
registerOid(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC", new KeyFactorySpi.EC());
- // BEGIN Android-removed: Unsupported algorithms
- /*
registerOid(provider, X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC());
registerOid(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV());
@@ -175,11 +171,8 @@ public class EC
provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA384KDFAndSharedInfo");
provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA512KDFAndSharedInfo");
- */
- // END Android-removed: Unsupported algorithms
registerOid(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC());
- // BEGIN Android-removed: Unsupported algorithms
- /*
+
registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "EC");
registerOid(provider, SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV());
@@ -197,21 +190,13 @@ public class EC
provider.addAlgorithm("KeyFactory.ECMQV", PREFIX + "KeyFactorySpi$ECMQV");
provider.addAlgorithm("KeyPairGenerator.ECMQV", PREFIX + "KeyPairGeneratorSpi$ECMQV");
}
- */
- // END Android-removed: Unsupported algorithms
-
+
provider.addAlgorithm("KeyFactory.EC", PREFIX + "KeyFactorySpi$EC");
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAlgorithm("KeyFactory.ECDSA", PREFIX + "KeyFactorySpi$ECDSA");
provider.addAlgorithm("KeyFactory.ECDH", PREFIX + "KeyFactorySpi$ECDH");
provider.addAlgorithm("KeyFactory.ECDHC", PREFIX + "KeyFactorySpi$ECDHC");
- */
- // END Android-removed: Unsupported algorithms
-
+
provider.addAlgorithm("KeyPairGenerator.EC", PREFIX + "KeyPairGeneratorSpi$EC");
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAlgorithm("KeyPairGenerator.ECDSA", PREFIX + "KeyPairGeneratorSpi$ECDSA");
provider.addAlgorithm("KeyPairGenerator.ECDH", PREFIX + "KeyPairGeneratorSpi$ECDH");
provider.addAlgorithm("KeyPairGenerator.ECDHWITHSHA1KDF", PREFIX + "KeyPairGeneratorSpi$ECDH");
@@ -226,10 +211,7 @@ public class EC
provider.addAlgorithm("Cipher.ECIESWITHDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC");
provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA");
- */
- // END Android-removed: Unsupported algorithms
- // BEGIN Android-changed: Change primary ID from ECDSA to SHA1withECDSA
provider.addAlgorithm("Signature.SHA1withECDSA", PREFIX + "SignatureSpi$ecDSA");
provider.addAlgorithm("Signature.NONEwithECDSA", PREFIX + "SignatureSpi$ecDSAnone");
@@ -240,9 +222,6 @@ public class EC
provider.addAlgorithm("Alg.Alias.Signature.SHA1WithECDSA", "SHA1withECDSA");
provider.addAlgorithm("Alg.Alias.Signature.ECDSAWithSHA1", "SHA1withECDSA");
provider.addAlgorithm("Alg.Alias.Signature.1.2.840.10045.4.1", "SHA1withECDSA");
- // END Android-changed: Change primary ID from ECDSA to SHA1withECDSA
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAlgorithm("Alg.Alias.Signature." + TeleTrusTObjectIdentifiers.ecSignWithSha1, "ECDSA");
provider.addAlgorithm("Signature.ECDDSA", PREFIX + "SignatureSpi$ecDetDSA");
@@ -262,15 +241,11 @@ public class EC
provider.addAlgorithm("Alg.Alias.Signature.SHA256WITHDETECDSA", "SHA256WITHECDDSA");
provider.addAlgorithm("Alg.Alias.Signature.SHA384WITHDETECDSA", "SHA384WITHECDDSA");
provider.addAlgorithm("Alg.Alias.Signature.SHA512WITHDETECDSA", "SHA512WITHECDDSA");
- */
- // END Android-removed: Unsupported algorithms
addSignatureAlgorithm(provider, "SHA224", "ECDSA", PREFIX + "SignatureSpi$ecDSA224", X9ObjectIdentifiers.ecdsa_with_SHA224);
addSignatureAlgorithm(provider, "SHA256", "ECDSA", PREFIX + "SignatureSpi$ecDSA256", X9ObjectIdentifiers.ecdsa_with_SHA256);
addSignatureAlgorithm(provider, "SHA384", "ECDSA", PREFIX + "SignatureSpi$ecDSA384", X9ObjectIdentifiers.ecdsa_with_SHA384);
addSignatureAlgorithm(provider, "SHA512", "ECDSA", PREFIX + "SignatureSpi$ecDSA512", X9ObjectIdentifiers.ecdsa_with_SHA512);
- // BEGIN Android-removed: Unsupported algorithms
- /*
addSignatureAlgorithm(provider, "SHA3-224", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_224", NISTObjectIdentifiers.id_ecdsa_with_sha3_224);
addSignatureAlgorithm(provider, "SHA3-256", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_256", NISTObjectIdentifiers.id_ecdsa_with_sha3_256);
addSignatureAlgorithm(provider, "SHA3-384", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_384", NISTObjectIdentifiers.id_ecdsa_with_sha3_384);
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
index 4eb01a34..b9afff87 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
@@ -36,7 +36,8 @@ public class RSA
public void configure(ConfigurableProvider provider)
{
- provider.addAlgorithm("AlgorithmParameters.OAEP", PREFIX + "AlgorithmParametersSpi$OAEP");
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("AlgorithmParameters.OAEP", PREFIX + "AlgorithmParametersSpi$OAEP");
provider.addAlgorithm("AlgorithmParameters.PSS", PREFIX + "AlgorithmParametersSpi$PSS");
// BEGIN Android-removed: Unsupported algorithms
@@ -95,6 +96,11 @@ public class RSA
provider.addAlgorithm("KeyFactory.RSA", PREFIX + "KeyFactorySpi");
provider.addAlgorithm("KeyPairGenerator.RSA", PREFIX + "KeyPairGeneratorSpi");
+ // BEGIN Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("KeyFactory.RSASSA-PSS", PREFIX + "KeyFactorySpi");
+ // provider.addAlgorithm("KeyPairGenerator.RSASSA-PSS", PREFIX + "KeyPairGeneratorSpi$PSS");
+ // END Android-removed: Unsupported algorithms
+
AsymmetricKeyInfoConverter keyFact = new KeyFactorySpi();
registerOid(provider, PKCSObjectIdentifiers.rsaEncryption, "RSA", keyFact);
@@ -145,43 +151,32 @@ public class RSA
{
addDigestSignature(provider, "MD4", PREFIX + "DigestSignatureSpi$MD4", PKCSObjectIdentifiers.md4WithRSAEncryption);
}
- */
- // END Android-removed: Unsupported algorithms
if (provider.hasAlgorithm("MessageDigest", "MD5"))
{
addDigestSignature(provider, "MD5", PREFIX + "DigestSignatureSpi$MD5", PKCSObjectIdentifiers.md5WithRSAEncryption);
- // Android-removed: Unsupported algorithms
- // addISO9796Signature(provider, "MD5", PREFIX + "ISOSignatureSpi$MD5WithRSAEncryption");
+ addISO9796Signature(provider, "MD5", PREFIX + "ISOSignatureSpi$MD5WithRSAEncryption");
}
if (provider.hasAlgorithm("MessageDigest", "SHA1"))
{
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1withRSA/PSS", "PSS");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1WITHRSAANDMGF1", "PSS");
addPSSSignature(provider, "SHA1", PREFIX + "PSSSignatureSpi$SHA1withRSA");
- */
- // END Android-removed: Unsupported algorithms
addDigestSignature(provider, "SHA1", PREFIX + "DigestSignatureSpi$SHA1", PKCSObjectIdentifiers.sha1WithRSAEncryption);
- // Android-removed: Unsupported algorithms
- // addISO9796Signature(provider, "SHA1", PREFIX + "ISOSignatureSpi$SHA1WithRSAEncryption");
+ addISO9796Signature(provider, "SHA1", PREFIX + "ISOSignatureSpi$SHA1WithRSAEncryption");
provider.addAlgorithm("Alg.Alias.Signature." + OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
provider.addAlgorithm("Alg.Alias.Signature.OID." + OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
- // BEGIN Android-removed: Unsupported algorithms
- // addX931Signature(provider, "SHA1", PREFIX + "X931SignatureSpi$SHA1WithRSAEncryption");
+ addX931Signature(provider, "SHA1", PREFIX + "X931SignatureSpi$SHA1WithRSAEncryption");
}
addDigestSignature(provider, "SHA224", PREFIX + "DigestSignatureSpi$SHA224", PKCSObjectIdentifiers.sha224WithRSAEncryption);
addDigestSignature(provider, "SHA256", PREFIX + "DigestSignatureSpi$SHA256", PKCSObjectIdentifiers.sha256WithRSAEncryption);
addDigestSignature(provider, "SHA384", PREFIX + "DigestSignatureSpi$SHA384", PKCSObjectIdentifiers.sha384WithRSAEncryption);
addDigestSignature(provider, "SHA512", PREFIX + "DigestSignatureSpi$SHA512", PKCSObjectIdentifiers.sha512WithRSAEncryption);
- // BEGIN Android-removed: Unsupported algorithms
- /*
addDigestSignature(provider, "SHA512(224)", PREFIX + "DigestSignatureSpi$SHA512_224", PKCSObjectIdentifiers.sha512_224WithRSAEncryption);
addDigestSignature(provider, "SHA512(256)", PREFIX + "DigestSignatureSpi$SHA512_256", PKCSObjectIdentifiers.sha512_256WithRSAEncryption);
@@ -289,6 +284,10 @@ public class RSA
provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/PSS", digest + "WITHRSAANDMGF1");
provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSAandMGF1", digest + "WITHRSAANDMGF1");
provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSAAndMGF1", digest + "WITHRSAANDMGF1");
+ // BEGIN Android-removed: unsupported algorithms
+ // provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSASSA-PSS", digest + "WITHRSAANDMGF1");
+ // provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSASSA-PSS", digest + "WITHRSAANDMGF1");
+ // provider.addAlgorithm("Alg.Alias.Signature." + digest + "WITHRSASSA-PSS", digest + "WITHRSAANDMGF1");
provider.addAlgorithm("Signature." + digest + "WITHRSAANDMGF1", className);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/X509.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/X509.java
index 12a9f6fd..05964d04 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/X509.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/X509.java
@@ -19,15 +19,17 @@ public class X509
public void configure(ConfigurableProvider provider)
{
// BEGIN Android-removed: Unsupported algorithms
- // provider.addAlgorithm("KeyFactory.X.509", "org.bouncycastle.jcajce.provider.asymmetric.x509.KeyFactory");
- // provider.addAlgorithm("Alg.Alias.KeyFactory.X509", "X.509");
- // END Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("KeyFactory.X.509", "org.bouncycastle.jcajce.provider.asymmetric.x509.KeyFactory");
+ provider.addAlgorithm("Alg.Alias.KeyFactory.X509", "X.509");
//
// certificate factories.
//
provider.addAlgorithm("CertificateFactory.X.509", "org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory");
provider.addAlgorithm("Alg.Alias.CertificateFactory.X509", "X.509");
+ */
+ // END Android-removed: Unsupported algorithms
}
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java
index b1ef7e5e..8fb8da78 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java
@@ -52,14 +52,7 @@ public class AlgorithmParameterGeneratorSpi
int certainty = PrimeCertaintyCalculator.getDefaultCertainty(strength);
- if (random != null)
- {
- pGen.init(strength, certainty, random);
- }
- else
- {
- pGen.init(strength, certainty, CryptoServicesRegistrar.getSecureRandom());
- }
+ pGen.init(strength, certainty, CryptoServicesRegistrar.getSecureRandom(random));
DHParameters p = pGen.generateParameters();
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java
index 21182ef1..f8b4bf5c 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java
@@ -27,6 +27,7 @@ import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
import org.bouncycastle.crypto.params.DHValidationParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
import org.bouncycastle.jcajce.spec.DHDomainParameterSpec;
+import org.bouncycastle.jcajce.spec.DHExtendedPrivateKeySpec;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
@@ -58,7 +59,14 @@ public class BCDHPrivateKey
DHPrivateKeySpec spec)
{
this.x = spec.getX();
- this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
+ if (spec instanceof DHExtendedPrivateKeySpec)
+ {
+ this.dhSpec = ((DHExtendedPrivateKeySpec)spec).getParams();
+ }
+ else
+ {
+ this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
+ }
}
public BCDHPrivateKey(
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java
index 039b8d3d..e9d3d1a5 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java
@@ -24,6 +24,7 @@ import org.bouncycastle.crypto.params.DHPublicKeyParameters;
import org.bouncycastle.crypto.params.DHValidationParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
import org.bouncycastle.jcajce.spec.DHDomainParameterSpec;
+import org.bouncycastle.jcajce.spec.DHExtendedPublicKeySpec;
public class BCDHPublicKey
implements DHPublicKey
@@ -40,8 +41,25 @@ public class BCDHPublicKey
DHPublicKeySpec spec)
{
this.y = spec.getY();
- this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
- this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(spec.getP(), spec.getG()));
+ if (spec instanceof DHExtendedPublicKeySpec)
+ {
+ this.dhSpec = ((DHExtendedPublicKeySpec)spec).getParams();
+ }
+ else
+ {
+ this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
+
+ }
+
+ if (dhSpec instanceof DHDomainParameterSpec)
+ {
+ DHDomainParameterSpec dhSp = (DHDomainParameterSpec)dhSpec;
+ this.dhPublicKey = new DHPublicKeyParameters(y, dhSp.getDomainParameters());
+ }
+ else
+ {
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(spec.getP(), spec.getG()));
+ }
}
BCDHPublicKey(
@@ -49,7 +67,15 @@ public class BCDHPublicKey
{
this.y = key.getY();
this.dhSpec = key.getParams();
- this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
+ if (dhSpec instanceof DHDomainParameterSpec)
+ {
+ DHDomainParameterSpec dhSp = (DHDomainParameterSpec)dhSpec;
+ this.dhPublicKey = new DHPublicKeyParameters(y, dhSp.getDomainParameters());
+ }
+ else
+ {
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
+ }
}
BCDHPublicKey(
@@ -105,12 +131,14 @@ public class BCDHPublicKey
if (params.getL() != null)
{
this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue());
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG(), null, dhSpec.getL()));
}
else
{
this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
}
- this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
+
}
else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java
index 601fddd6..0aa96915 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java
@@ -51,7 +51,7 @@ public class BCDSAPublicKey
DSAPublicKeyParameters params)
{
this.y = params.getY();
- if (params != null)
+ if (params.getParameters() != null)
{
this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG());
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
index 8d1653f1..b50c49ef 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
@@ -1,6 +1,7 @@
package org.bouncycastle.jcajce.provider.asymmetric.dsa;
import java.math.BigInteger;
+import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.PublicKey;
@@ -140,6 +141,11 @@ public class DSASigner
return signer.verifySignature(hash, sig[0], sig[1]);
}
+ protected AlgorithmParameters engineGetParameters()
+ {
+ return null;
+ }
+
protected void engineSetParameter(
AlgorithmParameterSpec params)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java
index 10b160f4..72a8bf9a 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java
@@ -77,6 +77,30 @@ public class KeyFactorySpi
throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
}
}
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPublicKeySpec.class) && key instanceof java.security.interfaces.DSAPublicKey)
+ {
+ DSAPublicKey k = (DSAPublicKey)key;
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPublicKeySpec(OpenSSHPublicKeyUtil.encodePublicKey(new DSAPublicKeyParameters(k.getY(), new DSAParameters(k.getParams().getP(), k.getParams().getQ(), k.getParams().getG()))));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec.class) && key instanceof java.security.interfaces.DSAPrivateKey)
+ {
+ DSAPrivateKey k = (DSAPrivateKey)key;
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec(OpenSSHPrivateKeyUtil.encodePrivateKey(new DSAPrivateKeyParameters(k.getX(), new DSAParameters(k.getParams().getP(), k.getParams().getQ(), k.getParams().getG()))));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
*/
// END Android-removed: Unsupported algorithms
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
index 7851b256..7d84ecb6 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
@@ -12,6 +12,7 @@ import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X962Parameters;
import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.asn1.x9.X9ECPoint;
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
@@ -123,7 +124,7 @@ public class AlgorithmParametersSpi
}
else
{
- ASN1ObjectIdentifier namedCurveOid = ECUtil.getNamedCurveOid(EC5Util.convertSpec(ecParameterSpec, false));
+ ASN1ObjectIdentifier namedCurveOid = ECUtil.getNamedCurveOid(EC5Util.convertSpec(ecParameterSpec));
if (namedCurveOid != null)
{
@@ -159,10 +160,10 @@ public class AlgorithmParametersSpi
}
else
{
- org.bouncycastle.jce.spec.ECParameterSpec ecSpec = EC5Util.convertSpec(ecParameterSpec, false);
+ org.bouncycastle.jce.spec.ECParameterSpec ecSpec = EC5Util.convertSpec(ecParameterSpec);
X9ECParameters ecP = new X9ECParameters(
ecSpec.getCurve(),
- ecSpec.getG(),
+ new X9ECPoint(ecSpec.getG(), false),
ecSpec.getN(),
ecSpec.getH(),
ecSpec.getSeed());
@@ -179,6 +180,6 @@ public class AlgorithmParametersSpi
@Override
protected String engineToString()
{
- return "EC AlgorithmParameters ";
+ return "EC Parameters";
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
index 714f9100..e1d737a3 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
@@ -6,7 +6,6 @@ import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.interfaces.ECPrivateKey;
import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.EllipticCurve;
import java.util.Enumeration;
@@ -298,14 +297,14 @@ public class BCECPrivateKey
return null;
}
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec()
{
if (ecSpec != null)
{
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
return configuration.getEcImplicitlyCa();
@@ -366,11 +365,6 @@ public class BCECPrivateKey
return ECUtil.privateKeyToString("EC", d, engineGetSpec());
}
- private org.bouncycastle.math.ec.ECPoint calculateQ(org.bouncycastle.jce.spec.ECParameterSpec spec)
- {
- return spec.getG().multiply(d).normalize();
- }
-
private DERBitString getPublicKeyDetails(BCECPublicKey pub)
{
try
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
index 9236787c..cad65c42 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
@@ -9,7 +9,6 @@ import java.security.spec.ECPoint;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.EllipticCurve;
-import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.DERBitString;
@@ -29,6 +28,7 @@ import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import org.bouncycastle.jce.interfaces.ECPointEncoder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.util.Properties;
public class BCECPublicKey
implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder
@@ -60,7 +60,7 @@ public class BCECPublicKey
{
this.algorithm = algorithm;
this.ecSpec = spec.getParams();
- this.ecPublicKey = new ECPublicKeyParameters(EC5Util.convertPoint(ecSpec, spec.getW(), false), EC5Util.getDomainParameters(configuration, spec.getParams()));
+ this.ecPublicKey = new ECPublicKeyParameters(EC5Util.convertPoint(ecSpec, spec.getW()), EC5Util.getDomainParameters(configuration, spec.getParams()));
this.configuration = configuration;
}
@@ -164,7 +164,8 @@ public class BCECPublicKey
{
this.algorithm = key.getAlgorithm();
this.ecSpec = key.getParams();
- this.ecPublicKey = new ECPublicKeyParameters(EC5Util.convertPoint(this.ecSpec, key.getW(), false), EC5Util.getDomainParameters(configuration, key.getParams()));
+ this.ecPublicKey = new ECPublicKeyParameters(EC5Util.convertPoint(this.ecSpec, key.getW()), EC5Util.getDomainParameters(configuration, key.getParams()));
+ this.configuration = configuration;
}
BCECPublicKey(
@@ -234,13 +235,16 @@ public class BCECPublicKey
public byte[] getEncoded()
{
- ASN1Encodable params = ECUtils.getDomainParametersFromName(ecSpec, withCompression);
- ASN1OctetString p = ASN1OctetString.getInstance(new X9ECPoint(ecPublicKey.getQ(), withCompression).toASN1Primitive());
+ boolean compress = withCompression || Properties.isOverrideSet("org.bouncycastle.ec.enable_pc");
- // stored curve is null if ImplicitlyCa
- SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets());
+ AlgorithmIdentifier algId = new AlgorithmIdentifier(
+ X9ObjectIdentifiers.id_ecPublicKey,
+ ECUtils.getDomainParametersFromName(ecSpec, compress));
- return KeyUtil.getEncodedSubjectPublicKeyInfo(info);
+ byte[] pubKeyOctets = ecPublicKey.getQ().getEncoded(compress);
+
+ // stored curve is null if ImplicitlyCa
+ return KeyUtil.getEncodedSubjectPublicKeyInfo(algId, pubKeyOctets);
}
public ECParameterSpec getParams()
@@ -255,7 +259,7 @@ public class BCECPublicKey
return null;
}
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
public ECPoint getW()
@@ -284,7 +288,7 @@ public class BCECPublicKey
{
if (ecSpec != null)
{
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
return configuration.getEcImplicitlyCa();
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
index 8a5c834c..4070b1c0 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
@@ -10,6 +10,7 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.x9.X962Parameters;
import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.asn1.x9.X9ECPoint;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
@@ -83,7 +84,7 @@ class ECUtils
X9ECParameters ecP = new X9ECParameters(
curve,
- EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression),
+ new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), withCompression),
ecSpec.getOrder(),
BigInteger.valueOf(ecSpec.getCofactor()),
ecSpec.getCurve().getSeed());
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
index 19b538a8..9a5f0ed3 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
@@ -24,6 +24,8 @@ import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+import org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec;
+import org.bouncycastle.jcajce.spec.OpenSSHPublicKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
@@ -68,7 +70,7 @@ public class KeyFactorySpi
Class spec)
throws InvalidKeySpecException
{
- if (spec.isAssignableFrom(java.security.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey)
+ if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(java.security.spec.ECPublicKeySpec.class)) && key instanceof ECPublicKey)
{
ECPublicKey k = (ECPublicKey)key;
if (k.getParams() != null)
@@ -82,7 +84,7 @@ public class KeyFactorySpi
return new java.security.spec.ECPublicKeySpec(k.getW(), EC5Util.convertSpec(EC5Util.convertCurve(implicitSpec.getCurve(), implicitSpec.getSeed()), implicitSpec));
}
}
- else if (spec.isAssignableFrom(java.security.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey)
+ else if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(java.security.spec.ECPrivateKeySpec.class)) && key instanceof ECPrivateKey)
{
ECPrivateKey k = (ECPrivateKey)key;
@@ -102,13 +104,13 @@ public class KeyFactorySpi
ECPublicKey k = (ECPublicKey)key;
if (k.getParams() != null)
{
- return new org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), EC5Util.convertSpec(k.getParams(), false));
+ return new org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW()), EC5Util.convertSpec(k.getParams()));
}
else
{
ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
- return new org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), implicitSpec);
+ return new org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW()), implicitSpec);
}
}
else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey)
@@ -117,7 +119,7 @@ public class KeyFactorySpi
if (k.getParams() != null)
{
- return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(k.getParams(), false));
+ return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(k.getParams()));
}
else
{
@@ -169,6 +171,46 @@ public class KeyFactorySpi
}
}
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPublicKeySpec.class) && key instanceof ECPublicKey)
+ {
+ if (key instanceof BCECPublicKey)
+ {
+ BCECPublicKey bcPk = (BCECPublicKey)key;
+ ECParameterSpec sc = bcPk.getParameters();
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPublicKeySpec(
+ OpenSSHPublicKeyUtil.encodePublicKey(
+ new ECPublicKeyParameters(bcPk.getQ(), new ECDomainParameters(sc.getCurve(), sc.getG(), sc.getN(), sc.getH(), sc.getSeed()))));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid key type: " + key.getClass().getName());
+ }
+ }
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec.class) && key instanceof ECPrivateKey)
+ {
+ if (key instanceof BCECPrivateKey)
+ {
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec(PrivateKeyInfo.getInstance(key.getEncoded()).parsePrivateKey().toASN1Primitive().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("cannot encoded key: " + e.getMessage());
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid key type: " + key.getClass().getName());
+ }
+ }
*/
// END Android-removed: Unsupported algorithms
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
index 17a2e1d6..66366626 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
@@ -21,6 +21,7 @@ import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec;
@@ -153,7 +154,16 @@ public abstract class KeyPairGeneratorSpi
}
else
{
- throw new InvalidAlgorithmParameterException("parameter object not a ECParameterSpec");
+ String name = ECUtil.getNameFrom(params);
+
+ if (name != null)
+ {
+ initializeNamedCurve(name, random);
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("invalid parameterSpec: " + params);
+ }
}
engine.init(param);
@@ -201,8 +211,20 @@ public abstract class KeyPairGeneratorSpi
protected ECKeyGenerationParameters createKeyGenParamsJCE(java.security.spec.ECParameterSpec p, SecureRandom r)
{
+ if (p instanceof ECNamedCurveSpec)
+ {
+ X9ECParameters x9P = ECUtils.getDomainParametersFromName(((ECNamedCurveSpec)p).getName());
+
+ if (x9P != null)
+ {
+ ECDomainParameters dp = new ECDomainParameters(x9P.getCurve(), x9P.getG(), x9P.getN(), x9P.getH());
+
+ return new ECKeyGenerationParameters(dp, r);
+ }
+ }
+
ECCurve curve = EC5Util.convertCurve(p.getCurve());
- ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false);
+ ECPoint g = EC5Util.convertPoint(curve, p.getGenerator());
BigInteger n = p.getOrder();
BigInteger h = BigInteger.valueOf(p.getCofactor());
ECDomainParameters dp = new ECDomainParameters(curve, g, n, h);
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
index 271f774c..9635e188 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
@@ -1,5 +1,6 @@
package org.bouncycastle.jcajce.provider.asymmetric.ec;
+import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.PublicKey;
@@ -61,6 +62,11 @@ public class SignatureSpi
}
}
+ protected AlgorithmParameters engineGetParameters()
+ {
+ return null;
+ }
+
static public class ecDSA
extends SignatureSpi
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java
index 0ac494fb..477c3f35 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java
@@ -1,17 +1,18 @@
package org.bouncycastle.jcajce.provider.asymmetric.rsa;
import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.spec.RSAPrivateCrtKeySpec;
-import org.bouncycastle.asn1.DERNull;
-import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.pkcs.RSAPrivateKey;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
+import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
import org.bouncycastle.util.Strings;
/**
@@ -48,6 +49,20 @@ public class BCRSAPrivateCrtKey
this.crtCoefficient = key.getQInv();
}
+ BCRSAPrivateCrtKey(
+ AlgorithmIdentifier algorithmIdentifier,
+ RSAPrivateCrtKeyParameters key)
+ {
+ super(algorithmIdentifier, key);
+
+ this.publicExponent = key.getPublicExponent();
+ this.primeP = key.getP();
+ this.primeQ = key.getQ();
+ this.primeExponentP = key.getDP();
+ this.primeExponentQ = key.getDQ();
+ this.crtCoefficient = key.getQInv();
+ }
+
/**
* construct a private key from an RSAPrivateCrtKeySpec
*
@@ -56,6 +71,10 @@ public class BCRSAPrivateCrtKey
BCRSAPrivateCrtKey(
RSAPrivateCrtKeySpec spec)
{
+ super(new RSAPrivateCrtKeyParameters(spec.getModulus(),
+ spec.getPublicExponent(), spec.getPrivateExponent(),
+ spec.getPrimeP(), spec.getPrimeQ(), spec.getPrimeExponentP(), spec.getPrimeExponentQ(), spec.getCrtCoefficient()));
+
this.modulus = spec.getModulus();
this.publicExponent = spec.getPublicExponent();
this.privateExponent = spec.getPrivateExponent();
@@ -74,6 +93,10 @@ public class BCRSAPrivateCrtKey
BCRSAPrivateCrtKey(
RSAPrivateCrtKey key)
{
+ super(new RSAPrivateCrtKeyParameters(key.getModulus(),
+ key.getPublicExponent(), key.getPrivateExponent(),
+ key.getPrimeP(), key.getPrimeQ(), key.getPrimeExponentP(), key.getPrimeExponentQ(), key.getCrtCoefficient()));
+
this.modulus = key.getModulus();
this.publicExponent = key.getPublicExponent();
this.privateExponent = key.getPrivateExponent();
@@ -91,7 +114,7 @@ public class BCRSAPrivateCrtKey
PrivateKeyInfo info)
throws IOException
{
- this(RSAPrivateKey.getInstance(info.parsePrivateKey()));
+ this(info.getPrivateKeyAlgorithm(), RSAPrivateKey.getInstance(info.parsePrivateKey()));
}
/**
@@ -100,6 +123,17 @@ public class BCRSAPrivateCrtKey
BCRSAPrivateCrtKey(
RSAPrivateKey key)
{
+ this(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER, key);
+ }
+
+ BCRSAPrivateCrtKey(
+ AlgorithmIdentifier algorithmIdentifier,
+ RSAPrivateKey key)
+ {
+ super(algorithmIdentifier, new RSAPrivateCrtKeyParameters(key.getModulus(),
+ key.getPublicExponent(), key.getPrivateExponent(),
+ key.getPrime1(), key.getPrime2(), key.getExponent1(), key.getExponent2(), key.getCoefficient()));
+
this.modulus = key.getModulus();
this.publicExponent = key.getPublicExponent();
this.privateExponent = key.getPrivateExponent();
@@ -128,7 +162,7 @@ public class BCRSAPrivateCrtKey
*/
public byte[] getEncoded()
{
- return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPrivateKey(getModulus(), getPublicExponent(), getPrivateExponent(), getPrimeP(), getPrimeQ(), getPrimeExponentP(), getPrimeExponentQ(), getCrtCoefficient()));
+ return KeyUtil.getEncodedPrivateKeyInfo(algorithmIdentifier, new RSAPrivateKey(getModulus(), getPublicExponent(), getPrivateExponent(), getPrimeP(), getPrimeQ(), getPrimeExponentP(), getPrimeExponentQ(), getCrtCoefficient()));
}
/**
@@ -222,6 +256,26 @@ public class BCRSAPrivateCrtKey
&& this.getCrtCoefficient().equals(key.getCrtCoefficient());
}
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
+ this.rsaPrivateKey = new RSAPrivateCrtKeyParameters(this.getModulus(),
+ this.getPublicExponent(), this.getPrivateExponent(),
+ this.getPrimeP(), this.getPrimeQ(),
+ this.getPrimeExponentP(), this.getPrimeExponentQ(), this.getCrtCoefficient());
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+ }
+
public String toString()
{
StringBuffer buf = new StringBuffer();
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java
index f529d9b8..f92a430a 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java
@@ -10,7 +10,6 @@ import java.util.Enumeration;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.crypto.params.RSAKeyParameters;
@@ -28,18 +27,30 @@ public class BCRSAPrivateKey
protected BigInteger modulus;
protected BigInteger privateExponent;
+ private byte[] algorithmIdentifierEnc = getEncoding(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER);
- private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
+ protected transient AlgorithmIdentifier algorithmIdentifier = BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER;
+ protected transient RSAKeyParameters rsaPrivateKey;
+ protected transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
- protected BCRSAPrivateKey()
+ BCRSAPrivateKey(
+ RSAKeyParameters key)
{
+ this.modulus = key.getModulus();
+ this.privateExponent = key.getExponent();
+ this.rsaPrivateKey = key;
}
BCRSAPrivateKey(
+ AlgorithmIdentifier algID,
RSAKeyParameters key)
{
+ this.algorithmIdentifier = algID;
+ this.algorithmIdentifierEnc = getEncoding(algID);
+
this.modulus = key.getModulus();
this.privateExponent = key.getExponent();
+ this.rsaPrivateKey = key;
}
BCRSAPrivateKey(
@@ -47,6 +58,7 @@ public class BCRSAPrivateKey
{
this.modulus = spec.getModulus();
this.privateExponent = spec.getPrivateExponent();
+ this.rsaPrivateKey = new RSAKeyParameters(true, modulus, privateExponent);
}
BCRSAPrivateKey(
@@ -54,12 +66,17 @@ public class BCRSAPrivateKey
{
this.modulus = key.getModulus();
this.privateExponent = key.getPrivateExponent();
+ this.rsaPrivateKey = new RSAKeyParameters(true, modulus, privateExponent);
}
- BCRSAPrivateKey(org.bouncycastle.asn1.pkcs.RSAPrivateKey key)
+ BCRSAPrivateKey(AlgorithmIdentifier algID, org.bouncycastle.asn1.pkcs.RSAPrivateKey key)
{
+ this.algorithmIdentifier = algID;
+ this.algorithmIdentifierEnc = getEncoding(algID);
+
this.modulus = key.getModulus();
this.privateExponent = key.getPrivateExponent();
+ this.rsaPrivateKey = new RSAKeyParameters(true, modulus, privateExponent);
}
public BigInteger getModulus()
@@ -74,6 +91,10 @@ public class BCRSAPrivateKey
public String getAlgorithm()
{
+ if (algorithmIdentifier.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ return "RSASSA-PSS";
+ }
return "RSA";
}
@@ -82,9 +103,14 @@ public class BCRSAPrivateKey
return "PKCS#8";
}
+ RSAKeyParameters engineGetKeyParameters()
+ {
+ return rsaPrivateKey;
+ }
+
public byte[] getEncoded()
{
- return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new org.bouncycastle.asn1.pkcs.RSAPrivateKey(getModulus(), ZERO, getPrivateExponent(), ZERO, ZERO, ZERO, ZERO, ZERO));
+ return KeyUtil.getEncodedPrivateKeyInfo(algorithmIdentifier, new org.bouncycastle.asn1.pkcs.RSAPrivateKey(getModulus(), ZERO, getPrivateExponent(), ZERO, ZERO, ZERO, ZERO, ZERO));
}
public boolean equals(Object o)
@@ -134,7 +160,15 @@ public class BCRSAPrivateKey
{
in.defaultReadObject();
+ if (algorithmIdentifierEnc == null)
+ {
+ algorithmIdentifierEnc = getEncoding(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER);
+ }
+
+ this.algorithmIdentifier = AlgorithmIdentifier.getInstance(algorithmIdentifierEnc);
+
this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
+ this.rsaPrivateKey = new RSAKeyParameters(true, modulus, privateExponent);
}
private void writeObject(
@@ -155,4 +189,16 @@ public class BCRSAPrivateKey
return buf.toString();
}
+
+ private static byte[] getEncoding(AlgorithmIdentifier algorithmIdentifier)
+ {
+ try
+ {
+ return algorithmIdentifier.getEncoded();
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java
index dd53dce6..2d7e11b5 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java
@@ -18,20 +18,30 @@ import org.bouncycastle.util.Strings;
public class BCRSAPublicKey
implements RSAPublicKey
{
- private static final AlgorithmIdentifier DEFAULT_ALGORITHM_IDENTIFIER = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
+ static final AlgorithmIdentifier DEFAULT_ALGORITHM_IDENTIFIER = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
static final long serialVersionUID = 2675817738516720772L;
private BigInteger modulus;
private BigInteger publicExponent;
+
private transient AlgorithmIdentifier algorithmIdentifier;
+ private transient RSAKeyParameters rsaPublicKey;
BCRSAPublicKey(
RSAKeyParameters key)
{
- this.algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER;
+ this(DEFAULT_ALGORITHM_IDENTIFIER, key);
+ }
+
+ BCRSAPublicKey(
+ AlgorithmIdentifier algId,
+ RSAKeyParameters key)
+ {
+ this.algorithmIdentifier = algId;
this.modulus = key.getModulus();
this.publicExponent = key.getExponent();
+ this.rsaPublicKey = key;
}
BCRSAPublicKey(
@@ -40,6 +50,7 @@ public class BCRSAPublicKey
this.algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER;
this.modulus = spec.getModulus();
this.publicExponent = spec.getPublicExponent();
+ this.rsaPublicKey = new RSAKeyParameters(false, modulus, publicExponent);
}
BCRSAPublicKey(
@@ -48,6 +59,7 @@ public class BCRSAPublicKey
this.algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER;
this.modulus = key.getModulus();
this.publicExponent = key.getPublicExponent();
+ this.rsaPublicKey = new RSAKeyParameters(false, modulus, publicExponent);
}
BCRSAPublicKey(
@@ -65,6 +77,7 @@ public class BCRSAPublicKey
this.algorithmIdentifier = info.getAlgorithm();
this.modulus = pubKey.getModulus();
this.publicExponent = pubKey.getPublicExponent();
+ this.rsaPublicKey = new RSAKeyParameters(false, modulus, publicExponent);
}
catch (IOException e)
{
@@ -94,6 +107,10 @@ public class BCRSAPublicKey
public String getAlgorithm()
{
+ if (algorithmIdentifier.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ return "RSASSA-PSS";
+ }
return "RSA";
}
@@ -107,6 +124,11 @@ public class BCRSAPublicKey
return KeyUtil.getEncodedSubjectPublicKeyInfo(algorithmIdentifier, new org.bouncycastle.asn1.pkcs.RSAPublicKey(getModulus(), getPublicExponent()));
}
+ RSAKeyParameters engineGetKeyParameters()
+ {
+ return rsaPublicKey;
+ }
+
public int hashCode()
{
return this.getModulus().hashCode() ^ this.getPublicExponent().hashCode();
@@ -160,6 +182,7 @@ public class BCRSAPublicKey
{
algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER;
}
+ this.rsaPublicKey = new RSAKeyParameters(false, modulus, publicExponent);
}
private void writeObject(
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java
index 89afe5ce..46a8ef4a 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java
@@ -42,19 +42,13 @@ public class KeyFactorySpi
Class spec)
throws InvalidKeySpecException
{
- if (spec.isAssignableFrom(RSAPublicKeySpec.class) && key instanceof RSAPublicKey)
+ if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(RSAPublicKeySpec.class)) && key instanceof RSAPublicKey)
{
RSAPublicKey k = (RSAPublicKey)key;
return new RSAPublicKeySpec(k.getModulus(), k.getPublicExponent());
}
- else if (spec.isAssignableFrom(RSAPrivateKeySpec.class) && key instanceof java.security.interfaces.RSAPrivateKey)
- {
- java.security.interfaces.RSAPrivateKey k = (java.security.interfaces.RSAPrivateKey)key;
-
- return new RSAPrivateKeySpec(k.getModulus(), k.getPrivateExponent());
- }
- else if (spec.isAssignableFrom(RSAPrivateCrtKeySpec.class) && key instanceof RSAPrivateCrtKey)
+ else if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(RSAPrivateCrtKeySpec.class)) && key instanceof RSAPrivateCrtKey)
{
RSAPrivateCrtKey k = (RSAPrivateCrtKey)key;
@@ -65,6 +59,12 @@ public class KeyFactorySpi
k.getPrimeExponentP(), k.getPrimeExponentQ(),
k.getCrtCoefficient());
}
+ else if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(RSAPrivateKeySpec.class)) && key instanceof java.security.interfaces.RSAPrivateKey)
+ {
+ java.security.interfaces.RSAPrivateKey k = (java.security.interfaces.RSAPrivateKey)key;
+
+ return new RSAPrivateKeySpec(k.getModulus(), k.getPrivateExponent());
+ }
// BEGIN Android-removed: Unsupported algorithms
/*
else if (spec.isAssignableFrom(OpenSSHPublicKeySpec.class) && key instanceof RSAPublicKey)
@@ -105,6 +105,44 @@ public class KeyFactorySpi
throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
}
}
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPublicKeySpec.class) && key instanceof RSAPublicKey)
+ {
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPublicKeySpec(
+ OpenSSHPublicKeyUtil.encodePublicKey(
+ new RSAKeyParameters(
+ false,
+ ((RSAPublicKey)key).getModulus(),
+ ((RSAPublicKey)key).getPublicExponent())
+ )
+ );
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec.class) && key instanceof RSAPrivateCrtKey)
+ {
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec(OpenSSHPrivateKeyUtil.encodePrivateKey(new RSAPrivateCrtKeyParameters(
+ ((RSAPrivateCrtKey)key).getModulus(),
+ ((RSAPrivateCrtKey)key).getPublicExponent(),
+ ((RSAPrivateCrtKey)key).getPrivateExponent(),
+ ((RSAPrivateCrtKey)key).getPrimeP(),
+ ((RSAPrivateCrtKey)key).getPrimeQ(),
+ ((RSAPrivateCrtKey)key).getPrimeExponentP(),
+ ((RSAPrivateCrtKey)key).getPrimeExponentQ(),
+ ((RSAPrivateCrtKey)key).getCrtCoefficient()
+ )));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
*/
// END Android-removed: Unsupported algorithms
@@ -223,7 +261,7 @@ public class KeyFactorySpi
if (rsaPrivKey.getCoefficient().intValue() == 0)
{
- return new BCRSAPrivateKey(rsaPrivKey);
+ return new BCRSAPrivateKey(keyInfo.getPrivateKeyAlgorithm(), rsaPrivKey);
}
else
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java
index 3b9d7abc..e3354838 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java
@@ -7,6 +7,9 @@ import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
+import org.bouncycastle.asn1.DERNull;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.generators.RSAKeyPairGenerator;
@@ -18,27 +21,33 @@ import org.bouncycastle.jcajce.provider.asymmetric.util.PrimeCertaintyCalculator
public class KeyPairGeneratorSpi
extends java.security.KeyPairGenerator
{
- public KeyPairGeneratorSpi(
- String algorithmName)
- {
- super(algorithmName);
- }
+ private static final AlgorithmIdentifier PKCS_ALGID = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
+ private static final AlgorithmIdentifier PSS_ALGID = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS);
final static BigInteger defaultPublicExponent = BigInteger.valueOf(0x10001);
RSAKeyGenerationParameters param;
RSAKeyPairGenerator engine;
+ AlgorithmIdentifier algId;
- public KeyPairGeneratorSpi()
+ public KeyPairGeneratorSpi(
+ String algorithmName,
+ AlgorithmIdentifier algId)
{
- super("RSA");
+ super(algorithmName);
+ this.algId = algId;
engine = new RSAKeyPairGenerator();
param = new RSAKeyGenerationParameters(defaultPublicExponent,
CryptoServicesRegistrar.getSecureRandom(), 2048, PrimeCertaintyCalculator.getDefaultCertainty(2048));
engine.init(param);
}
+ public KeyPairGeneratorSpi()
+ {
+ this("RSA", PKCS_ALGID);
+ }
+
public void initialize(
int strength,
SecureRandom random)
@@ -77,7 +86,16 @@ public class KeyPairGeneratorSpi
RSAKeyParameters pub = (RSAKeyParameters)pair.getPublic();
RSAPrivateCrtKeyParameters priv = (RSAPrivateCrtKeyParameters)pair.getPrivate();
- return new KeyPair(new BCRSAPublicKey(pub),
- new BCRSAPrivateCrtKey(priv));
+ return new KeyPair(new BCRSAPublicKey(algId, pub),
+ new BCRSAPrivateCrtKey(algId, priv));
+ }
+
+ public static class PSS
+ extends KeyPairGeneratorSpi
+ {
+ public PSS()
+ {
+ super("RSASSA-PSS", PSS_ALGID);
+ }
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java
index 4d046b8a..3bc00656 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java
@@ -43,13 +43,22 @@ public class RSAUtil
static RSAKeyParameters generatePublicKeyParameter(
RSAPublicKey key)
{
- return new RSAKeyParameters(false, key.getModulus(), key.getPublicExponent());
+ if (key instanceof BCRSAPublicKey)
+ {
+ return ((BCRSAPublicKey)key).engineGetKeyParameters();
+ }
+ return new RSAKeyParameters(false, key.getModulus(), key.getPublicExponent());
}
static RSAKeyParameters generatePrivateKeyParameter(
RSAPrivateKey key)
{
+ if (key instanceof BCRSAPrivateKey)
+ {
+ return ((BCRSAPrivateKey)key).engineGetKeyParameters();
+ }
+
if (key instanceof RSAPrivateCrtKey)
{
RSAPrivateCrtKey k = (RSAPrivateCrtKey)key;
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
index 91e15b7b..7741339d 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
@@ -13,12 +13,16 @@ import java.util.Map;
import java.util.Set;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1Sequence;
+// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
+// import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters;
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X962Parameters;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
+// import org.bouncycastle.jce.ECGOST3410NamedCurveTable;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
@@ -94,15 +98,33 @@ public class EC5Util
{
curve = configuration.getEcImplicitlyCa().getCurve();
}
- else if (acceptableCurves.isEmpty())
- {
- X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
-
- curve = ecP.getCurve();
- }
else
{
- throw new IllegalStateException("encoded parameters not acceptable");
+ ASN1Sequence pSeq = ASN1Sequence.getInstance(params.getParameters());
+ if (acceptableCurves.isEmpty())
+ {
+ if (pSeq.size() > 3)
+ {
+ X9ECParameters ecP = X9ECParameters.getInstance(pSeq);
+
+ curve = ecP.getCurve();
+ }
+ else // GOST parameters
+ {
+ // BEGIN Android-removed: unsupported algorithms
+ /*
+ ASN1ObjectIdentifier gostCurve = ASN1ObjectIdentifier.getInstance(pSeq.getObjectAt(0));
+
+ curve = ECGOST3410NamedCurves.getByOIDX9(gostCurve).getCurve();
+ */
+ // END Android-removed: unsupported algorithms
+ throw new IllegalStateException("GOST is not supported");
+ }
+ }
+ else
+ {
+ throw new IllegalStateException("encoded parameters not acceptable");
+ }
}
return curve;
@@ -122,7 +144,7 @@ public class EC5Util
}
else
{
- domainParameters = ECUtil.getDomainParameters(configuration, convertSpec(params, false));
+ domainParameters = ECUtil.getDomainParameters(configuration, convertSpec(params));
}
return domainParameters;
@@ -162,25 +184,51 @@ public class EC5Util
}
else
{
- X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
+ ASN1Sequence pSeq = ASN1Sequence.getInstance(params.getParameters());
+ if (pSeq.size() > 3)
+ {
+ X9ECParameters ecP = X9ECParameters.getInstance(pSeq);
- ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
+ ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
- if (ecP.getH() != null)
- {
- ecSpec = new ECParameterSpec(
- ellipticCurve,
- convertPoint(ecP.getG()),
- ecP.getN(),
- ecP.getH().intValue());
+ if (ecP.getH() != null)
+ {
+ ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ convertPoint(ecP.getG()),
+ ecP.getN(),
+ ecP.getH().intValue());
+ }
+ else
+ {
+ ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ convertPoint(ecP.getG()),
+ ecP.getN(),
+ 1); // TODO: not strictly correct... need to fix the test data...
+ }
}
- else
+ else // GOST parameters
{
- ecSpec = new ECParameterSpec(
+ // BEGIN Android-removed: unsupported algorithms
+ /*
+ GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(pSeq);
+
+ ECNamedCurveParameterSpec spec = ECGOST3410NamedCurveTable.getParameterSpec(ECGOST3410NamedCurves.getName(
+ gostParams.getPublicKeyParamSet()));
+
+ curve = spec.getCurve();
+ ellipticCurve = EC5Util.convertCurve(curve, spec.getSeed());
+
+ ecSpec = new ECNamedCurveSpec(
+ ECGOST3410NamedCurves.getName(gostParams.getPublicKeyParamSet()),
ellipticCurve,
- convertPoint(ecP.getG()),
- ecP.getN(),
- 1); // TODO: not strictly correct... need to fix the test data...
+ EC5Util.convertPoint(spec.getG()),
+ spec.getN(), spec.getH());
+
+ */
+ // END Android-removed: unsupported algorithms
+ ecSpec = null;
}
}
@@ -265,64 +313,46 @@ public class EC5Util
EllipticCurve ellipticCurve,
org.bouncycastle.jce.spec.ECParameterSpec spec)
{
+ ECPoint g = convertPoint(spec.getG());
+
if (spec instanceof ECNamedCurveParameterSpec)
{
- return new ECNamedCurveSpec(
- ((ECNamedCurveParameterSpec)spec).getName(),
- ellipticCurve,
- convertPoint(spec.getG()),
- spec.getN(),
- spec.getH());
+ String name = ((ECNamedCurveParameterSpec)spec).getName();
+
+ return new ECNamedCurveSpec(name, ellipticCurve, g, spec.getN(), spec.getH());
}
else
{
- return new ECParameterSpec(
- ellipticCurve,
- convertPoint(spec.getG()),
- spec.getN(),
- spec.getH().intValue());
+ return new ECParameterSpec(ellipticCurve, g, spec.getN(), spec.getH().intValue());
}
}
- public static org.bouncycastle.jce.spec.ECParameterSpec convertSpec(
- ECParameterSpec ecSpec,
- boolean withCompression)
+ public static org.bouncycastle.jce.spec.ECParameterSpec convertSpec(ECParameterSpec ecSpec)
{
ECCurve curve = convertCurve(ecSpec.getCurve());
+ org.bouncycastle.math.ec.ECPoint g = convertPoint(curve, ecSpec.getGenerator());
+ BigInteger n = ecSpec.getOrder();
+ BigInteger h = BigInteger.valueOf(ecSpec.getCofactor());
+ byte[] seed = ecSpec.getCurve().getSeed();
+
if (ecSpec instanceof ECNamedCurveSpec)
{
- return new org.bouncycastle.jce.spec.ECNamedCurveParameterSpec(
- ((ECNamedCurveSpec)ecSpec).getName(),
- curve,
- convertPoint(curve, ecSpec.getGenerator(), withCompression),
- ecSpec.getOrder(),
- BigInteger.valueOf(ecSpec.getCofactor()),
- ecSpec.getCurve().getSeed());
+ return new org.bouncycastle.jce.spec.ECNamedCurveParameterSpec(((ECNamedCurveSpec)ecSpec).getName(), curve,
+ g, n, h, seed);
}
else
{
- return new org.bouncycastle.jce.spec.ECParameterSpec(
- curve,
- convertPoint(curve, ecSpec.getGenerator(), withCompression),
- ecSpec.getOrder(),
- BigInteger.valueOf(ecSpec.getCofactor()),
- ecSpec.getCurve().getSeed());
+ return new org.bouncycastle.jce.spec.ECParameterSpec(curve, g, n, h, seed);
}
}
- public static org.bouncycastle.math.ec.ECPoint convertPoint(
- ECParameterSpec ecSpec,
- ECPoint point,
- boolean withCompression)
+ public static org.bouncycastle.math.ec.ECPoint convertPoint(ECParameterSpec ecSpec, ECPoint point)
{
- return convertPoint(convertCurve(ecSpec.getCurve()), point, withCompression);
+ return convertPoint(convertCurve(ecSpec.getCurve()), point);
}
- public static org.bouncycastle.math.ec.ECPoint convertPoint(
- ECCurve curve,
- ECPoint point,
- boolean withCompression)
+ public static org.bouncycastle.math.ec.ECPoint convertPoint(ECCurve curve, ECPoint point)
{
return curve.createPoint(point.getAffineX(), point.getAffineY());
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
index f0511a6a..5ab91636 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
@@ -1,9 +1,13 @@
package org.bouncycastle.jcajce.provider.asymmetric.util;
+import java.lang.reflect.Method;
import java.math.BigInteger;
+import java.security.AccessController;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
+import java.security.PrivilegedAction;
import java.security.PublicKey;
+import java.security.spec.AlgorithmParameterSpec;
import java.util.Enumeration;
import java.util.Map;
@@ -27,6 +31,7 @@ import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.ec.FixedPointCombMultiplier;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Fingerprint;
import org.bouncycastle.util.Strings;
@@ -150,7 +155,7 @@ public class ECUtil
ecP = (X9ECParameters)extraCurves.get(oid);
}
- domainParameters = new ECNamedDomainParameters(oid, ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed());
+ domainParameters = new ECNamedDomainParameters(oid, ecP);
}
else if (params.isImplicitlyCA())
{
@@ -184,9 +189,9 @@ public class ECUtil
else if (key instanceof java.security.interfaces.ECPublicKey)
{
java.security.interfaces.ECPublicKey pubKey = (java.security.interfaces.ECPublicKey)key;
- ECParameterSpec s = EC5Util.convertSpec(pubKey.getParams(), false);
+ ECParameterSpec s = EC5Util.convertSpec(pubKey.getParams());
return new ECPublicKeyParameters(
- EC5Util.convertPoint(pubKey.getParams(), pubKey.getW(), false),
+ EC5Util.convertPoint(pubKey.getParams(), pubKey.getW()),
new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
}
else
@@ -249,7 +254,7 @@ public class ECUtil
else if (key instanceof java.security.interfaces.ECPrivateKey)
{
java.security.interfaces.ECPrivateKey privKey = (java.security.interfaces.ECPrivateKey)key;
- ECParameterSpec s = EC5Util.convertSpec(privKey.getParams(), false);
+ ECParameterSpec s = EC5Util.convertSpec(privKey.getParams());
return new ECPrivateKeyParameters(
privKey.getS(),
new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
@@ -384,7 +389,7 @@ public class ECUtil
StringBuffer buf = new StringBuffer();
String nl = Strings.lineSeparator();
- org.bouncycastle.math.ec.ECPoint q = calculateQ(d, spec);
+ org.bouncycastle.math.ec.ECPoint q = new FixedPointCombMultiplier().multiply(spec.getG(), d).normalize();
buf.append(algorithm);
buf.append(" Private Key [").append(ECUtil.generateKeyFingerprint(q, spec)).append("]").append(nl);
@@ -394,11 +399,6 @@ public class ECUtil
return buf.toString();
}
- private static org.bouncycastle.math.ec.ECPoint calculateQ(BigInteger d, org.bouncycastle.jce.spec.ECParameterSpec spec)
- {
- return spec.getG().multiply(d).normalize();
- }
-
public static String publicKeyToString(String algorithm, org.bouncycastle.math.ec.ECPoint q, org.bouncycastle.jce.spec.ECParameterSpec spec)
{
StringBuffer buf = new StringBuffer();
@@ -424,4 +424,26 @@ public class ECUtil
return new Fingerprint(publicPoint.getEncoded(false)).toString();
}
+
+ public static String getNameFrom(final AlgorithmParameterSpec paramSpec)
+ {
+ return (String)AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ try
+ {
+ Method m = paramSpec.getClass().getMethod("getName");
+
+ return m.invoke(paramSpec);
+ }
+ catch (Exception e)
+ {
+ // ignore - maybe log?
+ }
+
+ return null;
+ }
+ });
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java
index 3e328dae..3273bd93 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java
@@ -83,13 +83,12 @@ public class PKCS12BagAttributeCarrierImpl
else
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
- Enumeration e = this.getBagAttributeKeys();
+ ASN1OutputStream aOut = ASN1OutputStream.create(bOut);
+ Enumeration e = this.getBagAttributeKeys();
while (e.hasMoreElements())
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(e.nextElement());
aOut.writeObject(oid);
aOut.writeObject((ASN1Encodable)pkcs12Attributes.get(oid));
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
index 7badbdc1..36c71593 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
@@ -8,43 +8,64 @@ import org.bouncycastle.util.encoders.Base64;
class PEMUtil
{
- private final String _header1;
- private final String _header2;
- private final String _header3;
- private final String _footer1;
- private final String _footer2;
- private final String _footer3;
-
- PEMUtil(
- String type)
+ /**
+ * Boundary class. Keeps track of the required header/footer pair for the
+ * current PEM object.
+ *
+ */
+ private class Boundaries
{
- _header1 = "-----BEGIN " + type + "-----";
- _header2 = "-----BEGIN X509 " + type + "-----";
- _header3 = "-----BEGIN PKCS7-----";
- _footer1 = "-----END " + type + "-----";
- _footer2 = "-----END X509 " + type + "-----";
- _footer3 = "-----END PKCS7-----";
+ private final String _header;
+ private final String _footer;
+
+ private Boundaries(String type)
+ {
+ this._header = "-----BEGIN " + type + "-----";
+ this._footer = "-----END " + type + "-----";
+ }
+
+ public boolean isTheExpectedHeader(String line)
+ {
+ return line.startsWith(_header);
+ }
+
+ public boolean isTheExpectedFooter(String line)
+ {
+ return line.startsWith(_footer);
+ }
}
- private String readLine(
- InputStream in)
- throws IOException
+ private final Boundaries[] _supportedBoundaries;
+
+ PEMUtil(String type)
{
- int c;
+ _supportedBoundaries = new Boundaries[]
+ { new Boundaries(type), new Boundaries("X509 " + type),
+ new Boundaries("PKCS7") };
+ }
+
+ private String readLine(InputStream in) throws IOException
+ {
+ int c;
StringBuffer l = new StringBuffer();
do
{
while (((c = in.read()) != '\r') && c != '\n' && (c >= 0))
{
- l.append((char)c);
+ l.append((char) c);
}
}
while (c >= 0 && l.length() == 0);
-
+
if (c < 0)
{
- return null;
+ // make sure to return the read bytes if the end of file is encountered
+ if (l.length() == 0)
+ {
+ return null;
+ }
+ return l.toString();
}
// make sure we parse to end of line.
@@ -66,6 +87,30 @@ class PEMUtil
return l.toString();
}
+ /**
+ * Returns a {@link Boundaries} object representing the passed in boundary
+ * string.
+ *
+ * @param line the boundary string
+ * @return the {@link Boundaries} object corresponding to the given boundary
+ * string or <code>null</code> if the passed in string is not a valid
+ * boundary.
+ */
+ private Boundaries getBoundaries(String line)
+ {
+ for (int i = 0; i != _supportedBoundaries.length; i++)
+ {
+ Boundaries boundary = _supportedBoundaries[i];
+
+ if (boundary.isTheExpectedHeader(line) || boundary.isTheExpectedFooter(line))
+ {
+ return boundary;
+ }
+ }
+
+ return null;
+ }
+
ASN1Sequence readPEMObject(
InputStream in)
throws IOException
@@ -73,22 +118,43 @@ class PEMUtil
String line;
StringBuffer pemBuf = new StringBuffer();
- while ((line = readLine(in)) != null)
+ Boundaries header = null;
+
+ while (header == null && (line = readLine(in)) != null)
{
- if (line.startsWith(_header1) || line.startsWith(_header2) || line.startsWith(_header3))
+ header = getBoundaries(line);
+ if (header != null && !header.isTheExpectedHeader(line))
{
- break;
+ throw new IOException("malformed PEM data: found footer where header was expected");
}
}
- while ((line = readLine(in)) != null)
+ if (header == null)
+ {
+ throw new IOException("malformed PEM data: no header found");
+ }
+
+ Boundaries footer = null;
+
+ while (footer == null && (line = readLine(in)) != null)
{
- if (line.startsWith(_footer1) || line.startsWith(_footer2) || line.startsWith(_footer3))
+ footer = getBoundaries(line);
+ if (footer != null)
{
- break;
+ if (!header.isTheExpectedFooter(line))
+ {
+ throw new IOException("malformed PEM data: header/footer mismatch");
+ }
}
+ else
+ {
+ pemBuf.append(line);
+ }
+ }
- pemBuf.append(line);
+ if (footer == null)
+ {
+ throw new IOException("malformed PEM data: no footer found");
}
if (pemBuf.length() != 0)
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureCreator.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureCreator.java
new file mode 100644
index 00000000..63369e0a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureCreator.java
@@ -0,0 +1,11 @@
+package org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Signature;
+
+interface SignatureCreator
+{
+ Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java
index 5a94c638..e7e3a76a 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java
@@ -36,8 +36,9 @@ class X509CRLEntryObject extends X509CRLEntry
private TBSCertList.CRLEntry c;
private X500Name certificateIssuer;
- private int hashValue;
- private boolean isHashValueSet;
+
+ private volatile boolean hashValueSet;
+ private volatile int hashValue;
protected X509CRLEntryObject(TBSCertList.CRLEntry c)
{
@@ -202,27 +203,35 @@ class X509CRLEntryObject extends X509CRLEntry
*/
public int hashCode()
{
- if (!isHashValueSet)
+ if (!hashValueSet)
{
hashValue = super.hashCode();
- isHashValueSet = true;
+ hashValueSet = true;
}
return hashValue;
}
- public boolean equals(Object o)
+ public boolean equals(Object other)
{
- if (o == this)
+ if (other == this)
{
return true;
}
- if (o instanceof X509CRLEntryObject)
+ if (other instanceof X509CRLEntryObject)
{
- X509CRLEntryObject other = (X509CRLEntryObject)o;
+ X509CRLEntryObject otherBC = (X509CRLEntryObject)other;
+
+ if (this.hashValueSet && otherBC.hashValueSet)
+ {
+ if (this.hashValue != otherBC.hashValue)
+ {
+ return false;
+ }
+ }
- return this.c.equals(other.c);
+ return this.c.equals(otherBC.c);
}
return super.equals(this);
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
new file mode 100644
index 00000000..e6c8fe90
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
@@ -0,0 +1,736 @@
+package org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CRLException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.ASN1InputStream;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERBitString;
+import org.bouncycastle.asn1.util.ASN1Dump;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.CRLDistPoint;
+import org.bouncycastle.asn1.x509.CRLNumber;
+import org.bouncycastle.asn1.x509.CertificateList;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.Extensions;
+import org.bouncycastle.asn1.x509.GeneralNames;
+import org.bouncycastle.asn1.x509.IssuingDistributionPoint;
+import org.bouncycastle.asn1.x509.TBSCertList;
+import org.bouncycastle.asn1.x509.Time;
+import org.bouncycastle.jcajce.CompositePublicKey;
+import org.bouncycastle.jcajce.io.OutputStreamFactory;
+import org.bouncycastle.jcajce.util.JcaJceHelper;
+import org.bouncycastle.jce.X509Principal;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+
+/**
+ * The following extensions are listed in RFC 2459 as relevant to CRLs
+ * <p>
+ * Authority Key Identifier
+ * Issuer Alternative Name
+ * CRL Number
+ * Delta CRL Indicator (critical)
+ * Issuing Distribution Point (critical)
+ */
+abstract class X509CRLImpl
+ extends X509CRL
+{
+ protected JcaJceHelper bcHelper;
+ protected CertificateList c;
+ protected String sigAlgName;
+ protected byte[] sigAlgParams;
+ protected boolean isIndirect;
+
+ X509CRLImpl(JcaJceHelper bcHelper, CertificateList c, String sigAlgName, byte[] sigAlgParams, boolean isIndirect)
+ {
+ this.bcHelper = bcHelper;
+ this.c = c;
+ this.sigAlgName = sigAlgName;
+ this.sigAlgParams = sigAlgParams;
+ this.isIndirect = isIndirect;
+ }
+
+ /**
+ * Will return true if any extensions are present and marked
+ * as critical as we currently dont handle any extensions!
+ */
+ public boolean hasUnsupportedCriticalExtension()
+ {
+ Set extns = getCriticalExtensionOIDs();
+
+ if (extns == null)
+ {
+ return false;
+ }
+
+ extns.remove(Extension.issuingDistributionPoint.getId());
+ extns.remove(Extension.deltaCRLIndicator.getId());
+
+ return !extns.isEmpty();
+ }
+
+ private Set getExtensionOIDs(boolean critical)
+ {
+ if (this.getVersion() == 2)
+ {
+ Extensions extensions = c.getTBSCertList().getExtensions();
+
+ if (extensions != null)
+ {
+ Set set = new HashSet();
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (critical == ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+ }
+
+ return null;
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(true);
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(false);
+ }
+
+ public byte[] getExtensionValue(String oid)
+ {
+ ASN1OctetString extValue = getExtensionValue(c, oid);
+ if (null != extValue)
+ {
+ try
+ {
+ return extValue.getEncoded();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException("error parsing " + e.toString());
+ }
+ }
+ return null;
+ }
+
+ public byte[] getEncoded()
+ throws CRLException
+ {
+ try
+ {
+ return c.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CRLException(e.toString());
+ }
+ }
+
+ public void verify(PublicKey key)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ try
+ {
+ return bcHelper.createSignature(sigName);
+ }
+ catch (Exception e)
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+
+ public void verify(PublicKey key, final String sigProvider)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ if (sigProvider != null)
+ {
+ return Signature.getInstance(sigName, sigProvider);
+ }
+ else
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+
+ public void verify(PublicKey key, final Provider sigProvider)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
+ try
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ if (sigProvider != null)
+ {
+ return Signature.getInstance(getSigAlgName(), sigProvider);
+ }
+ else
+ {
+ return Signature.getInstance(getSigAlgName());
+ }
+ }
+ });
+ }
+ catch (NoSuchProviderException e)
+ {
+ // can't happen, but just in case
+ throw new NoSuchAlgorithmException("provider issue: " + e.getMessage());
+ }
+ }
+
+ private void doVerify(PublicKey key, SignatureCreator sigCreator)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException, NoSuchProviderException
+ {
+ if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature()))
+ {
+ throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList.");
+ }
+
+ if (key instanceof CompositePublicKey && X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
+ {
+ List<PublicKey> pubKeys = ((CompositePublicKey)key).getPublicKeys();
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+
+ boolean success = false;
+ for (int i = 0; i != pubKeys.size(); i++)
+ {
+ if (pubKeys.get(i) == null)
+ {
+ continue;
+ }
+
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ String sigName = X509SignatureUtil.getSignatureName(sigAlg);
+
+ Signature signature = sigCreator.createSignature(sigName);
+
+ SignatureException sigExc = null;
+
+ try
+ {
+ checkSignature(
+ (PublicKey)pubKeys.get(i), signature,
+ sigAlg.getParameters(),
+ DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ success = true;
+ }
+ catch (SignatureException e)
+ {
+ sigExc = e;
+ }
+
+ if (sigExc != null)
+ {
+ throw sigExc;
+ }
+ }
+
+ if (!success)
+ {
+ throw new InvalidKeyException("no matching key found");
+ }
+ }
+ else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
+ {
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+
+ boolean success = false;
+ for (int i = 0; i != sigSeq.size(); i++)
+ {
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ String sigName = X509SignatureUtil.getSignatureName(sigAlg);
+
+ SignatureException sigExc = null;
+
+ try
+ {
+ Signature signature = sigCreator.createSignature(sigName);
+
+ checkSignature(
+ key, signature,
+ sigAlg.getParameters(),
+ DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+
+ success = true;
+ }
+ catch (InvalidKeyException e)
+ {
+ // ignore
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // ignore
+ }
+ catch (SignatureException e)
+ {
+ sigExc = e;
+ }
+
+ if (sigExc != null)
+ {
+ throw sigExc;
+ }
+ }
+
+ if (!success)
+ {
+ throw new InvalidKeyException("no matching key found");
+ }
+ }
+ else
+ {
+ Signature sig = sigCreator.createSignature(getSigAlgName());
+
+ if (sigAlgParams == null)
+ {
+ checkSignature(key, sig, null, this.getSignature());
+ }
+ else
+ {
+ try
+ {
+ checkSignature(key, sig, ASN1Primitive.fromByteArray(sigAlgParams), this.getSignature());
+ }
+ catch (IOException e)
+ {
+ throw new SignatureException("cannot decode signature parameters: " + e.getMessage());
+ }
+ }
+ }
+ }
+
+ private void checkSignature(PublicKey key, Signature sig, ASN1Encodable sigAlgParams, byte[] encSig)
+ throws NoSuchAlgorithmException, SignatureException, InvalidKeyException, CRLException
+ {
+ if (sigAlgParams != null)
+ {
+ // needs to be called before initVerify().
+ X509SignatureUtil.setSignatureParameters(sig, sigAlgParams);
+ }
+
+ sig.initVerify(key);
+
+ try
+ {
+ OutputStream sigOut = new BufferedOutputStream(OutputStreamFactory.createStream(sig), 512);
+
+ c.getTBSCertList().encodeTo(sigOut, ASN1Encoding.DER);
+
+ sigOut.close();
+ }
+ catch (IOException e)
+ {
+ throw new CRLException(e.toString());
+ }
+
+ if (!sig.verify(encSig))
+ {
+ throw new SignatureException("CRL does not verify with supplied public key.");
+ }
+ }
+
+ public int getVersion()
+ {
+ return c.getVersionNumber();
+ }
+
+ public Principal getIssuerDN()
+ {
+ return new X509Principal(X500Name.getInstance(c.getIssuer().toASN1Primitive()));
+ }
+
+ public X500Principal getIssuerX500Principal()
+ {
+ try
+ {
+ return new X500Principal(c.getIssuer().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("can't encode issuer DN");
+ }
+ }
+
+ public Date getThisUpdate()
+ {
+ return c.getThisUpdate().getDate();
+ }
+
+ public Date getNextUpdate()
+ {
+ Time nextUpdate = c.getNextUpdate();
+
+ return null == nextUpdate ? null : nextUpdate.getDate();
+ }
+
+ private Set loadCRLEntries()
+ {
+ Set entrySet = new HashSet();
+ Enumeration certs = c.getRevokedCertificateEnumeration();
+
+ X500Name previousCertificateIssuer = null; // the issuer
+ while (certs.hasMoreElements())
+ {
+ TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement();
+ X509CRLEntryObject crlEntry = new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer);
+ entrySet.add(crlEntry);
+ if (isIndirect && entry.hasExtensions())
+ {
+ Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
+
+ if (currentCaName != null)
+ {
+ previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
+ }
+ }
+ }
+
+ return entrySet;
+ }
+
+ public X509CRLEntry getRevokedCertificate(BigInteger serialNumber)
+ {
+ Enumeration certs = c.getRevokedCertificateEnumeration();
+
+ X500Name previousCertificateIssuer = null; // the issuer
+ while (certs.hasMoreElements())
+ {
+ TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement();
+
+ if (entry.getUserCertificate().hasValue(serialNumber))
+ {
+ return new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer);
+ }
+
+ if (isIndirect && entry.hasExtensions())
+ {
+ Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
+
+ if (currentCaName != null)
+ {
+ previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public Set getRevokedCertificates()
+ {
+ Set entrySet = loadCRLEntries();
+
+ if (!entrySet.isEmpty())
+ {
+ return Collections.unmodifiableSet(entrySet);
+ }
+
+ return null;
+ }
+
+ public byte[] getTBSCertList()
+ throws CRLException
+ {
+ try
+ {
+ return c.getTBSCertList().getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CRLException(e.toString());
+ }
+ }
+
+ public byte[] getSignature()
+ {
+ return c.getSignature().getOctets();
+ }
+
+ public String getSigAlgName()
+ {
+ return sigAlgName;
+ }
+
+ public String getSigAlgOID()
+ {
+ return c.getSignatureAlgorithm().getAlgorithm().getId();
+ }
+
+ public byte[] getSigAlgParams()
+ {
+ return Arrays.clone(sigAlgParams);
+ }
+
+ /**
+ * Returns a string representation of this CRL.
+ *
+ * @return a string representation of this CRL.
+ */
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append(" Version: ").append(this.getVersion()).append(
+ nl);
+ buf.append(" IssuerDN: ").append(this.getIssuerDN())
+ .append(nl);
+ buf.append(" This update: ").append(this.getThisUpdate())
+ .append(nl);
+ buf.append(" Next update: ").append(this.getNextUpdate())
+ .append(nl);
+ buf.append(" Signature Algorithm: ").append(this.getSigAlgName())
+ .append(nl);
+
+ X509SignatureUtil.prettyPrintSignature(this.getSignature(), buf, nl);
+
+ Extensions extensions = c.getTBSCertList().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ if (e.hasMoreElements())
+ {
+ buf.append(" Extensions: ").append(nl);
+ }
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.getExtnValue() != null)
+ {
+ byte[] octs = ext.getExtnValue().getOctets();
+ ASN1InputStream dIn = new ASN1InputStream(octs);
+ buf.append(" critical(").append(
+ ext.isCritical()).append(") ");
+ try
+ {
+ if (oid.equals(Extension.cRLNumber))
+ {
+ buf.append(
+ new CRLNumber(ASN1Integer.getInstance(
+ dIn.readObject()).getPositiveValue()))
+ .append(nl);
+ }
+ else if (oid.equals(Extension.deltaCRLIndicator))
+ {
+ buf.append(
+ "Base CRL: "
+ + new CRLNumber(ASN1Integer.getInstance(
+ dIn.readObject()).getPositiveValue()))
+ .append(nl);
+ }
+ else if (oid
+ .equals(Extension.issuingDistributionPoint))
+ {
+ buf.append(
+ IssuingDistributionPoint.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid
+ .equals(Extension.cRLDistributionPoints))
+ {
+ buf.append(
+ CRLDistPoint.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid.equals(Extension.freshestCRL))
+ {
+ buf.append(
+ CRLDistPoint.getInstance(dIn.readObject())).append(nl);
+ }
+ else
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append(
+ ASN1Dump.dumpAsString(dIn.readObject()))
+ .append(nl);
+ }
+ }
+ catch (Exception ex)
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append("*****").append(nl);
+ }
+ }
+ else
+ {
+ buf.append(nl);
+ }
+ }
+ }
+ Set set = getRevokedCertificates();
+ if (set != null)
+ {
+ Iterator it = set.iterator();
+ while (it.hasNext())
+ {
+ buf.append(it.next());
+ buf.append(nl);
+ }
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Checks whether the given certificate is on this CRL.
+ *
+ * @param cert the certificate to check for.
+ * @return true if the given certificate is on this CRL,
+ * false otherwise.
+ */
+ public boolean isRevoked(Certificate cert)
+ {
+ if (!cert.getType().equals("X.509"))
+ {
+ throw new IllegalArgumentException("X.509 CRL used with non X.509 Cert");
+ }
+
+ Enumeration certs = c.getRevokedCertificateEnumeration();
+
+ X500Name caName = c.getIssuer();
+
+ if (certs.hasMoreElements())
+ {
+ BigInteger serial = ((X509Certificate)cert).getSerialNumber();
+
+ while (certs.hasMoreElements())
+ {
+ TBSCertList.CRLEntry entry = TBSCertList.CRLEntry.getInstance(certs.nextElement());
+
+ if (isIndirect && entry.hasExtensions())
+ {
+ Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
+
+ if (currentCaName != null)
+ {
+ caName = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
+ }
+ }
+
+ if (entry.getUserCertificate().hasValue(serial))
+ {
+ X500Name issuer;
+
+ if (cert instanceof X509Certificate)
+ {
+ issuer = X500Name.getInstance(((X509Certificate)cert).getIssuerX500Principal().getEncoded());
+ }
+ else
+ {
+ try
+ {
+ issuer = org.bouncycastle.asn1.x509.Certificate.getInstance(cert.getEncoded()).getIssuer();
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IllegalArgumentException("Cannot process certificate: " + e.getMessage());
+ }
+ }
+
+ if (!caName.equals(issuer))
+ {
+ return false;
+ }
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ protected static byte[] getExtensionOctets(CertificateList c, String oid)
+ {
+ ASN1OctetString extValue = getExtensionValue(c, oid);
+ if (null != extValue)
+ {
+ return extValue.getOctets();
+ }
+ return null;
+ }
+
+ protected static ASN1OctetString getExtensionValue(CertificateList c, String oid)
+ {
+ Extensions exts = c.getTBSCertList().getExtensions();
+ if (null != exts)
+ {
+ Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
+ if (null != ext)
+ {
+ return ext.getExtnValue();
+ }
+ }
+ return null;
+ }
+}
+
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
new file mode 100644
index 00000000..6bc0324f
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
@@ -0,0 +1,29 @@
+package org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.security.cert.CRLException;
+
+import org.bouncycastle.asn1.x509.CertificateList;
+import org.bouncycastle.jcajce.util.JcaJceHelper;
+
+class X509CRLInternal extends X509CRLImpl
+{
+ private final byte[] encoding;
+
+ X509CRLInternal(JcaJceHelper bcHelper, CertificateList c, String sigAlgName, byte[] sigAlgParams, boolean isIndirect,
+ byte[] encoding)
+ {
+ super(bcHelper, c, sigAlgName, sigAlgParams, isIndirect);
+
+ this.encoding = encoding;
+ }
+
+ public byte[] getEncoded() throws CRLException
+ {
+ if (null == encoding)
+ {
+ throw new CRLException();
+ }
+
+ return encoding;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
index 4870cdb0..3a1af42a 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
@@ -1,681 +1,149 @@
package org.bouncycastle.jcajce.provider.asymmetric.x509;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Principal;
-import java.security.Provider;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
import java.security.cert.CRLException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509CRL;
-import java.security.cert.X509CRLEntry;
-import java.security.cert.X509Certificate;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import javax.security.auth.x500.X500Principal;
+import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Encoding;
-import org.bouncycastle.asn1.ASN1InputStream;
-import org.bouncycastle.asn1.ASN1Integer;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.ASN1OctetString;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.util.ASN1Dump;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.CRLDistPoint;
-import org.bouncycastle.asn1.x509.CRLNumber;
import org.bouncycastle.asn1.x509.CertificateList;
import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.Extensions;
-import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.IssuingDistributionPoint;
-import org.bouncycastle.asn1.x509.TBSCertList;
import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jce.X509Principal;
-import org.bouncycastle.util.Strings;
-import org.bouncycastle.util.encoders.Hex;
-/**
- * The following extensions are listed in RFC 2459 as relevant to CRLs
- *
- * Authority Key Identifier
- * Issuer Alternative Name
- * CRL Number
- * Delta CRL Indicator (critical)
- * Issuing Distribution Point (critical)
- */
class X509CRLObject
- extends X509CRL
+ extends X509CRLImpl
{
- private JcaJceHelper bcHelper;
- private CertificateList c;
- private String sigAlgName;
- private byte[] sigAlgParams;
- private boolean isIndirect;
- private boolean isHashCodeSet = false;
- private int hashCodeValue;
+ private final Object cacheLock = new Object();
+ private X509CRLInternal internalCRLValue;
- static boolean isIndirectCRL(X509CRL crl)
- throws CRLException
- {
- try
- {
- byte[] idp = crl.getExtensionValue(Extension.issuingDistributionPoint.getId());
- return idp != null
- && IssuingDistributionPoint.getInstance(ASN1OctetString.getInstance(idp).getOctets()).isIndirectCRL();
- }
- catch (Exception e)
- {
- throw new ExtCRLException(
- "Exception reading IssuingDistributionPoint", e);
- }
- }
+ private volatile boolean hashValueSet;
+ private volatile int hashValue;
- protected X509CRLObject(
- JcaJceHelper bcHelper,
- CertificateList c)
- throws CRLException
+ X509CRLObject(JcaJceHelper bcHelper, CertificateList c) throws CRLException
{
- this.bcHelper = bcHelper;
- this.c = c;
-
- try
- {
- this.sigAlgName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
-
- if (c.getSignatureAlgorithm().getParameters() != null)
- {
- this.sigAlgParams = ((ASN1Encodable)c.getSignatureAlgorithm().getParameters()).toASN1Primitive().getEncoded(ASN1Encoding.DER);
- }
- else
- {
- this.sigAlgParams = null;
- }
-
- this.isIndirect = isIndirectCRL(this);
- }
- catch (Exception e)
- {
- throw new CRLException("CRL contents invalid: " + e);
- }
+ super(bcHelper, c, createSigAlgName(c), createSigAlgParams(c), isIndirectCRL(c));
}
- /**
- * Will return true if any extensions are present and marked
- * as critical as we currently dont handle any extensions!
- */
- public boolean hasUnsupportedCriticalExtension()
+ public boolean equals(Object other)
{
- Set extns = getCriticalExtensionOIDs();
-
- if (extns == null)
+ if (this == other)
{
- return false;
+ return true;
}
- extns.remove(Extension.issuingDistributionPoint.getId());
- extns.remove(Extension.deltaCRLIndicator.getId());
-
- return !extns.isEmpty();
- }
-
- private Set getExtensionOIDs(boolean critical)
- {
- if (this.getVersion() == 2)
+ if (other instanceof X509CRLObject)
{
- Extensions extensions = c.getTBSCertList().getExtensions();
+ X509CRLObject otherBC = (X509CRLObject)other;
- if (extensions != null)
+ if (this.hashValueSet && otherBC.hashValueSet)
{
- Set set = new HashSet();
- Enumeration e = extensions.oids();
-
- while (e.hasMoreElements())
+ if (this.hashValue != otherBC.hashValue)
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
- Extension ext = extensions.getExtension(oid);
-
- if (critical == ext.isCritical())
- {
- set.add(oid.getId());
- }
+ return false;
}
-
- return set;
}
- }
-
- return null;
- }
-
- public Set getCriticalExtensionOIDs()
- {
- return getExtensionOIDs(true);
- }
-
- public Set getNonCriticalExtensionOIDs()
- {
- return getExtensionOIDs(false);
- }
-
- public byte[] getExtensionValue(String oid)
- {
- Extensions exts = c.getTBSCertList().getExtensions();
-
- if (exts != null)
- {
- Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
-
- if (ext != null)
+ else if (null == internalCRLValue || null == otherBC.internalCRLValue)
{
- try
- {
- return ext.getExtnValue().getEncoded();
- }
- catch (Exception e)
+ ASN1BitString signature = c.getSignature();
+ if (null != signature && !signature.equals(otherBC.c.getSignature()))
{
- throw new IllegalStateException("error parsing " + e.toString());
+ return false;
}
}
}
- return null;
- }
-
- public byte[] getEncoded()
- throws CRLException
- {
- try
- {
- return c.getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
- {
- throw new CRLException(e.toString());
- }
- }
-
- public void verify(PublicKey key)
- throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException
- {
- Signature sig;
-
- try
- {
- sig = bcHelper.createSignature(getSigAlgName());
- }
- catch (Exception e)
- {
- sig = Signature.getInstance(getSigAlgName());
- }
-
- doVerify(key, sig);
- }
-
- public void verify(PublicKey key, String sigProvider)
- throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException
- {
- Signature sig;
-
- if (sigProvider != null)
- {
- sig = Signature.getInstance(getSigAlgName(), sigProvider);
- }
- else
- {
- sig = Signature.getInstance(getSigAlgName());
- }
-
- doVerify(key, sig);
+ return getInternalCRL().equals(other);
}
- public void verify(PublicKey key, Provider sigProvider)
- throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, SignatureException
+ public int hashCode()
{
- Signature sig;
-
- if (sigProvider != null)
+ if (!hashValueSet)
{
- sig = Signature.getInstance(getSigAlgName(), sigProvider);
- }
- else
- {
- sig = Signature.getInstance(getSigAlgName());
+ hashValue = getInternalCRL().hashCode();
+ hashValueSet = true;
}
- doVerify(key, sig);
+ return hashValue;
}
- private void doVerify(PublicKey key, Signature sig)
- throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, SignatureException
+ private X509CRLInternal getInternalCRL()
{
- if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature()))
+ synchronized (cacheLock)
{
- throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList.");
- }
-
- if (sigAlgParams != null)
- {
- try
- {
- // needs to be called before initVerify().
- X509SignatureUtil.setSignatureParameters(sig, ASN1Primitive.fromByteArray(sigAlgParams));
- }
- catch (IOException e)
+ if (null != internalCRLValue)
{
- throw new SignatureException("cannot decode signature parameters: " + e.getMessage());
+ return internalCRLValue;
}
}
- sig.initVerify(key);
- sig.update(this.getTBSCertList());
-
- if (!sig.verify(this.getSignature()))
- {
- throw new SignatureException("CRL does not verify with supplied public key.");
- }
- }
-
- public int getVersion()
- {
- return c.getVersionNumber();
- }
-
- public Principal getIssuerDN()
- {
- return new X509Principal(X500Name.getInstance(c.getIssuer().toASN1Primitive()));
- }
-
- public X500Principal getIssuerX500Principal()
- {
+ byte[] encoding;
try
{
- return new X500Principal(c.getIssuer().getEncoded());
- }
- catch (IOException e)
- {
- throw new IllegalStateException("can't encode issuer DN");
+ encoding = getEncoded();
}
- }
-
- public Date getThisUpdate()
- {
- return c.getThisUpdate().getDate();
- }
-
- public Date getNextUpdate()
- {
- if (c.getNextUpdate() != null)
- {
- return c.getNextUpdate().getDate();
- }
-
- return null;
- }
-
- private Set loadCRLEntries()
- {
- Set entrySet = new HashSet();
- Enumeration certs = c.getRevokedCertificateEnumeration();
-
- X500Name previousCertificateIssuer = null; // the issuer
- while (certs.hasMoreElements())
+ catch (CRLException e)
{
- TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement();
- X509CRLEntryObject crlEntry = new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer);
- entrySet.add(crlEntry);
- if (isIndirect && entry.hasExtensions())
- {
- Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
-
- if (currentCaName != null)
- {
- previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
- }
- }
+ encoding = null;
}
- return entrySet;
- }
-
- public X509CRLEntry getRevokedCertificate(BigInteger serialNumber)
- {
- Enumeration certs = c.getRevokedCertificateEnumeration();
+ X509CRLInternal temp = new X509CRLInternal(bcHelper, c, sigAlgName,sigAlgParams, isIndirect, encoding);
- X500Name previousCertificateIssuer = null; // the issuer
- while (certs.hasMoreElements())
+ synchronized (cacheLock)
{
- TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement();
-
- if (serialNumber.equals(entry.getUserCertificate().getValue()))
- {
- return new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer);
- }
-
- if (isIndirect && entry.hasExtensions())
+ if (null == internalCRLValue)
{
- Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
-
- if (currentCaName != null)
- {
- previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
- }
+ internalCRLValue = temp;
}
- }
-
- return null;
- }
-
- public Set getRevokedCertificates()
- {
- Set entrySet = loadCRLEntries();
- if (!entrySet.isEmpty())
- {
- return Collections.unmodifiableSet(entrySet);
+ return internalCRLValue;
}
-
- return null;
}
- public byte[] getTBSCertList()
- throws CRLException
+ private static String createSigAlgName(CertificateList c) throws CRLException
{
try
{
- return c.getTBSCertList().getEncoded("DER");
+ return X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
}
- catch (IOException e)
- {
- throw new CRLException(e.toString());
- }
- }
-
- public byte[] getSignature()
- {
- return c.getSignature().getOctets();
- }
-
- public String getSigAlgName()
- {
- return sigAlgName;
- }
-
- public String getSigAlgOID()
- {
- return c.getSignatureAlgorithm().getAlgorithm().getId();
- }
-
- public byte[] getSigAlgParams()
- {
- if (sigAlgParams != null)
+ catch (Exception e)
{
- byte[] tmp = new byte[sigAlgParams.length];
-
- System.arraycopy(sigAlgParams, 0, tmp, 0, tmp.length);
-
- return tmp;
+ throw new CRLException("CRL contents invalid: " + e);
}
-
- return null;
}
- /**
- * Returns a string representation of this CRL.
- *
- * @return a string representation of this CRL.
- */
- public String toString()
+ private static byte[] createSigAlgParams(CertificateList c) throws CRLException
{
- StringBuffer buf = new StringBuffer();
- String nl = Strings.lineSeparator();
-
- buf.append(" Version: ").append(this.getVersion()).append(
- nl);
- buf.append(" IssuerDN: ").append(this.getIssuerDN())
- .append(nl);
- buf.append(" This update: ").append(this.getThisUpdate())
- .append(nl);
- buf.append(" Next update: ").append(this.getNextUpdate())
- .append(nl);
- buf.append(" Signature Algorithm: ").append(this.getSigAlgName())
- .append(nl);
-
- byte[] sig = this.getSignature();
-
- buf.append(" Signature: ").append(
- new String(Hex.encode(sig, 0, 20))).append(nl);
- for (int i = 20; i < sig.length; i += 20)
- {
- if (i < sig.length - 20)
- {
- buf.append(" ").append(
- new String(Hex.encode(sig, i, 20))).append(nl);
- }
- else
- {
- buf.append(" ").append(
- new String(Hex.encode(sig, i, sig.length - i))).append(nl);
- }
- }
-
- Extensions extensions = c.getTBSCertList().getExtensions();
-
- if (extensions != null)
- {
- Enumeration e = extensions.oids();
-
- if (e.hasMoreElements())
- {
- buf.append(" Extensions: ").append(nl);
- }
-
- while (e.hasMoreElements())
- {
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement();
- Extension ext = extensions.getExtension(oid);
-
- if (ext.getExtnValue() != null)
- {
- byte[] octs = ext.getExtnValue().getOctets();
- ASN1InputStream dIn = new ASN1InputStream(octs);
- buf.append(" critical(").append(
- ext.isCritical()).append(") ");
- try
- {
- if (oid.equals(Extension.cRLNumber))
- {
- buf.append(
- new CRLNumber(ASN1Integer.getInstance(
- dIn.readObject()).getPositiveValue()))
- .append(nl);
- }
- else if (oid.equals(Extension.deltaCRLIndicator))
- {
- buf.append(
- "Base CRL: "
- + new CRLNumber(ASN1Integer.getInstance(
- dIn.readObject()).getPositiveValue()))
- .append(nl);
- }
- else if (oid
- .equals(Extension.issuingDistributionPoint))
- {
- buf.append(
- IssuingDistributionPoint.getInstance(dIn.readObject())).append(nl);
- }
- else if (oid
- .equals(Extension.cRLDistributionPoints))
- {
- buf.append(
- CRLDistPoint.getInstance(dIn.readObject())).append(nl);
- }
- else if (oid.equals(Extension.freshestCRL))
- {
- buf.append(
- CRLDistPoint.getInstance(dIn.readObject())).append(nl);
- }
- else
- {
- buf.append(oid.getId());
- buf.append(" value = ").append(
- ASN1Dump.dumpAsString(dIn.readObject()))
- .append(nl);
- }
- }
- catch (Exception ex)
- {
- buf.append(oid.getId());
- buf.append(" value = ").append("*****").append(nl);
- }
- }
- else
- {
- buf.append(nl);
- }
- }
- }
- Set set = getRevokedCertificates();
- if (set != null)
+ try
{
- Iterator it = set.iterator();
- while (it.hasNext())
+ ASN1Encodable parameters = c.getSignatureAlgorithm().getParameters();
+ if (null == parameters)
{
- buf.append(it.next());
- buf.append(nl);
+ return null;
}
- }
- return buf.toString();
- }
- /**
- * Checks whether the given certificate is on this CRL.
- *
- * @param cert the certificate to check for.
- * @return true if the given certificate is on this CRL,
- * false otherwise.
- */
- public boolean isRevoked(Certificate cert)
- {
- if (!cert.getType().equals("X.509"))
- {
- throw new IllegalArgumentException("X.509 CRL used with non X.509 Cert");
+ return parameters.toASN1Primitive().getEncoded(ASN1Encoding.DER);
}
-
- Enumeration certs = c.getRevokedCertificateEnumeration();
-
- X500Name caName = c.getIssuer();
-
- if (certs.hasMoreElements())
+ catch (Exception e)
{
- BigInteger serial = ((X509Certificate)cert).getSerialNumber();
-
- while (certs.hasMoreElements())
- {
- TBSCertList.CRLEntry entry = TBSCertList.CRLEntry.getInstance(certs.nextElement());
-
- if (isIndirect && entry.hasExtensions())
- {
- Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
-
- if (currentCaName != null)
- {
- caName = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
- }
- }
-
- if (entry.getUserCertificate().getValue().equals(serial))
- {
- X500Name issuer;
-
- if (cert instanceof X509Certificate)
- {
- issuer = X500Name.getInstance(((X509Certificate)cert).getIssuerX500Principal().getEncoded());
- }
- else
- {
- try
- {
- issuer = org.bouncycastle.asn1.x509.Certificate.getInstance(cert.getEncoded()).getIssuer();
- }
- catch (CertificateEncodingException e)
- {
- throw new IllegalArgumentException("Cannot process certificate: " + e.getMessage());
- }
- }
-
- if (!caName.equals(issuer))
- {
- return false;
- }
-
- return true;
- }
- }
+ throw new CRLException("CRL contents invalid: " + e);
}
-
- return false;
}
- public boolean equals(Object other)
+ private static boolean isIndirectCRL(CertificateList c) throws CRLException
{
- if (this == other)
- {
- return true;
- }
-
- if (!(other instanceof X509CRL))
- {
- return false;
- }
-
- if (other instanceof X509CRLObject)
+ try
{
- X509CRLObject crlObject = (X509CRLObject)other;
-
- if (isHashCodeSet)
+ byte[] extOctets = getExtensionOctets(c, Extension.issuingDistributionPoint.getId());
+ if (null == extOctets)
{
- boolean otherIsHashCodeSet = crlObject.isHashCodeSet;
- if (otherIsHashCodeSet)
- {
- if (crlObject.hashCodeValue != hashCodeValue)
- {
- return false;
- }
- }
+ return false;
}
- return this.c.equals(crlObject.c);
+ return IssuingDistributionPoint.getInstance(extOctets).isIndirectCRL();
}
-
- return super.equals(other);
- }
-
- public int hashCode()
- {
- if (!isHashCodeSet)
+ catch (Exception e)
{
- isHashCodeSet = true;
- hashCodeValue = super.hashCode();
+ throw new ExtCRLException("Exception reading IssuingDistributionPoint", e);
}
-
- return hashCodeValue;
}
}
-
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
new file mode 100644
index 00000000..4907fb5e
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
@@ -0,0 +1,940 @@
+package org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.ASN1InputStream;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1String;
+import org.bouncycastle.asn1.DERBitString;
+import org.bouncycastle.asn1.DERIA5String;
+import org.bouncycastle.asn1.DERNull;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import org.bouncycastle.asn1.misc.NetscapeCertType;
+import org.bouncycastle.asn1.misc.NetscapeRevocationURL;
+import org.bouncycastle.asn1.misc.VerisignCzagExtension;
+import org.bouncycastle.asn1.util.ASN1Dump;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x500.style.RFC4519Style;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.BasicConstraints;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.Extensions;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.KeyUsage;
+import org.bouncycastle.asn1.x509.TBSCertificate;
+import org.bouncycastle.jcajce.CompositePublicKey;
+import org.bouncycastle.jcajce.interfaces.BCX509Certificate;
+import org.bouncycastle.jcajce.io.OutputStreamFactory;
+import org.bouncycastle.jcajce.util.JcaJceHelper;
+import org.bouncycastle.jce.X509Principal;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Integers;
+import org.bouncycastle.util.Properties;
+import org.bouncycastle.util.Strings;
+
+abstract class X509CertificateImpl
+ extends X509Certificate
+ implements BCX509Certificate
+{
+ protected JcaJceHelper bcHelper;
+ protected org.bouncycastle.asn1.x509.Certificate c;
+ protected BasicConstraints basicConstraints;
+ protected boolean[] keyUsage;
+ protected String sigAlgName;
+ protected byte[] sigAlgParams;
+
+ X509CertificateImpl(JcaJceHelper bcHelper, org.bouncycastle.asn1.x509.Certificate c,
+ BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams)
+ {
+ this.bcHelper = bcHelper;
+ this.c = c;
+ this.basicConstraints = basicConstraints;
+ this.keyUsage = keyUsage;
+ this.sigAlgName = sigAlgName;
+ this.sigAlgParams = sigAlgParams;
+ }
+
+ public X500Name getIssuerX500Name()
+ {
+ return c.getIssuer();
+ }
+
+ public TBSCertificate getTBSCertificateNative()
+ {
+ return c.getTBSCertificate();
+ }
+
+ public X500Name getSubjectX500Name()
+ {
+ return c.getSubject();
+ }
+
+ public void checkValidity()
+ throws CertificateExpiredException, CertificateNotYetValidException
+ {
+ this.checkValidity(new Date());
+ }
+
+ public void checkValidity(
+ Date date)
+ throws CertificateExpiredException, CertificateNotYetValidException
+ {
+ if (date.getTime() > this.getNotAfter().getTime()) // for other VM compatibility
+ {
+ throw new CertificateExpiredException("certificate expired on " + c.getEndDate().getTime());
+ }
+
+ if (date.getTime() < this.getNotBefore().getTime())
+ {
+ throw new CertificateNotYetValidException("certificate not valid till " + c.getStartDate().getTime());
+ }
+ }
+
+ public int getVersion()
+ {
+ return c.getVersionNumber();
+ }
+
+ public BigInteger getSerialNumber()
+ {
+ return c.getSerialNumber().getValue();
+ }
+
+ public Principal getIssuerDN()
+ {
+ return new X509Principal(c.getIssuer());
+ }
+
+ public X500Principal getIssuerX500Principal()
+ {
+ try
+ {
+ byte[] encoding = c.getIssuer().getEncoded(ASN1Encoding.DER);
+
+ return new X500Principal(encoding);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("can't encode issuer DN");
+ }
+ }
+
+ public Principal getSubjectDN()
+ {
+ return new X509Principal(c.getSubject());
+ }
+
+ public X500Principal getSubjectX500Principal()
+ {
+ try
+ {
+ byte[] encoding = c.getSubject().getEncoded(ASN1Encoding.DER);
+
+ return new X500Principal(encoding);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("can't encode subject DN");
+ }
+ }
+
+ public Date getNotBefore()
+ {
+ return c.getStartDate().getDate();
+ }
+
+ public Date getNotAfter()
+ {
+ return c.getEndDate().getDate();
+ }
+
+ public byte[] getTBSCertificate()
+ throws CertificateEncodingException
+ {
+ try
+ {
+ return c.getTBSCertificate().getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException(e.toString());
+ }
+ }
+
+ public byte[] getSignature()
+ {
+ return c.getSignature().getOctets();
+ }
+
+ /**
+ * return a more "meaningful" representation for the signature algorithm used in
+ * the certificate.
+ */
+ public String getSigAlgName()
+ {
+ return sigAlgName;
+ }
+
+ /**
+ * return the object identifier for the signature.
+ */
+ public String getSigAlgOID()
+ {
+ return c.getSignatureAlgorithm().getAlgorithm().getId();
+ }
+
+ /**
+ * return the signature parameters, or null if there aren't any.
+ */
+ public byte[] getSigAlgParams()
+ {
+ return Arrays.clone(sigAlgParams);
+ }
+
+ public boolean[] getIssuerUniqueID()
+ {
+ DERBitString id = c.getTBSCertificate().getIssuerUniqueId();
+
+ if (id != null)
+ {
+ byte[] bytes = id.getBytes();
+ boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
+
+ for (int i = 0; i != boolId.length; i++)
+ {
+ boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ }
+
+ return boolId;
+ }
+
+ return null;
+ }
+
+ public boolean[] getSubjectUniqueID()
+ {
+ DERBitString id = c.getTBSCertificate().getSubjectUniqueId();
+
+ if (id != null)
+ {
+ byte[] bytes = id.getBytes();
+ boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
+
+ for (int i = 0; i != boolId.length; i++)
+ {
+ boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ }
+
+ return boolId;
+ }
+
+ return null;
+ }
+
+ public boolean[] getKeyUsage()
+ {
+ return Arrays.clone(keyUsage);
+ }
+
+ public List getExtendedKeyUsage()
+ throws CertificateParsingException
+ {
+ byte[] extOctets = getExtensionOctets(c, "2.5.29.37");
+ if (null == extOctets)
+ {
+ return null;
+ }
+
+ try
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(ASN1Primitive.fromByteArray(extOctets));
+
+ List list = new ArrayList();
+ for (int i = 0; i != seq.size(); i++)
+ {
+ list.add(((ASN1ObjectIdentifier)seq.getObjectAt(i)).getId());
+ }
+ return Collections.unmodifiableList(list);
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException("error processing extended key usage extension");
+ }
+ }
+
+ public int getBasicConstraints()
+ {
+ if (basicConstraints != null)
+ {
+ if (basicConstraints.isCA())
+ {
+ if (basicConstraints.getPathLenConstraint() == null)
+ {
+ return Integer.MAX_VALUE;
+ }
+ else
+ {
+ return basicConstraints.getPathLenConstraint().intValue();
+ }
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ return -1;
+ }
+
+ public Collection getSubjectAlternativeNames()
+ throws CertificateParsingException
+ {
+ return getAlternativeNames(c, Extension.subjectAlternativeName.getId());
+ }
+
+ public Collection getIssuerAlternativeNames()
+ throws CertificateParsingException
+ {
+ return getAlternativeNames(c, Extension.issuerAlternativeName.getId());
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ if (this.getVersion() == 3)
+ {
+ Set set = new HashSet();
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+ }
+
+ return null;
+ }
+
+ public byte[] getExtensionValue(String oid)
+ {
+ ASN1OctetString extValue = getExtensionValue(c, oid);
+ if (null != extValue)
+ {
+ try
+ {
+ return extValue.getEncoded();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException("error parsing " + e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ if (this.getVersion() == 3)
+ {
+ Set set = new HashSet();
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (!ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+ }
+
+ return null;
+ }
+
+ public boolean hasUnsupportedCriticalExtension()
+ {
+ if (this.getVersion() == 3)
+ {
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+
+ if (oid.equals(Extension.keyUsage)
+ || oid.equals(Extension.certificatePolicies)
+ || oid.equals(Extension.policyMappings)
+ || oid.equals(Extension.inhibitAnyPolicy)
+ || oid.equals(Extension.cRLDistributionPoints)
+ || oid.equals(Extension.issuingDistributionPoint)
+ || oid.equals(Extension.deltaCRLIndicator)
+ || oid.equals(Extension.policyConstraints)
+ || oid.equals(Extension.basicConstraints)
+ || oid.equals(Extension.subjectAlternativeName)
+ || oid.equals(Extension.nameConstraints))
+ {
+ continue;
+ }
+
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.isCritical())
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public PublicKey getPublicKey()
+ {
+ try
+ {
+ return BouncyCastleProvider.getPublicKey(c.getSubjectPublicKeyInfo());
+ }
+ catch (IOException e)
+ {
+ return null; // should never happen...
+ }
+ }
+
+ public byte[] getEncoded()
+ throws CertificateEncodingException
+ {
+ try
+ {
+ return c.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException(e.toString());
+ }
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append(" [0] Version: ").append(this.getVersion()).append(nl);
+ buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl);
+ buf.append(" IssuerDN: ").append(this.getIssuerDN()).append(nl);
+ buf.append(" Start Date: ").append(this.getNotBefore()).append(nl);
+ buf.append(" Final Date: ").append(this.getNotAfter()).append(nl);
+ buf.append(" SubjectDN: ").append(this.getSubjectDN()).append(nl);
+ buf.append(" Public Key: ").append(this.getPublicKey()).append(nl);
+ buf.append(" Signature Algorithm: ").append(this.getSigAlgName()).append(nl);
+
+ X509SignatureUtil.prettyPrintSignature(this.getSignature(), buf, nl);
+
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ if (e.hasMoreElements())
+ {
+ buf.append(" Extensions: \n");
+ }
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.getExtnValue() != null)
+ {
+ byte[] octs = ext.getExtnValue().getOctets();
+ ASN1InputStream dIn = new ASN1InputStream(octs);
+ buf.append(" critical(").append(ext.isCritical()).append(") ");
+ try
+ {
+ if (oid.equals(Extension.basicConstraints))
+ {
+ buf.append(BasicConstraints.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid.equals(Extension.keyUsage))
+ {
+ buf.append(KeyUsage.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid.equals(MiscObjectIdentifiers.netscapeCertType))
+ {
+ buf.append(new NetscapeCertType(DERBitString.getInstance(dIn.readObject()))).append(nl);
+ }
+ else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL))
+ {
+ buf.append(new NetscapeRevocationURL(DERIA5String.getInstance(dIn.readObject()))).append(nl);
+ }
+ else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension))
+ {
+ buf.append(new VerisignCzagExtension(DERIA5String.getInstance(dIn.readObject()))).append(nl);
+ }
+ else
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl);
+ //buf.append(" value = ").append("*****").append(nl);
+ }
+ }
+ catch (Exception ex)
+ {
+ buf.append(oid.getId());
+ // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl);
+ buf.append(" value = ").append("*****").append(nl);
+ }
+ }
+ else
+ {
+ buf.append(nl);
+ }
+ }
+ }
+
+ return buf.toString();
+ }
+
+ public final void verify(
+ PublicKey key)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException
+ {
+ try
+ {
+ return bcHelper.createSignature(sigName);
+ }
+ catch (Exception e)
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+
+ public final void verify(
+ PublicKey key,
+ final String sigProvider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ if (sigProvider != null)
+ {
+ return Signature.getInstance(sigName, sigProvider);
+ }
+ else
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+
+ public final void verify(
+ PublicKey key,
+ final Provider sigProvider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
+ try
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException
+ {
+ if (sigProvider != null)
+ {
+ return Signature.getInstance(sigName, sigProvider);
+ }
+ else
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+ catch (NoSuchProviderException e)
+ {
+ // can't happen, but just in case
+ throw new NoSuchAlgorithmException("provider issue: " + e.getMessage());
+ }
+ }
+
+ private void doVerify(
+ PublicKey key,
+ SignatureCreator signatureCreator)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException, NoSuchProviderException
+ {
+ if (key instanceof CompositePublicKey && X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
+ {
+ List<PublicKey> pubKeys = ((CompositePublicKey)key).getPublicKeys();
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+
+ boolean success = false;
+ for (int i = 0; i != pubKeys.size(); i++)
+ {
+ if (pubKeys.get(i) == null)
+ {
+ continue;
+ }
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ String sigName = X509SignatureUtil.getSignatureName(sigAlg);
+
+ Signature signature = signatureCreator.createSignature(sigName);
+
+ SignatureException sigExc = null;
+
+ try
+ {
+ checkSignature(
+ (PublicKey)pubKeys.get(i), signature,
+ sigAlg.getParameters(),
+ DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ success = true;
+ }
+ catch (SignatureException e)
+ {
+ sigExc = e;
+ }
+
+ if (sigExc != null)
+ {
+ throw sigExc;
+ }
+ }
+
+ if (!success)
+ {
+ throw new InvalidKeyException("no matching key found");
+ }
+ }
+ else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
+ {
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+
+ boolean success = false;
+ for (int i = 0; i != sigSeq.size(); i++)
+ {
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ String sigName = X509SignatureUtil.getSignatureName(sigAlg);
+
+ SignatureException sigExc = null;
+
+ try
+ {
+ Signature signature = signatureCreator.createSignature(sigName);
+
+ checkSignature(
+ key, signature,
+ sigAlg.getParameters(),
+ DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+
+ success = true;
+ }
+ catch (InvalidKeyException e)
+ {
+ // ignore
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // ignore
+ }
+ catch (SignatureException e)
+ {
+ sigExc = e;
+ }
+
+ if (sigExc != null)
+ {
+ throw sigExc;
+ }
+ }
+
+ if (!success)
+ {
+ throw new InvalidKeyException("no matching key found");
+ }
+ }
+ else
+ {
+ String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
+
+ Signature signature = signatureCreator.createSignature(sigName);
+
+ if (key instanceof CompositePublicKey)
+ {
+ List<PublicKey> keys = ((CompositePublicKey)key).getPublicKeys();
+
+ for (int i = 0; i != keys.size(); i++)
+ {
+ try
+ {
+ checkSignature((PublicKey)keys.get(i), signature,
+ c.getSignatureAlgorithm().getParameters(), this.getSignature());
+ return; // found the match!
+ }
+ catch (InvalidKeyException e)
+ {
+ // continue;
+ }
+ }
+
+ throw new InvalidKeyException("no matching signature found");
+ }
+ else
+ {
+ checkSignature(key, signature,
+ c.getSignatureAlgorithm().getParameters(), this.getSignature());
+ }
+ }
+ }
+
+ private void checkSignature(
+ PublicKey key,
+ Signature signature,
+ ASN1Encodable params,
+ byte[] sigBytes)
+ throws CertificateException, NoSuchAlgorithmException,
+ SignatureException, InvalidKeyException
+ {
+ if (!isAlgIdEqual(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature()))
+ {
+ throw new CertificateException("signature algorithm in TBS cert not same as outer cert");
+ }
+
+ // TODO This should go after the initVerify?
+ X509SignatureUtil.setSignatureParameters(signature, params);
+
+ signature.initVerify(key);
+
+ try
+ {
+ OutputStream sigOut = new BufferedOutputStream(OutputStreamFactory.createStream(signature), 512);
+
+ c.getTBSCertificate().encodeTo(sigOut, ASN1Encoding.DER);
+
+ sigOut.close();
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException(e.toString());
+ }
+
+ if (!signature.verify(sigBytes))
+ {
+ throw new SignatureException("certificate does not verify with supplied key");
+ }
+ }
+
+ private boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2)
+ {
+ if (!id1.getAlgorithm().equals(id2.getAlgorithm()))
+ {
+ return false;
+ }
+
+ if (Properties.isOverrideSet("org.bouncycastle.x509.allow_absent_equiv_NULL"))
+ {
+ if (id1.getParameters() == null)
+ {
+ if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ 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;
+ }
+
+ private static Collection getAlternativeNames(org.bouncycastle.asn1.x509.Certificate c, String oid)
+ throws CertificateParsingException
+ {
+ byte[] extOctets = getExtensionOctets(c, oid);
+ if (extOctets == null)
+ {
+ return null;
+ }
+ try
+ {
+ Collection temp = new ArrayList();
+ Enumeration it = ASN1Sequence.getInstance(extOctets).getObjects();
+ while (it.hasMoreElements())
+ {
+ GeneralName genName = GeneralName.getInstance(it.nextElement());
+ List list = new ArrayList();
+ list.add(Integers.valueOf(genName.getTagNo()));
+ switch (genName.getTagNo())
+ {
+ case GeneralName.ediPartyName:
+ case GeneralName.x400Address:
+ case GeneralName.otherName:
+ list.add(genName.getEncoded());
+ break;
+ case GeneralName.directoryName:
+ list.add(X500Name.getInstance(RFC4519Style.INSTANCE, genName.getName()).toString());
+ break;
+ case GeneralName.dNSName:
+ case GeneralName.rfc822Name:
+ case GeneralName.uniformResourceIdentifier:
+ list.add(((ASN1String)genName.getName()).getString());
+ break;
+ case GeneralName.registeredID:
+ list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId());
+ break;
+ case GeneralName.iPAddress:
+ byte[] addrBytes = DEROctetString.getInstance(genName.getName()).getOctets();
+ final String addr;
+ try
+ {
+ addr = InetAddress.getByAddress(addrBytes).getHostAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ continue;
+ }
+ list.add(addr);
+ break;
+ default:
+ throw new IOException("Bad tag number: " + genName.getTagNo());
+ }
+
+ temp.add(Collections.unmodifiableList(list));
+ }
+ if (temp.size() == 0)
+ {
+ return null;
+ }
+ return Collections.unmodifiableCollection(temp);
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException(e.getMessage());
+ }
+ }
+
+ protected static byte[] getExtensionOctets(org.bouncycastle.asn1.x509.Certificate c, String oid)
+ {
+ ASN1OctetString extValue = getExtensionValue(c, oid);
+ if (null != extValue)
+ {
+ return extValue.getOctets();
+ }
+ return null;
+ }
+
+ protected static ASN1OctetString getExtensionValue(org.bouncycastle.asn1.x509.Certificate c, String oid)
+ {
+ Extensions exts = c.getTBSCertificate().getExtensions();
+ if (null != exts)
+ {
+ Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
+ if (null != ext)
+ {
+ return ext.getExtnValue();
+ }
+ }
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
new file mode 100644
index 00000000..b6d8ada1
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
@@ -0,0 +1,29 @@
+package org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.security.cert.CertificateEncodingException;
+
+import org.bouncycastle.asn1.x509.BasicConstraints;
+import org.bouncycastle.jcajce.util.JcaJceHelper;
+
+class X509CertificateInternal extends X509CertificateImpl
+{
+ private final byte[] encoding;
+
+ X509CertificateInternal(JcaJceHelper bcHelper, org.bouncycastle.asn1.x509.Certificate c,
+ BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams, byte[] encoding)
+ {
+ super(bcHelper, c, basicConstraints, keyUsage, sigAlgName, sigAlgParams);
+
+ this.encoding = encoding;
+ }
+
+ public byte[] getEncoded() throws CertificateEncodingException
+ {
+ if (null == encoding)
+ {
+ throw new CertificateEncodingException();
+ }
+
+ return encoding;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
index bfd7c254..f90da304 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
@@ -69,476 +69,140 @@ import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
class X509CertificateObject
- extends X509Certificate
+ extends X509CertificateImpl
implements PKCS12BagAttributeCarrier
{
- private JcaJceHelper bcHelper;
- private org.bouncycastle.asn1.x509.Certificate c;
- private BasicConstraints basicConstraints;
- private boolean[] keyUsage;
- private boolean hashValueSet;
- private int hashValue;
+ private final Object cacheLock = new Object();
+ private X509CertificateInternal internalCertificateValue;
+ private X500Principal issuerValue;
+ private PublicKey publicKeyValue;
+ private X500Principal subjectValue;
+ private long[] validityValues;
+
+ private volatile boolean hashValueSet;
+ private volatile int hashValue;
private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl();
- public X509CertificateObject(
- JcaJceHelper bcHelper,
- org.bouncycastle.asn1.x509.Certificate c)
+ X509CertificateObject(JcaJceHelper bcHelper, org.bouncycastle.asn1.x509.Certificate c)
throws CertificateParsingException
{
- this.bcHelper = bcHelper;
- this.c = c;
-
- try
- {
- byte[] bytes = this.getExtensionBytes("2.5.29.19");
-
- if (bytes != null)
- {
- basicConstraints = BasicConstraints.getInstance(ASN1Primitive.fromByteArray(bytes));
- }
- }
- catch (Exception e)
- {
- throw new CertificateParsingException("cannot construct BasicConstraints: " + e);
- }
-
- try
- {
- byte[] bytes = this.getExtensionBytes("2.5.29.15");
- if (bytes != null)
- {
- ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes));
-
- bytes = bits.getBytes();
- int length = (bytes.length * 8) - bits.getPadBits();
-
- keyUsage = new boolean[(length < 9) ? 9 : length];
-
- for (int i = 0; i != length; i++)
- {
- keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
- }
- }
- else
- {
- keyUsage = null;
- }
- }
- catch (Exception e)
- {
- throw new CertificateParsingException("cannot construct KeyUsage: " + e);
- }
+ super(bcHelper, c, createBasicConstraints(c), createKeyUsage(c), createSigAlgName(c), createSigAlgParams(c));
}
- public void checkValidity()
- throws CertificateExpiredException, CertificateNotYetValidException
+ public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException
{
- this.checkValidity(new Date());
- }
+ long checkTime = date.getTime();
+ long[] validityValues = getValidityValues();
- public void checkValidity(
- Date date)
- throws CertificateExpiredException, CertificateNotYetValidException
- {
- if (date.getTime() > this.getNotAfter().getTime()) // for other VM compatibility
+ if (checkTime > validityValues[1]) // for other VM compatibility
{
throw new CertificateExpiredException("certificate expired on " + c.getEndDate().getTime());
}
-
- if (date.getTime() < this.getNotBefore().getTime())
+ if (checkTime < validityValues[0])
{
throw new CertificateNotYetValidException("certificate not valid till " + c.getStartDate().getTime());
}
}
- public int getVersion()
- {
- return c.getVersionNumber();
- }
-
- public BigInteger getSerialNumber()
- {
- return c.getSerialNumber().getValue();
- }
-
- public Principal getIssuerDN()
- {
- try
- {
- return new X509Principal(X500Name.getInstance(c.getIssuer().getEncoded()));
- }
- catch (IOException e)
- {
- return null;
- }
- }
-
public X500Principal getIssuerX500Principal()
{
- try
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
- aOut.writeObject(c.getIssuer());
-
- return new X500Principal(bOut.toByteArray());
- }
- catch (IOException e)
- {
- throw new IllegalStateException("can't encode issuer DN");
- }
- }
-
- public Principal getSubjectDN()
- {
- return new X509Principal(X500Name.getInstance(c.getSubject().toASN1Primitive()));
- }
-
- public X500Principal getSubjectX500Principal()
- {
- try
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
- aOut.writeObject(c.getSubject());
-
- return new X500Principal(bOut.toByteArray());
- }
- catch (IOException e)
- {
- throw new IllegalStateException("can't encode issuer DN");
- }
- }
-
- public Date getNotBefore()
- {
- return c.getStartDate().getDate();
- }
-
- public Date getNotAfter()
- {
- return c.getEndDate().getDate();
- }
-
- public byte[] getTBSCertificate()
- throws CertificateEncodingException
- {
- try
- {
- return c.getTBSCertificate().getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
- {
- throw new CertificateEncodingException(e.toString());
- }
- }
-
- public byte[] getSignature()
- {
- return c.getSignature().getOctets();
- }
-
- /**
- * return a more "meaningful" representation for the signature algorithm used in
- * the certificate.
- */
- public String getSigAlgName()
- {
- return X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
- }
-
- /**
- * return the object identifier for the signature.
- */
- public String getSigAlgOID()
- {
- return c.getSignatureAlgorithm().getAlgorithm().getId();
- }
-
- /**
- * return the signature parameters, or null if there aren't any.
- */
- public byte[] getSigAlgParams()
- {
- if (c.getSignatureAlgorithm().getParameters() != null)
+ synchronized (cacheLock)
{
- try
+ if (null != issuerValue)
{
- return c.getSignatureAlgorithm().getParameters().toASN1Primitive().getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
- {
- return null;
+ return issuerValue;
}
}
- else
- {
- return null;
- }
- }
- public boolean[] getIssuerUniqueID()
- {
- DERBitString id = c.getTBSCertificate().getIssuerUniqueId();
+ X500Principal temp = super.getIssuerX500Principal();
- if (id != null)
+ synchronized (cacheLock)
{
- byte[] bytes = id.getBytes();
- boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
-
- for (int i = 0; i != boolId.length; i++)
+ if (null == issuerValue)
{
- boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ issuerValue = temp;
}
- return boolId;
+ return issuerValue;
}
-
- return null;
}
- public boolean[] getSubjectUniqueID()
+ public PublicKey getPublicKey()
{
- DERBitString id = c.getTBSCertificate().getSubjectUniqueId();
-
- if (id != null)
+ // Cache the public key to support repeated-use optimizations
+ synchronized (cacheLock)
{
- byte[] bytes = id.getBytes();
- boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
-
- for (int i = 0; i != boolId.length; i++)
+ if (null != publicKeyValue)
{
- boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ return publicKeyValue;
}
-
- return boolId;
}
-
- return null;
- }
-
- public boolean[] getKeyUsage()
- {
- return keyUsage;
- }
- public List getExtendedKeyUsage()
- throws CertificateParsingException
- {
- byte[] bytes = this.getExtensionBytes("2.5.29.37");
-
- if (bytes != null)
+ PublicKey temp = super.getPublicKey();
+ if (null == temp)
{
- try
- {
- ASN1InputStream dIn = new ASN1InputStream(bytes);
- ASN1Sequence seq = (ASN1Sequence)dIn.readObject();
- List list = new ArrayList();
-
- for (int i = 0; i != seq.size(); i++)
- {
- list.add(((ASN1ObjectIdentifier)seq.getObjectAt(i)).getId());
- }
-
- return Collections.unmodifiableList(list);
- }
- catch (Exception e)
- {
- throw new CertificateParsingException("error processing extended key usage extension");
- }
+ return null;
}
- return null;
- }
-
- public int getBasicConstraints()
- {
- if (basicConstraints != null)
+ synchronized (cacheLock)
{
- if (basicConstraints.isCA())
+ if (null == publicKeyValue)
{
- if (basicConstraints.getPathLenConstraint() == null)
- {
- return Integer.MAX_VALUE;
- }
- else
- {
- return basicConstraints.getPathLenConstraint().intValue();
- }
+ publicKeyValue = temp;
}
- else
- {
- return -1;
- }
- }
-
- return -1;
- }
-
- public Collection getSubjectAlternativeNames()
- throws CertificateParsingException
- {
- return getAlternativeNames(getExtensionBytes(Extension.subjectAlternativeName.getId()));
- }
-
- public Collection getIssuerAlternativeNames()
- throws CertificateParsingException
- {
- return getAlternativeNames(getExtensionBytes(Extension.issuerAlternativeName.getId()));
- }
-
- public Set getCriticalExtensionOIDs()
- {
- if (this.getVersion() == 3)
- {
- Set set = new HashSet();
- Extensions extensions = c.getTBSCertificate().getExtensions();
-
- if (extensions != null)
- {
- Enumeration e = extensions.oids();
- while (e.hasMoreElements())
- {
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
- Extension ext = extensions.getExtension(oid);
-
- if (ext.isCritical())
- {
- set.add(oid.getId());
- }
- }
-
- return set;
- }
+ return publicKeyValue;
}
-
- return null;
}
- private byte[] getExtensionBytes(String oid)
+ public X500Principal getSubjectX500Principal()
{
- Extensions exts = c.getTBSCertificate().getExtensions();
-
- if (exts != null)
+ synchronized (cacheLock)
{
- Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
- if (ext != null)
+ if (null != subjectValue)
{
- return ext.getExtnValue().getOctets();
+ return subjectValue;
}
}
- return null;
- }
+ X500Principal temp = super.getSubjectX500Principal();
- public byte[] getExtensionValue(String oid)
- {
- Extensions exts = c.getTBSCertificate().getExtensions();
-
- if (exts != null)
+ synchronized (cacheLock)
{
- Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
-
- if (ext != null)
+ if (null == subjectValue)
{
- try
- {
- return ext.getExtnValue().getEncoded();
- }
- catch (Exception e)
- {
- throw new IllegalStateException("error parsing " + e.toString());
- }
+ subjectValue = temp;
}
- }
- return null;
+ return subjectValue;
+ }
}
- public Set getNonCriticalExtensionOIDs()
+ public long[] getValidityValues()
{
- if (this.getVersion() == 3)
+ synchronized (cacheLock)
{
- Set set = new HashSet();
- Extensions extensions = c.getTBSCertificate().getExtensions();
-
- if (extensions != null)
+ if (null != validityValues)
{
- Enumeration e = extensions.oids();
-
- while (e.hasMoreElements())
- {
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
- Extension ext = extensions.getExtension(oid);
-
- if (!ext.isCritical())
- {
- set.add(oid.getId());
- }
- }
-
- return set;
+ return validityValues;
}
}
- return null;
- }
-
- public boolean hasUnsupportedCriticalExtension()
- {
- if (this.getVersion() == 3)
+ long[] temp = new long[]
{
- Extensions extensions = c.getTBSCertificate().getExtensions();
+ super.getNotBefore().getTime(),
+ super.getNotAfter().getTime()
+ };
- if (extensions != null)
+ synchronized (cacheLock)
+ {
+ if (null == validityValues)
{
- Enumeration e = extensions.oids();
-
- while (e.hasMoreElements())
- {
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
-
- if (oid.equals(Extension.keyUsage)
- || oid.equals(Extension.certificatePolicies)
- || oid.equals(Extension.policyMappings)
- || oid.equals(Extension.inhibitAnyPolicy)
- || oid.equals(Extension.cRLDistributionPoints)
- || oid.equals(Extension.issuingDistributionPoint)
- || oid.equals(Extension.deltaCRLIndicator)
- || oid.equals(Extension.policyConstraints)
- || oid.equals(Extension.basicConstraints)
- || oid.equals(Extension.subjectAlternativeName)
- || oid.equals(Extension.nameConstraints))
- {
- continue;
- }
-
- Extension ext = extensions.getExtension(oid);
-
- if (ext.isCritical())
- {
- return true;
- }
- }
+ validityValues = temp;
}
- }
-
- return false;
- }
- public PublicKey getPublicKey()
- {
- try
- {
- return BouncyCastleProvider.getPublicKey(c.getSubjectPublicKeyInfo());
- }
- catch (IOException e)
- {
- return null; // should never happen...
+ return validityValues;
}
}
@@ -563,36 +227,42 @@ class X509CertificateObject
}
public boolean equals(
- Object o)
+ Object other)
{
- if (o == this)
+ if (other == this)
{
return true;
}
- if (o instanceof X509CertificateObject)
+ if (other instanceof X509CertificateObject)
{
- X509CertificateObject other = (X509CertificateObject)o;
+ X509CertificateObject otherBC = (X509CertificateObject)other;
- if (this.hashValueSet && other.hashValueSet)
+ if (this.hashValueSet && otherBC.hashValueSet)
{
- if (this.hashValue != other.hashValue)
+ if (this.hashValue != otherBC.hashValue)
+ {
+ return false;
+ }
+ }
+ else if (null == internalCertificateValue || null == otherBC.internalCertificateValue)
+ {
+ ASN1BitString signature = c.getSignature();
+ if (null != signature && !signature.equals(otherBC.c.getSignature()))
{
return false;
}
}
-
- return this.c.equals(other.c);
}
- return super.equals(o);
+ return getInternalCertificate().equals(other);
}
- public synchronized int hashCode()
+ public int hashCode()
{
if (!hashValueSet)
{
- hashValue = super.hashCode();
+ hashValue = getInternalCertificate().hashCode();
hashValueSet = true;
}
@@ -609,7 +279,7 @@ class X509CertificateObject
try
{
int hashCode = 0;
- byte[] certData = this.getEncoded();
+ byte[] certData = getInternalCertificate().getEncoded();
for (int i = 1; i < certData.length; i++)
{
hashCode += certData[i] * i;
@@ -622,15 +292,12 @@ class X509CertificateObject
}
}
- public void setBagAttribute(
- ASN1ObjectIdentifier oid,
- ASN1Encodable attribute)
+ public void setBagAttribute(ASN1ObjectIdentifier oid, ASN1Encodable attribute)
{
attrCarrier.setBagAttribute(oid, attribute);
}
- public ASN1Encodable getBagAttribute(
- ASN1ObjectIdentifier oid)
+ public ASN1Encodable getBagAttribute(ASN1ObjectIdentifier oid)
{
return attrCarrier.getBagAttribute(oid);
}
@@ -640,284 +307,116 @@ class X509CertificateObject
return attrCarrier.getBagAttributeKeys();
}
- public String toString()
+ private X509CertificateInternal getInternalCertificate()
{
- StringBuffer buf = new StringBuffer();
- String nl = Strings.lineSeparator();
-
- buf.append(" [0] Version: ").append(this.getVersion()).append(nl);
- buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl);
- buf.append(" IssuerDN: ").append(this.getIssuerDN()).append(nl);
- buf.append(" Start Date: ").append(this.getNotBefore()).append(nl);
- buf.append(" Final Date: ").append(this.getNotAfter()).append(nl);
- buf.append(" SubjectDN: ").append(this.getSubjectDN()).append(nl);
- buf.append(" Public Key: ").append(this.getPublicKey()).append(nl);
- buf.append(" Signature Algorithm: ").append(this.getSigAlgName()).append(nl);
-
- byte[] sig = this.getSignature();
-
- buf.append(" Signature: ").append(new String(Hex.encode(sig, 0, 20))).append(nl);
- for (int i = 20; i < sig.length; i += 20)
+ synchronized (cacheLock)
{
- if (i < sig.length - 20)
- {
- buf.append(" ").append(new String(Hex.encode(sig, i, 20))).append(nl);
- }
- else
+ if (null != internalCertificateValue)
{
- buf.append(" ").append(new String(Hex.encode(sig, i, sig.length - i))).append(nl);
+ return internalCertificateValue;
}
}
- Extensions extensions = c.getTBSCertificate().getExtensions();
-
- if (extensions != null)
- {
- Enumeration e = extensions.oids();
-
- if (e.hasMoreElements())
- {
- buf.append(" Extensions: \n");
- }
-
- while (e.hasMoreElements())
- {
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
- Extension ext = extensions.getExtension(oid);
-
- if (ext.getExtnValue() != null)
- {
- byte[] octs = ext.getExtnValue().getOctets();
- ASN1InputStream dIn = new ASN1InputStream(octs);
- buf.append(" critical(").append(ext.isCritical()).append(") ");
- try
- {
- if (oid.equals(Extension.basicConstraints))
- {
- buf.append(BasicConstraints.getInstance(dIn.readObject())).append(nl);
- }
- else if (oid.equals(Extension.keyUsage))
- {
- buf.append(KeyUsage.getInstance(dIn.readObject())).append(nl);
- }
- else if (oid.equals(MiscObjectIdentifiers.netscapeCertType))
- {
- buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl);
- }
- else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL))
- {
- buf.append(new NetscapeRevocationURL((DERIA5String)dIn.readObject())).append(nl);
- }
- else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension))
- {
- buf.append(new VerisignCzagExtension((DERIA5String)dIn.readObject())).append(nl);
- }
- else
- {
- buf.append(oid.getId());
- buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl);
- //buf.append(" value = ").append("*****").append(nl);
- }
- }
- catch (Exception ex)
- {
- buf.append(oid.getId());
- // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl);
- buf.append(" value = ").append("*****").append(nl);
- }
- }
- else
- {
- buf.append(nl);
- }
- }
- }
-
- return buf.toString();
- }
-
- public final void verify(
- PublicKey key)
- throws CertificateException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException
- {
- Signature signature;
- String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
-
+ byte[] encoding;
try
{
- signature = bcHelper.createSignature(sigName);
+ encoding = getEncoded();
}
- catch (Exception e)
+ catch (CertificateEncodingException e)
{
- signature = Signature.getInstance(sigName);
+ encoding = null;
}
-
- checkSignature(key, signature);
- }
-
- public final void verify(
- PublicKey key,
- String sigProvider)
- throws CertificateException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException
- {
- String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
- Signature signature;
- if (sigProvider != null)
- {
- signature = Signature.getInstance(sigName, sigProvider);
- }
- else
+ X509CertificateInternal temp = new X509CertificateInternal(bcHelper, c, basicConstraints, keyUsage, sigAlgName,
+ sigAlgParams, encoding);
+
+ synchronized (cacheLock)
{
- signature = Signature.getInstance(sigName);
+ if (null == internalCertificateValue)
+ {
+ internalCertificateValue = temp;
+ }
+
+ return internalCertificateValue;
}
-
- checkSignature(key, signature);
}
- public final void verify(
- PublicKey key,
- Provider sigProvider)
- throws CertificateException, NoSuchAlgorithmException,
- InvalidKeyException, SignatureException
+ private static BasicConstraints createBasicConstraints(org.bouncycastle.asn1.x509.Certificate c)
+ throws CertificateParsingException
{
- String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
- Signature signature;
-
- if (sigProvider != null)
+ try
{
- signature = Signature.getInstance(sigName, sigProvider);
+ byte[] extOctets = getExtensionOctets(c, "2.5.29.19");
+ if (null == extOctets)
+ {
+ return null;
+ }
+
+ return BasicConstraints.getInstance(ASN1Primitive.fromByteArray(extOctets));
}
- else
+ catch (Exception e)
{
- signature = Signature.getInstance(sigName);
+ throw new CertificateParsingException("cannot construct BasicConstraints: " + e);
}
-
- checkSignature(key, signature);
}
- private void checkSignature(
- PublicKey key,
- Signature signature)
- throws CertificateException, NoSuchAlgorithmException,
- SignatureException, InvalidKeyException
+ private static boolean[] createKeyUsage(org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException
{
- if (!isAlgIdEqual(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature()))
+ try
{
- throw new CertificateException("signature algorithm in TBS cert not same as outer cert");
- }
+ byte[] extOctets = getExtensionOctets(c, "2.5.29.15");
+ if (null == extOctets)
+ {
+ return null;
+ }
- ASN1Encodable params = c.getSignatureAlgorithm().getParameters();
+ ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(extOctets));
- // TODO This should go after the initVerify?
- X509SignatureUtil.setSignatureParameters(signature, params);
+ byte[] bytes = bits.getBytes();
+ int length = (bytes.length * 8) - bits.getPadBits();
- signature.initVerify(key);
+ boolean[] keyUsage = new boolean[(length < 9) ? 9 : length];
- signature.update(this.getTBSCertificate());
+ for (int i = 0; i != length; i++)
+ {
+ keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ }
- if (!signature.verify(this.getSignature()))
+ return keyUsage;
+ }
+ catch (Exception e)
{
- throw new SignatureException("certificate does not verify with supplied key");
+ throw new CertificateParsingException("cannot construct KeyUsage: " + e);
}
}
- private boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2)
+ private static String createSigAlgName(org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException
{
- if (!id1.getAlgorithm().equals(id2.getAlgorithm()))
- {
- return false;
- }
-
- if (id1.getParameters() == null)
+ try
{
- if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE))
- {
- return false;
- }
-
- return true;
+ return X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
}
-
- if (id2.getParameters() == null)
+ catch (Exception e)
{
- if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE))
- {
- return false;
- }
-
- return true;
+ throw new CertificateParsingException("cannot construct SigAlgName: " + e);
}
-
- return id1.getParameters().equals(id2.getParameters());
}
- private static Collection getAlternativeNames(byte[] extVal)
- throws CertificateParsingException
+ private static byte[] createSigAlgParams(org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException
{
- if (extVal == null)
- {
- return null;
- }
try
{
- Collection temp = new ArrayList();
- Enumeration it = ASN1Sequence.getInstance(extVal).getObjects();
- while (it.hasMoreElements())
- {
- GeneralName genName = GeneralName.getInstance(it.nextElement());
- List list = new ArrayList();
- list.add(Integers.valueOf(genName.getTagNo()));
- switch (genName.getTagNo())
- {
- case GeneralName.ediPartyName:
- case GeneralName.x400Address:
- case GeneralName.otherName:
- list.add(genName.getEncoded());
- break;
- case GeneralName.directoryName:
- // Android-changed: Unknown reason
- // list.add(X500Name.getInstance(RFC4519Style.INSTANCE, genName.getName()).toString());
- list.add(X509Name.getInstance(genName.getName()).toString(true, X509Name.DefaultSymbols));
- break;
- case GeneralName.dNSName:
- case GeneralName.rfc822Name:
- case GeneralName.uniformResourceIdentifier:
- list.add(((ASN1String)genName.getName()).getString());
- break;
- case GeneralName.registeredID:
- list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId());
- break;
- case GeneralName.iPAddress:
- byte[] addrBytes = DEROctetString.getInstance(genName.getName()).getOctets();
- final String addr;
- try
- {
- addr = InetAddress.getByAddress(addrBytes).getHostAddress();
- }
- catch (UnknownHostException e)
- {
- continue;
- }
- list.add(addr);
- break;
- default:
- throw new IOException("Bad tag number: " + genName.getTagNo());
- }
-
- temp.add(Collections.unmodifiableList(list));
- }
- if (temp.size() == 0)
+ ASN1Encodable parameters = c.getSignatureAlgorithm().getParameters();
+ if (null == parameters)
{
return null;
}
- return Collections.unmodifiableCollection(temp);
+
+ return parameters.toASN1Primitive().getEncoded(ASN1Encoding.DER);
}
catch (Exception e)
{
- throw new CertificateParsingException(e.getMessage());
+ throw new CertificateParsingException("cannot construct SigAlgParams: " + e);
}
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
index d94dd16f..f83f213d 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
@@ -10,22 +10,43 @@ import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.PSSParameterSpec;
+import java.util.HashMap;
+import java.util.Map;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Null;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERNull;
+// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
+import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.jcajce.util.MessageDigestUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.util.encoders.Hex;
class X509SignatureUtil
{
- private static final ASN1Null derNull = DERNull.INSTANCE;
+ private static final Map<ASN1ObjectIdentifier, String> algNames = new HashMap<ASN1ObjectIdentifier, String>();
+
+ static
+ {
+ // algNames.put(EdECObjectIdentifiers.id_Ed25519, "Ed25519");
+ // algNames.put(EdECObjectIdentifiers.id_Ed448, "Ed448");
+ algNames.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1withDSA");
+ algNames.put(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1withDSA");
+ }
+
+ private static final ASN1Null derNull = DERNull.INSTANCE;
+
+ static boolean isCompositeAlgorithm(AlgorithmIdentifier algorithmIdentifier)
+ {
+ return MiscObjectIdentifiers.id_alg_composite.equals(algorithmIdentifier.getAlgorithm());
+ }
static void setSignatureParameters(
Signature signature,
@@ -34,8 +55,8 @@ class X509SignatureUtil
{
if (params != null && !derNull.equals(params))
{
- AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider());
-
+ AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider());
+
try
{
sigParams.init(params.toASN1Primitive().getEncoded());
@@ -44,7 +65,7 @@ class X509SignatureUtil
{
throw new SignatureException("IOException decoding parameters: " + e.getMessage());
}
-
+
if (signature.getAlgorithm().endsWith("MGF1"))
{
try
@@ -58,34 +79,63 @@ class X509SignatureUtil
}
}
}
-
+
static String getSignatureName(
- AlgorithmIdentifier sigAlgId)
+ AlgorithmIdentifier sigAlgId)
{
ASN1Encodable params = sigAlgId.getParameters();
-
+
if (params != null && !derNull.equals(params))
{
if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
{
RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params);
-
+
return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "withRSAandMGF1";
}
if (sigAlgId.getAlgorithm().equals(X9ObjectIdentifiers.ecdsa_with_SHA2))
{
ASN1Sequence ecDsaParams = ASN1Sequence.getInstance(params);
-
+
return getDigestAlgName((ASN1ObjectIdentifier)ecDsaParams.getObjectAt(0)) + "withECDSA";
}
}
+ // deal with the "weird" ones.
+ String algName = (String)algNames.get(sigAlgId.getAlgorithm());
+ if (algName != null)
+ {
+ return algName;
+ }
+
+ return findAlgName(sigAlgId.getAlgorithm());
+ }
+
+ /**
+ * Return the digest algorithm using one of the standard JCA string
+ * representations rather the the algorithm identifier (if possible).
+ */
+ private static String getDigestAlgName(
+ ASN1ObjectIdentifier digestAlgOID)
+ {
+ String name = MessageDigestUtils.getDigestName(digestAlgOID);
+
+ int dIndex = name.indexOf('-');
+ if (dIndex > 0 && !name.startsWith("SHA3"))
+ {
+ return name.substring(0, dIndex) + name.substring(dIndex + 1);
+ }
+
+ return name;
+ }
+
+ private static String findAlgName(ASN1ObjectIdentifier algOid)
+ {
Provider prov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);
if (prov != null)
{
- String algName = prov.getProperty("Alg.Alias.Signature." + sigAlgId.getAlgorithm().getId());
-
+ String algName = lookupAlg(prov, algOid);
if (algName != null)
{
return algName;
@@ -94,36 +144,61 @@ class X509SignatureUtil
Provider[] provs = Security.getProviders();
- //
- // search every provider looking for a real algorithm
- //
for (int i = 0; i != provs.length; i++)
{
- String algName = provs[i].getProperty("Alg.Alias.Signature." + sigAlgId.getAlgorithm().getId());
- if (algName != null)
+ if (prov != provs[i])
{
- return algName;
+ String algName = lookupAlg(provs[i], algOid);
+ if (algName != null)
+ {
+ return algName;
+ }
}
}
- return sigAlgId.getAlgorithm().getId();
+ return algOid.getId();
}
-
- /**
- * Return the digest algorithm using one of the standard JCA string
- * representations rather the the algorithm identifier (if possible).
- */
- private static String getDigestAlgName(
- ASN1ObjectIdentifier digestAlgOID)
+
+ private static String lookupAlg(Provider prov, ASN1ObjectIdentifier algOid)
{
- String name = MessageDigestUtils.getDigestName(digestAlgOID);
+ String algName = prov.getProperty("Alg.Alias.Signature." + algOid);
- int dIndex = name.indexOf('-');
- if (dIndex > 0 && !name.startsWith("SHA3"))
+ if (algName != null)
{
- return name.substring(0, dIndex) + name.substring(dIndex + 1);
+ return algName;
}
- return MessageDigestUtils.getDigestName(digestAlgOID);
+ algName = prov.getProperty("Alg.Alias.Signature.OID." + algOid);
+
+ if (algName != null)
+ {
+ return algName;
+ }
+
+ return null;
}
+
+ static void prettyPrintSignature(byte[] sig, StringBuffer buf, String nl)
+ {
+ if (sig.length > 20)
+ {
+ buf.append(" Signature: ").append(Hex.toHexString(sig, 0, 20)).append(nl);
+ for (int i = 20; i < sig.length; i += 20)
+ {
+ if (i < sig.length - 20)
+ {
+ buf.append(" ").append(Hex.toHexString(sig, i, 20)).append(nl);
+ }
+ else
+ {
+ buf.append(" ").append(Hex.toHexString(sig, i, sig.length - i)).append(nl);
+ }
+ }
+ }
+ else
+ {
+ buf.append(" Signature: ").append(Hex.toHexString(sig)).append(nl);
+ }
+ }
+
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java
index 768df66e..9818f864 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
@@ -51,5 +51,7 @@ public interface ConfigurableProvider
void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter);
+ AsymmetricKeyInfoConverter getKeyInfoConverter(ASN1ObjectIdentifier oid);
+
void addAttributes(String key, Map<String, String> attributeMap);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
index 3c5b78d7..9c3bddca 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
@@ -3,11 +3,14 @@ package org.bouncycastle.jcajce.provider.digest;
import java.security.MessageDigest;
import org.bouncycastle.crypto.Digest;
+// BEGIN Android-removed:
+// import org.bouncycastle.crypto.Xof;
public class BCMessageDigest
extends MessageDigest
{
protected Digest digest;
+ protected int digestSize;
protected BCMessageDigest(
Digest digest)
@@ -15,8 +18,21 @@ public class BCMessageDigest
super(digest.getAlgorithmName());
this.digest = digest;
+ this.digestSize = digest.getDigestSize();
}
+ // BEGIN Android-removed:
+ /*
+ protected BCMessageDigest(
+ Xof digest, int outputSize)
+ {
+ super(digest.getAlgorithmName());
+
+ this.digest = digest;
+ this.digestSize = outputSize / 8;
+ }
+ */
+ // END Android-removed:
public void engineReset()
{
digest.reset();
@@ -36,9 +52,14 @@ public class BCMessageDigest
digest.update(input, offset, len);
}
+ public int engineGetDigestLength()
+ {
+ return digestSize;
+ }
+
public byte[] engineDigest()
{
- byte[] digestBytes = new byte[digest.getDigestSize()];
+ byte[] digestBytes = new byte[digestSize];
digest.doFinal(digestBytes, 0);
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/MD5.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/MD5.java
index 93a7d716..2acf1011 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/MD5.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/MD5.java
@@ -67,11 +67,15 @@ public class MD5
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
provider.addAlgorithm("MessageDigest.MD5", PREFIX + "$Digest");
provider.addAlgorithm("Alg.Alias.MessageDigest." + PKCSObjectIdentifiers.md5, "MD5");
addHMACAlgorithm(provider, "MD5", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "MD5", IANAObjectIdentifiers.hmacMD5);
+ */
+ // END Android-removed: Unsupported algorithm
}
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA1.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA1.java
index 17a5462a..ba539d29 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA1.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA1.java
@@ -93,6 +93,8 @@ public class SHA1
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
provider.addAlgorithm("MessageDigest.SHA-1", PREFIX + "$Digest");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA1", "SHA-1");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA", "SHA-1");
@@ -101,6 +103,8 @@ public class SHA1
addHMACAlgorithm(provider, "SHA1", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "SHA1", PKCSObjectIdentifiers.id_hmacWithSHA1);
addHMACAlias(provider, "SHA1", IANAObjectIdentifiers.hmacSHA1);
+ */
+ // END Android-removed: Unsupported algorithm
provider.addAlgorithm("Mac.PBEWITHHMACSHA", PREFIX + "$SHA1Mac");
provider.addAlgorithm("Mac.PBEWITHHMACSHA1", PREFIX + "$SHA1Mac");
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 ac83fc23..5c6b699d 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
@@ -64,15 +64,18 @@ public class SHA224
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("MessageDigest.SHA-224", PREFIX + "$Digest");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA224", "SHA-224");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha224, "SHA-224");
provider.addAlgorithm("Mac.PBEWITHHMACSHA224", PREFIX + "$HashMac");
-
+
addHMACAlgorithm(provider, "SHA224", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "SHA224", PKCSObjectIdentifiers.id_hmacWithSHA224);
-
+ */
+ // END Android-removed: Unsupported algorithms
}
}
}
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 af375c22..48f99b4d 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
@@ -84,21 +84,23 @@ public class SHA256
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("MessageDigest.SHA-256", PREFIX + "$Digest");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA256", "SHA-256");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha256, "SHA-256");
- // BEGIN Android-removed: Unsupported algorithms
- // provider.addAlgorithm("SecretKeyFactory.PBEWITHHMACSHA256", PREFIX + "$PBEWithMacKeyFactory");
- // provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHHMACSHA-256", "PBEWITHHMACSHA256");
- // provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + NISTObjectIdentifiers.id_sha256, "PBEWITHHMACSHA256");
- // END Android-removed: Unsupported algorithms
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHHMACSHA256", PREFIX + "$PBEWithMacKeyFactory");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHHMACSHA-256", "PBEWITHHMACSHA256");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + NISTObjectIdentifiers.id_sha256, "PBEWITHHMACSHA256");
provider.addAlgorithm("Mac.PBEWITHHMACSHA256", PREFIX + "$HashMac");
addHMACAlgorithm(provider, "SHA256", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "SHA256", PKCSObjectIdentifiers.id_hmacWithSHA256);
addHMACAlias(provider, "SHA256", NISTObjectIdentifiers.id_sha256);
+ */
+ // END Android-removed: Unsupported algorithms
}
}
}
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 8bddcb23..8f083748 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
@@ -82,16 +82,19 @@ public class SHA384
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("MessageDigest.SHA-384", PREFIX + "$Digest");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA384", "SHA-384");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha384, "SHA-384");
- // Android-removed: Unsupported algorithms
- // provider.addAlgorithm("Mac.OLDHMACSHA384", PREFIX + "$OldSHA384");
+ provider.addAlgorithm("Mac.OLDHMACSHA384", PREFIX + "$OldSHA384");
provider.addAlgorithm("Mac.PBEWITHHMACSHA384", PREFIX + "$HashMac");
addHMACAlgorithm(provider, "SHA384", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "SHA384", PKCSObjectIdentifiers.id_hmacWithSHA384);
+ */
+ // END Android-removed: Unsupported algorithms
}
}
}
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 589e26a3..e227620e 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
@@ -168,12 +168,12 @@ public class SHA512
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("MessageDigest.SHA-512", PREFIX + "$Digest");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512", "SHA-512");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512, "SHA-512");
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAlgorithm("MessageDigest.SHA-512/224", PREFIX + "$DigestT224");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512/224", "SHA-512/224");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512_224, "SHA-512/224");
@@ -183,17 +183,15 @@ public class SHA512
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512_256, "SHA-512/256");
provider.addAlgorithm("Mac.OLDHMACSHA512", PREFIX + "$OldSHA512");
- */
- // END Android-removed: Unsupported algorithms
provider.addAlgorithm("Mac.PBEWITHHMACSHA512", PREFIX + "$HashMac");
addHMACAlgorithm(provider, "SHA512", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "SHA512", PKCSObjectIdentifiers.id_hmacWithSHA512);
- // BEGIN Android-removed: Unsupported algorithms
- // addHMACAlgorithm(provider, "SHA512/224", PREFIX + "$HashMacT224", PREFIX + "$KeyGeneratorT224");
- // addHMACAlgorithm(provider, "SHA512/256", PREFIX + "$HashMacT256", PREFIX + "$KeyGeneratorT256");
+ addHMACAlgorithm(provider, "SHA512/224", PREFIX + "$HashMacT224", PREFIX + "$KeyGeneratorT224");
+ addHMACAlgorithm(provider, "SHA512/256", PREFIX + "$HashMacT256", PREFIX + "$KeyGeneratorT256");
+ */
// END Android-removed: Unsupported algorithms
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
index f9ba6df4..2c439f4e 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
@@ -51,6 +51,8 @@ import org.bouncycastle.crypto.macs.HMac;
// Android-changed: Use default provider for JCA algorithms instead of BC
// Was: import org.bouncycastle.jcajce.util.BCJcaJceHelper;
import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+// import org.bouncycastle.jcajce.io.CipherInputStream;
+// import org.bouncycastle.jcajce.io.CipherOutputStream;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.jce.interfaces.BCKeyStore;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
@@ -145,7 +147,6 @@ public class BcKeyStoreSpi
byte[] salt = new byte[KEY_SALT_SIZE];
- random.setSeed(System.currentTimeMillis());
random.nextBytes(salt);
int iterationCount = MIN_ITERATIONS + (random.nextInt() & 0x3ff);
@@ -682,7 +683,7 @@ public class BcKeyStoreSpi
}
catch (Exception e)
{
- throw new KeyStoreException(e.toString());
+ throw new BCKeyStoreException(e.toString(), e);
}
}
@@ -1068,4 +1069,21 @@ public class BcKeyStoreSpi
super(1);
}
}
+
+ private static class BCKeyStoreException
+ extends KeyStoreException
+ {
+ private final Exception cause;
+
+ public BCKeyStoreException(String msg, Exception cause)
+ {
+ super(msg);
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
}
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 1251ff24..4c3e480d 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
@@ -2,7 +2,6 @@ package org.bouncycastle.jcajce.provider.keystore.pkcs12;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -57,11 +56,10 @@ import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.BEROctetString;
-import org.bouncycastle.asn1.BEROutputStream;
+import org.bouncycastle.asn1.BERSequence;
import org.bouncycastle.asn1.DERBMPString;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DEROctetString;
-import org.bouncycastle.asn1.DEROutputStream;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERSet;
// Android-removed: Unsupported algorithms
@@ -403,26 +401,16 @@ public class PKCS12KeyStoreSpi
X509Certificate x509c = (X509Certificate)c;
Certificate nextC = null;
- byte[] bytes = x509c.getExtensionValue(Extension.authorityKeyIdentifier.getId());
- if (bytes != null)
+ byte[] akiBytes = x509c.getExtensionValue(Extension.authorityKeyIdentifier.getId());
+ if (akiBytes != null)
{
- try
- {
- ASN1InputStream aIn = new ASN1InputStream(bytes);
-
- byte[] authBytes = ((ASN1OctetString)aIn.readObject()).getOctets();
- aIn = new ASN1InputStream(authBytes);
+ ASN1OctetString akiValue = ASN1OctetString.getInstance(akiBytes);
+ AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance(akiValue.getOctets());
- AuthorityKeyIdentifier id = AuthorityKeyIdentifier.getInstance(aIn.readObject());
- if (id.getKeyIdentifier() != null)
- {
- nextC = (Certificate)chainCerts.get(new CertId(id.getKeyIdentifier()));
- }
-
- }
- catch (IOException e)
+ byte[] keyID = aki.getKeyIdentifier();
+ if (null != keyID)
{
- throw new RuntimeException(e.toString());
+ nextC = (Certificate)chainCerts.get(new CertId(keyID));
}
}
@@ -782,11 +770,6 @@ public class PKCS12KeyStoreSpi
return;
}
- if (password == null)
- {
- throw new NullPointerException("No password supplied for PKCS#12 KeyStore.");
- }
-
BufferedInputStream bufIn = new BufferedInputStream(stream);
bufIn.mark(10);
@@ -819,6 +802,11 @@ public class PKCS12KeyStoreSpi
if (bag.getMacData() != null) // check the mac code
{
+ if (password == null)
+ {
+ throw new NullPointerException("no password supplied when one expected");
+ }
+
MacData mData = bag.getMacData();
DigestInfo dInfo = mData.getMac();
macAlgorithm = dInfo.getAlgorithmId();
@@ -860,23 +848,33 @@ public class PKCS12KeyStoreSpi
throw new IOException("error constructing MAC: " + e.toString());
}
}
+ // BEGIN Android-removed: keep v1.61 behaviour to keep backwards-compatibility
+ /*
+ else if (password != null)
+ {
+ if (!Properties.isOverrideSet("org.bouncycastle.pkcs12.ignore_useless_passwd"))
+ {
+ throw new IOException("password supplied for keystore that does not require one");
+ }
+ }
+ */
+ // END Android-removed: keep v1.61 behaviour to keep backwards-compatibility
keys = new IgnoresCaseHashtable();
localIds = new Hashtable();
if (info.getContentType().equals(data))
{
- bIn = new ASN1InputStream(((ASN1OctetString)info.getContent()).getOctets());
-
- AuthenticatedSafe authSafe = AuthenticatedSafe.getInstance(bIn.readObject());
+ ASN1OctetString content = ASN1OctetString.getInstance(info.getContent());
+ AuthenticatedSafe authSafe = AuthenticatedSafe.getInstance(content.getOctets());
ContentInfo[] c = authSafe.getContentInfo();
for (int i = 0; i != c.length; i++)
{
if (c[i].getContentType().equals(data))
{
- ASN1InputStream dIn = new ASN1InputStream(((ASN1OctetString)c[i].getContent()).getOctets());
- ASN1Sequence seq = (ASN1Sequence)dIn.readObject();
+ ASN1OctetString authSafeContent = ASN1OctetString.getInstance(c[i].getContent());
+ ASN1Sequence seq = ASN1Sequence.getInstance(authSafeContent.getOctets());
for (int j = 0; j != seq.size(); j++)
{
@@ -973,7 +971,7 @@ public class PKCS12KeyStoreSpi
EncryptedData d = EncryptedData.getInstance(c[i].getContent());
byte[] octets = cryptData(false, d.getEncryptionAlgorithm(),
password, wrongPKCS12Zero, d.getContent().getOctets());
- ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(octets);
+ ASN1Sequence seq = ASN1Sequence.getInstance(octets);
for (int j = 0; j != seq.size(); j++)
{
@@ -1308,10 +1306,69 @@ public class PKCS12KeyStoreSpi
private void doStore(OutputStream stream, char[] password, boolean useDEREncoding)
throws IOException
{
+ // BEGIN Android-changed: Upstream allows null passwords, but we maintain historical Android
+ // behaviour.
+ // See CtsKeystoreTestCases:android.keystore.cts.KeyStoreTest
if (password == null)
{
throw new NullPointerException("No password supplied for PKCS#12 KeyStore.");
}
+ /*
+ if (keys.size() == 0)
+ {
+ if (password == null)
+ {
+ Enumeration cs = certs.keys();
+
+ ASN1EncodableVector certSeq = new ASN1EncodableVector();
+
+ while (cs.hasMoreElements())
+ {
+ try
+ {
+ String certId = (String)cs.nextElement();
+ Certificate cert = (Certificate)certs.get(certId);
+
+ SafeBag sBag = createSafeBag(certId, cert);
+
+ certSeq.add(sBag);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IOException("Error encoding certificate: " + e.toString());
+ }
+ }
+
+ if (useDEREncoding)
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.DER);
+ }
+ else
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.BER);
+ }
+
+ return;
+ }
+ }
+ else
+ {
+ if (password == null)
+ {
+ throw new NullPointerException("no password supplied for PKCS#12 KeyStore");
+ }
+ }
+ */
+ // END Android-changed: Upstream allows null passwords, but we maintain historical Android
+ // behaviour.
//
// handle the key
@@ -1496,66 +1553,13 @@ public class PKCS12KeyStoreSpi
{
String certId = (String)cs.nextElement();
Certificate cert = (Certificate)certs.get(certId);
- boolean cAttrSet = false;
if (keys.get(certId) != null)
{
continue;
}
- CertBag cBag = new CertBag(
- x509Certificate,
- new DEROctetString(cert.getEncoded()));
- ASN1EncodableVector fName = new ASN1EncodableVector();
-
- if (cert instanceof PKCS12BagAttributeCarrier)
- {
- PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert;
- //
- // make sure we are using the local alias on store
- //
- DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
- if (nm == null || !nm.getString().equals(certId))
- {
- bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(certId));
- }
-
- Enumeration e = bagAttrs.getBagAttributeKeys();
-
- while (e.hasMoreElements())
- {
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
-
- // a certificate not immediately linked to a key doesn't require
- // a localKeyID and will confuse some PKCS12 implementations.
- //
- // If we find one, we'll prune it out.
- if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId))
- {
- continue;
- }
-
- ASN1EncodableVector fSeq = new ASN1EncodableVector();
-
- fSeq.add(oid);
- fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid)));
- fName.add(new DERSequence(fSeq));
-
- cAttrSet = true;
- }
- }
-
- if (!cAttrSet)
- {
- ASN1EncodableVector fSeq = new ASN1EncodableVector();
-
- fSeq.add(pkcs_9_at_friendlyName);
- fSeq.add(new DERSet(new DERBMPString(certId)));
-
- fName.add(new DERSequence(fSeq));
- }
-
- SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName));
+ SafeBag sBag = createSafeBag(certId, cert);
certSeq.add(sBag);
@@ -1640,20 +1644,7 @@ public class PKCS12KeyStoreSpi
AuthenticatedSafe auth = new AuthenticatedSafe(info);
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- DEROutputStream asn1Out;
- if (useDEREncoding)
- {
- asn1Out = new DEROutputStream(bOut);
- }
- else
- {
- asn1Out = new BEROutputStream(bOut);
- }
-
- asn1Out.writeObject(auth);
-
- byte[] pkg = bOut.toByteArray();
+ byte[] pkg = auth.getEncoded(useDEREncoding ? ASN1Encoding.DER : ASN1Encoding.BER);
ContentInfo mainInfo = new ContentInfo(data, new BEROctetString(pkg));
@@ -1686,16 +1677,69 @@ public class PKCS12KeyStoreSpi
//
Pfx pfx = new Pfx(mainInfo, mData);
- if (useDEREncoding)
+ pfx.encodeTo(stream, useDEREncoding ? ASN1Encoding.DER : ASN1Encoding.BER);
+ }
+
+ private SafeBag createSafeBag(String certId, Certificate cert)
+ throws CertificateEncodingException
+ {
+ CertBag cBag = new CertBag(
+ x509Certificate,
+ new DEROctetString(cert.getEncoded()));
+ ASN1EncodableVector fName = new ASN1EncodableVector();
+
+ boolean cAttrSet = false;
+ if (cert instanceof PKCS12BagAttributeCarrier)
{
- asn1Out = new DEROutputStream(stream);
+ PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert;
+ //
+ // make sure we are using the local alias on store
+ //
+ DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
+ if (nm == null || !nm.getString().equals(certId))
+ {
+ if (certId != null)
+ {
+ bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(certId));
+ }
+ }
+
+ Enumeration e = bagAttrs.getBagAttributeKeys();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+
+ // a certificate not immediately linked to a key doesn't require
+ // a localKeyID and will confuse some PKCS12 implementations.
+ //
+ // If we find one, we'll prune it out.
+ if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId))
+ {
+ continue;
+ }
+
+ ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ fSeq.add(oid);
+ fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid)));
+ fName.add(new DERSequence(fSeq));
+
+ cAttrSet = true;
+ }
}
- else
+
+ if (!cAttrSet)
{
- asn1Out = new BEROutputStream(stream);
+ ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ fSeq.add(pkcs_9_at_friendlyName);
+ fSeq.add(new DERSet(new DERBMPString(certId)));
+
+ fName.add(new DERSequence(fSeq));
}
- asn1Out.writeObject(pfx);
+ return new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName));
}
private Set getUsedCertificateSet()
@@ -1835,6 +1879,11 @@ public class PKCS12KeyStoreSpi
{
return orig.elements();
}
+
+ public int size()
+ {
+ return orig.size();
+ }
}
private static class DefaultSecretKeyProvider
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 0615fffe..e7d3ec24 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
@@ -26,6 +26,7 @@ import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.CipherKeyGenerator;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.Mac;
@@ -55,6 +56,7 @@ import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
// import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory;
import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher;
import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider;
+import org.bouncycastle.jcajce.provider.symmetric.util.GcmSpecUtil;
import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters;
import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory;
import org.bouncycastle.jcajce.spec.AEADParameterSpec;
@@ -140,7 +142,7 @@ public final class AES
{
public CCM()
{
- super(new CCMBlockCipher(new AESEngine()), false, 16);
+ super(new CCMBlockCipher(new AESEngine()), false, 12);
}
}
@@ -545,7 +547,7 @@ public final class AES
if (random == null)
{
- random = new SecureRandom();
+ random = CryptoServicesRegistrar.getSecureRandom();
}
random.nextBytes(iv);
@@ -849,6 +851,8 @@ public final class AES
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("AlgorithmParameters.AES", PREFIX + "$AlgParams");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + wrongAES128, "AES");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + wrongAES192, "AES");
@@ -861,9 +865,7 @@ public final class AES
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes128_GCM, "GCM");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes192_GCM, "GCM");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes256_GCM, "GCM");
-
- // BEGIN Android-removed: Unsupported algorithms
- /*
+
provider.addAlgorithm("AlgorithmParameters.CCM", PREFIX + "$AlgParamsCCM");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes128_CCM, "CCM");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes192_CCM, "CCM");
@@ -935,20 +937,14 @@ public final class AES
provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes128_GCM, "GCM");
provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes192_GCM, "GCM");
provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes256_GCM, "GCM");
- */
- // END Android-removed: Unsupported algorithms
-
- // BEGIN Android-changed: Use standard name for AES/GCM/NOPADDING instead of "GCM"
+
provider.addAttributes("Cipher.AES/GCM/NOPADDING", generalAesAttributes);
provider.addAlgorithm("Cipher.AES/GCM/NOPADDING", PREFIX + "$GCM");
provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes128_GCM, "AES/GCM/NOPADDING");
provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes192_GCM, "AES/GCM/NOPADDING");
provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes256_GCM, "AES/GCM/NOPADDING");
- // END Android-changed: Use standard name for AES/GCM/NOPADDING instead of "GCM"
-
+
provider.addAlgorithm("KeyGenerator.AES", PREFIX + "$KeyGen");
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAlgorithm("KeyGenerator." + wrongAES128, PREFIX + "$KeyGen128");
provider.addAlgorithm("KeyGenerator." + wrongAES192, PREFIX + "$KeyGen192");
provider.addAlgorithm("KeyGenerator." + wrongAES256, PREFIX + "$KeyGen256");
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/ARC4.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/ARC4.java
index d1305cbc..2739f4c3 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/ARC4.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/ARC4.java
@@ -95,10 +95,14 @@ public final class ARC4
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("Cipher.ARC4", PREFIX + "$Base");
provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.rc4, "ARC4");
provider.addAlgorithm("Alg.Alias.Cipher.ARCFOUR", "ARC4");
provider.addAlgorithm("Alg.Alias.Cipher.RC4", "ARC4");
+ */
+ // END Android-removed: Unsupported algorithms
provider.addAlgorithm("KeyGenerator.ARC4", PREFIX + "$KeyGen");
provider.addAlgorithm("Alg.Alias.KeyGenerator.RC4", "ARC4");
provider.addAlgorithm("Alg.Alias.KeyGenerator.1.2.840.113549.3.4", "ARC4");
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java
index 24785a43..daee8642 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java
@@ -397,22 +397,21 @@ public final class DESede
provider.addAlgorithm("Alg.Alias.Cipher.TDEA", "DESEDE");
provider.addAlgorithm("Alg.Alias.Cipher.TDEAWRAP", "DESEDEWRAP");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("Alg.Alias.KeyGenerator.TDEA", "DESEDE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.TDEA", "DESEDE");
- // Android-removed: Unsupported algorithms
- // provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator.TDEA", "DESEDE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator.TDEA", "DESEDE");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory.TDEA", "DESEDE");
+ */
+ // END Android-removed: Unsupported algorithms
- if (provider.hasAlgorithm("MessageDigest", "SHA-1"))
+ // Android-removed Bouncy Castle's SHA-1 implementation is removed but we still need PBEWithSHAAnd3-KeyTripleDES-CBC
+ // if (provider.hasAlgorithm("MessageDigest", "SHA-1"))
{
provider.addAlgorithm("Cipher.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES3Key");
- // BEGIN Android-removed: Unsupported algorithms
- // provider.addAlgorithm("Cipher.BROKENPBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$BrokePBEWithSHAAndDES3Key");
- // provider.addAlgorithm("Cipher.OLDPBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$OldPBEWithSHAAndDES3Key");
- // END Android-removed: Unsupported algorithms
provider.addAlgorithm("Cipher.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES2Key");
- // Android-removed: Unsupported algorithms
- // provider.addAlgorithm("Cipher.BROKENPBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$BrokePBEWithSHAAndDES2Key");
+
provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDDESEDE", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
@@ -425,16 +424,14 @@ public final class DESede
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDDESEDE-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
}
- provider.addAlgorithm("KeyGenerator.DESEDE", PREFIX + "$KeyGenerator");
// BEGIN Android-removed: Unsupported algorithms
- // provider.addAlgorithm("KeyGenerator." + PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$KeyGenerator3");
- // provider.addAlgorithm("KeyGenerator.DESEDEWRAP", PREFIX + "$KeyGenerator");
- // END Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("KeyGenerator.DESEDE", PREFIX + "$KeyGenerator");
+ provider.addAlgorithm("KeyGenerator." + PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$KeyGenerator3");
+ provider.addAlgorithm("KeyGenerator.DESEDEWRAP", PREFIX + "$KeyGenerator");
provider.addAlgorithm("SecretKeyFactory.DESEDE", PREFIX + "$KeyFactory");
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAlgorithm("SecretKeyFactory", OIWObjectIdentifiers.desEDE, PREFIX + "$KeyFactory");
provider.addAlgorithm("Mac.DESEDECMAC", PREFIX + "$CMAC");
@@ -451,11 +448,11 @@ public final class DESede
provider.addAlgorithm("Alg.Alias.Mac.DESEDE64WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1MACWITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
- */
- // END Android-removed: Unsupported algorithms
provider.addAlgorithm("AlgorithmParameters.DESEDE", PACKAGE + ".util.IvAlgorithmParameters");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE");
+ */
+ // END Android-removed: Unsupported algorithms
// BEGIN Android-removed: Unsupported algorithms
// provider.addAlgorithm("AlgorithmParameterGenerator.DESEDE", PREFIX + "$AlgParamGen");
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 8474f869..1af79b80 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
@@ -17,6 +17,7 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
// import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PBKDF2Params;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -39,18 +40,21 @@ public class PBEPBKDF2
static
{
- // Android-removed: Unsupported algorithm
- // prfCodes.put(CryptoProObjectIdentifiers.gostR3411Hmac, Integers.valueOf(PBE.GOST3411));
+ // 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));
- // Android-remove: Unsupported algorithms
- // 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));
- // prfCodes.put(NISTObjectIdentifiers.id_hmacWithSHA3_512, Integers.valueOf(PBE.SHA3_512));
+ 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));
+ prfCodes.put(NISTObjectIdentifiers.id_hmacWithSHA3_512, Integers.valueOf(PBE.SHA3_512));
+ prfCodes.put(GMObjectIdentifiers.hmac_sm3, Integers.valueOf(PBE.SM3));
+ */
+ // END Android-removed: Unsupported algorithm
}
private PBEPBKDF2()
@@ -92,7 +96,7 @@ public class PBEPBKDF2
Class paramSpec)
throws InvalidParameterSpecException
{
- if (paramSpec == PBEParameterSpec.class)
+ if (paramSpec == PBEParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
{
return new PBEParameterSpec(params.getSalt(),
params.getIterationCount().intValue());
@@ -536,6 +540,18 @@ public class PBEPBKDF2
}
// END Android-added: Android implementations of PBKDF2 algorithms.
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class PBKDF2withSM3
+ extends BasePBKDF2
+ {
+ public PBKDF2withSM3() {
+ super("PBKDF2", PKCS5S2_UTF8, SM3);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
public static class Mappings
extends AlgorithmProvider
{
@@ -574,6 +590,7 @@ public class PBEPBKDF2
provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA3-384", PREFIX + "$PBKDF2withSHA3_384");
provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA3-512", PREFIX + "$PBKDF2withSHA3_512");
provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACGOST3411", PREFIX + "$PBKDF2withGOST3411");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSM3", PREFIX + "$PBKDF2withSM3");
*/
// END Android-removed: Bouncy Castle versions of algorithms.
// BEGIN Android-added: Android versions of algorithms.
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java
index 9be3c997..3b6efbb8 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java
@@ -52,7 +52,7 @@ public class PBEPKCS12
Class paramSpec)
throws InvalidParameterSpecException
{
- if (paramSpec == PBEParameterSpec.class)
+ if (paramSpec == PBEParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
{
return new PBEParameterSpec(params.getIV(),
params.getIterations().intValue());
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC2.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC2.java
index c4248907..6c7fcc33 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC2.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC2.java
@@ -375,7 +375,7 @@ public final class RC2
}
}
- if (paramSpec == IvParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
+ if (paramSpec == IvParameterSpec.class)
{
return new IvParameterSpec(iv);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
index 85113e12..d4756dfe 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
@@ -1,27 +1,36 @@
package org.bouncycastle.jcajce.provider.symmetric.util;
-import java.security.spec.KeySpec;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.crypto.interfaces.PBEKey;
import javax.crypto.spec.PBEKeySpec;
+import javax.security.auth.Destroyable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.PBEParametersGenerator;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
+import org.bouncycastle.util.Arrays;
public class BCPBEKey
- implements PBEKey
+ implements PBEKey, Destroyable
{
+ private final AtomicBoolean hasBeenDestroyed = new AtomicBoolean(false);
+
String algorithm;
ASN1ObjectIdentifier oid;
int type;
int digest;
int keySize;
int ivSize;
- CipherParameters param;
- PBEKeySpec pbeKeySpec;
+
+ private final char[] password;
+ private final byte[] salt;
+ private final int iterationCount;
+
+ private final CipherParameters param;
+
boolean tryWrong = false;
/**
@@ -43,19 +52,25 @@ public class BCPBEKey
this.digest = digest;
this.keySize = keySize;
this.ivSize = ivSize;
- this.pbeKeySpec = pbeKeySpec;
+ this.password = pbeKeySpec.getPassword();
+ this.iterationCount = pbeKeySpec.getIterationCount();
+ this.salt = pbeKeySpec.getSalt();
this.param = param;
}
- public BCPBEKey(String algName,
- KeySpec pbeSpec, CipherParameters param)
+ public BCPBEKey(String algName, CipherParameters param)
{
this.algorithm = algName;
this.param = param;
+ this.password = null;
+ this.iterationCount = -1;
+ this.salt = null;
}
public String getAlgorithm()
{
+ checkDestroyed(this);
+
return algorithm;
}
@@ -66,6 +81,8 @@ public class BCPBEKey
public byte[] getEncoded()
{
+ checkDestroyed(this);
+
if (param != null)
{
KeyParameter kParam;
@@ -85,41 +102,51 @@ public class BCPBEKey
{
if (type == PBE.PKCS12)
{
- return PBEParametersGenerator.PKCS12PasswordToBytes(pbeKeySpec.getPassword());
+ return PBEParametersGenerator.PKCS12PasswordToBytes(password);
}
else if (type == PBE.PKCS5S2_UTF8)
{
- return PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(pbeKeySpec.getPassword());
+ return PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password);
}
else
{
- return PBEParametersGenerator.PKCS5PasswordToBytes(pbeKeySpec.getPassword());
+ return PBEParametersGenerator.PKCS5PasswordToBytes(password);
}
}
}
int getType()
{
+ checkDestroyed(this);
+
return type;
}
int getDigest()
{
+ checkDestroyed(this);
+
return digest;
}
int getKeySize()
{
+ checkDestroyed(this);
+
return keySize;
}
public int getIvSize()
{
+ checkDestroyed(this);
+
return ivSize;
}
public CipherParameters getParam()
{
+ checkDestroyed(this);
+
return param;
}
@@ -128,7 +155,14 @@ public class BCPBEKey
*/
public char[] getPassword()
{
- return pbeKeySpec.getPassword();
+ checkDestroyed(this);
+
+ if (password == null)
+ {
+ throw new IllegalStateException("no password available");
+ }
+
+ return Arrays.clone(password);
}
/* (non-Javadoc)
@@ -136,7 +170,9 @@ public class BCPBEKey
*/
public byte[] getSalt()
{
- return pbeKeySpec.getSalt();
+ checkDestroyed(this);
+
+ return Arrays.clone(salt);
}
/* (non-Javadoc)
@@ -144,11 +180,15 @@ public class BCPBEKey
*/
public int getIterationCount()
{
- return pbeKeySpec.getIterationCount();
+ checkDestroyed(this);
+
+ return iterationCount;
}
public ASN1ObjectIdentifier getOID()
{
+ checkDestroyed(this);
+
return oid;
}
@@ -161,4 +201,32 @@ public class BCPBEKey
{
return tryWrong;
}
+
+ public void destroy()
+ {
+ if (!hasBeenDestroyed.getAndSet(true))
+ {
+ if (password != null)
+ {
+ Arrays.fill(password, (char)0);
+ }
+ if (salt != null)
+ {
+ Arrays.fill(salt, (byte)0);
+ }
+ }
+ }
+
+ public boolean isDestroyed()
+ {
+ return hasBeenDestroyed.get();
+ }
+
+ static void checkDestroyed(Destroyable destroyable)
+ {
+ if (destroyable.isDestroyed())
+ {
+ throw new IllegalStateException("key has been destroyed");
+ }
+ }
}
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 269edf67..8c678059 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
@@ -1,7 +1,6 @@
package org.bouncycastle.jcajce.provider.symmetric.util;
import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
@@ -28,7 +27,9 @@ import javax.crypto.spec.PBEParameterSpec;
// import javax.crypto.spec.RC2ParameterSpec;
// import javax.crypto.spec.RC5ParameterSpec;
+import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.cms.GCMParameters;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
@@ -39,6 +40,7 @@ import org.bouncycastle.crypto.OutputLengthException;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.engines.DSTU7624Engine;
import org.bouncycastle.crypto.modes.AEADBlockCipher;
+import org.bouncycastle.crypto.modes.AEADCipher;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.modes.CCMBlockCipher;
import org.bouncycastle.crypto.modes.CFBBlockCipher;
@@ -82,47 +84,49 @@ import org.bouncycastle.jcajce.spec.AEADParameterSpec;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
// import org.bouncycastle.jcajce.spec.RepeatedSecretKeySpec;
+import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Strings;
public class BaseBlockCipher
extends BaseWrapCipher
implements PBE
{
+ private static final int BUF_SIZE = 512;
private static final Class gcmSpecClass = ClassUtil.loadClass(BaseBlockCipher.class, "javax.crypto.spec.GCMParameterSpec");
//
// specs we can handle.
//
- private Class[] availableSpecs =
- {
- // Android-removed: Unsupported algorithms
- // RC2ParameterSpec.class,
- // RC5ParameterSpec.class,
- gcmSpecClass,
- // Android-removed: Unsupported algorithms
- // GOST28147ParameterSpec.class
- IvParameterSpec.class,
- PBEParameterSpec.class
- };
-
- private BlockCipher baseEngine;
- private BlockCipherProvider engineProvider;
- private GenericBlockCipher cipher;
- private ParametersWithIV ivParam;
- private AEADParameters aeadParams;
+ private Class[] availableSpecs =
+ {
+ // Android-removed: Unsupported alhorithms
+ // RC2ParameterSpec.class,
+ // RC5ParameterSpec.class,
+ gcmSpecClass,
+ // Android-removed: unsupported algorithms
+ // GOST28147ParameterSpec.class,
+ IvParameterSpec.class,
+ PBEParameterSpec.class
+ };
+
+ private BlockCipher baseEngine;
+ private BlockCipherProvider engineProvider;
+ private GenericBlockCipher cipher;
+ private ParametersWithIV ivParam;
+ private AEADParameters aeadParams;
private int keySizeInBits;
private int scheme = -1;
private int digest;
- private int ivLength = 0;
+ private int ivLength = 0;
- private boolean padded;
- private boolean fixedIv = true;
- private PBEParameterSpec pbeSpec = null;
- private String pbeAlgorithm = null;
+ private boolean padded;
+ private boolean fixedIv = true;
+ private PBEParameterSpec pbeSpec = null;
+ private String pbeAlgorithm = null;
- private String modeName = null;
+ private String modeName = null;
protected BaseBlockCipher(
BlockCipher engine)
@@ -167,6 +171,17 @@ public class BaseBlockCipher
}
protected BaseBlockCipher(
+ AEADCipher engine,
+ boolean fixedIv,
+ int ivLength)
+ {
+ this.baseEngine = null;
+ this.fixedIv = fixedIv;
+ this.ivLength = ivLength;
+ this.cipher = new AEADGenericBlockCipher(engine);
+ }
+
+ protected BaseBlockCipher(
AEADBlockCipher engine,
boolean fixedIv,
int ivLength)
@@ -217,6 +232,10 @@ public class BaseBlockCipher
protected int engineGetBlockSize()
{
+ if (baseEngine == null)
+ {
+ return -1;
+ }
return baseEngine.getBlockSize();
}
@@ -231,13 +250,13 @@ public class BaseBlockCipher
}
protected int engineGetKeySize(
- Key key)
+ Key key)
{
return key.getEncoded().length * 8;
}
protected int engineGetOutputSize(
- int inputLen)
+ int inputLen)
{
return cipher.getOutputSize(inputLen);
}
@@ -260,19 +279,35 @@ public class BaseBlockCipher
}
else if (aeadParams != null)
{
- try
+ // CHACHA20-Poly1305
+ if (baseEngine == null)
{
- engineParams = createParametersInstance("GCM");
- engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize() / 8).getEncoded());
+ try
+ {
+ engineParams = createParametersInstance(PKCSObjectIdentifiers.id_alg_AEADChaCha20Poly1305.getId());
+ engineParams.init(new DEROctetString(aeadParams.getNonce()).getEncoded());
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.toString());
+ }
}
- catch (Exception e)
+ else
{
- throw new RuntimeException(e.toString());
+ try
+ {
+ engineParams = createParametersInstance("GCM");
+ engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize() / 8).getEncoded());
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.toString());
+ }
}
}
else if (ivParam != null)
{
- String name = cipher.getUnderlyingCipher().getAlgorithmName();
+ String name = cipher.getUnderlyingCipher().getAlgorithmName();
if (name.indexOf('/') >= 0)
{
@@ -295,28 +330,27 @@ public class BaseBlockCipher
}
protected void engineSetMode(
- String mode)
+ String mode)
throws NoSuchAlgorithmException
{
+ if (baseEngine == null)
+ {
+ throw new NoSuchAlgorithmException("no mode supported for this algorithm");
+ }
modeName = Strings.toUpperCase(mode);
- // Android-changed: Ignore case since modes are case insensitive
- // https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html
- if (modeName.equalsIgnoreCase("ECB"))
+ if (modeName.equals("ECB"))
{
ivLength = 0;
cipher = new BufferedGenericBlockCipher(baseEngine);
}
- // Android-changed: Ignore case since modes are case insensitive
- // https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html
- else if (modeName.equalsIgnoreCase("CBC"))
+ else if (modeName.equals("CBC"))
{
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(
- new CBCBlockCipher(baseEngine));
+ new CBCBlockCipher(baseEngine));
}
- // Android-changed: Use equals instead of startsWith to avoid unintentional matches
- else if (modeName.equalsIgnoreCase("OFB"))
+ else if (modeName.startsWith("OFB"))
{
ivLength = baseEngine.getBlockSize();
if (modeName.length() != 3)
@@ -324,16 +358,15 @@ public class BaseBlockCipher
int wordSize = Integer.parseInt(modeName.substring(3));
cipher = new BufferedGenericBlockCipher(
- new OFBBlockCipher(baseEngine, wordSize));
+ new OFBBlockCipher(baseEngine, wordSize));
}
else
{
cipher = new BufferedGenericBlockCipher(
- new OFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
+ new OFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
}
}
- // Android-changed: Use equals instead of startsWith to avoid unintentional matches
- else if (modeName.equalsIgnoreCase("CFB"))
+ else if (modeName.startsWith("CFB"))
{
ivLength = baseEngine.getBlockSize();
if (modeName.length() != 3)
@@ -341,31 +374,36 @@ public class BaseBlockCipher
int wordSize = Integer.parseInt(modeName.substring(3));
cipher = new BufferedGenericBlockCipher(
- new CFBBlockCipher(baseEngine, wordSize));
+ new CFBBlockCipher(baseEngine, wordSize));
}
else
{
cipher = new BufferedGenericBlockCipher(
- new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
+ new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
}
}
// BEGIN Android-removed: Unsupported modes
/*
- else if (modeName.startsWith("PGP"))
+ else if (modeName.startsWith("PGPCFB"))
{
- boolean inlineIV = modeName.equalsIgnoreCase("PGPCFBwithIV");
+ boolean inlineIV = modeName.equals("PGPCFBWITHIV");
+ if (!inlineIV && modeName.length() != 6)
+ {
+ throw new NoSuchAlgorithmException("no mode support for " + modeName);
+ }
+
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(
new PGPCFBBlockCipher(baseEngine, inlineIV));
}
- else if (modeName.equalsIgnoreCase("OpenPGPCFB"))
+ else if (modeName.equals("OPENPGPCFB"))
{
ivLength = 0;
cipher = new BufferedGenericBlockCipher(
new OpenPGPCFBBlockCipher(baseEngine));
}
- else if (modeName.startsWith("SIC"))
+ else if (modeName.equals("SIC"))
{
ivLength = baseEngine.getBlockSize();
if (ivLength < 16)
@@ -374,12 +412,11 @@ public class BaseBlockCipher
}
fixedIv = false;
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new SICBlockCipher(baseEngine)));
+ new SICBlockCipher(baseEngine)));
}
*/
// END Android-removed: Unsupported modes
- // Android-changed: Use equals instead of startsWith to avoid unintentional matches
- else if (modeName.equalsIgnoreCase("CTR"))
+ else if (modeName.equals("CTR"))
{
ivLength = baseEngine.getBlockSize();
fixedIv = false;
@@ -388,7 +425,7 @@ public class BaseBlockCipher
if (baseEngine instanceof DSTU7624Engine)
{
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new KCTRBlockCipher(baseEngine)));
+ new KCTRBlockCipher(baseEngine)));
}
else
{
@@ -401,28 +438,26 @@ public class BaseBlockCipher
}
// BEGIN Android-removed: Unsupported modes
/*
- else if (modeName.startsWith("GOFB"))
+ else if (modeName.equals("GOFB"))
{
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new GOFBBlockCipher(baseEngine)));
+ new GOFBBlockCipher(baseEngine)));
}
- else if (modeName.startsWith("GCFB"))
+ else if (modeName.equals("GCFB"))
{
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new GCFBBlockCipher(baseEngine)));
+ new GCFBBlockCipher(baseEngine)));
}
*/
// END Android-removed: Unsupported modes
- // Android-changed: Use equals instead of startsWith to avoid unintentional matches
- else if (modeName.equalsIgnoreCase("CTS"))
+ else if (modeName.equals("CTS"))
{
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(new CBCBlockCipher(baseEngine)));
}
- // Android-changed: Use equals instead of startsWith to avoid unintentional matches
- else if (modeName.equalsIgnoreCase("CCM"))
+ else if (modeName.equals("CCM"))
{
ivLength = 12; // CCM nonce 7..13 bytes
// BEGIN Android-removed: Unsupported algorithms
@@ -441,7 +476,7 @@ public class BaseBlockCipher
}
// BEGIN Android-removed: Unsupported modes
/*
- else if (modeName.startsWith("OCB"))
+ else if (modeName.equals("OCB"))
{
if (engineProvider != null)
{
@@ -456,15 +491,14 @@ public class BaseBlockCipher
throw new NoSuchAlgorithmException("can't support mode " + mode);
}
}
- else if (modeName.startsWith("EAX"))
+ else if (modeName.equals("EAX"))
{
ivLength = baseEngine.getBlockSize();
cipher = new AEADGenericBlockCipher(new EAXBlockCipher(baseEngine));
}
*/
// END Android-removed: Unsupported modes
- // Android-changed: Use equals instead of startsWith to not catch GCM-SIV
- else if (modeName.equalsIgnoreCase("GCM"))
+ else if (modeName.equals("GCM"))
{
ivLength = baseEngine.getBlockSize();
// BEGIN Android-removed: Unsupported algorithms
@@ -488,10 +522,15 @@ public class BaseBlockCipher
}
protected void engineSetPadding(
- String padding)
- throws NoSuchPaddingException
+ String padding)
+ throws NoSuchPaddingException
{
- String paddingName = Strings.toUpperCase(padding);
+ if (baseEngine == null)
+ {
+ throw new NoSuchPaddingException("no padding supported for this algorithm");
+ }
+
+ String paddingName = Strings.toUpperCase(padding);
if (paddingName.equals("NOPADDING"))
{
@@ -550,13 +589,13 @@ public class BaseBlockCipher
// END Android-added: Handling missing IVs
protected void engineInit(
- int opmode,
- Key key,
- AlgorithmParameterSpec params,
- SecureRandom random)
+ int opmode,
+ Key key,
+ final AlgorithmParameterSpec params,
+ SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException
{
- CipherParameters param;
+ CipherParameters param;
this.pbeSpec = null;
this.pbeAlgorithm = null;
@@ -574,7 +613,7 @@ public class BaseBlockCipher
//
// for RC5-64 we must have some default parameters
//
- if (params == null && baseEngine.getAlgorithmName().startsWith("RC5-64"))
+ if (params == null && (baseEngine != null && baseEngine.getAlgorithmName().startsWith("RC5-64")))
{
throw new InvalidAlgorithmParameterException("RC5 requires an RC5ParametersSpec to be passed in.");
}
@@ -598,7 +637,7 @@ public class BaseBlockCipher
throw new InvalidKeyException("PKCS12 requires a SecretKey/PBEKey");
}
- if (params instanceof PBEParameterSpec)
+ if (params instanceof PBEParameterSpec)
{
pbeSpec = (PBEParameterSpec)params;
}
@@ -803,10 +842,10 @@ public class BaseBlockCipher
/*
else if (params instanceof GOST28147ParameterSpec)
{
- GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
+ GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
param = new ParametersWithSBox(
- new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSbox());
+ new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSbox());
if (gost28147Param.getIV() != null && ivLength != 0)
{
@@ -823,7 +862,7 @@ public class BaseBlockCipher
}
else if (params instanceof RC2ParameterSpec)
{
- RC2ParameterSpec rc2Param = (RC2ParameterSpec)params;
+ RC2ParameterSpec rc2Param = (RC2ParameterSpec)params;
param = new RC2Parameters(key.getEncoded(), ((RC2ParameterSpec)params).getEffectiveKeyBits());
@@ -842,7 +881,7 @@ public class BaseBlockCipher
}
else if (params instanceof RC5ParameterSpec)
{
- RC5ParameterSpec rc5Param = (RC5ParameterSpec)params;
+ RC5ParameterSpec rc5Param = (RC5ParameterSpec)params;
param = new RC5Parameters(key.getEncoded(), ((RC5ParameterSpec)params).getRounds());
if (baseEngine.getAlgorithmName().startsWith("RC5"))
@@ -888,26 +927,17 @@ public class BaseBlockCipher
throw new InvalidAlgorithmParameterException("GCMParameterSpec can only be used with AEAD modes.");
}
- try
+ final KeyParameter keyParam;
+ if (param instanceof ParametersWithIV)
{
- Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]);
- Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]);
-
- KeyParameter keyParam;
- if (param instanceof ParametersWithIV)
- {
- keyParam = (KeyParameter)((ParametersWithIV)param).getParameters();
- }
- else
- {
- keyParam = (KeyParameter)param;
- }
- param = aeadParams = new AEADParameters(keyParam, ((Integer)tLen.invoke(params, new Object[0])).intValue(), (byte[])iv.invoke(params, new Object[0]));
+ keyParam = (KeyParameter)((ParametersWithIV)param).getParameters();
}
- catch (Exception e)
+ else
{
- throw new InvalidAlgorithmParameterException("Cannot process GCMParameterSpec.");
+ keyParam = (KeyParameter)param;
}
+
+ param = aeadParams = GcmSpecUtil.extractAeadParameters(keyParam, params);
}
else if (params != null && !(params instanceof PBEParameterSpec))
{
@@ -916,7 +946,7 @@ public class BaseBlockCipher
if ((ivLength != 0) && !(param instanceof ParametersWithIV) && !(param instanceof AEADParameters))
{
- SecureRandom ivRandom = random;
+ SecureRandom ivRandom = random;
if (ivRandom == null)
{
@@ -925,7 +955,7 @@ public class BaseBlockCipher
if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE))
{
- byte[] iv = new byte[ivLength];
+ byte[] iv = new byte[ivLength];
// BEGIN Android-changed: For PBE keys with no IV, log and use IV of 0
// These keys were accepted in BC 1.52 (and treated as having an IV of 0) but
@@ -981,7 +1011,6 @@ public class BaseBlockCipher
}
-
if (random != null && padded)
{
param = new ParametersWithRandom(param, random);
@@ -1005,12 +1034,20 @@ public class BaseBlockCipher
if (cipher instanceof AEADGenericBlockCipher && aeadParams == null)
{
- AEADBlockCipher aeadCipher = ((AEADGenericBlockCipher)cipher).cipher;
+ AEADCipher aeadCipher = ((AEADGenericBlockCipher)cipher).cipher;
aeadParams = new AEADParameters((KeyParameter)ivParam.getParameters(), aeadCipher.getMac().length * 8, ivParam.getIV());
}
}
- catch (final Exception e)
+ // BEGIN Android-removed: keeping pre 1.68 behaviour
+ /*
+ catch (IllegalArgumentException e)
+ {
+ throw new InvalidAlgorithmParameterException(e.getMessage(), e);
+ }
+ */
+ // END Android-removed: keeping pre 1.68 behaviour
+ catch (Exception e)
{
throw new InvalidKeyOrParametersException(e.getMessage(), e);
}
@@ -1078,33 +1115,17 @@ public class BaseBlockCipher
}
protected void engineInit(
- int opmode,
- Key key,
+ int opmode,
+ Key key,
AlgorithmParameters params,
- SecureRandom random)
- throws InvalidKeyException, InvalidAlgorithmParameterException
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
{
- AlgorithmParameterSpec paramSpec = null;
+ AlgorithmParameterSpec paramSpec = null;
if (params != null)
{
- for (int i = 0; i != availableSpecs.length; i++)
- {
- if (availableSpecs[i] == null)
- {
- continue;
- }
-
- try
- {
- paramSpec = params.getParameterSpec(availableSpecs[i]);
- break;
- }
- catch (Exception e)
- {
- // try again if possible
- }
- }
+ paramSpec = SpecUtil.extractSpec(params, availableSpecs);
if (paramSpec == null)
{
@@ -1113,14 +1134,14 @@ public class BaseBlockCipher
}
engineInit(opmode, key, paramSpec, random);
-
+
engineParams = params;
}
protected void engineInit(
- int opmode,
- Key key,
- SecureRandom random)
+ int opmode,
+ Key key,
+ SecureRandom random)
throws InvalidKeyException
{
try
@@ -1138,40 +1159,67 @@ public class BaseBlockCipher
cipher.updateAAD(input, offset, length);
}
- protected void engineUpdateAAD(ByteBuffer bytebuffer)
+ protected void engineUpdateAAD(ByteBuffer src)
{
- int offset = bytebuffer.arrayOffset() + bytebuffer.position();
- int length = bytebuffer.limit() - bytebuffer.position();
- engineUpdateAAD(bytebuffer.array(), offset, length);
+ int remaining = src.remaining();
+ if (remaining < 1)
+ {
+ // No data to update
+ }
+ else if (src.hasArray())
+ {
+ engineUpdateAAD(src.array(), src.arrayOffset() + src.position(), remaining);
+ src.position(src.limit());
+ }
+ else if (remaining <= BUF_SIZE)
+ {
+ byte[] data = new byte[remaining];
+ src.get(data);
+ engineUpdateAAD(data, 0, data.length);
+ Arrays.fill(data, (byte)0);
+ }
+ else
+ {
+ byte[] data = new byte[BUF_SIZE];
+ do
+ {
+ int length = Math.min(data.length, remaining);
+ src.get(data, 0, length);
+ engineUpdateAAD(data, 0, length);
+ remaining -= length;
+ }
+ while (remaining > 0);
+ Arrays.fill(data, (byte)0);
+ }
}
protected byte[] engineUpdate(
- byte[] input,
- int inputOffset,
- int inputLen)
+ byte[] input,
+ int inputOffset,
+ int inputLen)
{
- int length = cipher.getUpdateOutputSize(inputLen);
+ int length = cipher.getUpdateOutputSize(inputLen);
if (length > 0)
{
- byte[] out = new byte[length];
+ byte[] out = new byte[length];
- int len = cipher.processBytes(input, inputOffset, inputLen, out, 0);
+ int len = cipher.processBytes(input, inputOffset, inputLen, out, 0);
- if (len == 0)
- {
- return null;
- }
- else if (len != out.length)
- {
- byte[] tmp = new byte[len];
+ if (len == 0)
+ {
+ return null;
+ }
+ else if (len != out.length)
+ {
+ byte[] tmp = new byte[len];
- System.arraycopy(out, 0, tmp, 0, len);
+ System.arraycopy(out, 0, tmp, 0, len);
- return tmp;
- }
+ return tmp;
+ }
- return out;
+ return out;
}
cipher.processBytes(input, inputOffset, inputLen, null, 0);
@@ -1180,11 +1228,11 @@ public class BaseBlockCipher
}
protected int engineUpdate(
- byte[] input,
- int inputOffset,
- int inputLen,
- byte[] output,
- int outputOffset)
+ byte[] input,
+ int inputOffset,
+ int inputLen,
+ byte[] output,
+ int outputOffset)
throws ShortBufferException
{
if (outputOffset + cipher.getUpdateOutputSize(inputLen) > output.length)
@@ -1204,13 +1252,13 @@ public class BaseBlockCipher
}
protected byte[] engineDoFinal(
- byte[] input,
- int inputOffset,
- int inputLen)
+ byte[] input,
+ int inputOffset,
+ int inputLen)
throws IllegalBlockSizeException, BadPaddingException
{
- int len = 0;
- byte[] tmp = new byte[engineGetOutputSize(inputLen)];
+ int len = 0;
+ byte[] tmp = new byte[engineGetOutputSize(inputLen)];
if (inputLen != 0)
{
@@ -1231,7 +1279,12 @@ public class BaseBlockCipher
return tmp;
}
- byte[] out = new byte[len];
+ if (len > tmp.length)
+ {
+ throw new IllegalBlockSizeException("internal buffer overflow");
+ }
+
+ byte[] out = new byte[len];
System.arraycopy(tmp, 0, out, 0, len);
@@ -1239,14 +1292,14 @@ public class BaseBlockCipher
}
protected int engineDoFinal(
- byte[] input,
- int inputOffset,
- int inputLen,
- byte[] output,
- int outputOffset)
+ byte[] input,
+ int inputOffset,
+ int inputLen,
+ byte[] output,
+ int outputOffset)
throws IllegalBlockSizeException, BadPaddingException, ShortBufferException
{
- int len = 0;
+ int len = 0;
if (outputOffset + engineGetOutputSize(inputLen) > output.length)
{
@@ -1368,17 +1421,20 @@ public class BaseBlockCipher
throw new UnsupportedOperationException("AAD is not supported in the current mode.");
}
- public int processByte(byte in, byte[] out, int outOff) throws DataLengthException
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException
{
return cipher.processByte(in, out, outOff);
}
- public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException
{
return cipher.processBytes(in, inOff, len, out, outOff);
}
- public int doFinal(byte[] out, int outOff) throws IllegalStateException, BadPaddingException
+ public int doFinal(byte[] out, int outOff)
+ throws IllegalStateException, BadPaddingException
{
try
{
@@ -1396,7 +1452,8 @@ public class BaseBlockCipher
{
private static final Constructor aeadBadTagConstructor;
- static {
+ static
+ {
Class aeadBadTagClass = ClassUtil.loadClass(BaseBlockCipher.class, "javax.crypto.AEADBadTagException");
if (aeadBadTagClass != null)
{
@@ -1420,9 +1477,9 @@ public class BaseBlockCipher
}
}
- private AEADBlockCipher cipher;
+ private AEADCipher cipher;
- AEADGenericBlockCipher(AEADBlockCipher cipher)
+ AEADGenericBlockCipher(AEADCipher cipher)
{
this.cipher = cipher;
}
@@ -1435,7 +1492,12 @@ public class BaseBlockCipher
public String getAlgorithmName()
{
- return cipher.getUnderlyingCipher().getAlgorithmName();
+ if (cipher instanceof AEADBlockCipher)
+ {
+ return ((AEADBlockCipher)cipher).getUnderlyingCipher().getAlgorithmName();
+ }
+
+ return cipher.getAlgorithmName();
}
public boolean wrapOnNoPadding()
@@ -1445,7 +1507,12 @@ public class BaseBlockCipher
public org.bouncycastle.crypto.BlockCipher getUnderlyingCipher()
{
- return cipher.getUnderlyingCipher();
+ if (cipher instanceof AEADBlockCipher)
+ {
+ return ((AEADBlockCipher)cipher).getUnderlyingCipher();
+ }
+
+ return null;
}
public int getOutputSize(int len)
@@ -1463,17 +1530,20 @@ public class BaseBlockCipher
cipher.processAADBytes(input, offset, length);
}
- public int processByte(byte in, byte[] out, int outOff) throws DataLengthException
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException
{
return cipher.processByte(in, out, outOff);
}
- public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException
{
return cipher.processBytes(in, inOff, len, out, outOff);
}
- public int doFinal(byte[] out, int outOff) throws IllegalStateException, BadPaddingException
+ public int doFinal(byte[] out, int outOff)
+ throws IllegalStateException, BadPaddingException
{
try
{
@@ -1487,7 +1557,7 @@ public class BaseBlockCipher
try
{
aeadBadTag = (BadPaddingException)aeadBadTagConstructor
- .newInstance(new Object[]{e.getMessage()});
+ .newInstance(new Object[]{e.getMessage()});
}
catch (Exception i)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
index 29bd6a58..9f5ac19e 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
@@ -1,6 +1,5 @@
package org.bouncycastle.jcajce.provider.symmetric.util;
-import java.lang.reflect.Method;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
@@ -61,7 +60,7 @@ public class BaseMac
protected void engineInit(
Key key,
- AlgorithmParameterSpec params)
+ final AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException
{
CipherParameters param;
@@ -176,7 +175,7 @@ public class BaseMac
param = new KeyParameter(key.getEncoded());
}
- KeyParameter keyParam;
+ final KeyParameter keyParam;
if (param instanceof ParametersWithIV)
{
keyParam = (KeyParameter)((ParametersWithIV)param).getParameters();
@@ -214,17 +213,7 @@ public class BaseMac
}
else if (gcmSpecClass != null && gcmSpecClass.isAssignableFrom(params.getClass()))
{
- try
- {
- Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]);
- Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]);
-
- param = new AEADParameters(keyParam, ((Integer)tLen.invoke(params, new Object[0])).intValue(), (byte[])iv.invoke(params, new Object[0]));
- }
- catch (Exception e)
- {
- throw new InvalidAlgorithmParameterException("Cannot process GCMParameterSpec.");
- }
+ param = GcmSpecUtil.extractAeadParameters(keyParam, params);
}
else if (!(params instanceof PBEParameterSpec))
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java
index 06e5af0f..b3a98cf5 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java
@@ -64,6 +64,14 @@ public class BaseStreamCipher
protected BaseStreamCipher(
StreamCipher engine,
int ivLength,
+ int keySizeInBits)
+ {
+ this(engine, ivLength, keySizeInBits, -1);
+ }
+
+ protected BaseStreamCipher(
+ StreamCipher engine,
+ int ivLength,
int keySizeInBits,
int digest)
{
@@ -316,18 +324,7 @@ public class BaseStreamCipher
if (params != null)
{
- for (int i = 0; i != availableSpecs.length; i++)
- {
- try
- {
- paramSpec = params.getParameterSpec(availableSpecs[i]);
- break;
- }
- catch (Exception e)
- {
- continue;
- }
- }
+ paramSpec = SpecUtil.extractSpec(params, availableSpecs);
if (paramSpec == null)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java
index 4ebb2941..ccf5b4f1 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java
@@ -286,18 +286,7 @@ public abstract class BaseWrapCipher
if (params != null)
{
- for (int i = 0; i != availableSpecs.length; i++)
- {
- try
- {
- paramSpec = params.getParameterSpec(availableSpecs[i]);
- break;
- }
- catch (Exception e)
- {
- // try next spec
- }
- }
+ paramSpec = SpecUtil.extractSpec(params, availableSpecs);
if (paramSpec == null)
{
@@ -369,7 +358,10 @@ public abstract class BaseWrapCipher
throw new IllegalStateException("not supported in a wrapping mode");
}
- wrapStream.write(input, inputOffset, inputLen);
+ if (input != null)
+ {
+ wrapStream.write(input, inputOffset, inputLen);
+ }
try
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
new file mode 100644
index 00000000..6cf2020b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
@@ -0,0 +1,132 @@
+package org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.cms.GCMParameters;
+import org.bouncycastle.crypto.params.AEADParameters;
+import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.util.Integers;
+
+public class GcmSpecUtil
+{
+ static final Class gcmSpecClass = ClassUtil.loadClass(GcmSpecUtil.class, "javax.crypto.spec.GCMParameterSpec");
+
+ static final Method tLen;
+ static final Method iv;
+
+ static
+ {
+ if (gcmSpecClass != null)
+ {
+ tLen = extractMethod("getTLen");
+ iv = extractMethod("getIV");
+ }
+ else
+ {
+ tLen = null;
+ iv = null;
+ }
+ }
+
+ private static Method extractMethod(final String name)
+ {
+ try
+ {
+ return (Method)AccessController.doPrivileged(new PrivilegedExceptionAction()
+ {
+ public Object run()
+ throws Exception
+ {
+ return gcmSpecClass.getDeclaredMethod(name, new Class[0]);
+ }
+ });
+ }
+ catch (PrivilegedActionException e)
+ {
+ return null;
+ }
+ }
+
+ public static boolean gcmSpecExists()
+ {
+ return gcmSpecClass != null;
+ }
+
+ public static boolean isGcmSpec(AlgorithmParameterSpec paramSpec)
+ {
+ return gcmSpecClass != null && gcmSpecClass.isInstance(paramSpec);
+ }
+
+ public static boolean isGcmSpec(Class paramSpecClass)
+ {
+ return gcmSpecClass == paramSpecClass;
+ }
+
+ public static AlgorithmParameterSpec extractGcmSpec(ASN1Primitive spec)
+ throws InvalidParameterSpecException
+ {
+ try
+ {
+ GCMParameters gcmParams = GCMParameters.getInstance(spec);
+ Constructor constructor = gcmSpecClass.getConstructor(new Class[]{Integer.TYPE, byte[].class});
+
+ return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(gcmParams.getIcvLen() * 8), gcmParams.getNonce() });
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new InvalidParameterSpecException("No constructor found!"); // should never happen
+ }
+ catch (Exception e)
+ {
+ throw new InvalidParameterSpecException("Construction failed: " + e.getMessage()); // should never happen
+ }
+ }
+
+ static AEADParameters extractAeadParameters(final KeyParameter keyParam, final AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException
+ {
+ try
+ {
+ return (AEADParameters)AccessController.doPrivileged(new PrivilegedExceptionAction()
+ {
+ public Object run()
+ throws Exception
+ {
+ return new AEADParameters(keyParam, ((Integer)tLen.invoke(params, new Object[0])).intValue(), (byte[])iv.invoke(params, new Object[0]));
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ throw new InvalidAlgorithmParameterException("Cannot process GCMParameterSpec.");
+ }
+ }
+
+ public static GCMParameters extractGcmParameters(final AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ try
+ {
+ return (GCMParameters)AccessController.doPrivileged(new PrivilegedExceptionAction()
+ {
+ public Object run()
+ throws Exception
+ {
+ return new GCMParameters((byte[])iv.invoke(paramSpec, new Object[0]), ((Integer)tLen.invoke(paramSpec, new Object[0])).intValue() / 8);
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ throw new InvalidParameterSpecException("Cannot process GCMParameterSpec");
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
index fcfd4df6..a0621cf7 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
@@ -20,6 +20,7 @@ import org.bouncycastle.crypto.PBEParametersGenerator;
// import org.bouncycastle.crypto.digests.MD2Digest;
// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
// import org.bouncycastle.crypto.digests.TigerDigest;
+// import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator;
import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
@@ -49,10 +50,12 @@ public interface PBE
static final int SHA224 = 7;
static final int SHA384 = 8;
static final int SHA512 = 9;
- static final int SHA3_224 = 10;
- static final int SHA3_256 = 11;
- static final int SHA3_384 = 12;
- static final int SHA3_512 = 13;
+ // Android-removed: Unsupported algorithms
+ // static final int SHA3_224 = 10;
+ // static final int SHA3_256 = 11;
+ // static final int SHA3_384 = 12;
+ // static final int SHA3_512 = 13;
+ // static final int SM3 = 14;
static final int PKCS5S1 = 0;
static final int PKCS5S2 = 1;
@@ -160,6 +163,9 @@ public interface PBE
case SHA3_512:
generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_512());
break;
+ case SM3:
+ generator = new PKCS5S2ParametersGenerator(new SM3Digest());
+ break;
*/
// END Android-removed: Unsupported algorithms
default:
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/SpecUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/SpecUtil.java
new file mode 100644
index 00000000..f20c8c0b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/SpecUtil.java
@@ -0,0 +1,36 @@
+package org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.security.AlgorithmParameters;
+import java.security.spec.AlgorithmParameterSpec;
+
+class SpecUtil
+{
+ static AlgorithmParameterSpec extractSpec(AlgorithmParameters params, Class[] availableSpecs)
+ {
+ try
+ {
+ return params.getParameterSpec(AlgorithmParameterSpec.class);
+ }
+ catch (Exception e)
+ {
+ for (int i = 0; i != availableSpecs.length; i++)
+ {
+ if (availableSpecs[i] == null)
+ {
+ continue;
+ }
+
+ try
+ {
+ return params.getParameterSpec(availableSpecs[i]);
+ }
+ catch (Exception ex)
+ {
+ // try again if possible
+ }
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java
new file mode 100644
index 00000000..ee8f43c5
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java
@@ -0,0 +1,65 @@
+package org.bouncycastle.jcajce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class CompositeAlgorithmSpec
+ implements AlgorithmParameterSpec
+{
+ public static class Builder
+ {
+ private List<String> algorithmNames = new ArrayList<String>();
+ private List<AlgorithmParameterSpec> parameterSpecs = new ArrayList<AlgorithmParameterSpec>();
+
+ public Builder()
+ {
+ }
+
+ public Builder add(String algorithmName)
+ {
+ algorithmNames.add(algorithmName);
+ parameterSpecs.add(null);
+
+ return this;
+ }
+
+ public Builder add(String algorithmName, AlgorithmParameterSpec parameterSpec)
+ {
+ algorithmNames.add(algorithmName);
+ parameterSpecs.add(parameterSpec);
+
+ return this;
+ }
+
+ public CompositeAlgorithmSpec build()
+ {
+ if (algorithmNames.isEmpty())
+ {
+ throw new IllegalStateException("cannot call build with no algorithm names added");
+ }
+
+ return new CompositeAlgorithmSpec(this);
+ }
+ }
+
+ private final List<String> algorithmNames;
+ private final List<AlgorithmParameterSpec> parameterSpecs;
+
+ public CompositeAlgorithmSpec(Builder builder)
+ {
+ this.algorithmNames = Collections.unmodifiableList(new ArrayList<String>(builder.algorithmNames));
+ this.parameterSpecs = Collections.unmodifiableList(new ArrayList<AlgorithmParameterSpec>(builder.parameterSpecs));
+ }
+
+ public List<String> getAlgorithmNames()
+ {
+ return algorithmNames;
+ }
+
+ public List<AlgorithmParameterSpec> getParameterSpecs()
+ {
+ return parameterSpecs;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/DHExtendedPrivateKeySpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/DHExtendedPrivateKeySpec.java
new file mode 100644
index 00000000..f72dc3ce
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/DHExtendedPrivateKeySpec.java
@@ -0,0 +1,37 @@
+package org.bouncycastle.jcajce.spec;
+
+import java.math.BigInteger;
+
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPrivateKeySpec;
+
+/**
+ * A DHPrivateKeySpec that also carries a set of DH domain parameters.
+ */
+public class DHExtendedPrivateKeySpec
+ extends DHPrivateKeySpec
+{
+ private final DHParameterSpec params;
+
+ /**
+ * Base constructor.
+ *
+ * @param x the private value.
+ * @param params the domain parameter set.
+ */
+ public DHExtendedPrivateKeySpec(BigInteger x, DHParameterSpec params)
+ {
+ super(x, params.getP(), params.getG());
+ this.params = params;
+ }
+
+ /**
+ * Return the domain parameters associated with this key spec.
+ *
+ * @return the Diffie-Hellman domain parameters.
+ */
+ public DHParameterSpec getParams()
+ {
+ return params;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/DHExtendedPublicKeySpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/DHExtendedPublicKeySpec.java
new file mode 100644
index 00000000..86429a6d
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/DHExtendedPublicKeySpec.java
@@ -0,0 +1,37 @@
+package org.bouncycastle.jcajce.spec;
+
+import java.math.BigInteger;
+
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPublicKeySpec;
+
+/**
+ * A DHPublicKeySpec that also carries a set of DH domain parameters.
+ */
+public class DHExtendedPublicKeySpec
+ extends DHPublicKeySpec
+{
+ private final DHParameterSpec params;
+
+ /**
+ * Base constructor.
+ *
+ * @param y the public value.
+ * @param params the domain parameter set.
+ */
+ public DHExtendedPublicKeySpec(BigInteger y, DHParameterSpec params)
+ {
+ super(y, params.getP(), params.getG());
+ this.params = params;
+ }
+
+ /**
+ * Return the domain parameters associated with this key spec.
+ *
+ * @return the Diffie-Hellman domain parameters.
+ */
+ public DHParameterSpec getParams()
+ {
+ return params;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/OpenSSHPrivateKeySpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/OpenSSHPrivateKeySpec.java
new file mode 100644
index 00000000..95c7b692
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/OpenSSHPrivateKeySpec.java
@@ -0,0 +1,58 @@
+package org.bouncycastle.jcajce.spec;
+
+import java.security.spec.EncodedKeySpec;
+
+/**
+ * OpenSSHPrivateKeySpec holds and encoded OpenSSH private key.
+ * The format of the key can be either ASN.1 or OpenSSH.
+ */
+public class OpenSSHPrivateKeySpec
+ extends EncodedKeySpec
+{
+ private final String format;
+
+ /**
+ * Accept an encoded key and determine the format.
+ * <p>
+ * The encoded key should be the Base64 decoded blob between the "---BEGIN and ---END" markers.
+ * This constructor will endeavour to find the OpenSSH format magic value. If it can not then it
+ * will default to ASN.1. It does not attempt to validate the ASN.1
+ * <p>
+ * Example:
+ * OpenSSHPrivateKeySpec privSpec = new OpenSSHPrivateKeySpec(rawPriv);
+ * <p>
+ * KeyFactory kpf = KeyFactory.getInstance("RSA", "BC");
+ * PrivateKey prk = kpf.generatePrivate(privSpec);
+ * <p>
+ * OpenSSHPrivateKeySpec rcPrivateSpec = kpf.getKeySpec(prk, OpenSSHPrivateKeySpec.class);
+ *
+ * @param encodedKey The encoded key.
+ */
+ public OpenSSHPrivateKeySpec(byte[] encodedKey)
+ {
+ super(encodedKey);
+
+ if (encodedKey[0] == 0x30) // DER SEQUENCE
+ {
+ format = "ASN.1";
+ }
+ else if (encodedKey[0] == 'o')
+ {
+ format = "OpenSSH";
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown byte encoding");
+ }
+ }
+
+ /**
+ * Return the format, either OpenSSH for the OpenSSH propriety format or ASN.1.
+ *
+ * @return the format OpenSSH or ASN.1
+ */
+ public String getFormat()
+ {
+ return format;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/OpenSSHPublicKeySpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/OpenSSHPublicKeySpec.java
new file mode 100644
index 00000000..b6a84396
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/OpenSSHPublicKeySpec.java
@@ -0,0 +1,77 @@
+package org.bouncycastle.jcajce.spec;
+
+import java.security.spec.EncodedKeySpec;
+
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+
+/**
+ * Holds an OpenSSH encoded public key.
+ */
+public class OpenSSHPublicKeySpec
+ extends EncodedKeySpec
+{
+ private static final String[] allowedTypes = new String[]{"ssh-rsa", "ssh-ed25519", "ssh-dss"};
+ private final String type;
+
+
+ /**
+ * Construct and instance and determine the OpenSSH public key type.
+ * The current types are ssh-rsa, ssh-ed25519, ssh-dss and ecdsa-*
+ * <p>
+ * It does not validate the key beyond identifying the type.
+ *
+ * @param encodedKey
+ */
+ public OpenSSHPublicKeySpec(byte[] encodedKey)
+ {
+ super(encodedKey);
+
+ //
+ // The type is encoded at the start of the blob.
+ //
+ int pos = 0;
+ int i = (encodedKey[pos++] & 0xFF) << 24;
+ i |= (encodedKey[pos++] & 0xFF) << 16;
+ i |= (encodedKey[pos++] & 0xFF) << 8;
+ i |= (encodedKey[pos++] & 0xFF);
+
+ if ((pos + i) >= encodedKey.length)
+ {
+ throw new IllegalArgumentException("invalid public key blob: type field longer than blob");
+ }
+
+ this.type = Strings.fromByteArray(Arrays.copyOfRange(encodedKey, pos, pos + i));
+
+ if (type.startsWith("ecdsa"))
+ {
+ return; // These have a curve name and digest in them and can't be compared exactly.
+ }
+
+ for (int t = 0; t < allowedTypes.length; t++)
+ {
+ if (allowedTypes[t].equals(this.type))
+ {
+ return;
+ }
+ }
+
+ throw new IllegalArgumentException("unrecognised public key type " + type);
+
+ }
+
+ public String getFormat()
+ {
+ return "OpenSSH";
+ }
+
+ /**
+ * The type of OpenSSH public key.
+ *
+ * @return the type.
+ */
+ public String getType()
+ {
+ return type;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/AnnotatedPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/AnnotatedPrivateKey.java
new file mode 100644
index 00000000..d37943cf
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/AnnotatedPrivateKey.java
@@ -0,0 +1,116 @@
+package org.bouncycastle.jcajce.util;
+
+import java.security.PrivateKey;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Wrapper for a private key that carries annotations that can be used
+ * for tracking or debugging.
+ */
+public class AnnotatedPrivateKey
+ implements PrivateKey
+{
+ public static final String LABEL = "label";
+
+ private final PrivateKey key;
+ private final Map<String, Object> annotations;
+
+ AnnotatedPrivateKey(PrivateKey key, String label)
+ {
+ this.key = key;
+ this.annotations = Collections.singletonMap(LABEL, (Object)label);
+ }
+
+ AnnotatedPrivateKey(PrivateKey key, Map<String, Object> annotations)
+ {
+ this.key = key;
+ this.annotations = annotations;
+ }
+
+ public PrivateKey getKey()
+ {
+ return key;
+ }
+
+ public Map<String, Object> getAnnotations()
+ {
+ return annotations;
+ }
+
+ public String getAlgorithm()
+ {
+ return key.getAlgorithm();
+ }
+
+ public Object getAnnotation(String key)
+ {
+ return annotations.get(key);
+ }
+
+ /**
+ * Return a new annotated key with an additional annotation added to it.
+ *
+ * @param name the name of the annotation to add.
+ * @param annotation the object providing the annotation details.
+ * @return a new annotated key with the extra annotation.
+ */
+ public AnnotatedPrivateKey addAnnotation(String name, Object annotation)
+ {
+ Map<String, Object> newAnnotations = new HashMap<String, Object>(annotations);
+
+ newAnnotations.put(name, annotation);
+
+ return new AnnotatedPrivateKey(this.key, Collections.unmodifiableMap(newAnnotations));
+ }
+
+ /**
+ * Return a new annotated key with the named annotation removed.
+ *
+ * @param name the name of the annotation to remove.
+ * @return a new annotated key with the named annotation removed.
+ */
+ public AnnotatedPrivateKey removeAnnotation(String name)
+ {
+ Map<String, Object> newAnnotations = new HashMap<String, Object>(annotations);
+
+ newAnnotations.remove(name);
+
+ return new AnnotatedPrivateKey(this.key, Collections.unmodifiableMap(newAnnotations));
+ }
+
+ public String getFormat()
+ {
+ return key.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ return key.getEncoded();
+ }
+
+ public int hashCode()
+ {
+ return this.key.hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o instanceof AnnotatedPrivateKey)
+ {
+ return this.key.equals(((AnnotatedPrivateKey)o).key);
+ }
+ return this.key.equals(o);
+ }
+
+ public String toString()
+ {
+ if (annotations.containsKey(LABEL))
+ {
+ return annotations.get(LABEL).toString();
+ }
+
+ return key.toString();
+ }
+}
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 892aa00e..6c384585 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java
@@ -15,9 +15,12 @@ public class BCJcaJceHelper
private static synchronized Provider getBouncyCastleProvider()
{
- if (Security.getProvider("BC") != null)
+ final Provider system = Security.getProvider("BC");
+ // Avoid using the old, deprecated system BC provider on Android.
+ // See: https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html
+ if (system instanceof BouncyCastleProvider)
{
- return Security.getProvider("BC");
+ return system;
}
else if (bcProvider != null)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java
index 426efc09..b22c052f 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java
@@ -2,16 +2,24 @@ package org.bouncycastle.jcajce.util;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Signature;
+import java.security.cert.CertPathBuilder;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreParameters;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.crypto.Cipher;
+import javax.crypto.ExemptionMechanism;
import javax.crypto.KeyAgreement;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
@@ -80,12 +88,19 @@ public class DefaultJcaJceHelper
return KeyPairGenerator.getInstance(algorithm);
}
+ /** @deprecated Use createMessageDigest instead */
public MessageDigest createDigest(String algorithm)
throws NoSuchAlgorithmException
{
return MessageDigest.getInstance(algorithm);
}
+ public MessageDigest createMessageDigest(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return MessageDigest.getInstance(algorithm);
+ }
+
public Signature createSignature(String algorithm)
throws NoSuchAlgorithmException
{
@@ -103,4 +118,34 @@ public class DefaultJcaJceHelper
{
return SecureRandom.getInstance(algorithm);
}
+
+ public CertPathBuilder createCertPathBuilder(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return CertPathBuilder.getInstance(algorithm);
+ }
+
+ public CertPathValidator createCertPathValidator(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return CertPathValidator.getInstance(algorithm);
+ }
+
+ public CertStore createCertStore(String type, CertStoreParameters params)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException
+ {
+ return CertStore.getInstance(type, params);
+ }
+
+ public ExemptionMechanism createExemptionMechanism(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return ExemptionMechanism.getInstance(algorithm);
+ }
+
+ public KeyStore createKeyStore(String type)
+ throws KeyStoreException
+ {
+ return KeyStore.getInstance(type);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/ECKeyUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/ECKeyUtil.java
new file mode 100644
index 00000000..a37e4e12
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/ECKeyUtil.java
@@ -0,0 +1,106 @@
+package org.bouncycastle.jcajce.util;
+
+import java.io.IOException;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.asn1.x9.ECNamedCurveTable;
+import org.bouncycastle.asn1.x9.X962Parameters;
+import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.asn1.x9.X9ECPoint;
+import org.bouncycastle.crypto.ec.CustomNamedCurves;
+
+/**
+ * Utility class for EC Keys.
+ */
+public class ECKeyUtil
+{
+ /**
+ * Convert an ECPublicKey into an ECPublicKey which always encodes
+ * with point compression.
+ *
+ * @param ecPublicKey the originating public key.
+ * @return a wrapped version of ecPublicKey which uses point compression.
+ */
+ public static ECPublicKey createKeyWithCompression(ECPublicKey ecPublicKey)
+ {
+ return new ECPublicKeyWithCompression(ecPublicKey);
+ }
+
+ private static class ECPublicKeyWithCompression
+ implements ECPublicKey
+ {
+ private final ECPublicKey ecPublicKey;
+
+ public ECPublicKeyWithCompression(ECPublicKey ecPublicKey)
+ {
+ this.ecPublicKey = ecPublicKey;
+ }
+
+ public ECPoint getW()
+ {
+ return ecPublicKey.getW();
+ }
+
+ public String getAlgorithm()
+ {
+ return ecPublicKey.getAlgorithm();
+ }
+
+ public String getFormat()
+ {
+ return ecPublicKey.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(ecPublicKey.getEncoded());
+
+ X962Parameters params = X962Parameters.getInstance(publicKeyInfo.getAlgorithm().getParameters());
+
+ org.bouncycastle.math.ec.ECCurve curve;
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
+
+ X9ECParameters x9 = CustomNamedCurves.getByOID(oid);
+ if (x9 == null)
+ {
+ x9 = ECNamedCurveTable.getByOID(oid);
+ }
+ curve = x9.getCurve();
+ }
+ else if (params.isImplicitlyCA())
+ {
+ throw new IllegalStateException("unable to identify implictlyCA");
+ }
+ else
+ {
+ X9ECParameters x9 = X9ECParameters.getInstance(params.getParameters());
+ curve = x9.getCurve();
+ }
+
+ org.bouncycastle.math.ec.ECPoint p = curve.decodePoint(publicKeyInfo.getPublicKeyData().getOctets());
+ ASN1OctetString pEnc = ASN1OctetString.getInstance(new X9ECPoint(p,true).toASN1Primitive());
+
+ try
+ {
+ return new SubjectPublicKeyInfo(publicKeyInfo.getAlgorithm(), pEnc.getOctets()).getEncoded();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to encode EC public key: " + e.getMessage());
+ }
+ }
+
+ public ECParameterSpec getParams()
+ {
+ return ecPublicKey.getParams();
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java
index aa151cce..47614015 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java
@@ -2,17 +2,25 @@ package org.bouncycastle.jcajce.util;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Signature;
+import java.security.cert.CertPathBuilder;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreParameters;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.crypto.Cipher;
+import javax.crypto.ExemptionMechanism;
import javax.crypto.KeyAgreement;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
@@ -52,9 +60,13 @@ public interface JcaJceHelper
KeyPairGenerator createKeyPairGenerator(String algorithm)
throws NoSuchAlgorithmException, NoSuchProviderException;
+ /** @deprecated Use createMessageDigest instead */
MessageDigest createDigest(String algorithm)
throws NoSuchAlgorithmException, NoSuchProviderException;
+ MessageDigest createMessageDigest(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
Signature createSignature(String algorithm)
throws NoSuchAlgorithmException, NoSuchProviderException;
@@ -63,4 +75,19 @@ public interface JcaJceHelper
SecureRandom createSecureRandom(String algorithm)
throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ CertPathBuilder createCertPathBuilder(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ CertPathValidator createCertPathValidator(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ CertStore createCertStore(String type, CertStoreParameters params)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchProviderException;
+
+ ExemptionMechanism createExemptionMechanism(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ KeyStore createKeyStore(String type)
+ throws KeyStoreException, NoSuchProviderException;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java
index bc5da9a9..214f8639 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java
@@ -2,17 +2,25 @@ package org.bouncycastle.jcajce.util;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Signature;
+import java.security.cert.CertPathBuilder;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreParameters;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.crypto.Cipher;
+import javax.crypto.ExemptionMechanism;
import javax.crypto.KeyAgreement;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
@@ -87,12 +95,19 @@ public class NamedJcaJceHelper
return KeyPairGenerator.getInstance(algorithm, providerName);
}
+ /** @deprecated Use createMessageDigest instead */
public MessageDigest createDigest(String algorithm)
throws NoSuchAlgorithmException, NoSuchProviderException
{
return MessageDigest.getInstance(algorithm, providerName);
}
+ public MessageDigest createMessageDigest(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return MessageDigest.getInstance(algorithm, providerName);
+ }
+
public Signature createSignature(String algorithm)
throws NoSuchAlgorithmException, NoSuchProviderException
{
@@ -110,4 +125,34 @@ public class NamedJcaJceHelper
{
return SecureRandom.getInstance(algorithm, providerName);
}
+
+ public CertPathBuilder createCertPathBuilder(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return CertPathBuilder.getInstance(algorithm, providerName);
+ }
+
+ public CertPathValidator createCertPathValidator(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return CertPathValidator.getInstance(algorithm, providerName);
+ }
+
+ public CertStore createCertStore(String type, CertStoreParameters params)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchProviderException
+ {
+ return CertStore.getInstance(type, params, providerName);
+ }
+
+ public ExemptionMechanism createExemptionMechanism(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return ExemptionMechanism.getInstance(algorithm, providerName);
+ }
+
+ public KeyStore createKeyStore(String type)
+ throws KeyStoreException, NoSuchProviderException
+ {
+ return KeyStore.getInstance(type, providerName);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/PrivateKeyAnnotator.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/PrivateKeyAnnotator.java
new file mode 100644
index 00000000..24e664c6
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/PrivateKeyAnnotator.java
@@ -0,0 +1,31 @@
+package org.bouncycastle.jcajce.util;
+
+import java.security.PrivateKey;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Class for instancing AnnotatedPrivateKeys.
+ */
+public class PrivateKeyAnnotator
+{
+ /**
+ * Create an AnnotatedPrivateKey with a single annotation using AnnotatedPrivateKey.LABEL as a key.
+ *
+ * @param privKey the private key to be annotated.
+ * @param label the label to be associated with the private key.
+ * @return the newly annotated private key.
+ */
+ public static AnnotatedPrivateKey annotate(PrivateKey privKey, String label)
+ {
+ return new AnnotatedPrivateKey(privKey, label);
+ }
+
+ public static AnnotatedPrivateKey annotate(PrivateKey privKey, Map<String, Object> annotations)
+ {
+ Map savedAnnotations = new HashMap(annotations);
+
+ return new AnnotatedPrivateKey(privKey, Collections.unmodifiableMap(savedAnnotations));
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java
index f07b0a85..b9a28fa5 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java
@@ -2,17 +2,25 @@ package org.bouncycastle.jcajce.util;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Signature;
+import java.security.cert.CertPathBuilder;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreParameters;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.crypto.Cipher;
+import javax.crypto.ExemptionMechanism;
import javax.crypto.KeyAgreement;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
@@ -87,12 +95,19 @@ public class ProviderJcaJceHelper
return KeyPairGenerator.getInstance(algorithm, provider);
}
+ /** @deprecated Use createMessageDigest instead */
public MessageDigest createDigest(String algorithm)
throws NoSuchAlgorithmException
{
return MessageDigest.getInstance(algorithm, provider);
}
+ public MessageDigest createMessageDigest(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return MessageDigest.getInstance(algorithm, provider);
+ }
+
public Signature createSignature(String algorithm)
throws NoSuchAlgorithmException
{
@@ -110,4 +125,34 @@ public class ProviderJcaJceHelper
{
return SecureRandom.getInstance(algorithm, provider);
}
+
+ public CertPathBuilder createCertPathBuilder(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return CertPathBuilder.getInstance(algorithm, provider);
+ }
+
+ public CertPathValidator createCertPathValidator(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return CertPathValidator.getInstance(algorithm, provider);
+ }
+
+ public CertStore createCertStore(String type, CertStoreParameters params)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException
+ {
+ return CertStore.getInstance(type, params, provider);
+ }
+
+ public ExemptionMechanism createExemptionMechanism(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return ExemptionMechanism.getInstance(algorithm, provider);
+ }
+
+ public KeyStore createKeyStore(String type)
+ throws KeyStoreException
+ {
+ return KeyStore.getInstance(type, provider);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java b/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java
index 1c63c3b2..ee4dbbd3 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java
@@ -178,6 +178,7 @@ public class PKCS10CertificationRequest
noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384);
noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512);
noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1);
+ noParams.add(OIWObjectIdentifiers.dsaWithSHA1);
noParams.add(NISTObjectIdentifiers.dsa_with_sha224);
noParams.add(NISTObjectIdentifiers.dsa_with_sha256);
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java b/bcprov/src/main/java/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java
index e36848f4..2647051e 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java
@@ -10,6 +10,11 @@ public class ExtCertPathValidatorException
private Throwable cause;
+ public ExtCertPathValidatorException(String message)
+ {
+ super(message);
+ }
+
public ExtCertPathValidatorException(String message, Throwable cause)
{
super(message);
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java b/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
index 159224f2..0c9de937 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
@@ -115,7 +115,7 @@ public class NetscapeCertRequest
pubkeyinfo).getBytes());
keyAlg = pubkeyinfo.getAlgorithm();
- pubkey = KeyFactory.getInstance(keyAlg.getAlgorithm().getId(), "BC")
+ pubkey = KeyFactory.getInstance(keyAlg.getAlgorithm().getId())
.generatePublic(xspec);
}
@@ -203,8 +203,7 @@ public class NetscapeCertRequest
// Verify the signature .. shows the response was generated
// by someone who knew the associated private key
//
- Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId(),
- "BC");
+ Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId());
sig.initVerify(pubkey);
sig.update(content.getBytes());
@@ -223,8 +222,7 @@ public class NetscapeCertRequest
SignatureException, NoSuchProviderException,
InvalidKeySpecException
{
- Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId(),
- "BC");
+ Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId());
if (rand != null)
{
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 4458fc14..bb12aecf 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java
@@ -2,15 +2,20 @@ package org.bouncycastle.jce.provider;
import java.io.IOException;
import java.security.AccessController;
+import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.security.PublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+// import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers;
+// import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
@@ -28,6 +33,7 @@ import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
// import org.bouncycastle.pqc.jcajce.provider.sphincs.Sphincs256KeyFactorySpi;
// import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSKeyFactorySpi;
// import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSMTKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.lms.LMSKeyFactorySpi;
/**
* To add the provider at runtime use:
@@ -56,7 +62,7 @@ import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
public final class BouncyCastleProvider extends Provider
implements ConfigurableProvider
{
- private static String info = "BouncyCastle Security Provider v1.61";
+ private static String info = "BouncyCastle Security Provider v1.68";
public static final String PROVIDER_NAME = "BC";
@@ -64,6 +70,8 @@ public final class BouncyCastleProvider extends Provider
private static final Map keyInfoConverters = new HashMap();
+ private static final Class revChkClass = ClassUtil.loadClass(BouncyCastleProvider.class, "java.security.cert.PKIXRevocationChecker");
+
/*
* Configurable symmetric ciphers
*/
@@ -102,7 +110,7 @@ public final class BouncyCastleProvider extends Provider
private static final String[] ASYMMETRIC_GENERIC =
{
// Android-changed: Unsupported algorithms
- // "X509", "IES"
+ // "X509", "IES", "COMPOSITE"
"X509"
};
@@ -121,7 +129,8 @@ public final class BouncyCastleProvider extends Provider
{
// Android-changed: Unsupported algorithms
// "GOST3411", "Keccak", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224",
- // "SHA256", "SHA384", "SHA512", "SHA3", "Skein", "SM3", "Tiger", "Whirlpool", "Blake2b", "Blake2s", "DSTU7564"
+ // "SHA256", "SHA384", "SHA512", "SHA3", "Skein", "SM3", "Tiger", "Whirlpool", "Blake2b", "Blake2s", "DSTU7564",
+ // "Haraka"
"MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512",
};
@@ -151,7 +160,7 @@ public final class BouncyCastleProvider extends Provider
*/
public BouncyCastleProvider()
{
- super(PROVIDER_NAME, 1.61, info);
+ super(PROVIDER_NAME, 1.68, info);
AccessController.doPrivileged(new PrivilegedAction()
{
@@ -184,6 +193,7 @@ public final class BouncyCastleProvider extends Provider
loadAlgorithms(SECURE_RANDOM_PACKAGE, SECURE_RANDOMS);
loadPQCKeys(); // so we can handle certificates containing them.
+
//
// X509Store
//
@@ -196,7 +206,7 @@ public final class BouncyCastleProvider extends Provider
put("X509Store.CRL/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCRLs");
put("X509Store.ATTRIBUTECERTIFICATE/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPAttrCerts");
put("X509Store.CERTIFICATEPAIR/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCertPairs");
-
+
//
// X509StreamParser
//
@@ -220,8 +230,27 @@ public final class BouncyCastleProvider extends Provider
put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
+
+ if (revChkClass != null)
+ {
+ put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
+ put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi_8");
+ put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi_8");
+ put("CertPathValidator.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi_8");
+ put("CertPathBuilder.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi_8");
+ }
+ else
+ {
+ put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi");
+ put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
+ put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
+ put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
+ put("CertPathValidator.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
+ put("CertPathBuilder.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
+ }
*/
// END Android-removed: Unsupported algorithms
+
put("CertPathValidator.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
put("CertPathBuilder.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
put("CertStore.Collection", "org.bouncycastle.jce.provider.CertStoreCollectionSpi");
@@ -260,15 +289,15 @@ public final class BouncyCastleProvider extends Provider
addKeyInfoConverter(PQCObjectIdentifiers.sphincs256, new Sphincs256KeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.newHope, new NHKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.xmss, new XMSSKeyFactorySpi());
+ addKeyInfoConverter(IsaraObjectIdentifiers.id_alg_xmss, new XMSSKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.xmss_mt, new XMSSMTKeyFactorySpi());
+ addKeyInfoConverter(IsaraObjectIdentifiers.id_alg_xmssmt, new XMSSMTKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.mcEliece, new McElieceKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.mcElieceCca2, new McElieceCCA2KeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.rainbow, new RainbowKeyFactorySpi());
- addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_I, new QTESLAKeyFactorySpi());
- addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_III_size, new QTESLAKeyFactorySpi());
- addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_III_speed, new QTESLAKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_I, new QTESLAKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_III, new QTESLAKeyFactorySpi());
+ addKeyInfoConverter(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, new LMSKeyFactorySpi());
}
*/
// END Android-removed: Unsupported algorithms
@@ -310,6 +339,11 @@ public final class BouncyCastleProvider extends Provider
}
}
+ public AsymmetricKeyInfoConverter getKeyInfoConverter(ASN1ObjectIdentifier oid)
+ {
+ return (AsymmetricKeyInfoConverter)keyInfoConverters.get(oid);
+ }
+
public void addAttributes(String key, Map<String, String> attributeMap)
{
for (Iterator it = attributeMap.keySet().iterator(); it.hasNext();)
@@ -336,6 +370,22 @@ public final class BouncyCastleProvider extends Provider
public static PublicKey getPublicKey(SubjectPublicKeyInfo publicKeyInfo)
throws IOException
{
+ // Android-added: BC KeyFactories have been removed, so load them the standard way
+ try {
+ return KeyFactory
+ .getInstance(
+ publicKeyInfo.getAlgorithmId().getAlgorithm().getId())
+ .generatePublic(
+ new X509EncodedKeySpec(publicKeyInfo.getEncoded()));
+ } catch (java.security.NoSuchAlgorithmException ex) {
+ // Maintaining compatibility with upstream logic: if appropriate algorithm not found
+ // ("converter" in Android-removed section) return null instead of throwing.
+ return null;
+ } catch (java.security.spec.InvalidKeySpecException ex) {
+ throw new IOException(ex);
+ }
+ // Android-removed: see above
+ /*
AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(publicKeyInfo.getAlgorithm().getAlgorithm());
if (converter == null)
@@ -344,11 +394,28 @@ public final class BouncyCastleProvider extends Provider
}
return converter.generatePublic(publicKeyInfo);
+ */
}
public static PrivateKey getPrivateKey(PrivateKeyInfo privateKeyInfo)
throws IOException
{
+ // Android-added: BC KeyFactories have been removed, so load them the standard way
+ try {
+ return KeyFactory
+ .getInstance(
+ privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm().getId())
+ .generatePrivate(
+ new PKCS8EncodedKeySpec(privateKeyInfo.getEncoded()));
+ } catch (java.security.NoSuchAlgorithmException ex) {
+ // Maintaining compatibility with upstream logic: if appropriate algorithm not found
+ // ("converter" in Android-removed section) return null instead of throwing.
+ return null;
+ } catch (java.security.spec.InvalidKeySpecException ex) {
+ throw new IOException(ex);
+ }
+ // Android-removed: see above
+ /*
AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm());
if (converter == null)
@@ -357,5 +424,6 @@ public final class BouncyCastleProvider extends Provider
}
return converter.generatePrivate(privateKeyInfo);
+ */
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java
index 87b69273..473f05b8 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java
@@ -63,7 +63,7 @@ class BouncyCastleProviderConfiguration
}
else // assume java.security.spec
{
- curveSpec = EC5Util.convertSpec((java.security.spec.ECParameterSpec)parameter, false);
+ curveSpec = EC5Util.convertSpec((java.security.spec.ECParameterSpec)parameter);
}
if (curveSpec == null)
@@ -88,7 +88,7 @@ class BouncyCastleProviderConfiguration
}
else // assume java.security.spec
{
- ecImplicitCaParams = EC5Util.convertSpec((java.security.spec.ECParameterSpec)parameter, false);
+ ecImplicitCaParams = EC5Util.convertSpec((java.security.spec.ECParameterSpec)parameter);
}
}
else if (parameterName.equals(ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS))
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/CertBlacklist.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/CertBlocklist.java
index 1094b3bc..48e5ba07 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/CertBlacklist.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/CertBlocklist.java
@@ -33,27 +33,28 @@ import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.AndroidDigestFactory;
import org.bouncycastle.util.encoders.Hex;
-public class CertBlacklist {
- private static final Logger logger = Logger.getLogger(CertBlacklist.class.getName());
+public class CertBlocklist {
+ private static final Logger logger = Logger.getLogger(CertBlocklist.class.getName());
// public for testing
- public final Set<BigInteger> serialBlacklist;
- public final Set<byte[]> pubkeyBlacklist;
+ public final Set<BigInteger> serialBlocklist;
+ public final Set<byte[]> pubkeyBlocklist;
- public CertBlacklist() {
+ public CertBlocklist() {
String androidData = System.getenv("ANDROID_DATA");
- String blacklistRoot = androidData + "/misc/keychain/";
- String defaultPubkeyBlacklistPath = blacklistRoot + "pubkey_blacklist.txt";
- String defaultSerialBlacklistPath = blacklistRoot + "serial_blacklist.txt";
+ String blocklistRoot = androidData + "/misc/keychain/";
+ // TODO(b/162575432): change these paths to use inclusive language
+ String defaultPubkeyBlocklistPath = blocklistRoot + "pubkey_blacklist.txt";
+ String defaultSerialBlocklistPath = blocklistRoot + "serial_blacklist.txt";
- pubkeyBlacklist = readPublicKeyBlackList(defaultPubkeyBlacklistPath);
- serialBlacklist = readSerialBlackList(defaultSerialBlacklistPath);
+ pubkeyBlocklist = readPublicKeyBlockList(defaultPubkeyBlocklistPath);
+ serialBlocklist = readSerialBlockList(defaultSerialBlocklistPath);
}
/** Test only interface, not for public use */
- public CertBlacklist(String pubkeyBlacklistPath, String serialBlacklistPath) {
- pubkeyBlacklist = readPublicKeyBlackList(pubkeyBlacklistPath);
- serialBlacklist = readSerialBlackList(serialBlacklistPath);
+ public CertBlocklist(String pubkeyBlocklistPath, String serialBlocklistPath) {
+ pubkeyBlocklist = readPublicKeyBlockList(pubkeyBlocklistPath);
+ serialBlocklist = readSerialBlockList(serialBlocklistPath);
}
private static boolean isHex(String value) {
@@ -74,12 +75,12 @@ public class CertBlacklist {
return isHex(value);
}
- private static String readBlacklist(String path) {
+ private static String readBlocklist(String path) {
try {
return readFileAsString(path);
} catch (FileNotFoundException ignored) {
} catch (IOException e) {
- logger.log(Level.WARNING, "Could not read blacklist", e);
+ logger.log(Level.WARNING, "Could not read blocklist", e);
}
return "";
}
@@ -120,7 +121,7 @@ public class CertBlacklist {
}
}
- private static final Set<BigInteger> readSerialBlackList(String path) {
+ private static Set<BigInteger> readSerialBlockList(String path) {
/* Start out with a base set of known bad values.
*
@@ -147,13 +148,13 @@ public class CertBlacklist {
));
// attempt to augment it with values taken from gservices
- String serialBlacklist = readBlacklist(path);
- if (!serialBlacklist.equals("")) {
- for(String value : serialBlacklist.split(",")) {
+ String serialBlocklist = readBlocklist(path);
+ if (!serialBlocklist.equals("")) {
+ for(String value : serialBlocklist.split(",")) {
try {
bl.add(new BigInteger(value, 16));
} catch (NumberFormatException e) {
- logger.log(Level.WARNING, "Tried to blacklist invalid serial number " + value, e);
+ logger.log(Level.WARNING, "Tried to blocklist invalid serial number " + value, e);
}
}
}
@@ -162,7 +163,7 @@ public class CertBlacklist {
return Collections.unmodifiableSet(bl);
}
- private static final Set<byte[]> readPublicKeyBlackList(String path) {
+ private static Set<byte[]> readPublicKeyBlockList(String path) {
// start out with a base set of known bad values
Set<byte[]> bl = new HashSet<byte[]>(Arrays.asList(
@@ -197,14 +198,14 @@ public class CertBlacklist {
));
// attempt to augment it with values taken from gservices
- String pubkeyBlacklist = readBlacklist(path);
- if (!pubkeyBlacklist.equals("")) {
- for (String value : pubkeyBlacklist.split(",")) {
+ String pubkeyBlocklist = readBlocklist(path);
+ if (!pubkeyBlocklist.equals("")) {
+ for (String value : pubkeyBlocklist.split(",")) {
value = value.trim();
if (isPubkeyHash(value)) {
bl.add(value.getBytes());
} else {
- logger.log(Level.WARNING, "Tried to blacklist invalid pubkey " + value);
+ logger.log(Level.WARNING, "Tried to blocklist invalid pubkey " + value);
}
}
}
@@ -212,22 +213,22 @@ public class CertBlacklist {
return bl;
}
- public boolean isPublicKeyBlackListed(PublicKey publicKey) {
+ public boolean isPublicKeyBlockListed(PublicKey publicKey) {
byte[] encoded = publicKey.getEncoded();
Digest digest = AndroidDigestFactory.getSHA1();
digest.update(encoded, 0, encoded.length);
byte[] out = new byte[digest.getDigestSize()];
digest.doFinal(out, 0);
- for (byte[] blacklisted : pubkeyBlacklist) {
- if (Arrays.equals(blacklisted, Hex.encode(out))) {
+ for (byte[] blocklisted : pubkeyBlocklist) {
+ if (Arrays.equals(blocklisted, Hex.encode(out))) {
return true;
}
}
return false;
}
- public boolean isSerialNumberBlackListed(BigInteger serial) {
- return serialBlacklist.contains(serial);
+ public boolean isSerialNumberBlockListed(BigInteger serial) {
+ return serialBlocklist.contains(serial);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
index 0f783ec2..6f74c722 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
@@ -3,15 +3,18 @@ package org.bouncycastle.jce.provider;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
+import java.net.URI;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.cert.CRLException;
import java.security.cert.CertPath;
+import java.security.cert.CertPathBuilderException;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertStore;
import java.security.cert.CertStoreException;
import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
import java.security.cert.CertificateParsingException;
import java.security.cert.PolicyQualifierInfo;
import java.security.cert.TrustAnchor;
@@ -48,6 +51,7 @@ import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1OutputStream;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1String;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers;
@@ -66,11 +70,15 @@ import org.bouncycastle.asn1.x509.PolicyInformation;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.jcajce.PKIXCRLStore;
import org.bouncycastle.jcajce.PKIXCRLStoreSelector;
+import org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
import org.bouncycastle.jcajce.PKIXCertStore;
import org.bouncycastle.jcajce.PKIXCertStoreSelector;
+import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
import org.bouncycastle.jcajce.PKIXExtendedParameters;
import org.bouncycastle.jcajce.util.JcaJceHelper;
+import org.bouncycastle.jce.exception.ExtCertPathBuilderException;
import org.bouncycastle.jce.exception.ExtCertPathValidatorException;
+import org.bouncycastle.util.Properties;
import org.bouncycastle.util.Selector;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.StoreException;
@@ -79,8 +87,6 @@ import org.bouncycastle.x509.extension.X509ExtensionUtil;
class CertPathValidatorUtilities
{
- protected static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil();
-
protected static final String CERTIFICATE_POLICIES = Extension.certificatePolicies.getId();
protected static final String BASIC_CONSTRAINTS = Extension.basicConstraints.getId();
protected static final String POLICY_MAPPINGS = Extension.policyMappings.getId();
@@ -118,6 +124,36 @@ class CertPathValidatorUtilities
"privilegeWithdrawn",
"aACompromise"};
+ static Collection findTargets(PKIXExtendedBuilderParameters paramsPKIX) throws CertPathBuilderException
+ {
+ PKIXExtendedParameters baseParams = paramsPKIX.getBaseParameters();
+ PKIXCertStoreSelector certSelect = baseParams.getTargetConstraints();
+ LinkedHashSet targets = new LinkedHashSet();
+
+ try
+ {
+ CertPathValidatorUtilities.findCertificates(targets, certSelect, baseParams.getCertificateStores());
+ CertPathValidatorUtilities.findCertificates(targets, certSelect, baseParams.getCertStores());
+ }
+ catch (AnnotatedException e)
+ {
+ throw new ExtCertPathBuilderException("Error finding target certificate.", e);
+ }
+
+ if (!targets.isEmpty())
+ {
+ return targets;
+ }
+
+ Certificate target = certSelect.getCertificate();
+ if (null == target)
+ {
+ throw new CertPathBuilderException("No certificate found matching targetConstraints.");
+ }
+
+ return Collections.singleton(target);
+ }
+
/**
* Search the given Set of TrustAnchor's for one that is the
* issuer of the given X509 certificate. Uses the default provider
@@ -163,16 +199,11 @@ class CertPathValidatorUtilities
Exception invalidKeyEx = null;
X509CertSelector certSelectX509 = new X509CertSelector();
- X500Name certIssuer = PrincipalUtils.getEncodedIssuerPrincipal(cert);
- try
- {
- certSelectX509.setSubject(certIssuer.getEncoded());
- }
- catch (IOException ex)
- {
- throw new AnnotatedException("Cannot set subject search criteria for trust anchor.", ex);
- }
+ final X500Principal certIssuerPrincipal = cert.getIssuerX500Principal();
+ certSelectX509.setSubject(certIssuerPrincipal);
+
+ X500Name certIssuerName = null;
Iterator iter = trustAnchors.iterator();
while (iter.hasNext() && trust == null)
@@ -189,13 +220,20 @@ class CertPathValidatorUtilities
trust = null;
}
}
- else if (trust.getCAName() != null
+ else if (trust.getCA() != null
+ && trust.getCAName() != null
&& trust.getCAPublicKey() != null)
{
+ if (certIssuerName == null)
+ {
+ certIssuerName = X500Name.getInstance(certIssuerPrincipal.getEncoded());
+ }
+
try
{
- X500Name caName = PrincipalUtils.getCA(trust);
- if (certIssuer.equals(caName))
+ X500Name caName = X500Name.getInstance(trust.getCA().getEncoded());
+
+ if (certIssuerName.equals(caName))
{
trustPublicKey = trust.getCAPublicKey();
}
@@ -260,43 +298,35 @@ class CertPathValidatorUtilities
{
// if in the IssuerAltName extension an URI
// is given, add an additional X.509 store
- if (issuerAlternativeName != null)
+ if (issuerAlternativeName == null)
{
- GeneralNames issuerAltName = GeneralNames.getInstance(ASN1OctetString.getInstance(issuerAlternativeName).getOctets());
+ return Collections.EMPTY_LIST;
+ }
- GeneralName[] names = issuerAltName.getNames();
- List<PKIXCertStore> stores = new ArrayList<PKIXCertStore>();
+ GeneralNames issuerAltName = GeneralNames.getInstance(ASN1OctetString.getInstance(issuerAlternativeName).getOctets());
- for (int i = 0; i != names.length; i++)
- {
- GeneralName altName = names[i];
+ GeneralName[] names = issuerAltName.getNames();
+ List<PKIXCertStore> stores = new ArrayList<PKIXCertStore>();
- PKIXCertStore altStore = altNameCertStoreMap.get(altName);
+ for (int i = 0; i != names.length; i++)
+ {
+ GeneralName altName = names[i];
- if (altStore != null)
- {
- stores.add(altStore);
- }
+ PKIXCertStore altStore = altNameCertStoreMap.get(altName);
+ if (altStore != null)
+ {
+ stores.add(altStore);
}
-
- return stores;
- }
- else
- {
- return Collections.EMPTY_LIST;
}
+
+ return stores;
}
- protected static Date getValidDate(PKIXExtendedParameters paramsPKIX)
+ protected static Date getValidityDate(PKIXExtendedParameters paramsPKIX, Date currentDate)
{
- Date validDate = paramsPKIX.getDate();
+ Date validityDate = paramsPKIX.getValidityDate();
- if (validDate == null)
- {
- validDate = new Date();
- }
-
- return validDate;
+ return null == validityDate ? currentDate : validityDate;
}
protected static boolean isSelfIssued(X509Certificate cert)
@@ -304,7 +334,6 @@ class CertPathValidatorUtilities
return cert.getSubjectDN().equals(cert.getIssuerDN());
}
-
/**
* Extract the value of the given extension, if it exists.
*
@@ -312,32 +341,21 @@ class CertPathValidatorUtilities
* @param oid The object identifier to obtain.
* @throws AnnotatedException if the extension cannot be read.
*/
- protected static ASN1Primitive getExtensionValue(
- java.security.cert.X509Extension ext,
- String oid)
+ protected static ASN1Primitive getExtensionValue(java.security.cert.X509Extension ext, String oid)
throws AnnotatedException
{
byte[] bytes = ext.getExtensionValue(oid);
- if (bytes == null)
- {
- return null;
- }
- return getObject(oid, bytes);
+ return null == bytes ? null : getObject(oid, bytes);
}
- private static ASN1Primitive getObject(
- String oid,
- byte[] ext)
- throws AnnotatedException
+ private static ASN1Primitive getObject(String oid, byte[] ext) throws AnnotatedException
{
try
{
- ASN1InputStream aIn = new ASN1InputStream(ext);
- ASN1OctetString octs = (ASN1OctetString)aIn.readObject();
+ ASN1OctetString octs = ASN1OctetString.getInstance(ext);
- aIn = new ASN1InputStream(octs.getOctets());
- return aIn.readObject();
+ return ASN1Primitive.fromByteArray(octs.getOctets());
}
catch (Exception e)
{
@@ -345,17 +363,11 @@ class CertPathValidatorUtilities
}
}
- protected static AlgorithmIdentifier getAlgorithmIdentifier(
- PublicKey key)
- throws CertPathValidatorException
+ protected static AlgorithmIdentifier getAlgorithmIdentifier(PublicKey key) throws CertPathValidatorException
{
try
{
- ASN1InputStream aIn = new ASN1InputStream(key.getEncoded());
-
- SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(aIn.readObject());
-
- return info.getAlgorithm();
+ return SubjectPublicKeyInfo.getInstance(key.getEncoded()).getAlgorithm();
}
catch (Exception e)
{
@@ -381,10 +393,9 @@ class CertPathValidatorUtilities
}
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
+ ASN1OutputStream aOut = ASN1OutputStream.create(bOut);
Enumeration e = qualifiers.getObjects();
-
while (e.hasMoreElements())
{
try
@@ -650,23 +661,23 @@ class CertPathValidatorUtilities
}
/**
- * Return a Collection of all certificates or attribute certificates found
- * in the X509Store's that are matching the certSelect criteriums.
+ * Return a Collection of all certificates or attribute certificates found in the X509Store's
+ * that are matching the certSelect criteriums.
*
- * @param certSelect a {@link Selector} object that will be used to select
- * the certificates
- * @param certStores a List containing only {@link Store} objects. These
- * are used to search for certificates.
- * @return a Collection of all found {@link X509Certificate}
- * May be empty but never <code>null</code>.
+ * @param certs
+ * a {@link LinkedHashSet} to which the certificates will be added.
+ * @param certSelect
+ * a {@link Selector} object that will be used to select the certificates
+ * @param certStores
+ * a List containing only {@link Store} objects. These are used to search for
+ * certificates.
+ * @return a Collection of all found {@link X509Certificate} May be empty but never
+ * <code>null</code>.
*/
- protected static Collection findCertificates(PKIXCertStoreSelector certSelect,
- List certStores)
+ protected static void findCertificates(LinkedHashSet certs, PKIXCertStoreSelector certSelect, List certStores)
throws AnnotatedException
{
- Set certs = new LinkedHashSet();
Iterator iter = certStores.iterator();
-
while (iter.hasNext())
{
Object obj = iter.next();
@@ -682,8 +693,7 @@ class CertPathValidatorUtilities
}
catch (StoreException e)
{
- throw new AnnotatedException(
- "Problem while picking certificates from X.509 store.", e);
+ throw new AnnotatedException("Problem while picking certificates from X.509 store.", e);
}
}
else
@@ -691,68 +701,109 @@ class CertPathValidatorUtilities
// END Android-removed: Unknown reason
{
CertStore certStore = (CertStore)obj;
-
try
{
certs.addAll(PKIXCertStoreSelector.getCertificates(certSelect, certStore));
}
catch (CertStoreException e)
{
- throw new AnnotatedException(
- "Problem while picking certificates from certificate store.",
- e);
+ throw new AnnotatedException("Problem while picking certificates from certificate store.", e);
}
}
}
- return certs;
}
- static List<PKIXCRLStore> getAdditionalStoresFromCRLDistributionPoint(CRLDistPoint crldp, Map<GeneralName, PKIXCRLStore> namedCRLStoreMap)
+ static List<PKIXCRLStore> getAdditionalStoresFromCRLDistributionPoint(
+ CRLDistPoint crldp, Map<GeneralName, PKIXCRLStore> namedCRLStoreMap, Date validDate, JcaJceHelper helper)
throws AnnotatedException
{
- if (crldp != null)
+ if (null == crldp)
+ {
+ return Collections.EMPTY_LIST;
+ }
+
+ DistributionPoint dps[];
+ try
+ {
+ dps = crldp.getDistributionPoints();
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("Distribution points could not be read.", e);
+ }
+
+ List<PKIXCRLStore> stores = new ArrayList<PKIXCRLStore>();
+
+ for (int i = 0; i < dps.length; i++)
{
- DistributionPoint dps[] = null;
+ DistributionPointName dpn = dps[i].getDistributionPoint();
+ // look for URIs in fullName
+ if (dpn != null && dpn.getType() == DistributionPointName.FULL_NAME)
+ {
+ GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames();
+
+ for (int j = 0; j < genNames.length; j++)
+ {
+ PKIXCRLStore store = namedCRLStoreMap.get(genNames[j]);
+ if (store != null)
+ {
+ stores.add(store);
+ }
+ }
+ }
+ }
+
+ // if the named CRL store is empty, and we're told to check with CRLDP
+ if (stores.isEmpty() && Properties.isOverrideSet("org.bouncycastle.x509.enableCRLDP"))
+ {
+ CertificateFactory certFact;
try
{
- dps = crldp.getDistributionPoints();
+ certFact = helper.createCertificateFactory("X.509");
}
catch (Exception e)
{
- throw new AnnotatedException(
- "Distribution points could not be read.", e);
+ throw new AnnotatedException("cannot create certificate factory: " + e.getMessage(), e);
}
- List<PKIXCRLStore> stores = new ArrayList<PKIXCRLStore>();
for (int i = 0; i < dps.length; i++)
{
DistributionPointName dpn = dps[i].getDistributionPoint();
// look for URIs in fullName
- if (dpn != null)
+ if (dpn != null && dpn.getType() == DistributionPointName.FULL_NAME)
{
- if (dpn.getType() == DistributionPointName.FULL_NAME)
- {
- GeneralName[] genNames = GeneralNames.getInstance(
- dpn.getName()).getNames();
+ GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames();
- for (int j = 0; j < genNames.length; j++)
+ for (int j = 0; j < genNames.length; j++)
+ {
+ GeneralName name = genNames[i];
+ if (name.getTagNo() == GeneralName.uniformResourceIdentifier)
{
- PKIXCRLStore store = namedCRLStoreMap.get(genNames[j]);
- if (store != null)
+ try
{
- stores.add(store);
+ // BEGIN Android-removed
+ /*
+ URI distributionPoint = new URI(((ASN1String)name.getName()).getString());
+ PKIXCRLStore store = CrlCache.getCrl(certFact, validDate, distributionPoint);
+ if (store != null)
+ {
+ stores.add(store);
+ }
+ */
+ // END Android-removed
+ break;
+ }
+ catch (Exception e)
+ {
+ // ignore... TODO: maybe log
}
}
}
}
}
-
- return stores;
- }
- else
- {
- return Collections.EMPTY_LIST;
}
+
+ return stores;
}
/**
@@ -789,14 +840,12 @@ class CertPathValidatorUtilities
{
try
{
- issuers.add(X500Name.getInstance(genNames[j].getName()
- .toASN1Primitive().getEncoded()));
+ issuers.add(X500Name.getInstance(genNames[j].getName().toASN1Primitive().getEncoded()));
}
catch (IOException e)
{
throw new AnnotatedException(
- "CRL issuer information from distribution point cannot be decoded.",
- e);
+ "CRL issuer information from distribution point cannot be decoded.", e);
}
}
}
@@ -877,8 +926,7 @@ class CertPathValidatorUtilities
}
}
- private static BigInteger getSerialNumber(
- Object cert)
+ private static BigInteger getSerialNumber(Object cert)
{
return ((X509Certificate)cert).getSerialNumber();
}
@@ -890,8 +938,6 @@ class CertPathValidatorUtilities
CertStatus certStatus)
throws AnnotatedException
{
- X509CRLEntry crl_entry = null;
-
boolean isIndirect;
try
{
@@ -902,6 +948,7 @@ class CertPathValidatorUtilities
throw new AnnotatedException("Failed check for indirect CRL.", exception);
}
+ X509CRLEntry crl_entry;
if (isIndirect)
{
crl_entry = crl.getRevokedCertificate(getSerialNumber(cert));
@@ -920,15 +967,15 @@ class CertPathValidatorUtilities
}
else
{
- certIssuer = X500Name.getInstance(certificateIssuer.getEncoded());
+ certIssuer = PrincipalUtils.getX500Name(certificateIssuer);
}
- if (! PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(certIssuer))
+ if (!PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(certIssuer))
{
return;
}
}
- else if (! PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(PrincipalUtils.getIssuerPrincipal(crl)))
+ else if (!PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(PrincipalUtils.getIssuerPrincipal(crl)))
{
return; // not for our issuer, ignore
}
@@ -945,41 +992,35 @@ class CertPathValidatorUtilities
ASN1Enumerated reasonCode = null;
if (crl_entry.hasExtensions())
{
+ if (crl_entry.hasUnsupportedCriticalExtension())
+ {
+ throw new AnnotatedException("CRL entry has unsupported critical extensions.");
+ }
+
try
{
reasonCode = ASN1Enumerated
- .getInstance(CertPathValidatorUtilities
- .getExtensionValue(crl_entry,
- Extension.reasonCode.getId()));
+ .getInstance(CertPathValidatorUtilities.getExtensionValue(crl_entry, Extension.reasonCode.getId()));
}
catch (Exception e)
{
- throw new AnnotatedException(
- "Reason code CRL entry extension could not be decoded.",
- e);
+ throw new AnnotatedException("Reason code CRL entry extension could not be decoded.", e);
}
}
- // for reason keyCompromise, caCompromise, aACompromise or
- // unspecified
+ int reasonCodeValue = (null == reasonCode)
+ ? CRLReason.unspecified
+ : reasonCode.intValueExact();
+
+ // for reason keyCompromise, caCompromise, aACompromise or unspecified
if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime())
- || reasonCode == null
- || reasonCode.getValue().intValue() == 0
- || reasonCode.getValue().intValue() == 1
- || reasonCode.getValue().intValue() == 2
- || reasonCode.getValue().intValue() == 8)
+ || reasonCodeValue == CRLReason.unspecified
+ || reasonCodeValue == CRLReason.keyCompromise
+ || reasonCodeValue == CRLReason.cACompromise
+ || reasonCodeValue == CRLReason.aACompromise)
{
-
- // (i) or (j) (1)
- if (reasonCode != null)
- {
- certStatus.setCertStatus(reasonCode.getValue().intValue());
- }
- // (i) or (j) (2)
- else
- {
- certStatus.setCertStatus(CRLReason.unspecified);
- }
+ // (i) or (j)
+ certStatus.setCertStatus(reasonCodeValue);
certStatus.setRevocationDate(crl_entry.getRevocationDate());
}
}
@@ -994,7 +1035,10 @@ class CertPathValidatorUtilities
* CRLs.
*/
protected static Set getDeltaCRLs(Date validityDate,
- X509CRL completeCRL, List<CertStore> certStores, List<PKIXCRLStore> pkixCrlStores)
+ X509CRL completeCRL,
+ List<CertStore> certStores,
+ List<PKIXCRLStore> pkixCrlStores,
+ JcaJceHelper helper)
throws AnnotatedException
{
X509CRLSelector baseDeltaSelect = new X509CRLSelector();
@@ -1008,13 +1052,10 @@ class CertPathValidatorUtilities
throw new AnnotatedException("Cannot extract issuer from CRL.", e);
}
-
-
BigInteger completeCRLNumber = null;
try
{
- ASN1Primitive derObject = CertPathValidatorUtilities.getExtensionValue(completeCRL,
- CRL_NUMBER);
+ ASN1Primitive derObject = CertPathValidatorUtilities.getExtensionValue(completeCRL, CRL_NUMBER);
if (derObject != null)
{
completeCRLNumber = ASN1Integer.getInstance(derObject).getPositiveValue();
@@ -1027,22 +1068,19 @@ class CertPathValidatorUtilities
}
// 5.2.4 (b)
- byte[] idp = null;
+ byte[] idp;
try
{
idp = completeCRL.getExtensionValue(ISSUING_DISTRIBUTION_POINT);
}
catch (Exception e)
{
- throw new AnnotatedException(
- "Issuing distribution point extension value could not be read.",
- e);
+ throw new AnnotatedException("Issuing distribution point extension value could not be read.", e);
}
// 5.2.4 (d)
- baseDeltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber
- .add(BigInteger.valueOf(1)));
+ baseDeltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber.add(BigInteger.valueOf(1)));
PKIXCRLStoreSelector.Builder selBuilder = new PKIXCRLStoreSelector.Builder(baseDeltaSelect);
@@ -1055,8 +1093,61 @@ class CertPathValidatorUtilities
PKIXCRLStoreSelector deltaSelect = selBuilder.build();
// find delta CRLs
- Set temp = CRL_UTIL.findCRLs(deltaSelect, validityDate, certStores, pkixCrlStores);
+ Set temp = PKIXCRLUtil.findCRLs(deltaSelect, validityDate, certStores, pkixCrlStores);
+ // if the named CRL store is empty, and we're told to check with CRLDP
+ if (temp.isEmpty() && Properties.isOverrideSet("org.bouncycastle.x509.enableCRLDP"))
+ {
+ CertificateFactory certFact;
+ try
+ {
+ certFact = helper.createCertificateFactory("X.509");
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("cannot create certificate factory: " + e.getMessage(), e);
+ }
+
+ CRLDistPoint id = CRLDistPoint.getInstance(idp);
+ DistributionPoint[] dps = id.getDistributionPoints();
+ for (int i = 0; i < dps.length; i++)
+ {
+ DistributionPointName dpn = dps[i].getDistributionPoint();
+ // look for URIs in fullName
+ if (dpn != null && dpn.getType() == DistributionPointName.FULL_NAME)
+ {
+ GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames();
+
+ for (int j = 0; j < genNames.length; j++)
+ {
+ GeneralName name = genNames[i];
+ if (name.getTagNo() == GeneralName.uniformResourceIdentifier)
+ {
+ try
+ {
+ // BEGIN Android-removed
+ /*
+ PKIXCRLStore store = CrlCache.getCrl(certFact, validityDate,
+ new URI(((ASN1String)name.getName()).getString()));
+ if (store != null)
+ {
+ temp = PKIXCRLUtil.findCRLs(deltaSelect, validityDate, Collections.EMPTY_LIST,
+ Collections.singletonList(store));
+ }
+ */
+ // END Android-removed
+ break;
+ }
+ catch (Exception e)
+ {
+ // ignore... TODO: maybe log
+ }
+ }
+ }
+ }
+ }
+ }
+
Set result = new HashSet();
for (Iterator it = temp.iterator(); it.hasNext(); )
@@ -1097,24 +1188,22 @@ class CertPathValidatorUtilities
* @throws AnnotatedException if an exception occurs while picking the CRLs
* or no CRLs are found.
*/
- protected static Set getCompleteCRLs(DistributionPoint dp, Object cert,
- Date currentDate, PKIXExtendedParameters paramsPKIX)
- throws AnnotatedException
+ protected static Set getCompleteCRLs(PKIXCertRevocationCheckerParameters params, DistributionPoint dp, Object cert,
+ PKIXExtendedParameters paramsPKIX, Date validityDate)
+ throws AnnotatedException, RecoverableCertPathValidatorException
{
X509CRLSelector baseCrlSelect = new X509CRLSelector();
try
{
Set issuers = new HashSet();
-
issuers.add(PrincipalUtils.getEncodedIssuerPrincipal(cert));
CertPathValidatorUtilities.getCRLIssuersFromDistributionPoint(dp, issuers, baseCrlSelect);
}
catch (AnnotatedException e)
{
- throw new AnnotatedException(
- "Could not get issuer information from distribution point.", e);
+ throw new AnnotatedException("Could not get issuer information from distribution point.", e);
}
if (cert instanceof X509Certificate)
@@ -1122,84 +1211,62 @@ class CertPathValidatorUtilities
baseCrlSelect.setCertificateChecking((X509Certificate)cert);
}
- PKIXCRLStoreSelector crlSelect = new PKIXCRLStoreSelector.Builder(baseCrlSelect).setCompleteCRLEnabled(true).build();
+ PKIXCRLStoreSelector crlSelect = new PKIXCRLStoreSelector.Builder(baseCrlSelect).setCompleteCRLEnabled(true)
+ .build();
- Date validityDate = currentDate;
+ Set crls = PKIXCRLUtil.findCRLs(crlSelect, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores());
- if (paramsPKIX.getDate() != null)
- {
- validityDate = paramsPKIX.getDate();
- }
-
- Set crls = CRL_UTIL.findCRLs(crlSelect, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores());
-
- checkCRLsNotEmpty(crls, cert);
+ checkCRLsNotEmpty(params, crls, cert);
return crls;
}
- protected static Date getValidCertDateFromValidityModel(
- PKIXExtendedParameters paramsPKIX, CertPath certPath, int index)
- throws AnnotatedException
+ protected static Date getValidCertDateFromValidityModel(Date validityDate, int validityModel, CertPath certPath,
+ int index) throws AnnotatedException
{
- if (paramsPKIX.getValidityModel() == PKIXExtendedParameters.CHAIN_VALIDITY_MODEL)
+ if (PKIXExtendedParameters.CHAIN_VALIDITY_MODEL != validityModel || index <= 0)
{
- // if end cert use given signing/encryption/... time
- if (index <= 0)
+ // use given signing/encryption/... time (or current date)
+ return validityDate;
+ }
+
+ X509Certificate issuedCert = (X509Certificate)certPath.getCertificates().get(index - 1);
+
+ if (index - 1 == 0)
+ {
+ // use time when cert was issued, if available
+ ASN1GeneralizedTime dateOfCertgen = null;
+ try
+ {
+ byte[] extBytes = ((X509Certificate)certPath.getCertificates().get(index - 1))
+ .getExtensionValue(ISISMTTObjectIdentifiers.id_isismtt_at_dateOfCertGen.getId());
+ if (extBytes != null)
+ {
+ dateOfCertgen = ASN1GeneralizedTime.getInstance(ASN1Primitive.fromByteArray(extBytes));
+ }
+ }
+ catch (IOException e)
{
- return CertPathValidatorUtilities.getValidDate(paramsPKIX);
- // else use time when previous cert was created
+ throw new AnnotatedException("Date of cert gen extension could not be read.");
}
- else
+ catch (IllegalArgumentException e)
+ {
+ throw new AnnotatedException("Date of cert gen extension could not be read.");
+ }
+ if (dateOfCertgen != null)
{
- if (index - 1 == 0)
+ try
{
- ASN1GeneralizedTime dateOfCertgen = null;
- try
- {
- byte[] extBytes = ((X509Certificate)certPath.getCertificates().get(index - 1)).getExtensionValue(ISISMTTObjectIdentifiers.id_isismtt_at_dateOfCertGen.getId());
- if (extBytes != null)
- {
- dateOfCertgen = ASN1GeneralizedTime.getInstance(ASN1Primitive.fromByteArray(extBytes));
- }
- }
- catch (IOException e)
- {
- throw new AnnotatedException(
- "Date of cert gen extension could not be read.");
- }
- catch (IllegalArgumentException e)
- {
- throw new AnnotatedException(
- "Date of cert gen extension could not be read.");
- }
- if (dateOfCertgen != null)
- {
- try
- {
- return dateOfCertgen.getDate();
- }
- catch (ParseException e)
- {
- throw new AnnotatedException(
- "Date from date of cert gen extension could not be parsed.",
- e);
- }
- }
- return ((X509Certificate)certPath.getCertificates().get(
- index - 1)).getNotBefore();
+ return dateOfCertgen.getDate();
}
- else
+ catch (ParseException e)
{
- return ((X509Certificate)certPath.getCertificates().get(
- index - 1)).getNotBefore();
+ throw new AnnotatedException("Date from date of cert gen extension could not be parsed.", e);
}
}
}
- else
- {
- return getValidDate(paramsPKIX);
- }
+
+ return issuedCert.getNotBefore();
}
/**
@@ -1287,10 +1354,10 @@ class CertPathValidatorUtilities
{
selector.setSubject(PrincipalUtils.getIssuerPrincipal(cert).getEncoded());
}
- catch (IOException e)
+ catch (Exception e)
{
throw new AnnotatedException(
- "Subject criteria for certificate selector to find issuer certificate could not be set.", e);
+ "Subject criteria for certificate selector to find issuer certificate could not be set.", e);
}
try
@@ -1312,37 +1379,24 @@ class CertPathValidatorUtilities
}
PKIXCertStoreSelector certSelect = new PKIXCertStoreSelector.Builder(selector).build();
- Set certs = new LinkedHashSet();
-
- Iterator iter;
+ LinkedHashSet certs = new LinkedHashSet();
try
{
- List matches = new ArrayList();
-
- matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, certStores));
- matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixCertStores));
-
- iter = matches.iterator();
+ CertPathValidatorUtilities.findCertificates(certs, certSelect, certStores);
+ CertPathValidatorUtilities.findCertificates(certs, certSelect, pkixCertStores);
}
catch (AnnotatedException e)
{
throw new AnnotatedException("Issuer certificate cannot be searched.", e);
}
- X509Certificate issuer = null;
- while (iter.hasNext())
- {
- issuer = (X509Certificate)iter.next();
- // issuer cannot be verified because possible DSA inheritance
- // parameters are missing
- certs.add(issuer);
- }
+ // issuers cannot be verified because possible DSA inheritance parameters are missing
+
return certs;
}
- protected static void verifyX509Certificate(X509Certificate cert, PublicKey publicKey,
- String sigProvider)
+ protected static void verifyX509Certificate(X509Certificate cert, PublicKey publicKey, String sigProvider)
throws GeneralSecurityException
{
if (sigProvider == null)
@@ -1355,8 +1409,8 @@ class CertPathValidatorUtilities
}
}
- static void checkCRLsNotEmpty(Set crls, Object cert)
- throws AnnotatedException
+ static void checkCRLsNotEmpty(PKIXCertRevocationCheckerParameters params, Set crls, Object cert)
+ throws RecoverableCertPathValidatorException
{
if (crls.isEmpty())
{
@@ -1364,13 +1418,15 @@ class CertPathValidatorUtilities
{
X509AttributeCertificate aCert = (X509AttributeCertificate)cert;
- throw new AnnotatedException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\"");
+ throw new RecoverableCertPathValidatorException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\"", null,
+ params.getCertPath(), params.getIndex());
}
else
{
X509Certificate xCert = (X509Certificate)cert;
- throw new AnnotatedException("No CRLs found for issuer \"" + RFC4519Style.INSTANCE.toString(PrincipalUtils.getIssuerPrincipal(xCert)) + "\"");
+ throw new RecoverableCertPathValidatorException("No CRLs found for issuer \"" + RFC4519Style.INSTANCE.toString(PrincipalUtils.getIssuerPrincipal(xCert)) + "\"", null,
+ params.getCertPath(), params.getIndex());
}
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java
index 1e99c86f..26616b45 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java
@@ -28,6 +28,7 @@ import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X962Parameters;
import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.asn1.x9.X9ECPoint;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
@@ -189,7 +190,7 @@ public class JCEECPrivateKey
private void populateFromPrivKeyInfo(PrivateKeyInfo info)
throws IOException
{
- X962Parameters params = new X962Parameters((ASN1Primitive)info.getPrivateKeyAlgorithm().getParameters());
+ X962Parameters params = X962Parameters.getInstance(info.getPrivateKeyAlgorithm().getParameters());
if (params.isNamedCurve())
{
@@ -300,7 +301,7 @@ public class JCEECPrivateKey
X9ECParameters ecP = new X9ECParameters(
curve,
- EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression),
+ new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), withCompression),
ecSpec.getOrder(),
BigInteger.valueOf(ecSpec.getCofactor()),
ecSpec.getCurve().getSeed());
@@ -354,14 +355,14 @@ public class JCEECPrivateKey
return null;
}
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec()
{
if (ecSpec != null)
{
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java
index 916f6fd8..67a8cd71 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java
@@ -14,7 +14,6 @@ import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DEROctetString;
@@ -41,8 +40,6 @@ import org.bouncycastle.jce.interfaces.ECPointEncoder;
// import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.math.ec.ECCurve;
-import org.bouncycastle.math.ec.custom.sec.SecP256K1Point;
-import org.bouncycastle.math.ec.custom.sec.SecP256R1Point;
import org.bouncycastle.util.Strings;
public class JCEECPublicKey
@@ -73,7 +70,7 @@ public class JCEECPublicKey
{
this.algorithm = algorithm;
this.ecSpec = spec.getParams();
- this.q = EC5Util.convertPoint(ecSpec, spec.getW(), false);
+ this.q = EC5Util.convertPoint(ecSpec, spec.getW());
}
public JCEECPublicKey(
@@ -96,7 +93,7 @@ public class JCEECPublicKey
{
org.bouncycastle.jce.spec.ECParameterSpec s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
- q = s.getCurve().createPoint(q.getAffineXCoord().toBigInteger(), q.getAffineYCoord().toBigInteger(), false);
+ q = s.getCurve().createPoint(q.getAffineXCoord().toBigInteger(), q.getAffineYCoord().toBigInteger());
}
this.ecSpec = null;
}
@@ -174,7 +171,7 @@ public class JCEECPublicKey
{
this.algorithm = key.getAlgorithm();
this.ecSpec = key.getParams();
- this.q = EC5Util.convertPoint(this.ecSpec, key.getW(), false);
+ this.q = EC5Util.convertPoint(this.ecSpec, key.getW());
}
JCEECPublicKey(
@@ -185,9 +182,11 @@ public class JCEECPublicKey
private void populateFromPubKeyInfo(SubjectPublicKeyInfo info)
{
+ AlgorithmIdentifier algID = info.getAlgorithm();
// BEGIN Android-removed: Unsupported algorithms
/*
- if (info.getAlgorithmId().getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3410_2001))
+
+ if (algID.getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3410_2001))
{
DERBitString bits = info.getPublicKeyData();
ASN1OctetString key;
@@ -212,7 +211,7 @@ public class JCEECPublicKey
x9Encoding[i + 32] = keyEnc[64 - i];
}
- gostParams = new GOST3410PublicKeyAlgParameters((ASN1Sequence)info.getAlgorithmId().getParameters());
+ gostParams = GOST3410PublicKeyAlgParameters.getInstance(algID.getParameters());
ECNamedCurveParameterSpec spec = ECGOST3410NamedCurveTable.getParameterSpec(ECGOST3410NamedCurves.getName(gostParams.getPublicKeyParamSet()));
@@ -232,7 +231,7 @@ public class JCEECPublicKey
*/
// END Android-removed: Unsupported algorithms
{
- X962Parameters params = new X962Parameters((ASN1Primitive)info.getAlgorithmId().getParameters());
+ X962Parameters params = X962Parameters.getInstance(algID.getParameters());
ECCurve curve;
EllipticCurve ellipticCurve;
@@ -337,7 +336,7 @@ public class JCEECPublicKey
X9ECParameters ecP = new X9ECParameters(
curve,
- EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression),
+ new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), withCompression),
ecSpec.getOrder(),
BigInteger.valueOf(ecSpec.getCofactor()),
ecSpec.getCurve().getSeed());
@@ -346,10 +345,10 @@ public class JCEECPublicKey
}
}
- BigInteger bX = this.q.getAffineXCoord().toBigInteger();
- BigInteger bY = this.q.getAffineYCoord().toBigInteger();
- byte[] encKey = new byte[64];
+ BigInteger bX = this.q.getAffineXCoord().toBigInteger();
+ BigInteger bY = this.q.getAffineYCoord().toBigInteger();
+ byte[] encKey = new byte[64];
extractBytes(encKey, 0, bX);
extractBytes(encKey, 32, bY);
@@ -385,7 +384,7 @@ public class JCEECPublicKey
X9ECParameters ecP = new X9ECParameters(
curve,
- EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression),
+ new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), withCompression),
ecSpec.getOrder(),
BigInteger.valueOf(ecSpec.getCofactor()),
ecSpec.getCurve().getSeed());
@@ -393,11 +392,9 @@ public class JCEECPublicKey
params = new X962Parameters(ecP);
}
- ECCurve curve = this.engineGetQ().getCurve();
- ASN1OctetString p = (ASN1OctetString)
- new X9ECPoint(curve.createPoint(this.getQ().getAffineXCoord().toBigInteger(), this.getQ().getAffineYCoord().toBigInteger(), withCompression)).toASN1Primitive();
+ byte[] pubKeyOctets = this.getQ().getEncoded(withCompression);
- info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets());
+ info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), pubKeyOctets);
}
return KeyUtil.getEncodedSubjectPublicKeyInfo(info);
@@ -431,7 +428,7 @@ public class JCEECPublicKey
return null;
}
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
public ECPoint getW()
@@ -458,7 +455,7 @@ public class JCEECPublicKey
{
if (ecSpec != null)
{
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java
index 97a38aca..c1925328 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCRLUtil.java
@@ -16,18 +16,18 @@ import org.bouncycastle.jcajce.PKIXCRLStoreSelector;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.StoreException;
-class PKIXCRLUtil
+abstract class PKIXCRLUtil
{
- public Set findCRLs(PKIXCRLStoreSelector crlselect, Date validityDate, List certStores, List pkixCrlStores)
+ static Set findCRLs(PKIXCRLStoreSelector crlselect, Date validityDate, List certStores, List pkixCrlStores)
throws AnnotatedException
{
- Set initialSet = new HashSet();
+ HashSet initialSet = new HashSet();
// get complete CRL(s)
try
{
- initialSet.addAll(findCRLs(crlselect, pkixCrlStores));
- initialSet.addAll(findCRLs(crlselect, certStores));
+ findCRLs(initialSet, crlselect, pkixCrlStores);
+ findCRLs(initialSet, crlselect, certStores);
}
catch (AnnotatedException e)
{
@@ -45,14 +45,7 @@ class PKIXCRLUtil
{
X509Certificate cert = crlselect.getCertificateChecking();
- if (cert != null)
- {
- if (crl.getThisUpdate().before(cert.getNotAfter()))
- {
- finalSet.add(crl);
- }
- }
- else
+ if (null == cert || crl.getThisUpdate().before(cert.getNotAfter()))
{
finalSet.add(crl);
}
@@ -63,27 +56,23 @@ class PKIXCRLUtil
}
/**
- * Return a Collection of all CRLs found in the X509Store's that are
- * matching the crlSelect criteriums.
+ * Add to a HashSet any and all CRLs found in the X509Store's that are matching the crlSelect
+ * critera.
*
- * @param crlSelect a {@link org.bouncycastle.jcajce.PKIXCRLStoreSelector} object that will be used
- * to select the CRLs
- * @param crlStores a List containing only
- * {@link Store} objects.
- * These are used to search for CRLs
- *
- * @return a Collection of all found {@link java.security.cert.X509CRL X509CRL} objects. May be
- * empty but never <code>null</code>.
+ * @param crls
+ * the {@link HashSet} to add the CRLs to.
+ * @param crlSelect
+ * a {@link org.bouncycastle.jcajce.PKIXCRLStoreSelector} object that will be used to
+ * select the CRLs
+ * @param crlStores
+ * a List containing only {@link Store} objects. These are used to search for CRLs
*/
- private final Collection findCRLs(PKIXCRLStoreSelector crlSelect,
- List crlStores) throws AnnotatedException
+ private static void findCRLs(HashSet crls, PKIXCRLStoreSelector crlSelect, List crlStores) throws AnnotatedException
{
- Set crls = new HashSet();
- Iterator iter = crlStores.iterator();
-
AnnotatedException lastException = null;
boolean foundValidStore = false;
+ Iterator iter = crlStores.iterator();
while (iter.hasNext())
{
Object obj = iter.next();
@@ -101,8 +90,7 @@ class PKIXCRLUtil
}
catch (StoreException e)
{
- lastException = new AnnotatedException(
- "Exception searching in X.509 CRL store.", e);
+ lastException = new AnnotatedException("Exception searching in X.509 CRL store.", e);
}
}
else
@@ -118,16 +106,14 @@ class PKIXCRLUtil
}
catch (CertStoreException e)
{
- lastException = new AnnotatedException(
- "Exception searching in X.509 CRL store.", e);
+ lastException = new AnnotatedException("Exception searching in X.509 CRL store.", e);
}
}
}
+
if (!foundValidStore && lastException != null)
{
throw lastException;
}
- return crls;
}
-
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java
index b9086219..9ba3a387 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java
@@ -19,11 +19,9 @@ import java.util.List;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.jcajce.PKIXCertStore;
-import org.bouncycastle.jcajce.PKIXCertStoreSelector;
import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
import org.bouncycastle.jcajce.PKIXExtendedParameters;
import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory;
-import org.bouncycastle.jce.exception.ExtCertPathBuilderException;
import org.bouncycastle.x509.ExtendedPKIXBuilderParameters;
import org.bouncycastle.x509.ExtendedPKIXParameters;
@@ -35,6 +33,18 @@ import org.bouncycastle.x509.ExtendedPKIXParameters;
public class PKIXCertPathBuilderSpi
extends CertPathBuilderSpi
{
+ private final boolean isForCRLCheck;
+
+ public PKIXCertPathBuilderSpi()
+ {
+ this(false);
+ }
+
+ PKIXCertPathBuilderSpi(boolean isForCRLCheck)
+ {
+ this.isForCRLCheck = isForCRLCheck;
+ }
+
/**
* Build and validate a CertPath using the given parameter.
*
@@ -88,26 +98,7 @@ public class PKIXCertPathBuilderSpi
X509Certificate cert;
// search target certificates
-
- PKIXCertStoreSelector certSelect = paramsPKIX.getBaseParameters().getTargetConstraints();
-
- try
- {
- targets = CertPathValidatorUtilities.findCertificates(certSelect, paramsPKIX.getBaseParameters().getCertificateStores());
- targets.addAll(CertPathValidatorUtilities.findCertificates(certSelect, paramsPKIX.getBaseParameters().getCertStores()));
- }
- catch (AnnotatedException e)
- {
- throw new ExtCertPathBuilderException(
- "Error finding target certificate.", e);
- }
-
- if (targets.isEmpty())
- {
-
- throw new CertPathBuilderException(
- "No certificate found matching targetContraints.");
- }
+ targets = CertPathValidatorUtilities.findTargets(paramsPKIX);
CertPathBuilderResult result = null;
@@ -175,7 +166,7 @@ public class PKIXCertPathBuilderSpi
try
{
cFact = new CertificateFactory();
- validator = new PKIXCertPathValidatorSpi();
+ validator = new PKIXCertPathValidatorSpi(isForCRLCheck);
}
catch (Exception e)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
index 16659525..b142f973 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
@@ -15,6 +15,7 @@ import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
+import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -28,6 +29,8 @@ import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.TBSCertificate;
import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
import org.bouncycastle.jcajce.PKIXExtendedParameters;
+// BEGIN Android-removed:
+// import org.bouncycastle.jcajce.interfaces.BCX509Certificate;
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.jce.exception.ExtCertPathValidatorException;
@@ -41,15 +44,22 @@ public class PKIXCertPathValidatorSpi
extends CertPathValidatorSpi
{
private final JcaJceHelper helper = new BCJcaJceHelper();
+ private final boolean isForCRLCheck;
public PKIXCertPathValidatorSpi()
{
+ this(false);
}
- // BEGIN Android-added: Avoid loading blacklist during class init
+
+ public PKIXCertPathValidatorSpi(boolean isForCRLCheck)
+ {
+ this.isForCRLCheck = isForCRLCheck;
+ }
+ // BEGIN Android-added: Avoid loading blocklist during class init
private static class NoPreloadHolder {
- private final static CertBlacklist blacklist = new CertBlacklist();
+ private final static CertBlocklist blocklist = new CertBlocklist();
}
- // END Android-added: Avoid loading blacklist during class init
+ // END Android-added: Avoid loading blocklist during class init
public CertPathValidatorResult engineValidate(
CertPath certPath,
@@ -105,13 +115,13 @@ public class PKIXCertPathValidatorSpi
{
throw new CertPathValidatorException("Certification path is empty.", null, certPath, -1);
}
- // BEGIN Android-added: Support blacklisting known-bad certs
+ // BEGIN Android-added: Support blocklisting known-bad certs
{
X509Certificate cert = (X509Certificate) certs.get(0);
if (cert != null) {
BigInteger serial = cert.getSerialNumber();
- if (NoPreloadHolder.blacklist.isSerialNumberBlackListed(serial)) {
+ if (NoPreloadHolder.blocklist.isSerialNumberBlockListed(serial)) {
// emulate CRL exception message in RFC3280CertPathUtilities.checkCRLs
String message = "Certificate revocation of serial 0x" + serial.toString(16);
System.out.println(message);
@@ -120,12 +130,13 @@ public class PKIXCertPathValidatorSpi
}
}
}
- // END Android-added: Support blacklisting known-bad certs
+ // END Android-added: Support blocklisting known-bad certs
//
// (b)
//
- // Date validDate = CertPathValidatorUtilities.getValidDate(paramsPKIX);
+ final Date currentDate = new Date();
+ final Date validityDate = CertPathValidatorUtilities.getValidityDate(paramsPKIX, currentDate);
//
// (c)
@@ -253,7 +264,7 @@ public class PKIXCertPathValidatorSpi
workingPublicKey = trust.getCAPublicKey();
}
}
- catch (IllegalArgumentException ex)
+ catch (RuntimeException ex)
{
throw new ExtCertPathValidatorException("Subject of trust anchor could not be (re)encoded.", ex, certPath,
-1);
@@ -298,19 +309,32 @@ public class PKIXCertPathValidatorSpi
((PKIXCertPathChecker) certIter.next()).init(false);
}
+ //
+ // initialize RevocationChecker
+ //
+ ProvCrlRevocationChecker revocationChecker;
+ if (paramsPKIX.isRevocationEnabled())
+ {
+ revocationChecker = new ProvCrlRevocationChecker(helper);
+ }
+ else
+ {
+ revocationChecker = null;
+ }
+
X509Certificate cert = null;
for (index = certs.size() - 1; index >= 0; index--)
{
- // BEGIN Android-added: Support blacklisting known-bad certs
- if (NoPreloadHolder.blacklist.isPublicKeyBlackListed(workingPublicKey)) {
+ // BEGIN Android-added: Support blocklisting known-bad certs
+ if (NoPreloadHolder.blocklist.isPublicKeyBlockListed(workingPublicKey)) {
// emulate CRL exception message in RFC3280CertPathUtilities.checkCRLs
String message = "Certificate revocation of public key " + workingPublicKey;
System.out.println(message);
AnnotatedException e = new AnnotatedException(message);
throw new CertPathValidatorException(e.getMessage(), e, certPath, index);
}
- // END Android-added: Support blacklisting known-bad certs
+ // END Android-added: Support blocklisting known-bad certs
// try
// {
//
@@ -340,13 +364,13 @@ public class PKIXCertPathValidatorSpi
// 6.1.3
//
- RFC3280CertPathUtilities.processCertA(certPath, paramsPKIX, index, workingPublicKey,
- verificationAlreadyPerformed, workingIssuerName, sign, helper);
+ RFC3280CertPathUtilities.processCertA(certPath, paramsPKIX, validityDate, revocationChecker, index,
+ workingPublicKey, verificationAlreadyPerformed, workingIssuerName, sign);
- RFC3280CertPathUtilities.processCertBC(certPath, index, nameConstraintValidator);
+ RFC3280CertPathUtilities.processCertBC(certPath, index, nameConstraintValidator, isForCRLCheck);
validPolicyTree = RFC3280CertPathUtilities.processCertD(certPath, index, acceptablePolicies,
- validPolicyTree, policyNodes, inhibitAnyPolicy);
+ validPolicyTree, policyNodes, inhibitAnyPolicy, isForCRLCheck);
validPolicyTree = RFC3280CertPathUtilities.processCertE(certPath, index, validPolicyTree);
@@ -505,6 +529,27 @@ public class PKIXCertPathValidatorSpi
static void checkCertificate(X509Certificate cert)
throws AnnotatedException
{
+ // BEGIN Android-removed:
+ /*
+ if (cert instanceof BCX509Certificate)
+ {
+ RuntimeException cause = null;
+ try
+ {
+ if (null != ((BCX509Certificate)cert).getTBSCertificateNative())
+ {
+ return;
+ }
+ }
+ catch (RuntimeException e)
+ {
+ cause = e;
+ }
+
+ throw new AnnotatedException("unable to process TBSCertificate", cause);
+ }
+ */
+ // END Android-removed:
try
{
TBSCertificate.getInstance(cert.getTBSCertificate());
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java
index 07427122..71faea9b 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java
@@ -1,1455 +1,58 @@
package org.bouncycastle.jce.provider;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Sequence;
-import org.bouncycastle.asn1.DERIA5String;
+import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralSubtree;
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Integers;
-import org.bouncycastle.util.Strings;
+import org.bouncycastle.asn1.x509.NameConstraintValidatorException;
public class PKIXNameConstraintValidator
{
- private Set excludedSubtreesDN = new HashSet();
-
- private Set excludedSubtreesDNS = new HashSet();
-
- private Set excludedSubtreesEmail = new HashSet();
-
- private Set excludedSubtreesURI = new HashSet();
-
- private Set excludedSubtreesIP = new HashSet();
-
- private Set permittedSubtreesDN;
-
- private Set permittedSubtreesDNS;
-
- private Set permittedSubtreesEmail;
-
- private Set permittedSubtreesURI;
-
- private Set permittedSubtreesIP;
+ org.bouncycastle.asn1.x509.PKIXNameConstraintValidator validator = new org.bouncycastle.asn1.x509.PKIXNameConstraintValidator();
public PKIXNameConstraintValidator()
{
}
- private static boolean withinDNSubtree(
- ASN1Sequence dns,
- ASN1Sequence subtree)
- {
- if (subtree.size() < 1)
- {
- return false;
- }
-
- if (subtree.size() > dns.size())
- {
- return false;
- }
-
- for (int j = subtree.size() - 1; j >= 0; j--)
- {
- if (!subtree.getObjectAt(j).equals(dns.getObjectAt(j)))
- {
- return false;
- }
- }
-
- return true;
- }
-
- public void checkPermittedDN(ASN1Sequence dns)
- throws PKIXNameConstraintValidatorException
- {
- checkPermittedDN(permittedSubtreesDN, dns);
- }
-
- public void checkExcludedDN(ASN1Sequence dns)
- throws PKIXNameConstraintValidatorException
- {
- checkExcludedDN(excludedSubtreesDN, dns);
- }
-
- private void checkPermittedDN(Set permitted, ASN1Sequence dns)
- throws PKIXNameConstraintValidatorException
- {
- if (permitted == null)
- {
- return;
- }
-
- if (permitted.isEmpty() && dns.size() == 0)
- {
- return;
- }
- Iterator it = permitted.iterator();
-
- while (it.hasNext())
- {
- ASN1Sequence subtree = (ASN1Sequence)it.next();
-
- if (withinDNSubtree(dns, subtree))
- {
- return;
- }
- }
-
- throw new PKIXNameConstraintValidatorException(
- "Subject distinguished name is not from a permitted subtree");
- }
-
- private void checkExcludedDN(Set excluded, ASN1Sequence dns)
- throws PKIXNameConstraintValidatorException
- {
- if (excluded.isEmpty())
- {
- return;
- }
-
- Iterator it = excluded.iterator();
-
- while (it.hasNext())
- {
- ASN1Sequence subtree = (ASN1Sequence)it.next();
-
- if (withinDNSubtree(dns, subtree))
- {
- throw new PKIXNameConstraintValidatorException(
- "Subject distinguished name is from an excluded subtree");
- }
- }
- }
-
- private Set intersectDN(Set permitted, Set dns)
- {
- Set intersect = new HashSet();
- for (Iterator it = dns.iterator(); it.hasNext();)
- {
- ASN1Sequence dn = ASN1Sequence.getInstance(((GeneralSubtree)it
- .next()).getBase().getName().toASN1Primitive());
- if (permitted == null)
- {
- if (dn != null)
- {
- intersect.add(dn);
- }
- }
- else
- {
- Iterator _iter = permitted.iterator();
- while (_iter.hasNext())
- {
- ASN1Sequence subtree = (ASN1Sequence)_iter.next();
-
- if (withinDNSubtree(dn, subtree))
- {
- intersect.add(dn);
- }
- else if (withinDNSubtree(subtree, dn))
- {
- intersect.add(subtree);
- }
- }
- }
- }
- return intersect;
- }
-
- private Set unionDN(Set excluded, ASN1Sequence dn)
- {
- if (excluded.isEmpty())
- {
- if (dn == null)
- {
- return excluded;
- }
- excluded.add(dn);
-
- return excluded;
- }
- else
- {
- Set intersect = new HashSet();
-
- Iterator it = excluded.iterator();
- while (it.hasNext())
- {
- ASN1Sequence subtree = (ASN1Sequence)it.next();
-
- if (withinDNSubtree(dn, subtree))
- {
- intersect.add(subtree);
- }
- else if (withinDNSubtree(subtree, dn))
- {
- intersect.add(dn);
- }
- else
- {
- intersect.add(subtree);
- intersect.add(dn);
- }
- }
-
- return intersect;
- }
- }
-
- private Set intersectEmail(Set permitted, Set emails)
- {
- Set intersect = new HashSet();
- for (Iterator it = emails.iterator(); it.hasNext();)
- {
- String email = extractNameAsString(((GeneralSubtree)it.next())
- .getBase());
-
- if (permitted == null)
- {
- if (email != null)
- {
- intersect.add(email);
- }
- }
- else
- {
- Iterator it2 = permitted.iterator();
- while (it2.hasNext())
- {
- String _permitted = (String)it2.next();
-
- intersectEmail(email, _permitted, intersect);
- }
- }
- }
- return intersect;
- }
-
- private Set unionEmail(Set excluded, String email)
- {
- if (excluded.isEmpty())
- {
- if (email == null)
- {
- return excluded;
- }
- excluded.add(email);
- return excluded;
- }
- else
- {
- Set union = new HashSet();
-
- Iterator it = excluded.iterator();
- while (it.hasNext())
- {
- String _excluded = (String)it.next();
-
- unionEmail(_excluded, email, union);
- }
-
- return union;
- }
- }
-
- /**
- * Returns the intersection of the permitted IP ranges in
- * <code>permitted</code> with <code>ip</code>.
- *
- * @param permitted A <code>Set</code> of permitted IP addresses with
- * their subnet mask as byte arrays.
- * @param ips The IP address with its subnet mask.
- * @return The <code>Set</code> of permitted IP ranges intersected with
- * <code>ip</code>.
- */
- private Set intersectIP(Set permitted, Set ips)
- {
- Set intersect = new HashSet();
- for (Iterator it = ips.iterator(); it.hasNext();)
- {
- byte[] ip = ASN1OctetString.getInstance(
- ((GeneralSubtree)it.next()).getBase().getName()).getOctets();
- if (permitted == null)
- {
- if (ip != null)
- {
- intersect.add(ip);
- }
- }
- else
- {
- Iterator it2 = permitted.iterator();
- while (it2.hasNext())
- {
- byte[] _permitted = (byte[])it2.next();
- intersect.addAll(intersectIPRange(_permitted, ip));
- }
- }
- }
- return intersect;
- }
-
- /**
- * Returns the union of the excluded IP ranges in <code>excluded</code>
- * with <code>ip</code>.
- *
- * @param excluded A <code>Set</code> of excluded IP addresses with their
- * subnet mask as byte arrays.
- * @param ip The IP address with its subnet mask.
- * @return The <code>Set</code> of excluded IP ranges unified with
- * <code>ip</code> as byte arrays.
- */
- private Set unionIP(Set excluded, byte[] ip)
- {
- if (excluded.isEmpty())
- {
- if (ip == null)
- {
- return excluded;
- }
- excluded.add(ip);
-
- return excluded;
- }
- else
- {
- Set union = new HashSet();
-
- Iterator it = excluded.iterator();
- while (it.hasNext())
- {
- byte[] _excluded = (byte[])it.next();
- union.addAll(unionIPRange(_excluded, ip));
- }
-
- return union;
- }
- }
-
- /**
- * Calculates the union if two IP ranges.
- *
- * @param ipWithSubmask1 The first IP address with its subnet mask.
- * @param ipWithSubmask2 The second IP address with its subnet mask.
- * @return A <code>Set</code> with the union of both addresses.
- */
- private Set unionIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2)
- {
- Set set = new HashSet();
-
- // difficult, adding always all IPs is not wrong
- if (Arrays.areEqual(ipWithSubmask1, ipWithSubmask2))
- {
- set.add(ipWithSubmask1);
- }
- else
- {
- set.add(ipWithSubmask1);
- set.add(ipWithSubmask2);
- }
- return set;
- }
-
- /**
- * Calculates the interesction if two IP ranges.
- *
- * @param ipWithSubmask1 The first IP address with its subnet mask.
- * @param ipWithSubmask2 The second IP address with its subnet mask.
- * @return A <code>Set</code> with the single IP address with its subnet
- * mask as a byte array or an empty <code>Set</code>.
- */
- private Set intersectIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2)
- {
- if (ipWithSubmask1.length != ipWithSubmask2.length)
- {
- return Collections.EMPTY_SET;
- }
- byte[][] temp = extractIPsAndSubnetMasks(ipWithSubmask1, ipWithSubmask2);
- byte ip1[] = temp[0];
- byte subnetmask1[] = temp[1];
- byte ip2[] = temp[2];
- byte subnetmask2[] = temp[3];
-
- byte minMax[][] = minMaxIPs(ip1, subnetmask1, ip2, subnetmask2);
- byte[] min;
- byte[] max;
- max = min(minMax[1], minMax[3]);
- min = max(minMax[0], minMax[2]);
-
- // minimum IP address must be bigger than max
- if (compareTo(min, max) == 1)
- {
- return Collections.EMPTY_SET;
- }
- // OR keeps all significant bits
- byte[] ip = or(minMax[0], minMax[2]);
- byte[] subnetmask = or(subnetmask1, subnetmask2);
- return Collections.singleton(ipWithSubnetMask(ip, subnetmask));
- }
-
- /**
- * Concatenates the IP address with its subnet mask.
- *
- * @param ip The IP address.
- * @param subnetMask Its subnet mask.
- * @return The concatenated IP address with its subnet mask.
- */
- private byte[] ipWithSubnetMask(byte[] ip, byte[] subnetMask)
- {
- int ipLength = ip.length;
- byte[] temp = new byte[ipLength * 2];
- System.arraycopy(ip, 0, temp, 0, ipLength);
- System.arraycopy(subnetMask, 0, temp, ipLength, ipLength);
- return temp;
- }
-
- /**
- * Splits the IP addresses and their subnet mask.
- *
- * @param ipWithSubmask1 The first IP address with the subnet mask.
- * @param ipWithSubmask2 The second IP address with the subnet mask.
- * @return An array with two elements. Each element contains the IP address
- * and the subnet mask in this order.
- */
- private byte[][] extractIPsAndSubnetMasks(
- byte[] ipWithSubmask1,
- byte[] ipWithSubmask2)
- {
- int ipLength = ipWithSubmask1.length / 2;
- byte ip1[] = new byte[ipLength];
- byte subnetmask1[] = new byte[ipLength];
- System.arraycopy(ipWithSubmask1, 0, ip1, 0, ipLength);
- System.arraycopy(ipWithSubmask1, ipLength, subnetmask1, 0, ipLength);
-
- byte ip2[] = new byte[ipLength];
- byte subnetmask2[] = new byte[ipLength];
- System.arraycopy(ipWithSubmask2, 0, ip2, 0, ipLength);
- System.arraycopy(ipWithSubmask2, ipLength, subnetmask2, 0, ipLength);
- return new byte[][]
- {ip1, subnetmask1, ip2, subnetmask2};
- }
-
- /**
- * Based on the two IP addresses and their subnet masks the IP range is
- * computed for each IP address - subnet mask pair and returned as the
- * minimum IP address and the maximum address of the range.
- *
- * @param ip1 The first IP address.
- * @param subnetmask1 The subnet mask of the first IP address.
- * @param ip2 The second IP address.
- * @param subnetmask2 The subnet mask of the second IP address.
- * @return A array with two elements. The first/second element contains the
- * min and max IP address of the first/second IP address and its
- * subnet mask.
- */
- private byte[][] minMaxIPs(
- byte[] ip1,
- byte[] subnetmask1,
- byte[] ip2,
- byte[] subnetmask2)
- {
- int ipLength = ip1.length;
- byte[] min1 = new byte[ipLength];
- byte[] max1 = new byte[ipLength];
-
- byte[] min2 = new byte[ipLength];
- byte[] max2 = new byte[ipLength];
-
- for (int i = 0; i < ipLength; i++)
- {
- min1[i] = (byte)(ip1[i] & subnetmask1[i]);
- max1[i] = (byte)(ip1[i] & subnetmask1[i] | ~subnetmask1[i]);
-
- min2[i] = (byte)(ip2[i] & subnetmask2[i]);
- max2[i] = (byte)(ip2[i] & subnetmask2[i] | ~subnetmask2[i]);
- }
-
- return new byte[][]{min1, max1, min2, max2};
- }
-
- private void checkPermittedEmail(Set permitted, String email)
- throws PKIXNameConstraintValidatorException
- {
- if (permitted == null)
- {
- return;
- }
-
- Iterator it = permitted.iterator();
-
- while (it.hasNext())
- {
- String str = ((String)it.next());
-
- if (emailIsConstrained(email, str))
- {
- return;
- }
- }
-
- if (email.length() == 0 && permitted.size() == 0)
- {
- return;
- }
-
- throw new PKIXNameConstraintValidatorException(
- "Subject email address is not from a permitted subtree.");
- }
-
- private void checkExcludedEmail(Set excluded, String email)
- throws PKIXNameConstraintValidatorException
- {
- if (excluded.isEmpty())
- {
- return;
- }
-
- Iterator it = excluded.iterator();
-
- while (it.hasNext())
- {
- String str = (String)it.next();
-
- if (emailIsConstrained(email, str))
- {
- throw new PKIXNameConstraintValidatorException(
- "Email address is from an excluded subtree.");
- }
- }
- }
-
- /**
- * Checks if the IP <code>ip</code> is included in the permitted set
- * <code>permitted</code>.
- *
- * @param permitted A <code>Set</code> of permitted IP addresses with
- * their subnet mask as byte arrays.
- * @param ip The IP address.
- * @throws PKIXNameConstraintValidatorException
- * if the IP is not permitted.
- */
- private void checkPermittedIP(Set permitted, byte[] ip)
- throws PKIXNameConstraintValidatorException
- {
- if (permitted == null)
- {
- return;
- }
-
- Iterator it = permitted.iterator();
-
- while (it.hasNext())
- {
- byte[] ipWithSubnet = (byte[])it.next();
-
- if (isIPConstrained(ip, ipWithSubnet))
- {
- return;
- }
- }
- if (ip.length == 0 && permitted.size() == 0)
- {
- return;
- }
- throw new PKIXNameConstraintValidatorException(
- "IP is not from a permitted subtree.");
- }
-
- /**
- * Checks if the IP <code>ip</code> is included in the excluded set
- * <code>excluded</code>.
- *
- * @param excluded A <code>Set</code> of excluded IP addresses with their
- * subnet mask as byte arrays.
- * @param ip The IP address.
- * @throws PKIXNameConstraintValidatorException
- * if the IP is excluded.
- */
- private void checkExcludedIP(Set excluded, byte[] ip)
- throws PKIXNameConstraintValidatorException
- {
- if (excluded.isEmpty())
- {
- return;
- }
-
- Iterator it = excluded.iterator();
-
- while (it.hasNext())
- {
- byte[] ipWithSubnet = (byte[])it.next();
-
- if (isIPConstrained(ip, ipWithSubnet))
- {
- throw new PKIXNameConstraintValidatorException(
- "IP is from an excluded subtree.");
- }
- }
- }
-
- /**
- * Checks if the IP address <code>ip</code> is constrained by
- * <code>constraint</code>.
- *
- * @param ip The IP address.
- * @param constraint The constraint. This is an IP address concatenated with
- * its subnetmask.
- * @return <code>true</code> if constrained, <code>false</code>
- * otherwise.
- */
- private boolean isIPConstrained(byte ip[], byte[] constraint)
- {
- int ipLength = ip.length;
-
- if (ipLength != (constraint.length / 2))
- {
- return false;
- }
-
- byte[] subnetMask = new byte[ipLength];
- System.arraycopy(constraint, ipLength, subnetMask, 0, ipLength);
-
- byte[] permittedSubnetAddress = new byte[ipLength];
-
- byte[] ipSubnetAddress = new byte[ipLength];
-
- // the resulting IP address by applying the subnet mask
- for (int i = 0; i < ipLength; i++)
- {
- permittedSubnetAddress[i] = (byte)(constraint[i] & subnetMask[i]);
- ipSubnetAddress[i] = (byte)(ip[i] & subnetMask[i]);
- }
-
- return Arrays.areEqual(permittedSubnetAddress, ipSubnetAddress);
- }
-
- private boolean emailIsConstrained(String email, String constraint)
+ public int hashCode()
{
- String sub = email.substring(email.indexOf('@') + 1);
- // a particular mailbox or @domain
- if (constraint.indexOf('@') != -1)
- {
- if (email.equalsIgnoreCase(constraint))
- {
- return true;
- }
- if (sub.equalsIgnoreCase(constraint.substring(1)))
- {
- return true;
- }
- }
- // on particular host
- else if (!(constraint.charAt(0) == '.'))
- {
- if (sub.equalsIgnoreCase(constraint))
- {
- return true;
- }
- }
- // address in sub domain
- else if (withinDomain(sub, constraint))
- {
- return true;
- }
- return false;
+ return validator.hashCode();
}
- private boolean withinDomain(String testDomain, String domain)
+ public boolean equals(Object o)
{
- String tempDomain = domain;
- if (tempDomain.startsWith("."))
- {
- tempDomain = tempDomain.substring(1);
- }
- String[] domainParts = Strings.split(tempDomain, '.');
- String[] testDomainParts = Strings.split(testDomain, '.');
- // must have at least one subdomain
- if (testDomainParts.length <= domainParts.length)
+ if (!(o instanceof PKIXNameConstraintValidator))
{
return false;
}
- int d = testDomainParts.length - domainParts.length;
- for (int i = -1; i < domainParts.length; i++)
- {
- if (i == -1)
- {
- if (testDomainParts[i + d].equals(""))
- {
- return false;
- }
- }
- else if (!domainParts[i].equalsIgnoreCase(testDomainParts[i + d]))
- {
- return false;
- }
- }
- return true;
- }
-
- private void checkPermittedDNS(Set permitted, String dns)
- throws PKIXNameConstraintValidatorException
- {
- if (permitted == null)
- {
- return;
- }
-
- Iterator it = permitted.iterator();
-
- while (it.hasNext())
- {
- String str = ((String)it.next());
-
- // is sub domain
- if (withinDomain(dns, str) || dns.equalsIgnoreCase(str))
- {
- return;
- }
- }
- if (dns.length() == 0 && permitted.size() == 0)
- {
- return;
- }
- throw new PKIXNameConstraintValidatorException(
- "DNS is not from a permitted subtree.");
- }
-
- private void checkExcludedDNS(Set excluded, String dns)
- throws PKIXNameConstraintValidatorException
- {
- if (excluded.isEmpty())
- {
- return;
- }
-
- Iterator it = excluded.iterator();
-
- while (it.hasNext())
- {
- String str = ((String)it.next());
-
- // is sub domain or the same
- if (withinDomain(dns, str) || dns.equalsIgnoreCase(str))
- {
- throw new PKIXNameConstraintValidatorException(
- "DNS is from an excluded subtree.");
- }
- }
- }
-
- /**
- * The common part of <code>email1</code> and <code>email2</code> is
- * added to the union <code>union</code>. If <code>email1</code> and
- * <code>email2</code> have nothing in common they are added both.
- *
- * @param email1 Email address constraint 1.
- * @param email2 Email address constraint 2.
- * @param union The union.
- */
- private void unionEmail(String email1, String email2, Set union)
- {
- // email1 is a particular address
- if (email1.indexOf('@') != -1)
- {
- String _sub = email1.substring(email1.indexOf('@') + 1);
- // both are a particular mailbox
- if (email2.indexOf('@') != -1)
- {
- if (email1.equalsIgnoreCase(email2))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(_sub, email2))
- {
- union.add(email2);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (_sub.equalsIgnoreCase(email2))
- {
- union.add(email2);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- }
- // email1 specifies a domain
- else if (email1.startsWith("."))
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email1.indexOf('@') + 1);
- if (withinDomain(_sub, email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2)
- || email1.equalsIgnoreCase(email2))
- {
- union.add(email2);
- }
- else if (withinDomain(email2, email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- else
- {
- if (withinDomain(email2, email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- }
- // email specifies a host
- else
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email1.indexOf('@') + 1);
- if (_sub.equalsIgnoreCase(email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2))
- {
- union.add(email2);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (email1.equalsIgnoreCase(email2))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- }
- }
-
- private void unionURI(String email1, String email2, Set union)
- {
- // email1 is a particular address
- if (email1.indexOf('@') != -1)
- {
- String _sub = email1.substring(email1.indexOf('@') + 1);
- // both are a particular mailbox
- if (email2.indexOf('@') != -1)
- {
- if (email1.equalsIgnoreCase(email2))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(_sub, email2))
- {
- union.add(email2);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (_sub.equalsIgnoreCase(email2))
- {
- union.add(email2);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- }
- // email1 specifies a domain
- else if (email1.startsWith("."))
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email1.indexOf('@') + 1);
- if (withinDomain(_sub, email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2)
- || email1.equalsIgnoreCase(email2))
- {
- union.add(email2);
- }
- else if (withinDomain(email2, email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- else
- {
- if (withinDomain(email2, email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- }
- // email specifies a host
- else
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email1.indexOf('@') + 1);
- if (_sub.equalsIgnoreCase(email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2))
- {
- union.add(email2);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (email1.equalsIgnoreCase(email2))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- }
- }
-
- private Set intersectDNS(Set permitted, Set dnss)
- {
- Set intersect = new HashSet();
- for (Iterator it = dnss.iterator(); it.hasNext();)
- {
- String dns = extractNameAsString(((GeneralSubtree)it.next())
- .getBase());
- if (permitted == null)
- {
- if (dns != null)
- {
- intersect.add(dns);
- }
- }
- else
- {
- Iterator _iter = permitted.iterator();
- while (_iter.hasNext())
- {
- String _permitted = (String)_iter.next();
-
- if (withinDomain(_permitted, dns))
- {
- intersect.add(_permitted);
- }
- else if (withinDomain(dns, _permitted))
- {
- intersect.add(dns);
- }
- }
- }
- }
-
- return intersect;
- }
-
- protected Set unionDNS(Set excluded, String dns)
- {
- if (excluded.isEmpty())
- {
- if (dns == null)
- {
- return excluded;
- }
- excluded.add(dns);
-
- return excluded;
- }
- else
- {
- Set union = new HashSet();
-
- Iterator _iter = excluded.iterator();
- while (_iter.hasNext())
- {
- String _permitted = (String)_iter.next();
-
- if (withinDomain(_permitted, dns))
- {
- union.add(dns);
- }
- else if (withinDomain(dns, _permitted))
- {
- union.add(_permitted);
- }
- else
- {
- union.add(_permitted);
- union.add(dns);
- }
- }
-
- return union;
- }
- }
-
- /**
- * The most restricting part from <code>email1</code> and
- * <code>email2</code> is added to the intersection <code>intersect</code>.
- *
- * @param email1 Email address constraint 1.
- * @param email2 Email address constraint 2.
- * @param intersect The intersection.
- */
- private void intersectEmail(String email1, String email2, Set intersect)
- {
- // email1 is a particular address
- if (email1.indexOf('@') != -1)
- {
- String _sub = email1.substring(email1.indexOf('@') + 1);
- // both are a particular mailbox
- if (email2.indexOf('@') != -1)
- {
- if (email1.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(_sub, email2))
- {
- intersect.add(email1);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (_sub.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- }
- }
- // email specifies a domain
- else if (email1.startsWith("."))
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email1.indexOf('@') + 1);
- if (withinDomain(_sub, email1))
- {
- intersect.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2)
- || email1.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- else if (withinDomain(email2, email1))
- {
- intersect.add(email2);
- }
- }
- else
- {
- if (withinDomain(email2, email1))
- {
- intersect.add(email2);
- }
- }
- }
- // email1 specifies a host
- else
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email2.indexOf('@') + 1);
- if (_sub.equalsIgnoreCase(email1))
- {
- intersect.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2))
- {
- intersect.add(email1);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (email1.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- }
- }
+ PKIXNameConstraintValidator constraintValidator = (PKIXNameConstraintValidator)o;
+ return this.validator.equals(constraintValidator.validator);
}
- private void checkExcludedURI(Set excluded, String uri)
+ public void checkPermittedDN(ASN1Sequence dns)
throws PKIXNameConstraintValidatorException
{
- if (excluded.isEmpty())
+ try
{
- return;
+ this.validator.checkPermittedDN(X500Name.getInstance(dns));
}
-
- Iterator it = excluded.iterator();
-
- while (it.hasNext())
+ catch (NameConstraintValidatorException e)
{
- String str = ((String)it.next());
-
- if (isUriConstrained(uri, str))
- {
- throw new PKIXNameConstraintValidatorException(
- "URI is from an excluded subtree.");
- }
+ throw new PKIXNameConstraintValidatorException(e.getMessage(), e);
}
}
- private Set intersectURI(Set permitted, Set uris)
- {
- Set intersect = new HashSet();
- for (Iterator it = uris.iterator(); it.hasNext();)
- {
- String uri = extractNameAsString(((GeneralSubtree)it.next())
- .getBase());
- if (permitted == null)
- {
- if (uri != null)
- {
- intersect.add(uri);
- }
- }
- else
- {
- Iterator _iter = permitted.iterator();
- while (_iter.hasNext())
- {
- String _permitted = (String)_iter.next();
- intersectURI(_permitted, uri, intersect);
- }
- }
- }
- return intersect;
- }
-
- private Set unionURI(Set excluded, String uri)
- {
- if (excluded.isEmpty())
- {
- if (uri == null)
- {
- return excluded;
- }
- excluded.add(uri);
-
- return excluded;
- }
- else
- {
- Set union = new HashSet();
-
- Iterator _iter = excluded.iterator();
- while (_iter.hasNext())
- {
- String _excluded = (String)_iter.next();
-
- unionURI(_excluded, uri, union);
- }
-
- return union;
- }
- }
-
- private void intersectURI(String email1, String email2, Set intersect)
- {
- // email1 is a particular address
- if (email1.indexOf('@') != -1)
- {
- String _sub = email1.substring(email1.indexOf('@') + 1);
- // both are a particular mailbox
- if (email2.indexOf('@') != -1)
- {
- if (email1.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(_sub, email2))
- {
- intersect.add(email1);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (_sub.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- }
- }
- // email specifies a domain
- else if (email1.startsWith("."))
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email1.indexOf('@') + 1);
- if (withinDomain(_sub, email1))
- {
- intersect.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2)
- || email1.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- else if (withinDomain(email2, email1))
- {
- intersect.add(email2);
- }
- }
- else
- {
- if (withinDomain(email2, email1))
- {
- intersect.add(email2);
- }
- }
- }
- // email1 specifies a host
- else
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email2.indexOf('@') + 1);
- if (_sub.equalsIgnoreCase(email1))
- {
- intersect.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2))
- {
- intersect.add(email1);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (email1.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- }
- }
- }
-
- private void checkPermittedURI(Set permitted, String uri)
+ public void checkExcludedDN(ASN1Sequence dns)
throws PKIXNameConstraintValidatorException
{
- if (permitted == null)
+ try
{
- return;
+ this.validator.checkExcludedDN(X500Name.getInstance(dns));
}
-
- Iterator it = permitted.iterator();
-
- while (it.hasNext())
+ catch (NameConstraintValidatorException e)
{
- String str = ((String)it.next());
-
- if (isUriConstrained(uri, str))
- {
- return;
- }
- }
- if (uri.length() == 0 && permitted.size() == 0)
- {
- return;
- }
- throw new PKIXNameConstraintValidatorException(
- "URI is not from a permitted subtree.");
- }
-
- private boolean isUriConstrained(String uri, String constraint)
- {
- String host = extractHostFromURL(uri);
- // a host
- if (!constraint.startsWith("."))
- {
- if (host.equalsIgnoreCase(constraint))
- {
- return true;
- }
- }
-
- // in sub domain or domain
- else if (withinDomain(host, constraint))
- {
- return true;
- }
-
- return false;
- }
-
- private static String extractHostFromURL(String url)
- {
- // see RFC 1738
- // remove ':' after protocol, e.g. http:
- String sub = url.substring(url.indexOf(':') + 1);
- // extract host from Common Internet Scheme Syntax, e.g. http://
- if (sub.indexOf("//") != -1)
- {
- sub = sub.substring(sub.indexOf("//") + 2);
- }
- // first remove port, e.g. http://test.com:21
- if (sub.lastIndexOf(':') != -1)
- {
- sub = sub.substring(0, sub.lastIndexOf(':'));
- }
- // remove user and password, e.g. http://john:password@test.com
- sub = sub.substring(sub.indexOf(':') + 1);
- sub = sub.substring(sub.indexOf('@') + 1);
- // remove local parts, e.g. http://test.com/bla
- if (sub.indexOf('/') != -1)
- {
- sub = sub.substring(0, sub.indexOf('/'));
+ throw new PKIXNameConstraintValidatorException(e.getMessage(), e);
}
- return sub;
}
/**
@@ -1462,28 +65,13 @@ public class PKIXNameConstraintValidator
public void checkPermitted(GeneralName name)
throws PKIXNameConstraintValidatorException
{
- switch (name.getTagNo())
+ try
{
- case 1:
- checkPermittedEmail(permittedSubtreesEmail,
- extractNameAsString(name));
- break;
- case 2:
- checkPermittedDNS(permittedSubtreesDNS, DERIA5String.getInstance(
- name.getName()).getString());
- break;
- case 4:
- checkPermittedDN(ASN1Sequence.getInstance(name.getName()
- .toASN1Primitive()));
- break;
- case 6:
- checkPermittedURI(permittedSubtreesURI, DERIA5String.getInstance(
- name.getName()).getString());
- break;
- case 7:
- byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets();
-
- checkPermittedIP(permittedSubtreesIP, ip);
+ validator.checkPermitted(name);
+ }
+ catch (NameConstraintValidatorException e)
+ {
+ throw new PKIXNameConstraintValidatorException(e.getMessage(), e);
}
}
@@ -1498,33 +86,19 @@ public class PKIXNameConstraintValidator
public void checkExcluded(GeneralName name)
throws PKIXNameConstraintValidatorException
{
- switch (name.getTagNo())
+ try
{
- case 1:
- checkExcludedEmail(excludedSubtreesEmail, extractNameAsString(name));
- break;
- case 2:
- checkExcludedDNS(excludedSubtreesDNS, DERIA5String.getInstance(
- name.getName()).getString());
- break;
- case 4:
- checkExcludedDN(ASN1Sequence.getInstance(name.getName()
- .toASN1Primitive()));
- break;
- case 6:
- checkExcludedURI(excludedSubtreesURI, DERIA5String.getInstance(
- name.getName()).getString());
- break;
- case 7:
- byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets();
-
- checkExcludedIP(excludedSubtreesIP, ip);
+ validator.checkExcluded(name);
+ }
+ catch (NameConstraintValidatorException e)
+ {
+ throw new PKIXNameConstraintValidatorException(e.getMessage(), e);
}
}
public void intersectPermittedSubtree(GeneralSubtree permitted)
{
- intersectPermittedSubtree(new GeneralSubtree[] { permitted });
+ validator.intersectPermittedSubtree(permitted);
}
/**
@@ -1536,396 +110,26 @@ public class PKIXNameConstraintValidator
public void intersectPermittedSubtree(GeneralSubtree[] permitted)
{
- Map subtreesMap = new HashMap();
-
- // group in sets in a map ordered by tag no.
- for (int i = 0; i != permitted.length; i++)
- {
- GeneralSubtree subtree = permitted[i];
- Integer tagNo = Integers.valueOf(subtree.getBase().getTagNo());
- if (subtreesMap.get(tagNo) == null)
- {
- subtreesMap.put(tagNo, new HashSet());
- }
- ((Set)subtreesMap.get(tagNo)).add(subtree);
- }
-
- for (Iterator it = subtreesMap.entrySet().iterator(); it.hasNext();)
- {
- Map.Entry entry = (Map.Entry)it.next();
-
- // go through all subtree groups
- switch (((Integer)entry.getKey()).intValue())
- {
- case 1:
- permittedSubtreesEmail = intersectEmail(permittedSubtreesEmail,
- (Set)entry.getValue());
- break;
- case 2:
- permittedSubtreesDNS = intersectDNS(permittedSubtreesDNS,
- (Set)entry.getValue());
- break;
- case 4:
- permittedSubtreesDN = intersectDN(permittedSubtreesDN,
- (Set)entry.getValue());
- break;
- case 6:
- permittedSubtreesURI = intersectURI(permittedSubtreesURI,
- (Set)entry.getValue());
- break;
- case 7:
- permittedSubtreesIP = intersectIP(permittedSubtreesIP,
- (Set)entry.getValue());
- }
- }
- }
-
- private String extractNameAsString(GeneralName name)
- {
- return DERIA5String.getInstance(name.getName()).getString();
+ validator.intersectPermittedSubtree(permitted);
}
public void intersectEmptyPermittedSubtree(int nameType)
{
- switch (nameType)
- {
- case 1:
- permittedSubtreesEmail = new HashSet();
- break;
- case 2:
- permittedSubtreesDNS = new HashSet();
- break;
- case 4:
- permittedSubtreesDN = new HashSet();
- break;
- case 6:
- permittedSubtreesURI = new HashSet();
- break;
- case 7:
- permittedSubtreesIP = new HashSet();
- }
+ validator.intersectEmptyPermittedSubtree(nameType);
}
-
- /**
+
+ /**
* Adds a subtree to the excluded set of these name constraints.
*
* @param subtree A subtree with an excluded GeneralName.
*/
public void addExcludedSubtree(GeneralSubtree subtree)
{
- GeneralName base = subtree.getBase();
-
- switch (base.getTagNo())
- {
- case 1:
- excludedSubtreesEmail = unionEmail(excludedSubtreesEmail,
- extractNameAsString(base));
- break;
- case 2:
- excludedSubtreesDNS = unionDNS(excludedSubtreesDNS,
- extractNameAsString(base));
- break;
- case 4:
- excludedSubtreesDN = unionDN(excludedSubtreesDN,
- (ASN1Sequence)base.getName().toASN1Primitive());
- break;
- case 6:
- excludedSubtreesURI = unionURI(excludedSubtreesURI,
- extractNameAsString(base));
- break;
- case 7:
- excludedSubtreesIP = unionIP(excludedSubtreesIP, ASN1OctetString
- .getInstance(base.getName()).getOctets());
- break;
- }
- }
-
- /**
- * Returns the maximum IP address.
- *
- * @param ip1 The first IP address.
- * @param ip2 The second IP address.
- * @return The maximum IP address.
- */
- private static byte[] max(byte[] ip1, byte[] ip2)
- {
- for (int i = 0; i < ip1.length; i++)
- {
- if ((ip1[i] & 0xFFFF) > (ip2[i] & 0xFFFF))
- {
- return ip1;
- }
- }
- return ip2;
- }
-
- /**
- * Returns the minimum IP address.
- *
- * @param ip1 The first IP address.
- * @param ip2 The second IP address.
- * @return The minimum IP address.
- */
- private static byte[] min(byte[] ip1, byte[] ip2)
- {
- for (int i = 0; i < ip1.length; i++)
- {
- if ((ip1[i] & 0xFFFF) < (ip2[i] & 0xFFFF))
- {
- return ip1;
- }
- }
- return ip2;
- }
-
- /**
- * Compares IP address <code>ip1</code> with <code>ip2</code>. If ip1
- * is equal to ip2 0 is returned. If ip1 is bigger 1 is returned, -1
- * otherwise.
- *
- * @param ip1 The first IP address.
- * @param ip2 The second IP address.
- * @return 0 if ip1 is equal to ip2, 1 if ip1 is bigger, -1 otherwise.
- */
- private static int compareTo(byte[] ip1, byte[] ip2)
- {
- if (Arrays.areEqual(ip1, ip2))
- {
- return 0;
- }
- if (Arrays.areEqual(max(ip1, ip2), ip1))
- {
- return 1;
- }
- return -1;
- }
-
- /**
- * Returns the logical OR of the IP addresses <code>ip1</code> and
- * <code>ip2</code>.
- *
- * @param ip1 The first IP address.
- * @param ip2 The second IP address.
- * @return The OR of <code>ip1</code> and <code>ip2</code>.
- */
- private static byte[] or(byte[] ip1, byte[] ip2)
- {
- byte[] temp = new byte[ip1.length];
- for (int i = 0; i < ip1.length; i++)
- {
- temp[i] = (byte)(ip1[i] | ip2[i]);
- }
- return temp;
- }
-
- public int hashCode()
- {
- return hashCollection(excludedSubtreesDN)
- + hashCollection(excludedSubtreesDNS)
- + hashCollection(excludedSubtreesEmail)
- + hashCollection(excludedSubtreesIP)
- + hashCollection(excludedSubtreesURI)
- + hashCollection(permittedSubtreesDN)
- + hashCollection(permittedSubtreesDNS)
- + hashCollection(permittedSubtreesEmail)
- + hashCollection(permittedSubtreesIP)
- + hashCollection(permittedSubtreesURI);
- }
-
- private int hashCollection(Collection coll)
- {
- if (coll == null)
- {
- return 0;
- }
- int hash = 0;
- Iterator it1 = coll.iterator();
- while (it1.hasNext())
- {
- Object o = it1.next();
- if (o instanceof byte[])
- {
- hash += Arrays.hashCode((byte[])o);
- }
- else
- {
- hash += o.hashCode();
- }
- }
- return hash;
- }
-
- public boolean equals(Object o)
- {
- if (!(o instanceof PKIXNameConstraintValidator))
- {
- return false;
- }
- PKIXNameConstraintValidator constraintValidator = (PKIXNameConstraintValidator)o;
- return collectionsAreEqual(constraintValidator.excludedSubtreesDN, excludedSubtreesDN)
- && collectionsAreEqual(constraintValidator.excludedSubtreesDNS, excludedSubtreesDNS)
- && collectionsAreEqual(constraintValidator.excludedSubtreesEmail, excludedSubtreesEmail)
- && collectionsAreEqual(constraintValidator.excludedSubtreesIP, excludedSubtreesIP)
- && collectionsAreEqual(constraintValidator.excludedSubtreesURI, excludedSubtreesURI)
- && collectionsAreEqual(constraintValidator.permittedSubtreesDN, permittedSubtreesDN)
- && collectionsAreEqual(constraintValidator.permittedSubtreesDNS, permittedSubtreesDNS)
- && collectionsAreEqual(constraintValidator.permittedSubtreesEmail, permittedSubtreesEmail)
- && collectionsAreEqual(constraintValidator.permittedSubtreesIP, permittedSubtreesIP)
- && collectionsAreEqual(constraintValidator.permittedSubtreesURI, permittedSubtreesURI);
- }
-
- private boolean collectionsAreEqual(Collection coll1, Collection coll2)
- {
- if (coll1 == coll2)
- {
- return true;
- }
- if (coll1 == null || coll2 == null)
- {
- return false;
- }
- if (coll1.size() != coll2.size())
- {
- return false;
- }
- Iterator it1 = coll1.iterator();
-
- while (it1.hasNext())
- {
- Object a = it1.next();
- Iterator it2 = coll2.iterator();
- boolean found = false;
- while (it2.hasNext())
- {
- Object b = it2.next();
- if (equals(a, b))
- {
- found = true;
- break;
- }
- }
- if (!found)
- {
- return false;
- }
- }
- return true;
- }
-
- private boolean equals(Object o1, Object o2)
- {
- if (o1 == o2)
- {
- return true;
- }
- if (o1 == null || o2 == null)
- {
- return false;
- }
- if (o1 instanceof byte[] && o2 instanceof byte[])
- {
- return Arrays.areEqual((byte[])o1, (byte[])o2);
- }
- else
- {
- return o1.equals(o2);
- }
- }
-
- /**
- * Stringifies an IPv4 or v6 address with subnet mask.
- *
- * @param ip The IP with subnet mask.
- * @return The stringified IP address.
- */
- private String stringifyIP(byte[] ip)
- {
- String temp = "";
- for (int i = 0; i < ip.length / 2; i++)
- {
- temp += Integer.toString(ip[i] & 0x00FF) + ".";
- }
- temp = temp.substring(0, temp.length() - 1);
- temp += "/";
- for (int i = ip.length / 2; i < ip.length; i++)
- {
- temp += Integer.toString(ip[i] & 0x00FF) + ".";
- }
- temp = temp.substring(0, temp.length() - 1);
- return temp;
- }
-
- private String stringifyIPCollection(Set ips)
- {
- String temp = "";
- temp += "[";
- for (Iterator it = ips.iterator(); it.hasNext();)
- {
- temp += stringifyIP((byte[])it.next()) + ",";
- }
- if (temp.length() > 1)
- {
- temp = temp.substring(0, temp.length() - 1);
- }
- temp += "]";
- return temp;
+ validator.addExcludedSubtree(subtree);
}
public String toString()
{
- String temp = "";
- temp += "permitted:\n";
- if (permittedSubtreesDN != null)
- {
- temp += "DN:\n";
- temp += permittedSubtreesDN.toString() + "\n";
- }
- if (permittedSubtreesDNS != null)
- {
- temp += "DNS:\n";
- temp += permittedSubtreesDNS.toString() + "\n";
- }
- if (permittedSubtreesEmail != null)
- {
- temp += "Email:\n";
- temp += permittedSubtreesEmail.toString() + "\n";
- }
- if (permittedSubtreesURI != null)
- {
- temp += "URI:\n";
- temp += permittedSubtreesURI.toString() + "\n";
- }
- if (permittedSubtreesIP != null)
- {
- temp += "IP:\n";
- temp += stringifyIPCollection(permittedSubtreesIP) + "\n";
- }
- temp += "excluded:\n";
- if (!excludedSubtreesDN.isEmpty())
- {
- temp += "DN:\n";
- temp += excludedSubtreesDN.toString() + "\n";
- }
- if (!excludedSubtreesDNS.isEmpty())
- {
- temp += "DNS:\n";
- temp += excludedSubtreesDNS.toString() + "\n";
- }
- if (!excludedSubtreesEmail.isEmpty())
- {
- temp += "Email:\n";
- temp += excludedSubtreesEmail.toString() + "\n";
- }
- if (!excludedSubtreesURI.isEmpty())
- {
- temp += "URI:\n";
- temp += excludedSubtreesURI.toString() + "\n";
- }
- if (!excludedSubtreesIP.isEmpty())
- {
- temp += "IP:\n";
- temp += stringifyIPCollection(excludedSubtreesIP) + "\n";
- }
- return temp;
+ return validator.toString();
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java
index b06d5e5b..df1a6c27 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java
@@ -3,8 +3,22 @@ package org.bouncycastle.jce.provider;
public class PKIXNameConstraintValidatorException
extends Exception
{
+ private Throwable cause;
+
public PKIXNameConstraintValidatorException(String msg)
{
super(msg);
}
+
+ public PKIXNameConstraintValidatorException(String msg, Throwable e)
+ {
+ super(msg);
+
+ this.cause = e;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/PrincipalUtils.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/PrincipalUtils.java
index 9059079e..155abaf4 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PrincipalUtils.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PrincipalUtils.java
@@ -2,34 +2,20 @@ package org.bouncycastle.jce.provider;
import java.security.cert.TrustAnchor;
import java.security.cert.X509CRL;
-import java.security.cert.X509CRLEntry;
import java.security.cert.X509Certificate;
import javax.security.auth.x500.X500Principal;
import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x500.X500NameStyle;
+// import org.bouncycastle.jcajce.interfaces.BCX509Certificate;
import org.bouncycastle.x509.X509AttributeCertificate;
class PrincipalUtils
{
- static X500Name getSubjectPrincipal(X509Certificate cert)
- {
- return X500Name.getInstance(cert.getSubjectX500Principal().getEncoded());
- }
-
- static X500Name getIssuerPrincipal(X509CRL crl)
- {
- return X500Name.getInstance(crl.getIssuerX500Principal().getEncoded());
- }
-
- static X500Name getIssuerPrincipal(X509Certificate cert)
- {
- return X500Name.getInstance(cert.getIssuerX500Principal().getEncoded());
- }
-
static X500Name getCA(TrustAnchor trustAnchor)
{
- return X500Name.getInstance(trustAnchor.getCA().getEncoded());
+ return getX500Name(notNull(trustAnchor).getCA());
}
/**
@@ -38,8 +24,7 @@ class PrincipalUtils
* @param cert The attribute certificate or certificate.
* @return The issuer as <code>X500Principal</code>.
*/
- static X500Name getEncodedIssuerPrincipal(
- Object cert)
+ static X500Name getEncodedIssuerPrincipal(Object cert)
{
if (cert instanceof X509Certificate)
{
@@ -47,7 +32,110 @@ class PrincipalUtils
}
else
{
- return X500Name.getInstance(((X500Principal)((X509AttributeCertificate)cert).getIssuer().getPrincipals()[0]).getEncoded());
+ return getX500Name((X500Principal)((X509AttributeCertificate)cert).getIssuer().getPrincipals()[0]);
+ }
+ }
+
+ static X500Name getIssuerPrincipal(X509Certificate certificate)
+ {
+ // BEGIN Android-removed: unsupported
+ /*
+ if (certificate instanceof BCX509Certificate)
+ {
+ return notNull(((BCX509Certificate)certificate).getIssuerX500Name());
+ }
+ */
+ // END Android-removed: unsupported
+ return getX500Name(notNull(certificate).getIssuerX500Principal());
+ }
+
+ static X500Name getIssuerPrincipal(X509CRL crl)
+ {
+ return getX500Name(notNull(crl).getIssuerX500Principal());
+ }
+
+ static X500Name getSubjectPrincipal(X509Certificate certificate)
+ {
+ // BEGIN Android-removed: unsupported
+ /*
+ if (certificate instanceof BCX509Certificate)
+ {
+ return notNull(((BCX509Certificate)certificate).getSubjectX500Name());
+ }
+ */
+ // END Android-removed: unsupported
+ return getX500Name(notNull(certificate).getSubjectX500Principal());
+ }
+
+ static X500Name getX500Name(X500Principal principal)
+ {
+ X500Name name = X500Name.getInstance(getEncoded(principal));
+ return notNull(name);
+ }
+
+ static X500Name getX500Name(X500NameStyle style, X500Principal principal)
+ {
+ X500Name name = X500Name.getInstance(style, getEncoded(principal));
+ return notNull(name);
+ }
+
+ private static byte[] getEncoded(X500Principal principal)
+ {
+ byte[] encoding = notNull(principal).getEncoded();
+ return notNull(encoding);
+ }
+
+ private static byte[] notNull(byte[] encoding)
+ {
+ if (null == encoding)
+ {
+ throw new IllegalStateException();
+ }
+ return encoding;
+ }
+
+ private static TrustAnchor notNull(TrustAnchor trustAnchor)
+ {
+ if (null == trustAnchor)
+ {
+ throw new IllegalStateException();
+ }
+ return trustAnchor;
+ }
+
+ private static X509Certificate notNull(X509Certificate certificate)
+ {
+ if (null == certificate)
+ {
+ throw new IllegalStateException();
+ }
+ return certificate;
+ }
+
+ private static X509CRL notNull(X509CRL crl)
+ {
+ if (null == crl)
+ {
+ throw new IllegalStateException();
+ }
+ return crl;
+ }
+
+ private static X500Name notNull(X500Name name)
+ {
+ if (null == name)
+ {
+ throw new IllegalStateException();
+ }
+ return name;
+ }
+
+ private static X500Principal notNull(X500Principal principal)
+ {
+ if (null == principal)
+ {
+ throw new IllegalStateException();
}
+ return principal;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/ProvCrlRevocationChecker.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/ProvCrlRevocationChecker.java
new file mode 100644
index 00000000..6f62483e
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/ProvCrlRevocationChecker.java
@@ -0,0 +1,67 @@
+package org.bouncycastle.jce.provider;
+
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+import org.bouncycastle.jcajce.PKIXCertRevocationChecker;
+import org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
+import org.bouncycastle.jcajce.util.JcaJceHelper;
+
+class ProvCrlRevocationChecker
+ implements PKIXCertRevocationChecker
+{
+ private final JcaJceHelper helper;
+
+ private PKIXCertRevocationCheckerParameters params;
+ private Date currentDate = null;
+
+ public ProvCrlRevocationChecker(JcaJceHelper helper)
+ {
+ this.helper = helper;
+ }
+
+ public void setParameter(String name, Object value)
+ {
+
+ }
+
+ public void initialize(PKIXCertRevocationCheckerParameters params)
+ {
+ this.params = params;
+ this.currentDate = new Date();
+ }
+
+ public void init(boolean forForward)
+ throws CertPathValidatorException
+ {
+ if (forForward)
+ {
+ throw new CertPathValidatorException("forward checking not supported");
+ }
+
+ this.params = null;
+ this.currentDate = new Date();
+ }
+
+ public void check(Certificate certificate)
+ throws CertPathValidatorException
+ {
+ try
+ {
+ RFC3280CertPathUtilities.checkCRLs(params, params.getParamsPKIX(), currentDate, params.getValidDate(),
+ (X509Certificate)certificate, params.getSigningCert(), params.getWorkingPublicKey(),
+ params.getCertPath().getCertificates(), helper);
+ }
+ catch (AnnotatedException e)
+ {
+ Throwable cause = e;
+ if (null != e.getCause())
+ {
+ cause = e.getCause();
+ }
+ throw new CertPathValidatorException(e.getMessage(), cause, params.getCertPath(), params.getIndex());
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
index 1ed22d59..f3c8d16c 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
@@ -6,23 +6,23 @@ import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.security.cert.CertPath;
import java.security.cert.CertPathBuilderException;
+import java.security.cert.CertPathBuilderSpi;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.PKIXCertPathChecker;
import java.security.cert.X509CRL;
-import java.security.cert.X509CRLSelector;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.security.cert.X509Extension;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -30,7 +30,6 @@ import java.util.TimeZone;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
-import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
@@ -54,17 +53,19 @@ import org.bouncycastle.asn1.x509.IssuingDistributionPoint;
import org.bouncycastle.asn1.x509.NameConstraints;
import org.bouncycastle.asn1.x509.PolicyInformation;
import org.bouncycastle.jcajce.PKIXCRLStore;
-import org.bouncycastle.jcajce.PKIXCRLStoreSelector;
+import org.bouncycastle.jcajce.PKIXCertRevocationChecker;
+import org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
import org.bouncycastle.jcajce.PKIXCertStoreSelector;
import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
import org.bouncycastle.jcajce.PKIXExtendedParameters;
+import org.bouncycastle.jcajce.provider.symmetric.util.ClassUtil;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.jce.exception.ExtCertPathValidatorException;
import org.bouncycastle.util.Arrays;
class RFC3280CertPathUtilities
{
- private static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil();
+ private static final Class revChkClass = ClassUtil.loadClass(RFC3280CertPathUtilities.class, "java.security.cert.PKIXRevocationChecker");
/**
* If the complete CRL includes an issuing distribution point (IDP) CRL
@@ -171,8 +172,7 @@ class RFC3280CertPathUtilities
genNames = new GeneralName[1];
try
{
- genNames[0] = new GeneralName(X500Name.getInstance(PrincipalUtils
- .getEncodedIssuerPrincipal(cert).getEncoded()));
+ genNames[0] = new GeneralName(PrincipalUtils.getEncodedIssuerPrincipal(cert));
}
catch (Exception e)
{
@@ -470,11 +470,11 @@ class RFC3280CertPathUtilities
PKIXCertStoreSelector selector = new PKIXCertStoreSelector.Builder(certSelector).build();
// get CRL signing certs
- Collection coll;
+ LinkedHashSet coll = new LinkedHashSet();
try
{
- coll = CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getCertificateStores());
- coll.addAll(CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getCertStores()));
+ CertPathValidatorUtilities.findCertificates(coll, selector, paramsPKIX.getCertificateStores());
+ CertPathValidatorUtilities.findCertificates(coll, selector, paramsPKIX.getCertStores());
}
catch (AnnotatedException e)
{
@@ -504,7 +504,11 @@ class RFC3280CertPathUtilities
}
try
{
- PKIXCertPathBuilderSpi builder = new PKIXCertPathBuilderSpi();
+ // BEGIN Android-changed:
+ // CertPathBuilderSpi builder = (revChkClass != null)
+ // ? new PKIXCertPathBuilderSpi_8(true) : new PKIXCertPathBuilderSpi(true);
+ // END Android-changed:
+ CertPathBuilderSpi builder = new PKIXCertPathBuilderSpi(true);
X509CertSelector tmpCertSelector = new X509CertSelector();
tmpCertSelector.setCertificate(signingCert);
@@ -555,9 +559,9 @@ class RFC3280CertPathUtilities
for (int i = 0; i < validCerts.size(); i++)
{
X509Certificate signCert = (X509Certificate)validCerts.get(i);
- boolean[] keyusage = signCert.getKeyUsage();
+ boolean[] keyUsage = signCert.getKeyUsage();
- if (keyusage != null && (keyusage.length < 7 || !keyusage[CRL_SIGN]))
+ if (keyUsage != null && (keyUsage.length <= CRL_SIGN || !keyUsage[CRL_SIGN]))
{
lastException = new AnnotatedException(
"Issuer certificate key usage extension does not permit CRL signing.");
@@ -630,119 +634,6 @@ class RFC3280CertPathUtilities
return null;
}
- protected static Set processCRLA1i(
- Date currentDate,
- PKIXExtendedParameters paramsPKIX,
- X509Certificate cert,
- X509CRL crl)
- throws AnnotatedException
- {
- Set set = new HashSet();
- if (paramsPKIX.isUseDeltasEnabled())
- {
- CRLDistPoint freshestCRL = null;
- try
- {
- freshestCRL = CRLDistPoint
- .getInstance(CertPathValidatorUtilities.getExtensionValue(cert, FRESHEST_CRL));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Freshest CRL extension could not be decoded from certificate.", e);
- }
- if (freshestCRL == null)
- {
- try
- {
- freshestCRL = CRLDistPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl,
- FRESHEST_CRL));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Freshest CRL extension could not be decoded from CRL.", e);
- }
- }
- if (freshestCRL != null)
- {
- List crlStores = new ArrayList();
-
- crlStores.addAll(paramsPKIX.getCRLStores());
-
- try
- {
- crlStores.addAll(CertPathValidatorUtilities.getAdditionalStoresFromCRLDistributionPoint(freshestCRL, paramsPKIX.getNamedCRLStoreMap()));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException(
- "No new delta CRL locations could be added from Freshest CRL extension.", e);
- }
-
- // get delta CRL(s)
- try
- {
- set.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, crl, paramsPKIX.getCertStores(), crlStores));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Exception obtaining delta CRLs.", e);
- }
- }
- }
- return set;
- }
-
- protected static Set[] processCRLA1ii(
- Date currentDate,
- PKIXExtendedParameters paramsPKIX,
- X509Certificate cert,
- X509CRL crl)
- throws AnnotatedException
- {
- Set deltaSet = new HashSet();
- X509CRLSelector crlselect = new X509CRLSelector();
- crlselect.setCertificateChecking(cert);
-
- try
- {
- crlselect.addIssuerName(PrincipalUtils.getIssuerPrincipal(crl).getEncoded());
- }
- catch (IOException e)
- {
- throw new AnnotatedException("Cannot extract issuer from CRL." + e, e);
- }
-
- PKIXCRLStoreSelector extSelect = new PKIXCRLStoreSelector.Builder(crlselect).setCompleteCRLEnabled(true).build();
-
- Date validityDate = currentDate;
-
- if (paramsPKIX.getDate() != null)
- {
- validityDate = paramsPKIX.getDate();
- }
-
- Set completeSet = CRL_UTIL.findCRLs(extSelect, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores());
-
- if (paramsPKIX.isUseDeltasEnabled())
- {
- // get delta CRL(s)
- try
- {
- deltaSet.addAll(CertPathValidatorUtilities.getDeltaCRLs(validityDate, crl, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores()));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Exception obtaining delta CRLs.", e);
- }
- }
- return new Set[]
- {
- completeSet,
- deltaSet};
- }
-
-
-
/**
* If use-deltas is set, verify the issuer and scope of the delta CRL.
*
@@ -761,6 +652,12 @@ class RFC3280CertPathUtilities
{
return;
}
+
+ if (deltaCRL.hasUnsupportedCriticalExtension())
+ {
+ throw new AnnotatedException("delta CRL has unsupported critical extensions");
+ }
+
IssuingDistributionPoint completeidp = null;
try
{
@@ -902,7 +799,7 @@ class RFC3280CertPathUtilities
ASN1Sequence pm = null;
try
{
- pm = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ pm = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.POLICY_MAPPINGS));
}
catch (AnnotatedException ex)
@@ -1085,7 +982,7 @@ class RFC3280CertPathUtilities
ASN1Sequence pm = null;
try
{
- pm = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ pm = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.POLICY_MAPPINGS));
}
catch (AnnotatedException ex)
@@ -1103,7 +1000,7 @@ class RFC3280CertPathUtilities
ASN1ObjectIdentifier subjectDomainPolicy = null;
try
{
- ASN1Sequence mapping = DERSequence.getInstance(mappings.getObjectAt(j));
+ ASN1Sequence mapping = ASN1Sequence.getInstance(mappings.getObjectAt(j));
issuerDomainPolicy = ASN1ObjectIdentifier.getInstance(mapping.getObjectAt(0));
subjectDomainPolicy = ASN1ObjectIdentifier.getInstance(mapping.getObjectAt(1));
@@ -1123,7 +1020,7 @@ class RFC3280CertPathUtilities
if (RFC3280CertPathUtilities.ANY_POLICY.equals(subjectDomainPolicy.getId()))
{
- throw new CertPathValidatorException("SubjectDomainPolicy is anyPolicy,", null, certPath, index);
+ throw new CertPathValidatorException("SubjectDomainPolicy is anyPolicy", null, certPath, index);
}
}
}
@@ -1160,7 +1057,7 @@ class RFC3280CertPathUtilities
ASN1Sequence certPolicies = null;
try
{
- certPolicies = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ certPolicies = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.CERTIFICATE_POLICIES));
}
catch (AnnotatedException e)
@@ -1178,7 +1075,8 @@ class RFC3280CertPathUtilities
protected static void processCertBC(
CertPath certPath,
int index,
- PKIXNameConstraintValidator nameConstraintValidator)
+ PKIXNameConstraintValidator nameConstraintValidator,
+ boolean isForCRLCheck)
throws CertPathValidatorException
{
List certs = certPath.getCertificates();
@@ -1189,14 +1087,19 @@ class RFC3280CertPathUtilities
//
// (b), (c) permitted and excluded subtree checking.
//
- if (!(CertPathValidatorUtilities.isSelfIssued(cert) && (i < n)))
+ // 4.2.1.10 Name constraints are not applied to self-issued certificates (unless
+ // the certificate is the final certificate in the path)
+ // as we use the validator for path CRL checking, we need to flag when the
+ // certificate is self issued, but not really the last one in the path we are actually
+ // checking.
+ if (!(CertPathValidatorUtilities.isSelfIssued(cert) && ((i < n) || isForCRLCheck)))
{
X500Name principal = PrincipalUtils.getSubjectPrincipal(cert);
ASN1Sequence dns;
try
{
- dns = DERSequence.getInstance(principal.getEncoded());
+ dns = ASN1Sequence.getInstance(principal);
}
catch (Exception e)
{
@@ -1279,7 +1182,8 @@ class RFC3280CertPathUtilities
Set acceptablePolicies,
PKIXPolicyNode validPolicyTree,
List[] policyNodes,
- int inhibitAnyPolicy)
+ int inhibitAnyPolicy,
+ boolean isForCRLCheck)
throws CertPathValidatorException
{
List certs = certPath.getCertificates();
@@ -1294,7 +1198,7 @@ class RFC3280CertPathUtilities
ASN1Sequence certPolicies = null;
try
{
- certPolicies = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ certPolicies = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.CERTIFICATE_POLICIES));
}
catch (AnnotatedException e)
@@ -1365,7 +1269,7 @@ class RFC3280CertPathUtilities
//
// (d) (2)
//
- if ((inhibitAnyPolicy > 0) || ((i < n) && CertPathValidatorUtilities.isSelfIssued(cert)))
+ if ((inhibitAnyPolicy > 0) || ((i < n || isForCRLCheck) && CertPathValidatorUtilities.isSelfIssued(cert)))
{
e = certPolicies.getObjects();
@@ -1478,13 +1382,14 @@ class RFC3280CertPathUtilities
protected static void processCertA(
CertPath certPath,
PKIXExtendedParameters paramsPKIX,
+ Date validityDate,
+ PKIXCertRevocationChecker revocationChecker,
int index,
PublicKey workingPublicKey,
boolean verificationAlreadyPerformed,
X500Name workingIssuerName,
- X509Certificate sign,
- JcaJceHelper helper)
- throws ExtCertPathValidatorException
+ X509Certificate sign)
+ throws CertPathValidatorException
{
List certs = certPath.getCertificates();
X509Certificate cert = (X509Certificate)certs.get(index);
@@ -1506,12 +1411,22 @@ class RFC3280CertPathUtilities
}
}
+ final Date validCertDate;
try
{
- // (a) (2)
- //
- cert.checkValidity(CertPathValidatorUtilities
- .getValidCertDateFromValidityModel(paramsPKIX, certPath, index));
+ validCertDate = CertPathValidatorUtilities.getValidCertDateFromValidityModel(validityDate,
+ paramsPKIX.getValidityModel(), certPath, index);
+ }
+ catch (AnnotatedException e)
+ {
+ throw new ExtCertPathValidatorException("Could not validate time of certificate.", e, certPath, index);
+ }
+
+ // (a) (2)
+ //
+ try
+ {
+ cert.checkValidity(validCertDate);
}
catch (CertificateExpiredException e)
{
@@ -1521,40 +1436,26 @@ class RFC3280CertPathUtilities
{
throw new ExtCertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index);
}
- catch (AnnotatedException e)
- {
- throw new ExtCertPathValidatorException("Could not validate time of certificate.", e, certPath, index);
- }
//
// (a) (3)
//
- if (paramsPKIX.isRevocationEnabled())
+ if (revocationChecker != null)
{
- try
- {
- checkCRLs(paramsPKIX, cert, CertPathValidatorUtilities.getValidCertDateFromValidityModel(paramsPKIX,
- certPath, index), sign, workingPublicKey, certs, helper);
- }
- catch (AnnotatedException e)
- {
- Throwable cause = e;
- if (null != e.getCause())
- {
- cause = e.getCause();
- }
- throw new ExtCertPathValidatorException(e.getMessage(), cause, certPath, index);
- }
+ revocationChecker.initialize(new PKIXCertRevocationCheckerParameters(paramsPKIX, validCertDate, certPath,
+ index, sign, workingPublicKey));
+
+ revocationChecker.check(cert);
}
//
// (a) (4) name chaining
//
- if (!PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(workingIssuerName))
+ X500Name issuer = PrincipalUtils.getIssuerPrincipal(cert);
+ if (!issuer.equals(workingIssuerName))
{
- throw new ExtCertPathValidatorException("IssuerName(" + PrincipalUtils.getEncodedIssuerPrincipal(cert)
- + ") does not match SubjectName(" + workingIssuerName + ") of signing certificate.", null,
- certPath, index);
+ throw new ExtCertPathValidatorException("IssuerName(" + issuer + ") does not match SubjectName("
+ + workingIssuerName + ") of signing certificate.", null, certPath, index);
}
}
@@ -1572,7 +1473,7 @@ class RFC3280CertPathUtilities
ASN1Sequence pc = null;
try
{
- pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ pc = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
}
catch (Exception e)
@@ -1591,11 +1492,10 @@ class RFC3280CertPathUtilities
{
try
{
-
ASN1TaggedObject constraint = ASN1TaggedObject.getInstance(policyConstraints.nextElement());
if (constraint.getTagNo() == 0)
{
- tmpInt = ASN1Integer.getInstance(constraint, false).getValue().intValue();
+ tmpInt = ASN1Integer.getInstance(constraint, false).intValueExact();
if (tmpInt < explicitPolicy)
{
return tmpInt;
@@ -1627,7 +1527,7 @@ class RFC3280CertPathUtilities
ASN1Sequence pc = null;
try
{
- pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ pc = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
}
catch (Exception e)
@@ -1649,7 +1549,7 @@ class RFC3280CertPathUtilities
ASN1TaggedObject constraint = ASN1TaggedObject.getInstance(policyConstraints.nextElement());
if (constraint.getTagNo() == 1)
{
- tmpInt = ASN1Integer.getInstance(constraint, false).getValue().intValue();
+ tmpInt = ASN1Integer.getInstance(constraint, false).intValueExact();
if (tmpInt < policyMapping)
{
return tmpInt;
@@ -1681,7 +1581,7 @@ class RFC3280CertPathUtilities
NameConstraints nc = null;
try
{
- ASN1Sequence ncSeq = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ ASN1Sequence ncSeq = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.NAME_CONSTRAINTS));
if (ncSeq != null)
{
@@ -1734,38 +1634,52 @@ class RFC3280CertPathUtilities
}
/**
- * Checks a distribution point for revocation information for the
- * certificate <code>cert</code>.
+ * Checks a distribution point for revocation information for the certificate <code>cert</code>.
*
- * @param dp The distribution point to consider.
- * @param paramsPKIX PKIX parameters.
- * @param cert Certificate to check if it is revoked.
- * @param validDate The date when the certificate revocation status should be
- * checked.
- * @param defaultCRLSignCert The issuer certificate of the certificate <code>cert</code>.
- * @param defaultCRLSignKey The public key of the issuer certificate
- * <code>defaultCRLSignCert</code>.
- * @param certStatus The current certificate revocation status.
- * @param reasonMask The reasons mask which is already checked.
- * @param certPathCerts The certificates of the certification path.
- * @throws AnnotatedException if the certificate is revoked or the status cannot be checked
- * or some error occurs.
+ * @param dp
+ * The distribution point to consider.
+ * @param paramsPKIX
+ * PKIX parameters.
+ * @param currentDate
+ * The date at which this check is being run.
+ * @param validityDate
+ * The date when the certificate revocation status should be checked.
+ * @param cert
+ * Certificate to check if it is revoked.
+ * @param defaultCRLSignCert
+ * The issuer certificate of the certificate <code>cert</code>.
+ * @param defaultCRLSignKey
+ * The public key of the issuer certificate <code>defaultCRLSignCert</code>.
+ * @param certStatus
+ * The current certificate revocation status.
+ * @param reasonMask
+ * The reasons mask which is already checked.
+ * @param certPathCerts
+ * The certificates of the certification path.
+ * @throws AnnotatedException
+ * if the certificate is revoked or the status cannot be checked or some error
+ * occurs.
*/
private static void checkCRL(
+ PKIXCertRevocationCheckerParameters params,
DistributionPoint dp,
PKIXExtendedParameters paramsPKIX,
+ Date currentDate,
+ Date validityDate,
X509Certificate cert,
- Date validDate,
X509Certificate defaultCRLSignCert,
PublicKey defaultCRLSignKey,
CertStatus certStatus,
ReasonsMask reasonMask,
List certPathCerts,
JcaJceHelper helper)
- throws AnnotatedException
+ throws AnnotatedException, RecoverableCertPathValidatorException
{
- Date currentDate = new Date(System.currentTimeMillis());
- if (validDate.getTime() > currentDate.getTime())
+ if (currentDate == null)
+ {
+ boolean debug = true;
+ }
+ if (validityDate.getTime() > currentDate.getTime())
{
throw new AnnotatedException("Validation time is in future.");
}
@@ -1778,7 +1692,7 @@ class RFC3280CertPathUtilities
* getAdditionalStore()
*/
- Set crls = CertPathValidatorUtilities.getCompleteCRLs(dp, cert, currentDate, paramsPKIX);
+ Set crls = CertPathValidatorUtilities.getCompleteCRLs(params, dp, cert, paramsPKIX, validityDate);
boolean validCrlFound = false;
AnnotatedException lastException = null;
Iterator crl_iter = crls.iterator();
@@ -1811,17 +1725,10 @@ class RFC3280CertPathUtilities
X509CRL deltaCRL = null;
- Date validityDate = currentDate;
-
- if (paramsPKIX.getDate() != null)
- {
- validityDate = paramsPKIX.getDate();
- }
-
if (paramsPKIX.isUseDeltasEnabled())
{
// get delta CRLs
- Set deltaCRLs = CertPathValidatorUtilities.getDeltaCRLs(validityDate, crl, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores());
+ Set deltaCRLs = CertPathValidatorUtilities.getDeltaCRLs(validityDate, crl, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores(), helper);
// we only want one valid delta CRL
// (h)
deltaCRL = RFC3280CertPathUtilities.processCRLH(deltaCRLs, key);
@@ -1852,7 +1759,7 @@ class RFC3280CertPathUtilities
throw new AnnotatedException("No valid CRL for current time found.");
}
}
-
+
RFC3280CertPathUtilities.processCRLB1(dp, cert, crl);
// (b) (2)
@@ -1862,10 +1769,10 @@ class RFC3280CertPathUtilities
RFC3280CertPathUtilities.processCRLC(deltaCRL, crl, paramsPKIX);
// (i)
- RFC3280CertPathUtilities.processCRLI(validDate, deltaCRL, cert, certStatus, paramsPKIX);
+ RFC3280CertPathUtilities.processCRLI(validityDate, deltaCRL, cert, certStatus, paramsPKIX);
// (j)
- RFC3280CertPathUtilities.processCRLJ(validDate, crl, cert, certStatus);
+ RFC3280CertPathUtilities.processCRLJ(validityDate, crl, cert, certStatus);
// (k)
if (certStatus.getCertStatus() == CRLReason.removeFromCRL)
@@ -1920,25 +1827,35 @@ class RFC3280CertPathUtilities
/**
* Checks a certificate if it is revoked.
*
- * @param paramsPKIX PKIX parameters.
- * @param cert Certificate to check if it is revoked.
- * @param validDate The date when the certificate revocation status should be
- * checked.
- * @param sign The issuer certificate of the certificate <code>cert</code>.
- * @param workingPublicKey The public key of the issuer certificate <code>sign</code>.
- * @param certPathCerts The certificates of the certification path.
- * @throws AnnotatedException if the certificate is revoked or the status cannot be checked
- * or some error occurs.
+ * @param paramsPKIX
+ * PKIX parameters.
+ * @param currentDate
+ * The date at which this check is being run.
+ * @param validityDate
+ * The date when the certificate revocation status should be checked.
+ * @param cert
+ * Certificate to check if it is revoked.
+ * @param sign
+ * The issuer certificate of the certificate <code>cert</code>.
+ * @param workingPublicKey
+ * The public key of the issuer certificate <code>sign</code>.
+ * @param certPathCerts
+ * The certificates of the certification path.
+ * @throws AnnotatedException
+ * if the certificate is revoked or the status cannot be checked or some error
+ * occurs.
*/
protected static void checkCRLs(
+ PKIXCertRevocationCheckerParameters params,
PKIXExtendedParameters paramsPKIX,
+ Date currentDate,
+ Date validityDate,
X509Certificate cert,
- Date validDate,
X509Certificate sign,
PublicKey workingPublicKey,
List certPathCerts,
JcaJceHelper helper)
- throws AnnotatedException
+ throws AnnotatedException, RecoverableCertPathValidatorException
{
AnnotatedException lastException = null;
CRLDistPoint crldp = null;
@@ -1955,7 +1872,8 @@ class RFC3280CertPathUtilities
PKIXExtendedParameters.Builder paramsBldr = new PKIXExtendedParameters.Builder(paramsPKIX);
try
{
- List extras = CertPathValidatorUtilities.getAdditionalStoresFromCRLDistributionPoint(crldp, paramsPKIX.getNamedCRLStoreMap());
+ List extras = CertPathValidatorUtilities.getAdditionalStoresFromCRLDistributionPoint(crldp,
+ paramsPKIX.getNamedCRLStoreMap(), validityDate, helper);
for (Iterator it = extras.iterator(); it.hasNext();)
{
paramsBldr.addCRLStore((PKIXCRLStore)it.next());
@@ -1989,7 +1907,8 @@ class RFC3280CertPathUtilities
{
try
{
- checkCRL(dps[i], finalParams, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts, helper);
+ checkCRL(params, dps[i], finalParams, currentDate, validityDate, cert, sign, workingPublicKey,
+ certStatus, reasonsMask, certPathCerts, helper);
validCrlFound = true;
}
catch (AnnotatedException e)
@@ -2015,21 +1934,20 @@ class RFC3280CertPathUtilities
* omitted and a distribution point name of the certificate
* issuer.
*/
- ASN1Primitive issuer = null;
+ X500Name issuer;
try
{
- issuer = new ASN1InputStream(PrincipalUtils.getEncodedIssuerPrincipal(cert).getEncoded())
- .readObject();
+ issuer = PrincipalUtils.getIssuerPrincipal(cert);
}
- catch (Exception e)
+ catch (RuntimeException e)
{
throw new AnnotatedException("Issuer from certificate for CRL could not be reencoded.", e);
}
DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames(
new GeneralName(GeneralName.directoryName, issuer))), null, null);
PKIXExtendedParameters paramsPKIXClone = (PKIXExtendedParameters)paramsPKIX.clone();
- checkCRL(dp, paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask,
- certPathCerts, helper);
+ checkCRL(params, dp, paramsPKIXClone, currentDate, validityDate, cert, sign, workingPublicKey,
+ certStatus, reasonsMask, certPathCerts, helper);
validCrlFound = true;
}
catch (AnnotatedException e)
@@ -2090,7 +2008,7 @@ class RFC3280CertPathUtilities
if (iap != null)
{
- int _inhibitAnyPolicy = iap.getValue().intValue();
+ int _inhibitAnyPolicy = iap.intValueExact();
if (_inhibitAnyPolicy < inhibitAnyPolicy)
{
@@ -2125,12 +2043,12 @@ class RFC3280CertPathUtilities
{
if (!(bc.isCA()))
{
- throw new CertPathValidatorException("Not a CA certificate");
+ throw new CertPathValidatorException("Not a CA certificate", null, certPath, index);
}
}
else
{
- throw new CertPathValidatorException("Intermediate certificate lacks BasicConstraints");
+ throw new CertPathValidatorException("Intermediate certificate lacks BasicConstraints", null, certPath, index);
}
}
@@ -2208,9 +2126,9 @@ class RFC3280CertPathUtilities
//
// (n)
//
- boolean[] _usage = cert.getKeyUsage();
+ boolean[] keyUsage = cert.getKeyUsage();
- if ((_usage != null) && !_usage[RFC3280CertPathUtilities.KEY_CERT_SIGN])
+ if (keyUsage != null && (keyUsage.length <= KEY_CERT_SIGN || !keyUsage[KEY_CERT_SIGN]))
{
throw new ExtCertPathValidatorException(
"Issuer certificate keyusage extension is critical and does not permit key signing.", null,
@@ -2363,7 +2281,7 @@ class RFC3280CertPathUtilities
ASN1Sequence pc = null;
try
{
- pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ pc = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
}
catch (AnnotatedException e)
@@ -2382,7 +2300,7 @@ class RFC3280CertPathUtilities
case 0:
try
{
- tmpInt = ASN1Integer.getInstance(constraint, false).getValue().intValue();
+ tmpInt = ASN1Integer.getInstance(constraint, false).intValueExact();
}
catch (Exception e)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/RecoverableCertPathValidatorException.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/RecoverableCertPathValidatorException.java
new file mode 100644
index 00000000..90a2478b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/RecoverableCertPathValidatorException.java
@@ -0,0 +1,13 @@
+package org.bouncycastle.jce.provider;
+
+import java.security.cert.CertPath;
+import java.security.cert.CertPathValidatorException;
+
+class RecoverableCertPathValidatorException
+ extends CertPathValidatorException
+{
+ public RecoverableCertPathValidatorException(String msg, Throwable cause, CertPath certPath, int index)
+ {
+ super(msg, cause, certPath, index);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/WrappedRevocationChecker.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/WrappedRevocationChecker.java
new file mode 100644
index 00000000..c27768bf
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/WrappedRevocationChecker.java
@@ -0,0 +1,36 @@
+package org.bouncycastle.jce.provider;
+
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.Certificate;
+import java.security.cert.PKIXCertPathChecker;
+
+import org.bouncycastle.jcajce.PKIXCertRevocationChecker;
+import org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
+
+class WrappedRevocationChecker
+ implements PKIXCertRevocationChecker
+{
+ private final PKIXCertPathChecker checker;
+
+ public WrappedRevocationChecker(PKIXCertPathChecker checker)
+ {
+ this.checker = checker;
+ }
+
+ public void setParameter(String name, Object value)
+ {
+ // ignore.
+ }
+
+ public void initialize(PKIXCertRevocationCheckerParameters params)
+ throws CertPathValidatorException
+ {
+ checker.init(false);
+ }
+
+ public void check(Certificate cert)
+ throws CertPathValidatorException
+ {
+ checker.check(cert);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java
index b8308207..5b32a132 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java
@@ -346,7 +346,7 @@ public class X509CRLObject
{
TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement();
- if (serialNumber.equals(entry.getUserCertificate().getValue()))
+ if (entry.getUserCertificate().hasValue(serialNumber))
{
return new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer);
}
@@ -583,7 +583,7 @@ public class X509CRLObject
}
}
- if (entry.getUserCertificate().getValue().equals(serial))
+ if (entry.getUserCertificate().hasValue(serial))
{
X500Name issuer;
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java
index a35fa650..4bbd5126 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java
@@ -1,6 +1,5 @@
package org.bouncycastle.jce.provider;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.net.InetAddress;
@@ -37,7 +36,6 @@ import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.ASN1OutputStream;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1String;
@@ -165,26 +163,14 @@ public class X509CertificateObject
public Principal getIssuerDN()
{
- try
- {
- return new X509Principal(X500Name.getInstance(c.getIssuer().getEncoded()));
- }
- catch (IOException e)
- {
- return null;
- }
+ return new X509Principal(c.getIssuer());
}
public X500Principal getIssuerX500Principal()
{
try
{
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
- aOut.writeObject(c.getIssuer());
-
- return new X500Principal(bOut.toByteArray());
+ return new X500Principal(c.getIssuer().getEncoded());
}
catch (IOException e)
{
@@ -194,19 +180,14 @@ public class X509CertificateObject
public Principal getSubjectDN()
{
- return new X509Principal(X500Name.getInstance(c.getSubject().toASN1Primitive()));
+ return new X509Principal(c.getSubject());
}
public X500Principal getSubjectX500Principal()
{
try
{
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
- aOut.writeObject(c.getSubject());
-
- return new X500Principal(bOut.toByteArray());
+ return new X500Principal(c.getSubject().getEncoded());
}
catch (IOException e)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/AbstractECLookupTable.java b/bcprov/src/main/java/org/bouncycastle/math/ec/AbstractECLookupTable.java
new file mode 100644
index 00000000..44225eca
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/AbstractECLookupTable.java
@@ -0,0 +1,10 @@
+package org.bouncycastle.math.ec;
+
+public abstract class AbstractECLookupTable
+ implements ECLookupTable
+{
+ public ECPoint lookupVar(int index)
+ {
+ return lookup(index);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java
index f0b1585d..0aab9eb4 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java
@@ -3,9 +3,11 @@ package org.bouncycastle.math.ec;
import java.math.BigInteger;
import org.bouncycastle.math.ec.endo.ECEndomorphism;
+import org.bouncycastle.math.ec.endo.EndoUtil;
import org.bouncycastle.math.ec.endo.GLVEndomorphism;
import org.bouncycastle.math.field.FiniteField;
import org.bouncycastle.math.field.PolynomialExtensionField;
+import org.bouncycastle.math.raw.Nat;
public class ECAlgorithms
{
@@ -175,8 +177,9 @@ public class ECAlgorithms
}
/**
- * Simple shift-and-add multiplication. Serves as reference implementation
- * to verify (possibly faster) implementations, and for very small scalars.
+ * Simple shift-and-add multiplication. Serves as reference implementation to verify (possibly
+ * faster) implementations, and for very small scalars. CAUTION: This implementation is NOT
+ * constant-time in any way. It is only intended to be used for diagnostics.
*
* @param p
* The point to multiply.
@@ -280,46 +283,63 @@ public class ECAlgorithms
{
boolean negK = k.signum() < 0, negL = l.signum() < 0;
- k = k.abs();
- l = l.abs();
+ BigInteger kAbs = k.abs(), lAbs = l.abs();
+
+ int minWidthP = WNafUtil.getWindowSize(kAbs.bitLength(), 8);
+ int minWidthQ = WNafUtil.getWindowSize(lAbs.bitLength(), 8);
- int widthP = Math.max(2, Math.min(16, WNafUtil.getWindowSize(k.bitLength())));
- int widthQ = Math.max(2, Math.min(16, WNafUtil.getWindowSize(l.bitLength())));
+ WNafPreCompInfo infoP = WNafUtil.precompute(P, minWidthP, true);
+ WNafPreCompInfo infoQ = WNafUtil.precompute(Q, minWidthQ, true);
+
+ // When P, Q are 'promoted' (i.e. reused several times), switch to fixed-point algorithm
+ {
+ ECCurve c = P.getCurve();
+ int combSize = FixedPointUtil.getCombSize(c);
+ if (!negK && !negL
+ && k.bitLength() <= combSize && l.bitLength() <= combSize
+ && infoP.isPromoted() && infoQ.isPromoted())
+ {
+ return implShamirsTrickFixedPoint(P, k, Q, l);
+ }
+ }
- WNafPreCompInfo infoP = WNafUtil.precompute(P, widthP, true);
- WNafPreCompInfo infoQ = WNafUtil.precompute(Q, widthQ, true);
+ int widthP = Math.min(8, infoP.getWidth());
+ int widthQ = Math.min(8, infoQ.getWidth());
ECPoint[] preCompP = negK ? infoP.getPreCompNeg() : infoP.getPreComp();
ECPoint[] preCompQ = negL ? infoQ.getPreCompNeg() : infoQ.getPreComp();
ECPoint[] preCompNegP = negK ? infoP.getPreComp() : infoP.getPreCompNeg();
ECPoint[] preCompNegQ = negL ? infoQ.getPreComp() : infoQ.getPreCompNeg();
- byte[] wnafP = WNafUtil.generateWindowNaf(widthP, k);
- byte[] wnafQ = WNafUtil.generateWindowNaf(widthQ, l);
+ byte[] wnafP = WNafUtil.generateWindowNaf(widthP, kAbs);
+ byte[] wnafQ = WNafUtil.generateWindowNaf(widthQ, lAbs);
return implShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ);
}
- static ECPoint implShamirsTrickWNaf(ECPoint P, BigInteger k, ECPointMap pointMapQ, BigInteger l)
+ static ECPoint implShamirsTrickWNaf(ECEndomorphism endomorphism, ECPoint P, BigInteger k, BigInteger l)
{
boolean negK = k.signum() < 0, negL = l.signum() < 0;
k = k.abs();
l = l.abs();
- int width = Math.max(2, Math.min(16, WNafUtil.getWindowSize(Math.max(k.bitLength(), l.bitLength()))));
+ int minWidth = WNafUtil.getWindowSize(Math.max(k.bitLength(), l.bitLength()), 8);
+
+ WNafPreCompInfo infoP = WNafUtil.precompute(P, minWidth, true);
+ ECPoint Q = EndoUtil.mapPoint(endomorphism, P);
+ WNafPreCompInfo infoQ = WNafUtil.precomputeWithPointMap(Q, endomorphism.getPointMap(), infoP, true);
- ECPoint Q = WNafUtil.mapPointWithPrecomp(P, width, true, pointMapQ);
- WNafPreCompInfo infoP = WNafUtil.getWNafPreCompInfo(P);
- WNafPreCompInfo infoQ = WNafUtil.getWNafPreCompInfo(Q);
+ int widthP = Math.min(8, infoP.getWidth());
+ int widthQ = Math.min(8, infoQ.getWidth());
ECPoint[] preCompP = negK ? infoP.getPreCompNeg() : infoP.getPreComp();
ECPoint[] preCompQ = negL ? infoQ.getPreCompNeg() : infoQ.getPreComp();
ECPoint[] preCompNegP = negK ? infoP.getPreComp() : infoP.getPreCompNeg();
ECPoint[] preCompNegQ = negL ? infoQ.getPreComp() : infoQ.getPreCompNeg();
- byte[] wnafP = WNafUtil.generateWindowNaf(width, k);
- byte[] wnafQ = WNafUtil.generateWindowNaf(width, l);
+ byte[] wnafP = WNafUtil.generateWindowNaf(widthP, k);
+ byte[] wnafQ = WNafUtil.generateWindowNaf(widthQ, l);
return implShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ);
}
@@ -388,8 +408,12 @@ public class ECAlgorithms
{
BigInteger ki = ks[i]; negs[i] = ki.signum() < 0; ki = ki.abs();
- int width = Math.max(2, Math.min(16, WNafUtil.getWindowSize(ki.bitLength())));
- infos[i] = WNafUtil.precompute(ps[i], width, true);
+ int minWidth = WNafUtil.getWindowSize(ki.bitLength(), 8);
+ WNafPreCompInfo info = WNafUtil.precompute(ps[i], minWidth, true);
+
+ int width = Math.min(8, info.getWidth());
+
+ infos[i] = info;
wnafs[i] = WNafUtil.generateWindowNaf(width, ki);
}
@@ -410,25 +434,24 @@ public class ECAlgorithms
abs[j++] = ab[1];
}
- ECPointMap pointMap = glvEndomorphism.getPointMap();
if (glvEndomorphism.hasEfficientPointMap())
{
- return ECAlgorithms.implSumOfMultiplies(ps, pointMap, abs);
+ return implSumOfMultiplies(glvEndomorphism, ps, abs);
}
ECPoint[] pqs = new ECPoint[len << 1];
for (int i = 0, j = 0; i < len; ++i)
{
- ECPoint p = ps[i], q = pointMap.map(p);
+ ECPoint p = ps[i];
+ ECPoint q = EndoUtil.mapPoint(glvEndomorphism, p);
pqs[j++] = p;
pqs[j++] = q;
}
-
- return ECAlgorithms.implSumOfMultiplies(pqs, abs);
+ return implSumOfMultiplies(pqs, abs);
}
- static ECPoint implSumOfMultiplies(ECPoint[] ps, ECPointMap pointMap, BigInteger[] ks)
+ static ECPoint implSumOfMultiplies(ECEndomorphism endomorphism, ECPoint[] ps, BigInteger[] ks)
{
int halfCount = ps.length, fullCount = halfCount << 1;
@@ -436,6 +459,8 @@ public class ECAlgorithms
WNafPreCompInfo[] infos = new WNafPreCompInfo[fullCount];
byte[][] wnafs = new byte[fullCount][];
+ ECPointMap pointMap = endomorphism.getPointMap();
+
for (int i = 0; i < halfCount; ++i)
{
int j0 = i << 1, j1 = j0 + 1;
@@ -443,13 +468,20 @@ public class ECAlgorithms
BigInteger kj0 = ks[j0]; negs[j0] = kj0.signum() < 0; kj0 = kj0.abs();
BigInteger kj1 = ks[j1]; negs[j1] = kj1.signum() < 0; kj1 = kj1.abs();
- int width = Math.max(2, Math.min(16, WNafUtil.getWindowSize(Math.max(kj0.bitLength(), kj1.bitLength()))));
+ int minWidth = WNafUtil.getWindowSize(Math.max(kj0.bitLength(), kj1.bitLength()), 8);
+
+ ECPoint P = ps[i];
+ WNafPreCompInfo infoP = WNafUtil.precompute(P, minWidth, true);
+ ECPoint Q = EndoUtil.mapPoint(endomorphism, P);
+ WNafPreCompInfo infoQ = WNafUtil.precomputeWithPointMap(Q, pointMap, infoP, true);
+
+ int widthP = Math.min(8, infoP.getWidth());
+ int widthQ = Math.min(8, infoQ.getWidth());
- ECPoint P = ps[i], Q = WNafUtil.mapPointWithPrecomp(P, width, true, pointMap);
- infos[j0] = WNafUtil.getWNafPreCompInfo(P);
- infos[j1] = WNafUtil.getWNafPreCompInfo(Q);
- wnafs[j0] = WNafUtil.generateWindowNaf(width, kj0);
- wnafs[j1] = WNafUtil.generateWindowNaf(width, kj1);
+ infos[j0] = infoP;
+ infos[j1] = infoQ;
+ wnafs[j0] = WNafUtil.generateWindowNaf(widthP, kj0);
+ wnafs[j1] = WNafUtil.generateWindowNaf(widthQ, kj1);
}
return implSumOfMultiplies(negs, infos, wnafs);
@@ -508,4 +540,77 @@ public class ECAlgorithms
return R;
}
+
+ private static ECPoint implShamirsTrickFixedPoint(ECPoint p, BigInteger k, ECPoint q, BigInteger l)
+ {
+ ECCurve c = p.getCurve();
+ int combSize = FixedPointUtil.getCombSize(c);
+
+ if (k.bitLength() > combSize || l.bitLength() > combSize)
+ {
+ /*
+ * TODO The comb works best when the scalars are less than the (possibly unknown) order.
+ * Still, if we want to handle larger scalars, we could allow customization of the comb
+ * size, or alternatively we could deal with the 'extra' bits either by running the comb
+ * multiple times as necessary, or by using an alternative multiplier as prelude.
+ */
+ throw new IllegalStateException("fixed-point comb doesn't support scalars larger than the curve order");
+ }
+
+ FixedPointPreCompInfo infoP = FixedPointUtil.precompute(p);
+ FixedPointPreCompInfo infoQ = FixedPointUtil.precompute(q);
+
+ ECLookupTable lookupTableP = infoP.getLookupTable();
+ ECLookupTable lookupTableQ = infoQ.getLookupTable();
+
+ int widthP = infoP.getWidth();
+ int widthQ = infoQ.getWidth();
+
+ // TODO This shouldn't normally happen, but a better "solution" is desirable anyway
+ if (widthP != widthQ)
+ {
+ FixedPointCombMultiplier m = new FixedPointCombMultiplier();
+ ECPoint r1 = m.multiply(p, k);
+ ECPoint r2 = m.multiply(q, l);
+ return r1.add(r2);
+ }
+
+ int width = widthP;
+
+ int d = (combSize + width - 1) / width;
+
+ ECPoint R = c.getInfinity();
+
+ int fullComb = d * width;
+ int[] K = Nat.fromBigInteger(fullComb, k);
+ int[] L = Nat.fromBigInteger(fullComb, l);
+
+ int top = fullComb - 1;
+ for (int i = 0; i < d; ++i)
+ {
+ int secretIndexK = 0, secretIndexL = 0;
+
+ for (int j = top - i; j >= 0; j -= d)
+ {
+ int secretBitK = K[j >>> 5] >>> (j & 0x1F);
+ secretIndexK ^= secretBitK >>> 1;
+ secretIndexK <<= 1;
+ secretIndexK ^= secretBitK;
+
+ int secretBitL = L[j >>> 5] >>> (j & 0x1F);
+ secretIndexL ^= secretBitL >>> 1;
+ secretIndexL <<= 1;
+ secretIndexL ^= secretBitL;
+ }
+
+ ECPoint addP = lookupTableP.lookupVar(secretIndexK);
+ ECPoint addQ = lookupTableQ.lookupVar(secretIndexL);
+
+ ECPoint T = addP.add(addQ);
+
+ R = R.twicePlus(T);
+ }
+
+ return R.add(infoP.getOffset()).add(infoQ.getOffset());
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java
index 7c10c78b..8f00c6bd 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java
@@ -1,6 +1,7 @@
package org.bouncycastle.math.ec;
import java.math.BigInteger;
+import java.security.SecureRandom;
import java.util.Hashtable;
import java.util.Random;
@@ -107,6 +108,10 @@ public abstract class ECCurve
public abstract boolean isValidFieldElement(BigInteger x);
+ public abstract ECFieldElement randomFieldElement(SecureRandom r);
+
+ public abstract ECFieldElement randomFieldElementMult(SecureRandom r);
+
public synchronized Config configure()
{
return new Config(this.coord, this.endomorphism, this.multiplier);
@@ -122,39 +127,16 @@ public abstract class ECCurve
return p;
}
- /**
- * @deprecated per-point compression property will be removed, use {@link #validatePoint(BigInteger, BigInteger)}
- * and refer {@link ECPoint#getEncoded(boolean)}
- */
- public ECPoint validatePoint(BigInteger x, BigInteger y, boolean withCompression)
- {
- ECPoint p = createPoint(x, y, withCompression);
- if (!p.isValid())
- {
- throw new IllegalArgumentException("Invalid point coordinates");
- }
- return p;
- }
-
public ECPoint createPoint(BigInteger x, BigInteger y)
{
- return createPoint(x, y, false);
- }
-
- /**
- * @deprecated per-point compression property will be removed, use {@link #createPoint(BigInteger, BigInteger)}
- * and refer {@link ECPoint#getEncoded(boolean)}
- */
- public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression)
- {
- return createRawPoint(fromBigInteger(x), fromBigInteger(y), withCompression);
+ return createRawPoint(fromBigInteger(x), fromBigInteger(y));
}
protected abstract ECCurve cloneCurve();
- protected abstract ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression);
+ protected abstract ECPoint createRawPoint(ECFieldElement x, ECFieldElement y);
- protected abstract ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression);
+ protected abstract ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs);
protected ECMultiplier createDefaultMultiplier()
{
@@ -246,7 +228,7 @@ public abstract class ECCurve
// TODO Default behaviour could be improved if the two curves have the same coordinate system by copying any Z coordinates.
p = p.normalize();
- return createPoint(p.getXCoord().toBigInteger(), p.getYCoord().toBigInteger(), p.withCompression);
+ return createPoint(p.getXCoord().toBigInteger(), p.getYCoord().toBigInteger());
}
/**
@@ -369,9 +351,11 @@ public abstract class ECCurve
}
/**
- * Sets the default <code>ECMultiplier</code>, unless already set.
+ * Sets the default <code>ECMultiplier</code>, unless already set.
+ *
+ * We avoid synchronizing for performance reasons, so there is no uniqueness guarantee.
*/
- public synchronized ECMultiplier getMultiplier()
+ public ECMultiplier getMultiplier()
{
if (this.multiplier == null)
{
@@ -492,7 +476,7 @@ public abstract class ECCurve
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -517,7 +501,26 @@ public abstract class ECCurve
pos += (FE_BYTES * 2);
}
- return createRawPoint(fromBigInteger(new BigInteger(1, x)), fromBigInteger(new BigInteger(1, y)), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ byte[] x = new byte[FE_BYTES], y = new byte[FE_BYTES];
+ int pos = index * FE_BYTES * 2;
+
+ for (int j = 0; j < FE_BYTES; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_BYTES + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(byte[] x, byte[] y)
+ {
+ return createRawPoint(fromBigInteger(new BigInteger(1, x)), fromBigInteger(new BigInteger(1, y)));
}
};
}
@@ -589,6 +592,30 @@ public abstract class ECCurve
return x != null && x.signum() >= 0 && x.compareTo(this.getField().getCharacteristic()) < 0;
}
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ BigInteger p = getField().getCharacteristic();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElement(r, p));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElement(r, p));
+ return fe1.multiply(fe2);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ BigInteger p = getField().getCharacteristic();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElementMult(r, p));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElementMult(r, p));
+ return fe1.multiply(fe2);
+ }
+
protected ECPoint decompressPoint(int yTilde, BigInteger X1)
{
ECFieldElement x = this.fromBigInteger(X1);
@@ -609,7 +636,29 @@ public abstract class ECCurve
y = y.negate();
}
- return this.createRawPoint(x, y, true);
+ return this.createRawPoint(x, y);
+ }
+
+ private static BigInteger implRandomFieldElement(SecureRandom r, BigInteger p)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(p.bitLength(), r);
+ }
+ while (x.compareTo(p) >= 0);
+ return x;
+ }
+
+ private static BigInteger implRandomFieldElementMult(SecureRandom r, BigInteger p)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(p.bitLength(), r);
+ }
+ while (x.signum() <= 0 || x.compareTo(p) >= 0);
+ return x;
}
}
@@ -637,7 +686,7 @@ public abstract class ECCurve
this.q = q;
this.r = ECFieldElement.Fp.calculateResidue(q);
- this.infinity = new ECPoint.Fp(this, null, null, false);
+ this.infinity = new ECPoint.Fp(this, null, null);
this.a = fromBigInteger(a);
this.b = fromBigInteger(b);
@@ -646,21 +695,13 @@ public abstract class ECCurve
this.coord = FP_DEFAULT_COORDS;
}
- /**
- * @deprecated use constructor taking order/cofactor
- */
- protected Fp(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b)
- {
- this(q, r, a, b, null, null);
- }
-
protected Fp(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor)
{
super(q);
this.q = q;
this.r = r;
- this.infinity = new ECPoint.Fp(this, null, null, false);
+ this.infinity = new ECPoint.Fp(this, null, null);
this.a = a;
this.b = b;
@@ -703,14 +744,14 @@ public abstract class ECCurve
return new ECFieldElement.Fp(this.q, this.r, x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new ECPoint.Fp(this, x, y, withCompression);
+ return new ECPoint.Fp(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new ECPoint.Fp(this, x, y, zs, withCompression);
+ return new ECPoint.Fp(this, x, y, zs);
}
public ECPoint importPoint(ECPoint p)
@@ -725,8 +766,7 @@ public abstract class ECCurve
return new ECPoint.Fp(this,
fromBigInteger(p.x.toBigInteger()),
fromBigInteger(p.y.toBigInteger()),
- new ECFieldElement[]{ fromBigInteger(p.zs[0].toBigInteger()) },
- p.withCompression);
+ new ECFieldElement[]{ fromBigInteger(p.zs[0].toBigInteger()) });
default:
break;
}
@@ -790,12 +830,7 @@ public abstract class ECCurve
super(buildField(m, k1, k2, k3));
}
- public boolean isValidFieldElement(BigInteger x)
- {
- return x != null && x.signum() >= 0 && x.bitLength() <= this.getFieldSize();
- }
-
- public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression)
+ public ECPoint createPoint(BigInteger x, BigInteger y)
{
ECFieldElement X = this.fromBigInteger(x), Y = this.fromBigInteger(y);
@@ -822,7 +857,7 @@ public abstract class ECCurve
// ECFieldElement Z = X;
// X = X.square();
// Y = Y.add(X);
-// return createRawPoint(X, Y, new ECFieldElement[]{ Z }, withCompression);
+// return createRawPoint(X, Y, new ECFieldElement[]{ Z });
// }
else
{
@@ -837,7 +872,30 @@ public abstract class ECCurve
}
}
- return this.createRawPoint(X, Y, withCompression);
+ return this.createRawPoint(X, Y);
+ }
+
+ public boolean isValidFieldElement(BigInteger x)
+ {
+ return x != null && x.signum() >= 0 && x.bitLength() <= this.getFieldSize();
+ }
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int m = getFieldSize();
+ return fromBigInteger(BigIntegers.createRandomBigInteger(m, r));
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ int m = getFieldSize();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElementMult(r, m));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElementMult(r, m));
+ return fe1.multiply(fe2);
}
/**
@@ -889,7 +947,7 @@ public abstract class ECCurve
throw new IllegalArgumentException("Invalid point compression");
}
- return this.createRawPoint(x, y, true);
+ return this.createRawPoint(x, y);
}
/**
@@ -903,6 +961,27 @@ public abstract class ECCurve
*/
protected ECFieldElement solveQuadraticEquation(ECFieldElement beta)
{
+ ECFieldElement.AbstractF2m betaF2m = (ECFieldElement.AbstractF2m)beta;
+
+ boolean fastTrace = betaF2m.hasFastTrace();
+ if (fastTrace && 0 != betaF2m.trace())
+ {
+ return null;
+ }
+
+ int m = this.getFieldSize();
+
+ // For odd m, use the half-trace
+ if (0 != (m & 1))
+ {
+ ECFieldElement r = betaF2m.halfTrace();
+ if (fastTrace || r.square().add(r).add(beta).isZero())
+ {
+ return r;
+ }
+ return null;
+ }
+
if (beta.isZero())
{
return beta;
@@ -910,7 +989,6 @@ public abstract class ECCurve
ECFieldElement gamma, z, zeroElement = this.fromBigInteger(ECConstants.ZERO);
- int m = this.getFieldSize();
Random rand = new Random();
do
{
@@ -956,6 +1034,17 @@ public abstract class ECCurve
{
return this.order != null && this.cofactor != null && this.b.isOne() && (this.a.isZero() || this.a.isOne());
}
+
+ private static BigInteger implRandomFieldElementMult(SecureRandom r, int m)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(m, r);
+ }
+ while (x.signum() <= 0);
+ return x;
+ }
}
/**
@@ -1128,7 +1217,7 @@ public abstract class ECCurve
this.order = order;
this.cofactor = cofactor;
- this.infinity = new ECPoint.F2m(this, null, null, false);
+ this.infinity = new ECPoint.F2m(this, null, null);
this.a = fromBigInteger(a);
this.b = fromBigInteger(b);
this.coord = F2M_DEFAULT_COORDS;
@@ -1145,7 +1234,7 @@ public abstract class ECCurve
this.order = order;
this.cofactor = cofactor;
- this.infinity = new ECPoint.F2m(this, null, null, false);
+ this.infinity = new ECPoint.F2m(this, null, null);
this.a = a;
this.b = b;
this.coord = F2M_DEFAULT_COORDS;
@@ -1189,14 +1278,14 @@ public abstract class ECCurve
return new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new ECPoint.F2m(this, x, y, withCompression);
+ return new ECPoint.F2m(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new ECPoint.F2m(this, x, y, zs, withCompression);
+ return new ECPoint.F2m(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -1250,7 +1339,7 @@ public abstract class ECCurve
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -1275,7 +1364,28 @@ public abstract class ECCurve
pos += (FE_LONGS * 2);
}
- return createRawPoint(new ECFieldElement.F2m(m, ks, new LongArray(x)), new ECFieldElement.F2m(m, ks, new LongArray(y)), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ long[] x = Nat.create64(FE_LONGS), y = Nat.create64(FE_LONGS);
+ int pos = index * FE_LONGS * 2;
+
+ for (int j = 0; j < FE_LONGS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_LONGS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(long[] x, long[] y)
+ {
+ ECFieldElement.F2m X = new ECFieldElement.F2m(m, ks, new LongArray(x));
+ ECFieldElement.F2m Y = new ECFieldElement.F2m(m, ks, new LongArray(y));
+ return createRawPoint(X, Y);
}
};
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java
index 49d1c2f1..43c83e0e 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java
@@ -3,10 +3,9 @@ package org.bouncycastle.math.ec;
import java.math.BigInteger;
import java.util.Random;
-import org.bouncycastle.math.raw.Mod;
-import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.BigIntegers;
+import org.bouncycastle.util.Integers;
public abstract class ECFieldElement
implements ECConstants
@@ -417,13 +416,7 @@ public abstract class ECFieldElement
protected BigInteger modInverse(BigInteger x)
{
- int bits = getFieldSize();
- int len = (bits + 31) >> 5;
- int[] p = Nat.fromBigInteger(bits, q);
- int[] n = Nat.fromBigInteger(bits, x);
- int[] z = Nat.create(len);
- Mod.invert(p, n, z);
- return Nat.toBigInteger(len, z);
+ return BigIntegers.modOddInverse(q, x);
}
protected BigInteger modMult(BigInteger x1, BigInteger x2)
@@ -510,27 +503,59 @@ public abstract class ECFieldElement
throw new IllegalStateException("Half-trace only defined for odd m");
}
- ECFieldElement fe = this;
- ECFieldElement ht = fe;
- for (int i = 2; i < m; i += 2)
+// ECFieldElement ht = this;
+// for (int i = 1; i < m; i += 2)
+// {
+// ht = ht.squarePow(2).add(this);
+// }
+
+ int n = (m + 1) >>> 1;
+ int k = 31 - Integers.numberOfLeadingZeros(n);
+ int nk = 1;
+
+ ECFieldElement ht = this;
+ while (k > 0)
{
- fe = fe.squarePow(2);
- ht = ht.add(fe);
+ ht = ht.squarePow(nk << 1).add(ht);
+ nk = n >>> --k;
+ if (0 != (nk & 1))
+ {
+ ht = ht.squarePow(2).add(this);
+ }
}
return ht;
}
+ public boolean hasFastTrace()
+ {
+ return false;
+ }
+
public int trace()
{
int m = this.getFieldSize();
- ECFieldElement fe = this;
- ECFieldElement tr = fe;
- for (int i = 1; i < m; ++i)
+
+// ECFieldElement tr = this;
+// for (int i = 1; i < m; ++i)
+// {
+// tr = tr.square().add(this);
+// }
+
+ int k = 31 - Integers.numberOfLeadingZeros(m);
+ int mk = 1;
+
+ ECFieldElement tr = this;
+ while (k > 0)
{
- fe = fe.square();
- tr = tr.add(fe);
+ tr = tr.squarePow(mk).add(tr);
+ mk = m >>> --k;
+ if (0 != (mk & 1))
+ {
+ tr = tr.square().add(this);
+ }
}
+
if (tr.isZero())
{
return 0;
@@ -683,42 +708,6 @@ public abstract class ECFieldElement
return m;
}
- /**
- * Checks, if the ECFieldElements <code>a</code> and <code>b</code>
- * are elements of the same field <code>F<sub>2<sup>m</sup></sub></code>
- * (having the same representation).
- * @param a field element.
- * @param b field element to be compared.
- * @throws IllegalArgumentException if <code>a</code> and <code>b</code>
- * are not elements of the same field
- * <code>F<sub>2<sup>m</sup></sub></code> (having the same
- * representation).
- */
- public static void checkFieldElements(
- ECFieldElement a,
- ECFieldElement b)
- {
- if ((!(a instanceof F2m)) || (!(b instanceof F2m)))
- {
- throw new IllegalArgumentException("Field elements are not "
- + "both instances of ECFieldElement.F2m");
- }
-
- ECFieldElement.F2m aF2m = (ECFieldElement.F2m)a;
- ECFieldElement.F2m bF2m = (ECFieldElement.F2m)b;
-
- if (aF2m.representation != bF2m.representation)
- {
- // Should never occur
- throw new IllegalArgumentException("One of the F2m field elements has incorrect representation");
- }
-
- if ((aF2m.m != bF2m.m) || !Arrays.areEqual(aF2m.ks, bF2m.ks))
- {
- throw new IllegalArgumentException("Field elements are not elements of the same field F2m");
- }
- }
-
public ECFieldElement add(final ECFieldElement b)
{
// No check performed here for performance reasons. Instead the
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECLookupTable.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECLookupTable.java
index 7ff5c6a4..2874f6be 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECLookupTable.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECLookupTable.java
@@ -4,4 +4,5 @@ public interface ECLookupTable
{
int getSize();
ECPoint lookup(int index);
+ ECPoint lookupVar(int index);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java
index 57dfa339..cc4f63a4 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java
@@ -1,8 +1,11 @@
package org.bouncycastle.math.ec;
import java.math.BigInteger;
+import java.security.SecureRandom;
import java.util.Hashtable;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
+
/**
* base class for points on elliptic curves.
*/
@@ -46,8 +49,6 @@ public abstract class ECPoint
protected ECFieldElement y;
protected ECFieldElement[] zs;
- protected boolean withCompression;
-
// Hashtable is (String -> PreCompInfo)
protected Hashtable preCompTable = null;
@@ -224,13 +225,31 @@ public abstract class ECPoint
}
default:
{
- ECFieldElement Z1 = getZCoord(0);
- if (Z1.isOne())
+ ECFieldElement z = getZCoord(0);
+ if (z.isOne())
{
return this;
}
- return normalize(Z1.invert());
+ if (null == curve)
+ {
+ throw new IllegalStateException("Detached points must be in affine coordinates");
+ }
+
+ /*
+ * Use blinding to avoid the side-channel leak identified and analyzed in the paper
+ * "Yet another GCD based inversion side-channel affecting ECC implementations" by Nir
+ * Drucker and Shay Gueron.
+ *
+ * To blind the calculation of z^-1, choose a multiplicative (i.e. non-zero) field
+ * element 'b' uniformly at random, then calculate the result instead as (z * b)^-1 * b.
+ * Any side-channel in the implementation of 'inverse' now only leaks information about
+ * the value (z * b), and no longer reveals information about 'z' itself.
+ */
+ SecureRandom r = CryptoServicesRegistrar.getSecureRandom();
+ ECFieldElement b = curve.randomFieldElementMult(r);
+ ECFieldElement zInv = z.multiply(b).invert().multiply(b);
+ return normalize(zInv);
}
}
}
@@ -260,7 +279,7 @@ public abstract class ECPoint
protected ECPoint createScaledPoint(ECFieldElement sx, ECFieldElement sy)
{
- return this.getCurve().createRawPoint(getRawXCoord().multiply(sx), getRawYCoord().multiply(sy), this.withCompression);
+ return this.getCurve().createRawPoint(getRawXCoord().multiply(sx), getRawYCoord().multiply(sy));
}
public boolean isInfinity()
@@ -268,14 +287,6 @@ public abstract class ECPoint
return x == null || y == null || (zs.length > 0 && zs[0].isZero());
}
- /**
- * @deprecated per-point compression property will be removed, refer {@link #getEncoded(boolean)}
- */
- public boolean isCompressed()
- {
- return this.withCompression;
- }
-
public boolean isValid()
{
return implIsValid(false, true);
@@ -336,14 +347,28 @@ public abstract class ECPoint
{
return isInfinity()
? this
- : getCurve().createRawPoint(getRawXCoord().multiply(scale), getRawYCoord(), getRawZCoords(), this.withCompression);
+ : getCurve().createRawPoint(getRawXCoord().multiply(scale), getRawYCoord(), getRawZCoords());
+ }
+
+ public ECPoint scaleXNegateY(ECFieldElement scale)
+ {
+ return isInfinity()
+ ? this
+ : getCurve().createRawPoint(getRawXCoord().multiply(scale), getRawYCoord().negate(), getRawZCoords());
}
public ECPoint scaleY(ECFieldElement scale)
{
return isInfinity()
? this
- : getCurve().createRawPoint(getRawXCoord(), getRawYCoord().multiply(scale), getRawZCoords(), this.withCompression);
+ : getCurve().createRawPoint(getRawXCoord(), getRawYCoord().multiply(scale), getRawZCoords());
+ }
+
+ public ECPoint scaleYNegateX(ECFieldElement scale)
+ {
+ return isInfinity()
+ ? this
+ : getCurve().createRawPoint(getRawXCoord().negate(), getRawYCoord().multiply(scale), getRawZCoords());
}
public boolean equals(ECPoint other)
@@ -450,15 +475,6 @@ public abstract class ECPoint
}
/**
- * @deprecated per-point compression property will be removed, refer {@link #getEncoded(boolean)}
- * @return a byte encoding.
- */
- public byte[] getEncoded()
- {
- return getEncoded(this.withCompression);
- }
-
- /**
* Get an encoding of the point value, optionally in compressed format.
*
* @param compressed whether to generate a compressed point encoding.
@@ -613,38 +629,19 @@ public abstract class ECPoint
*/
public static class Fp extends AbstractFp
{
- /**
- * Create a point that encodes with or without point compression.
- *
- * @param curve the curve to use
- * @param x affine x co-ordinate
- * @param y affine y co-ordinate
- * @param withCompression if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer {@link #getEncoded(boolean)}
- */
- public Fp(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ Fp(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- Fp(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ Fp(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
{
- return new ECPoint.Fp(null, this.getAffineXCoord(), this.getAffineYCoord(), false);
+ return new ECPoint.Fp(null, this.getAffineXCoord(), this.getAffineYCoord());
}
public ECFieldElement getZCoord(int index)
@@ -701,7 +698,7 @@ public abstract class ECPoint
ECFieldElement X3 = gamma.square().subtract(X1).subtract(X2);
ECFieldElement Y3 = gamma.multiply(X1.subtract(X3)).subtract(Y1);
- return new ECPoint.Fp(curve, X3, Y3, this.withCompression);
+ return new ECPoint.Fp(curve, X3, Y3);
}
case ECCurve.COORD_HOMOGENEOUS:
@@ -743,7 +740,7 @@ public abstract class ECPoint
ECFieldElement Y3 = vSquaredV2.subtract(A).multiplyMinusProduct(u, u2, vCubed);
ECFieldElement Z3 = vCubed.multiply(w);
- return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
case ECCurve.COORD_JACOBIAN:
@@ -866,7 +863,7 @@ public abstract class ECPoint
zs = new ECFieldElement[]{ Z3 };
}
- return new ECPoint.Fp(curve, X3, Y3, zs, this.withCompression);
+ return new ECPoint.Fp(curve, X3, Y3, zs);
}
default:
@@ -905,7 +902,7 @@ public abstract class ECPoint
ECFieldElement X3 = gamma.square().subtract(two(X1));
ECFieldElement Y3 = gamma.multiply(X1.subtract(X3)).subtract(Y1);
- return new ECPoint.Fp(curve, X3, Y3, this.withCompression);
+ return new ECPoint.Fp(curve, X3, Y3);
}
case ECCurve.COORD_HOMOGENEOUS:
@@ -935,7 +932,7 @@ public abstract class ECPoint
ECFieldElement _4sSquared = Z1IsOne ? two(_2t) : _2s.square();
ECFieldElement Z3 = two(_4sSquared).multiply(s);
- return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
case ECCurve.COORD_JACOBIAN:
@@ -994,7 +991,7 @@ public abstract class ECPoint
// Alternative calculation of Z3 using fast square
// ECFieldElement Z3 = doubleProductFromSquares(Y1, Z1, Y1Squared, Z1Squared);
- return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
case ECCurve.COORD_JACOBIAN_MODIFIED:
@@ -1073,7 +1070,7 @@ public abstract class ECPoint
ECFieldElement X4 = (L2.subtract(L1)).multiply(L1.add(L2)).add(X2);
ECFieldElement Y4 = (X1.subtract(X4)).multiply(L2).subtract(Y1);
- return new ECPoint.Fp(curve, X4, Y4, this.withCompression);
+ return new ECPoint.Fp(curve, X4, Y4);
}
case ECCurve.COORD_JACOBIAN_MODIFIED:
{
@@ -1126,7 +1123,7 @@ public abstract class ECPoint
ECFieldElement X4 = (L2.subtract(L1)).multiply(L1.add(L2)).add(X1);
ECFieldElement Y4 = (X1.subtract(X4)).multiply(L2).subtract(Y1);
- return new ECPoint.Fp(curve, X4, Y4, this.withCompression);
+ return new ECPoint.Fp(curve, X4, Y4);
}
case ECCurve.COORD_JACOBIAN_MODIFIED:
{
@@ -1222,15 +1219,15 @@ public abstract class ECPoint
{
case ECCurve.COORD_AFFINE:
ECFieldElement zInv = Z1.invert(), zInv2 = zInv.square(), zInv3 = zInv2.multiply(zInv);
- return new Fp(curve, X1.multiply(zInv2), Y1.multiply(zInv3), this.withCompression);
+ return new Fp(curve, X1.multiply(zInv2), Y1.multiply(zInv3));
case ECCurve.COORD_HOMOGENEOUS:
X1 = X1.multiply(Z1);
Z1 = Z1.multiply(Z1.square());
- return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1 }, this.withCompression);
+ return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1 });
case ECCurve.COORD_JACOBIAN:
- return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1 }, this.withCompression);
+ return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1 });
case ECCurve.COORD_JACOBIAN_MODIFIED:
- return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1, W1 }, this.withCompression);
+ return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1, W1 });
default:
throw new IllegalStateException("unsupported coordinate system");
}
@@ -1278,10 +1275,10 @@ public abstract class ECPoint
if (ECCurve.COORD_AFFINE != coord)
{
- return new ECPoint.Fp(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new ECPoint.Fp(curve, this.x, this.y.negate(), this.zs);
}
- return new ECPoint.Fp(curve, this.x, this.y.negate(), this.withCompression);
+ return new ECPoint.Fp(curve, this.x, this.y.negate());
}
protected ECFieldElement calculateJacobianModifiedW(ECFieldElement Z, ECFieldElement ZSquared)
@@ -1337,7 +1334,7 @@ public abstract class ECPoint
ECFieldElement W3 = calculateW ? two(_8T.multiply(W1)) : null;
ECFieldElement Z3 = Z1.isOne() ? _2Y1 : _2Y1.multiply(Z1);
- return new ECPoint.Fp(this.getCurve(), X3, Y3, new ECFieldElement[]{ Z3, W3 }, this.withCompression);
+ return new ECPoint.Fp(this.getCurve(), X3, Y3, new ECFieldElement[]{ Z3, W3 });
}
}
@@ -1427,35 +1424,46 @@ public abstract class ECPoint
if (ECConstants.TWO.equals(cofactor))
{
/*
- * Check that the trace of (X + A) is 0, then there exists a solution to L^2 + L = X + A,
- * and so a halving is possible, so this point is the double of another.
+ * Check that 0 == Tr(X + A); then there exists a solution to L^2 + L = X + A, and
+ * so a halving is possible, so this point is the double of another.
+ *
+ * Note: Tr(A) == 1 for cofactor 2 curves.
*/
ECPoint N = this.normalize();
ECFieldElement X = N.getAffineXCoord();
- ECFieldElement rhs = X.add(curve.getA());
- return ((ECFieldElement.AbstractF2m)rhs).trace() == 0;
+ return 0 != ((ECFieldElement.AbstractF2m)X).trace();
}
if (ECConstants.FOUR.equals(cofactor))
{
/*
* Solve L^2 + L = X + A to find the half of this point, if it exists (fail if not).
- * Generate both possibilities for the square of the half-point's x-coordinate (w),
- * and check if Tr(w + A) == 0 for at least one; then a second halving is possible
- * (see comments for cofactor 2 above), so this point is four times another.
*
- * Note: Tr(x^2) == Tr(x).
+ * Note: Tr(A) == 0 for cofactor 4 curves.
*/
ECPoint N = this.normalize();
ECFieldElement X = N.getAffineXCoord();
- ECFieldElement lambda = ((ECCurve.AbstractF2m)curve).solveQuadraticEquation(X.add(curve.getA()));
- if (lambda == null)
+ ECFieldElement L = ((ECCurve.AbstractF2m)curve).solveQuadraticEquation(X.add(curve.getA()));
+ if (null == L)
{
return false;
}
- ECFieldElement w = X.multiply(lambda).add(N.getAffineYCoord());
- ECFieldElement t = w.add(curve.getA());
- return ((ECFieldElement.AbstractF2m)t).trace() == 0
- || ((ECFieldElement.AbstractF2m)(t.add(X))).trace() == 0;
+
+ /*
+ * A solution exists, therefore 0 == Tr(X + A) == Tr(X).
+ */
+ ECFieldElement Y = N.getAffineYCoord();
+ ECFieldElement T = X.multiply(L).add(Y);
+
+ /*
+ * Either T or (T + X) is the square of a half-point's x coordinate (hx). In either
+ * case, the half-point can be halved again when 0 == Tr(hx + A).
+ *
+ * Note: Tr(hx + A) == Tr(hx) == Tr(hx^2) == Tr(T) == Tr(T + X)
+ *
+ * Check that 0 == Tr(T); then there exists a solution to L^2 + L = hx + A, and so a
+ * second halving is possible and this point is four times some other.
+ */
+ return 0 == ((ECFieldElement.AbstractF2m)T).trace();
}
return super.satisfiesOrder();
@@ -1480,7 +1488,7 @@ public abstract class ECPoint
ECFieldElement X2 = X.multiply(scale);
ECFieldElement L2 = L.add(X).divide(scale).add(X2);
- return this.getCurve().createRawPoint(X, L2, this.getRawZCoords(), this.withCompression); // earlier JDK
+ return this.getCurve().createRawPoint(X, L2, this.getRawZCoords()); // earlier JDK
}
case ECCurve.COORD_LAMBDA_PROJECTIVE:
{
@@ -1492,7 +1500,7 @@ public abstract class ECPoint
ECFieldElement L2 = L.add(X).add(X2);
ECFieldElement Z2 = Z.multiply(scale);
- return this.getCurve().createRawPoint(X2, L2, new ECFieldElement[]{ Z2 }, this.withCompression); // earlier JDK
+ return this.getCurve().createRawPoint(X2, L2, new ECFieldElement[]{ Z2 }); // earlier JDK
}
default:
{
@@ -1501,6 +1509,11 @@ public abstract class ECPoint
}
}
+ public ECPoint scaleXNegateY(ECFieldElement scale)
+ {
+ return scaleX(scale);
+ }
+
public ECPoint scaleY(ECFieldElement scale)
{
if (this.isInfinity())
@@ -1520,7 +1533,7 @@ public abstract class ECPoint
// Y is actually Lambda (X + Y/X) here
ECFieldElement L2 = L.add(X).multiply(scale).add(X);
- return this.getCurve().createRawPoint(X, L2, this.getRawZCoords(), this.withCompression); // earlier JDK
+ return this.getCurve().createRawPoint(X, L2, this.getRawZCoords()); // earlier JDK
}
default:
{
@@ -1529,6 +1542,11 @@ public abstract class ECPoint
}
}
+ public ECPoint scaleYNegateX(ECFieldElement scale)
+ {
+ return scaleY(scale);
+ }
+
public ECPoint subtract(ECPoint b)
{
if (b.isInfinity())
@@ -1558,14 +1576,14 @@ public abstract class ECPoint
case ECCurve.COORD_LAMBDA_AFFINE:
{
ECFieldElement Y1 = this.y;
- return (ECPoint.AbstractF2m)curve.createRawPoint(X1.square(), Y1.square(), this.withCompression);
+ return (ECPoint.AbstractF2m)curve.createRawPoint(X1.square(), Y1.square());
}
case ECCurve.COORD_HOMOGENEOUS:
case ECCurve.COORD_LAMBDA_PROJECTIVE:
{
ECFieldElement Y1 = this.y, Z1 = this.zs[0];
return (ECPoint.AbstractF2m)curve.createRawPoint(X1.square(), Y1.square(),
- new ECFieldElement[]{ Z1.square() }, this.withCompression);
+ new ECFieldElement[]{ Z1.square() });
}
default:
{
@@ -1592,14 +1610,14 @@ public abstract class ECPoint
case ECCurve.COORD_LAMBDA_AFFINE:
{
ECFieldElement Y1 = this.y;
- return (ECPoint.AbstractF2m)curve.createRawPoint(X1.squarePow(pow), Y1.squarePow(pow), this.withCompression);
+ return (ECPoint.AbstractF2m)curve.createRawPoint(X1.squarePow(pow), Y1.squarePow(pow));
}
case ECCurve.COORD_HOMOGENEOUS:
case ECCurve.COORD_LAMBDA_PROJECTIVE:
{
ECFieldElement Y1 = this.y, Z1 = this.zs[0];
return (ECPoint.AbstractF2m)curve.createRawPoint(X1.squarePow(pow), Y1.squarePow(pow),
- new ECFieldElement[]{ Z1.squarePow(pow) }, this.withCompression);
+ new ECFieldElement[]{ Z1.squarePow(pow) });
}
default:
{
@@ -1614,52 +1632,23 @@ public abstract class ECPoint
*/
public static class F2m extends AbstractF2m
{
- /**
- * @param curve base curve
- * @param x x point
- * @param y y point
- * @param withCompression true if encode with point compression.
- *
- * @deprecated per-point compression property will be removed, refer {@link #getEncoded(boolean)}
- */
- public F2m(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ F2m(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- if (x != null)
- {
- // Check if x and y are elements of the same field
- ECFieldElement.F2m.checkFieldElements(this.x, this.y);
-
- // Check if x and a are elements of the same field
- if (curve != null)
- {
- ECFieldElement.F2m.checkFieldElements(this.x, this.curve.getA());
- }
- }
-
- this.withCompression = withCompression;
-
// checkCurveEquation();
}
- F2m(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ F2m(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
- this.withCompression = withCompression;
-
// checkCurveEquation();
}
protected ECPoint detach()
{
- return new ECPoint.F2m(null, this.getAffineXCoord(), this.getAffineYCoord(), false); // earlier JDK
+ return new ECPoint.F2m(null, this.getAffineXCoord(), this.getAffineYCoord()); // earlier JDK
}
public ECFieldElement getYCoord()
@@ -1762,7 +1751,7 @@ public abstract class ECPoint
ECFieldElement X3 = L.square().add(L).add(dx).add(curve.getA());
ECFieldElement Y3 = L.multiply(X1.add(X3)).add(X3).add(Y1);
- return new ECPoint.F2m(curve, X3, Y3, this.withCompression);
+ return new ECPoint.F2m(curve, X3, Y3);
}
case ECCurve.COORD_HOMOGENEOUS:
{
@@ -1799,7 +1788,7 @@ public abstract class ECPoint
ECFieldElement Y3 = U.multiplyPlusProduct(X1, V, Y1).multiplyPlusProduct(VSqZ2, uv, A);
ECFieldElement Z3 = VCu.multiply(W);
- return new ECPoint.F2m(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.F2m(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
case ECCurve.COORD_LAMBDA_PROJECTIVE:
{
@@ -1859,7 +1848,7 @@ public abstract class ECPoint
X3 = L.square().add(L).add(X1).add(curve.getA());
if (X3.isZero())
{
- return new ECPoint.F2m(curve, X3, curve.getB().sqrt(), this.withCompression);
+ return new ECPoint.F2m(curve, X3, curve.getB().sqrt());
}
ECFieldElement Y3 = L.multiply(X1.add(X3)).add(X3).add(Y1);
@@ -1876,7 +1865,7 @@ public abstract class ECPoint
X3 = AU1.multiply(AU2);
if (X3.isZero())
{
- return new ECPoint.F2m(curve, X3, curve.getB().sqrt(), this.withCompression);
+ return new ECPoint.F2m(curve, X3, curve.getB().sqrt());
}
ECFieldElement ABZ2 = A.multiply(B);
@@ -1894,7 +1883,7 @@ public abstract class ECPoint
}
}
- return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 });
}
default:
{
@@ -1915,7 +1904,7 @@ public abstract class ECPoint
ECFieldElement X1 = this.x;
if (X1.isZero())
{
- // A point with X == 0 is it's own additive inverse
+ // A point with X == 0 is its own additive inverse
return curve.getInfinity();
}
@@ -1932,7 +1921,7 @@ public abstract class ECPoint
ECFieldElement X3 = L1.square().add(L1).add(curve.getA());
ECFieldElement Y3 = X1.squarePlusProduct(X3, L1.addOne());
- return new ECPoint.F2m(curve, X3, Y3, this.withCompression);
+ return new ECPoint.F2m(curve, X3, Y3);
}
case ECCurve.COORD_HOMOGENEOUS:
{
@@ -1953,7 +1942,7 @@ public abstract class ECPoint
ECFieldElement Y3 = X1Sq.square().multiplyPlusProduct(V, h, sv);
ECFieldElement Z3 = V.multiply(vSquared);
- return new ECPoint.F2m(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.F2m(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
case ECCurve.COORD_LAMBDA_PROJECTIVE:
{
@@ -1967,7 +1956,7 @@ public abstract class ECPoint
ECFieldElement T = L1.square().add(L1Z1).add(aZ1Sq);
if (T.isZero())
{
- return new ECPoint.F2m(curve, T, curve.getB().sqrt(), withCompression);
+ return new ECPoint.F2m(curve, T, curve.getB().sqrt());
}
ECFieldElement X3 = T.square();
@@ -2004,7 +1993,7 @@ public abstract class ECPoint
L3 = X1Z1.squarePlusProduct(T, L1Z1).add(X3).add(Z3);
}
- return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 });
}
default:
{
@@ -2029,7 +2018,7 @@ public abstract class ECPoint
ECFieldElement X1 = this.x;
if (X1.isZero())
{
- // A point with X == 0 is it's own additive inverse
+ // A point with X == 0 is its own additive inverse
return b;
}
@@ -2072,14 +2061,14 @@ public abstract class ECPoint
if (A.isZero())
{
- return new ECPoint.F2m(curve, A, curve.getB().sqrt(), withCompression);
+ return new ECPoint.F2m(curve, A, curve.getB().sqrt());
}
ECFieldElement X3 = A.square().multiply(X2Z1Sq);
ECFieldElement Z3 = A.multiply(B).multiply(Z1Sq);
ECFieldElement L3 = A.add(B).square().multiplyPlusProduct(T, L2plus1, Z3);
- return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 });
}
default:
{
@@ -2106,23 +2095,23 @@ public abstract class ECPoint
case ECCurve.COORD_AFFINE:
{
ECFieldElement Y = this.y;
- return new ECPoint.F2m(curve, X, Y.add(X), this.withCompression);
+ return new ECPoint.F2m(curve, X, Y.add(X));
}
case ECCurve.COORD_HOMOGENEOUS:
{
ECFieldElement Y = this.y, Z = this.zs[0];
- return new ECPoint.F2m(curve, X, Y.add(X), new ECFieldElement[]{ Z }, this.withCompression);
+ return new ECPoint.F2m(curve, X, Y.add(X), new ECFieldElement[]{ Z });
}
case ECCurve.COORD_LAMBDA_AFFINE:
{
ECFieldElement L = this.y;
- return new ECPoint.F2m(curve, X, L.addOne(), this.withCompression);
+ return new ECPoint.F2m(curve, X, L.addOne());
}
case ECCurve.COORD_LAMBDA_PROJECTIVE:
{
// L is actually Lambda (X + Y/X) here
ECFieldElement L = this.y, Z = this.zs[0];
- return new ECPoint.F2m(curve, X, L.add(Z), new ECFieldElement[]{ Z }, this.withCompression);
+ return new ECPoint.F2m(curve, X, L.add(Z), new ECFieldElement[]{ Z });
}
default:
{
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/GLVMultiplier.java b/bcprov/src/main/java/org/bouncycastle/math/ec/GLVMultiplier.java
index 09b83668..626bff82 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/GLVMultiplier.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/GLVMultiplier.java
@@ -2,6 +2,7 @@ package org.bouncycastle.math.ec;
import java.math.BigInteger;
+import org.bouncycastle.math.ec.endo.EndoUtil;
import org.bouncycastle.math.ec.endo.GLVEndomorphism;
public class GLVMultiplier extends AbstractECMultiplier
@@ -31,12 +32,13 @@ public class GLVMultiplier extends AbstractECMultiplier
BigInteger[] ab = glvEndomorphism.decomposeScalar(k.mod(n));
BigInteger a = ab[0], b = ab[1];
- ECPointMap pointMap = glvEndomorphism.getPointMap();
if (glvEndomorphism.hasEfficientPointMap())
{
- return ECAlgorithms.implShamirsTrickWNaf(p, a, pointMap, b);
+ return ECAlgorithms.implShamirsTrickWNaf(glvEndomorphism, p, a, b);
}
- return ECAlgorithms.implShamirsTrickWNaf(p, a, pointMap.map(p), b);
+ ECPoint q = EndoUtil.mapPoint(glvEndomorphism, p);
+
+ return ECAlgorithms.implShamirsTrickWNaf(p, a, q, b);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ScaleXNegateYPointMap.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ScaleXNegateYPointMap.java
new file mode 100644
index 00000000..035d7ec2
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ScaleXNegateYPointMap.java
@@ -0,0 +1,16 @@
+package org.bouncycastle.math.ec;
+
+public class ScaleXNegateYPointMap implements ECPointMap
+{
+ protected final ECFieldElement scale;
+
+ public ScaleXNegateYPointMap(ECFieldElement scale)
+ {
+ this.scale = scale;
+ }
+
+ public ECPoint map(ECPoint p)
+ {
+ return p.scaleXNegateY(scale);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ScaleYNegateXPointMap.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ScaleYNegateXPointMap.java
new file mode 100644
index 00000000..049b9a39
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ScaleYNegateXPointMap.java
@@ -0,0 +1,16 @@
+package org.bouncycastle.math.ec;
+
+public class ScaleYNegateXPointMap implements ECPointMap
+{
+ protected final ECFieldElement scale;
+
+ public ScaleYNegateXPointMap(ECFieldElement scale)
+ {
+ this.scale = scale;
+ }
+
+ public ECPoint map(ECPoint p)
+ {
+ return p.scaleYNegateX(scale);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/WNafL2RMultiplier.java b/bcprov/src/main/java/org/bouncycastle/math/ec/WNafL2RMultiplier.java
index 90b08475..99e447be 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/WNafL2RMultiplier.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/WNafL2RMultiplier.java
@@ -2,6 +2,8 @@ package org.bouncycastle.math.ec;
import java.math.BigInteger;
+import org.bouncycastle.util.Integers;
+
/**
* Class implementing the WNAF (Window Non-Adjacent Form) multiplication
* algorithm.
@@ -17,12 +19,12 @@ public class WNafL2RMultiplier extends AbstractECMultiplier
*/
protected ECPoint multiplyPositive(ECPoint p, BigInteger k)
{
- // Clamp the window width in the range [2, 16]
- int width = Math.max(2, Math.min(16, getWindowSize(k.bitLength())));
+ int minWidth = WNafUtil.getWindowSize(k.bitLength());
- WNafPreCompInfo wnafPreCompInfo = WNafUtil.precompute(p, width, true);
- ECPoint[] preComp = wnafPreCompInfo.getPreComp();
- ECPoint[] preCompNeg = wnafPreCompInfo.getPreCompNeg();
+ WNafPreCompInfo info = WNafUtil.precompute(p, minWidth, true);
+ ECPoint[] preComp = info.getPreComp();
+ ECPoint[] preCompNeg = info.getPreCompNeg();
+ int width = info.getWidth();
int[] wnaf = WNafUtil.generateCompactWindowNaf(width, k);
@@ -45,7 +47,7 @@ public class WNafL2RMultiplier extends AbstractECMultiplier
// Optimization can only be used for values in the lower half of the table
if ((n << 2) < (1 << width))
{
- int highest = LongArray.bitLengths[n];
+ int highest = 32 - Integers.numberOfLeadingZeros(n);
// TODO Get addition/doubling cost ratio from curve and compare to 'scale' to see if worth substituting?
int scale = width - highest;
@@ -82,15 +84,4 @@ public class WNafL2RMultiplier extends AbstractECMultiplier
return R;
}
-
- /**
- * Determine window width to use for a scalar multiplication of the given size.
- *
- * @param bits the bit-length of the scalar to multiply by
- * @return the window size to use
- */
- protected int getWindowSize(int bits)
- {
- return WNafUtil.getWindowSize(bits);
- }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/WNafPreCompInfo.java b/bcprov/src/main/java/org/bouncycastle/math/ec/WNafPreCompInfo.java
index e8f16e65..a6808c1b 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/WNafPreCompInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/WNafPreCompInfo.java
@@ -6,6 +6,10 @@ package org.bouncycastle.math.ec;
*/
public class WNafPreCompInfo implements PreCompInfo
{
+ volatile int promotionCountdown = 4;
+
+ protected int confWidth = -1;
+
/**
* Array holding the precomputed <code>ECPoint</code>s used for a Window
* NAF multiplication.
@@ -24,6 +28,43 @@ public class WNafPreCompInfo implements PreCompInfo
*/
protected ECPoint twice = null;
+ protected int width = -1;
+
+ int decrementPromotionCountdown()
+ {
+ int t = promotionCountdown;
+ if (t > 0)
+ {
+ promotionCountdown = --t;
+ }
+ return t;
+ }
+
+ int getPromotionCountdown()
+ {
+ return promotionCountdown;
+ }
+
+ void setPromotionCountdown(int promotionCountdown)
+ {
+ this.promotionCountdown = promotionCountdown;
+ }
+
+ public boolean isPromoted()
+ {
+ return promotionCountdown <= 0;
+ }
+
+ public int getConfWidth()
+ {
+ return confWidth;
+ }
+
+ public void setConfWidth(int confWidth)
+ {
+ this.confWidth = confWidth;
+ }
+
public ECPoint[] getPreComp()
{
return preComp;
@@ -53,4 +94,14 @@ public class WNafPreCompInfo implements PreCompInfo
{
this.twice = twice;
}
+
+ public int getWidth()
+ {
+ return width;
+ }
+
+ public void setWidth(int width)
+ {
+ this.width = width;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/WNafUtil.java b/bcprov/src/main/java/org/bouncycastle/math/ec/WNafUtil.java
index f383308a..fb4d67ec 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/WNafUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/WNafUtil.java
@@ -7,11 +7,54 @@ public abstract class WNafUtil
public static final String PRECOMP_NAME = "bc_wnaf";
private static final int[] DEFAULT_WINDOW_SIZE_CUTOFFS = new int[]{ 13, 41, 121, 337, 897, 2305 };
+ private static final int MAX_WIDTH = 16;
private static final byte[] EMPTY_BYTES = new byte[0];
private static final int[] EMPTY_INTS = new int[0];
private static final ECPoint[] EMPTY_POINTS = new ECPoint[0];
+ public static void configureBasepoint(ECPoint p)
+ {
+ final ECCurve c = p.getCurve();
+ if (null == c)
+ {
+ return;
+ }
+
+ BigInteger n = c.getOrder();
+ int bits = (null == n) ? c.getFieldSize() + 1 : n.bitLength();
+ final int confWidth = Math.min(MAX_WIDTH, getWindowSize(bits) + 3);
+
+ c.precompute(p, PRECOMP_NAME, new PreCompCallback()
+ {
+ public PreCompInfo precompute(PreCompInfo existing)
+ {
+ WNafPreCompInfo existingWNaf = (existing instanceof WNafPreCompInfo) ? (WNafPreCompInfo)existing : null;
+
+ if (null != existingWNaf && existingWNaf.getConfWidth() == confWidth)
+ {
+ existingWNaf.setPromotionCountdown(0);
+ return existingWNaf;
+ }
+
+ WNafPreCompInfo result = new WNafPreCompInfo();
+
+ result.setPromotionCountdown(0);
+ result.setConfWidth(confWidth);
+
+ if (null != existingWNaf)
+ {
+ result.setPreComp(existingWNaf.getPreComp());
+ result.setPreCompNeg(existingWNaf.getPreCompNeg());
+ result.setTwice(existingWNaf.getTwice());
+ result.setWidth(existingWNaf.getWidth());
+ }
+
+ return result;
+ }
+ });
+ }
+
public static int[] generateCompactNaf(BigInteger k)
{
if ((k.bitLength() >>> 16) != 0)
@@ -315,7 +358,19 @@ public abstract class WNafUtil
*/
public static int getWindowSize(int bits)
{
- return getWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS);
+ return getWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS, MAX_WIDTH);
+ }
+
+ /**
+ * Determine window width to use for a scalar multiplication of the given size.
+ *
+ * @param bits the bit-length of the scalar to multiply by
+ * @param maxWidth the maximum window width to return
+ * @return the window size to use
+ */
+ public static int getWindowSize(int bits, int maxWidth)
+ {
+ return getWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS, maxWidth);
}
/**
@@ -327,6 +382,19 @@ public abstract class WNafUtil
*/
public static int getWindowSize(int bits, int[] windowSizeCutoffs)
{
+ return getWindowSize(bits, windowSizeCutoffs, MAX_WIDTH);
+ }
+
+ /**
+ * Determine window width to use for a scalar multiplication of the given size.
+ *
+ * @param bits the bit-length of the scalar to multiply by
+ * @param windowSizeCutoffs a monotonically increasing list of bit sizes at which to increment the window width
+ * @param maxWidth the maximum window width to return
+ * @return the window size to use
+ */
+ public static int getWindowSize(int bits, int[] windowSizeCutoffs, int maxWidth)
+ {
int w = 0;
for (; w < windowSizeCutoffs.length; ++w)
{
@@ -335,55 +403,11 @@ public abstract class WNafUtil
break;
}
}
- return w + 2;
- }
-
- public static ECPoint mapPointWithPrecomp(ECPoint p, final int width, final boolean includeNegated,
- final ECPointMap pointMap)
- {
- final ECCurve c = p.getCurve();
- final WNafPreCompInfo wnafPreCompP = precompute(p, width, includeNegated);
-
- ECPoint q = pointMap.map(p);
- c.precompute(q, PRECOMP_NAME, new PreCompCallback()
- {
- public PreCompInfo precompute(PreCompInfo existing)
- {
- WNafPreCompInfo result = new WNafPreCompInfo();
-
- ECPoint twiceP = wnafPreCompP.getTwice();
- if (twiceP != null)
- {
- ECPoint twiceQ = pointMap.map(twiceP);
- result.setTwice(twiceQ);
- }
-
- ECPoint[] preCompP = wnafPreCompP.getPreComp();
- ECPoint[] preCompQ = new ECPoint[preCompP.length];
- for (int i = 0; i < preCompP.length; ++i)
- {
- preCompQ[i] = pointMap.map(preCompP[i]);
- }
- result.setPreComp(preCompQ);
- if (includeNegated)
- {
- ECPoint[] preCompNegQ = new ECPoint[preCompQ.length];
- for (int i = 0; i < preCompNegQ.length; ++i)
- {
- preCompNegQ[i] = preCompQ[i].negate();
- }
- result.setPreCompNeg(preCompNegQ);
- }
-
- return result;
- }
- });
-
- return q;
+ return Math.max(2, Math.min(maxWidth, w + 2));
}
- public static WNafPreCompInfo precompute(final ECPoint p, final int width, final boolean includeNegated)
+ public static WNafPreCompInfo precompute(final ECPoint p, final int minWidth, final boolean includeNegated)
{
final ECCurve c = p.getCurve();
@@ -393,25 +417,38 @@ public abstract class WNafUtil
{
WNafPreCompInfo existingWNaf = (existing instanceof WNafPreCompInfo) ? (WNafPreCompInfo)existing : null;
- int reqPreCompLen = 1 << Math.max(0, width - 2);
+ int width = Math.max(2, Math.min(MAX_WIDTH, minWidth));
+ int reqPreCompLen = 1 << (width - 2);
- if (checkExisting(existingWNaf, reqPreCompLen, includeNegated))
+ if (checkExisting(existingWNaf, width, reqPreCompLen, includeNegated))
{
+ existingWNaf.decrementPromotionCountdown();
return existingWNaf;
}
+ WNafPreCompInfo result = new WNafPreCompInfo();
+
ECPoint[] preComp = null, preCompNeg = null;
ECPoint twiceP = null;
- if (existingWNaf != null)
+ if (null != existingWNaf)
{
+ int promotionCountdown = existingWNaf.decrementPromotionCountdown();
+ result.setPromotionCountdown(promotionCountdown);
+
+ int confWidth = existingWNaf.getConfWidth();
+ result.setConfWidth(confWidth);
+
preComp = existingWNaf.getPreComp();
preCompNeg = existingWNaf.getPreCompNeg();
twiceP = existingWNaf.getTwice();
}
+ width = Math.min(MAX_WIDTH, Math.max(result.getConfWidth(), width));
+ reqPreCompLen = 1 << (width - 2);
+
int iniPreCompLen = 0;
- if (preComp == null)
+ if (null == preComp)
{
preComp = EMPTY_POINTS;
}
@@ -446,7 +483,7 @@ public abstract class WNafUtil
else
{
ECPoint isoTwiceP = twiceP, last = preComp[curPreCompLen - 1];
- if (isoTwiceP == null)
+ if (null == isoTwiceP)
{
isoTwiceP = preComp[0].twice();
twiceP = isoTwiceP;
@@ -506,7 +543,7 @@ public abstract class WNafUtil
if (includeNegated)
{
int pos;
- if (preCompNeg == null)
+ if (null == preCompNeg)
{
pos = 0;
preCompNeg = new ECPoint[reqPreCompLen];
@@ -527,23 +564,96 @@ public abstract class WNafUtil
}
}
- WNafPreCompInfo result = new WNafPreCompInfo();
result.setPreComp(preComp);
result.setPreCompNeg(preCompNeg);
result.setTwice(twiceP);
+ result.setWidth(width);
+ return result;
+ }
+
+ private boolean checkExisting(WNafPreCompInfo existingWNaf, int width, int reqPreCompLen, boolean includeNegated)
+ {
+ return null != existingWNaf
+ && existingWNaf.getWidth() >= Math.max(existingWNaf.getConfWidth(), width)
+ && checkTable(existingWNaf.getPreComp(), reqPreCompLen)
+ && (!includeNegated || checkTable(existingWNaf.getPreCompNeg(), reqPreCompLen));
+ }
+
+ private boolean checkTable(ECPoint[] table, int reqLen)
+ {
+ return null != table && table.length >= reqLen;
+ }
+ });
+ }
+
+ public static WNafPreCompInfo precomputeWithPointMap(final ECPoint p, final ECPointMap pointMap, final WNafPreCompInfo fromWNaf,
+ final boolean includeNegated)
+ {
+ final ECCurve c = p.getCurve();
+
+ return (WNafPreCompInfo)c.precompute(p, PRECOMP_NAME, new PreCompCallback()
+ {
+ public PreCompInfo precompute(PreCompInfo existing)
+ {
+ WNafPreCompInfo existingWNaf = (existing instanceof WNafPreCompInfo) ? (WNafPreCompInfo)existing : null;
+
+ int width = fromWNaf.getWidth();
+ int reqPreCompLen = fromWNaf.getPreComp().length;
+
+ if (checkExisting(existingWNaf, width, reqPreCompLen, includeNegated))
+ {
+ existingWNaf.decrementPromotionCountdown();
+ return existingWNaf;
+ }
+
+ /*
+ * TODO Ideally this method would support incremental calculation, but given the
+ * existing use-cases it would be of little-to-no benefit.
+ */
+ WNafPreCompInfo result = new WNafPreCompInfo();
+
+ result.setPromotionCountdown(fromWNaf.getPromotionCountdown());
+
+ ECPoint twiceFrom = fromWNaf.getTwice();
+ if (null != twiceFrom)
+ {
+ ECPoint twice = pointMap.map(twiceFrom);
+ result.setTwice(twice);
+ }
+
+ ECPoint[] preCompFrom = fromWNaf.getPreComp();
+ ECPoint[] preComp = new ECPoint[preCompFrom.length];
+ for (int i = 0; i < preCompFrom.length; ++i)
+ {
+ preComp[i] = pointMap.map(preCompFrom[i]);
+ }
+ result.setPreComp(preComp);
+ result.setWidth(width);
+
+ if (includeNegated)
+ {
+ ECPoint[] preCompNeg = new ECPoint[preComp.length];
+ for (int i = 0; i < preCompNeg.length; ++i)
+ {
+ preCompNeg[i] = preComp[i].negate();
+ }
+ result.setPreCompNeg(preCompNeg);
+ }
+
return result;
}
- private boolean checkExisting(WNafPreCompInfo existingWNaf, int reqPreCompLen, boolean includeNegated)
+ private boolean checkExisting(WNafPreCompInfo existingWNaf, int width, int reqPreCompLen, boolean includeNegated)
{
- return existingWNaf != null
+ return null != existingWNaf
+ && existingWNaf.getWidth() >= width
&& checkTable(existingWNaf.getPreComp(), reqPreCompLen)
&& (!includeNegated || checkTable(existingWNaf.getPreCompNeg(), reqPreCompLen));
}
private boolean checkTable(ECPoint[] table, int reqLen)
{
- return table != null && table.length >= reqLen;
+ return null != table && table.length >= reqLen;
}
});
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java
index f160ab31..fa7fe83c 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java
@@ -1,7 +1,9 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.ec.AbstractECLookupTable;
import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
@@ -12,10 +14,10 @@ import org.bouncycastle.util.encoders.Hex;
public class SecP192K1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"));
+ public static final BigInteger q = SecP192K1FieldElement.Q;
- private static final int SecP192K1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final int SECP192K1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP192K1_AFFINE_ZS = new ECFieldElement[] { new SecP192K1FieldElement(ECConstants.ONE) };
protected SecP192K1Point infinity;
@@ -27,10 +29,10 @@ public class SecP192K1Curve extends ECCurve.AbstractFp
this.a = fromBigInteger(ECConstants.ZERO);
this.b = fromBigInteger(BigInteger.valueOf(3));
- this.order = new BigInteger(1, Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"));
this.cofactor = BigInteger.valueOf(1);
- this.coord = SecP192K1_DEFAULT_COORDS;
+ this.coord = SECP192K1_DEFAULT_COORDS;
}
protected ECCurve cloneCurve()
@@ -64,14 +66,14 @@ public class SecP192K1Curve extends ECCurve.AbstractFp
return new SecP192K1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP192K1Point(this, x, y, withCompression);
+ return new SecP192K1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP192K1Point(this, x, y, zs, withCompression);
+ return new SecP192K1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -94,7 +96,7 @@ public class SecP192K1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -119,8 +121,41 @@ public class SecP192K1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP192K1FieldElement(x), new SecP192K1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat192.create(), y = Nat192.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP192K1FieldElement(x), new SecP192K1FieldElement(y), SECP192K1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat192.create();
+ SecP192K1Field.random(r, x);
+ return new SecP192K1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat192.create();
+ SecP192K1Field.randomMult(r, x);
+ return new SecP192K1FieldElement(x);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java
index 1a0bde81..8b6c042f 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java
@@ -1,16 +1,19 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.math.raw.Nat192;
+import org.bouncycastle.util.Pack;
public class SecP192K1Field
{
// 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1
static final int[] P = new int[]{ 0xFFFFEE37, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- static final int[] PExt = new int[]{ 0x013C4FD1, 0x00002392, 0x00000001, 0x00000000, 0x00000000,
- 0x00000000, 0xFFFFDC6E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x013C4FD1, 0x00002392, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0xFFFFDC6E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
private static final int[] PExtInv = new int[]{ 0xFEC3B02F, 0xFFFFDC6D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0x00002391, 0x00000002 };
private static final int P5 = 0xFFFFFFFF;
@@ -70,6 +73,22 @@ public class SecP192K1Field
}
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 6; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat192.createExt();
@@ -91,9 +110,9 @@ public class SecP192K1Field
public static void negate(int[] x, int[] z)
{
- if (Nat192.isZero(x))
+ if (0 != isZero(x))
{
- Nat192.zero(z);
+ Nat192.sub(P, P, z);
}
else
{
@@ -101,6 +120,26 @@ public class SecP192K1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[6 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 6);
+ }
+ while (0 == Nat.lessThan(6, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
long cc = Nat192.mul33Add(PInv33, xx, 6, xx, 0, z, 0);
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java
index 39e62afa..b4999348 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java
@@ -3,13 +3,14 @@ package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
import org.bouncycastle.math.ec.ECFieldElement;
-import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat192;
import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.encoders.Hex;
public class SecP192K1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP192K1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"));
protected int[] x;
@@ -95,7 +96,7 @@ public class SecP192K1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat192.create();
- Mod.invert(SecP192K1Field.P, ((SecP192K1FieldElement)b).x, z);
+ SecP192K1Field.inv(((SecP192K1FieldElement)b).x, z);
SecP192K1Field.multiply(z, x, z);
return new SecP192K1FieldElement(z);
}
@@ -118,7 +119,7 @@ public class SecP192K1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP192K1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat192.create();
- Mod.invert(SecP192K1Field.P, x, z);
+ SecP192K1Field.inv(x, z);
return new SecP192K1FieldElement(z);
}
@@ -132,7 +133,7 @@ public class SecP192K1FieldElement extends ECFieldElement.AbstractFp
* Raise this element to the exponent 2^190 - 2^30 - 2^10 - 2^6 - 2^5 - 2^4 - 2^1
*
* Breaking up the exponent's binary representation into "repunits", we get:
- * { 159 1s } { 1 0s } { 19 1s } { 1 0s } { 3 1s } { 3 0s} { 3 1s } { 1 0s }
+ * { 159 1s } { 1 0s } { 19 1s } { 1 0s } { 3 1s } { 3 0s } { 3 1s } { 1 0s }
*
* Therefore we need an addition chain containing 3, 19, 159 (the lengths of the repunits)
* We use: 1, 2, [3], 6, 8, 16, [19], 35, 70, 140, [159]
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java
index e4ecf01d..a0f7e05d 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java
@@ -8,56 +8,14 @@ import org.bouncycastle.math.raw.Nat192;
public class SecP192K1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs,
- boolean withCompression)
+ SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -188,7 +146,7 @@ public class SecP192K1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
- return new SecP192K1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP192K1Point(curve, X3, Y3, zs);
}
// B.3 pg 62
@@ -248,7 +206,7 @@ public class SecP192K1Point extends ECPoint.AbstractFp
SecP192K1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP192K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, this.withCompression);
+ return new SecP192K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -293,6 +251,6 @@ public class SecP192K1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP192K1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP192K1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java
index a43a5966..d7ecc5b7 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java
@@ -1,7 +1,10 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.ec.AbstractECLookupTable;
+import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECLookupTable;
@@ -11,10 +14,10 @@ import org.bouncycastle.util.encoders.Hex;
public class SecP192R1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"));
+ public static final BigInteger q = SecP192R1FieldElement.Q;
- private static final int SecP192R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final int SECP192R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP192R1_AFFINE_ZS = new ECFieldElement[] { new SecP192R1FieldElement(ECConstants.ONE) };
protected SecP192R1Point infinity;
@@ -25,13 +28,13 @@ public class SecP192R1Curve extends ECCurve.AbstractFp
this.infinity = new SecP192R1Point(this, null, null);
this.a = fromBigInteger(new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")));
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")));
this.b = fromBigInteger(new BigInteger(1,
- Hex.decode("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")));
- this.order = new BigInteger(1, Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"));
+ Hex.decodeStrict("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"));
this.cofactor = BigInteger.valueOf(1);
- this.coord = SecP192R1_DEFAULT_COORDS;
+ this.coord = SECP192R1_DEFAULT_COORDS;
}
protected ECCurve cloneCurve()
@@ -65,14 +68,14 @@ public class SecP192R1Curve extends ECCurve.AbstractFp
return new SecP192R1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP192R1Point(this, x, y, withCompression);
+ return new SecP192R1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP192R1Point(this, x, y, zs, withCompression);
+ return new SecP192R1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -95,7 +98,7 @@ public class SecP192R1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -120,8 +123,41 @@ public class SecP192R1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP192R1FieldElement(x), new SecP192R1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat192.create(), y = Nat192.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP192R1FieldElement(x), new SecP192R1FieldElement(y), SECP192R1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat192.create();
+ SecP192R1Field.random(r, x);
+ return new SecP192R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat192.create();
+ SecP192R1Field.randomMult(r, x);
+ return new SecP192R1FieldElement(x);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java
index 75e2f5c2..5e0dd0d7 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java
@@ -1,9 +1,12 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.math.raw.Nat192;
+import org.bouncycastle.util.Pack;
public class SecP192R1Field
{
@@ -11,8 +14,8 @@ public class SecP192R1Field
// 2^192 - 2^64 - 1
static final int[] P = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001,
- 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000,
+ 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFE,
0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000002 };
private static final int P5 = 0xFFFFFFFF;
@@ -71,6 +74,22 @@ public class SecP192R1Field
}
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 6; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat192.createExt();
@@ -92,9 +111,9 @@ public class SecP192R1Field
public static void negate(int[] x, int[] z)
{
- if (Nat192.isZero(x))
+ if (0 != isZero(x))
{
- Nat192.zero(z);
+ Nat192.sub(P, P, z);
}
else
{
@@ -102,6 +121,26 @@ public class SecP192R1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[6 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 6);
+ }
+ while (0 == Nat.lessThan(6, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
long xx06 = xx[6] & M, xx07 = xx[7] & M, xx08 = xx[8] & M;
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java
index 15fdcd63..1540c4a9 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java
@@ -3,13 +3,14 @@ package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
import org.bouncycastle.math.ec.ECFieldElement;
-import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat192;
import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.encoders.Hex;
public class SecP192R1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP192R1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"));
protected int[] x;
@@ -95,7 +96,7 @@ public class SecP192R1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat192.create();
- Mod.invert(SecP192R1Field.P, ((SecP192R1FieldElement)b).x, z);
+ SecP192R1Field.inv(((SecP192R1FieldElement)b).x, z);
SecP192R1Field.multiply(z, x, z);
return new SecP192R1FieldElement(z);
}
@@ -118,7 +119,7 @@ public class SecP192R1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP192R1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat192.create();
- Mod.invert(SecP192R1Field.P, x, z);
+ SecP192R1Field.inv(x, z);
return new SecP192R1FieldElement(z);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java
index f60fc131..00fdd2c5 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java
@@ -8,55 +8,14 @@ import org.bouncycastle.math.raw.Nat192;
public class SecP192R1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -187,7 +146,7 @@ public class SecP192R1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
- return new SecP192R1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP192R1Point(curve, X3, Y3, zs);
}
// B.3 pg 62
@@ -260,7 +219,7 @@ public class SecP192R1Point extends ECPoint.AbstractFp
SecP192R1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP192R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new SecP192R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -305,6 +264,6 @@ public class SecP192R1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP192R1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP192R1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java
index 6b28be79..a48dfcb3 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java
@@ -1,7 +1,9 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.ec.AbstractECLookupTable;
import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
@@ -12,10 +14,10 @@ import org.bouncycastle.util.encoders.Hex;
public class SecP224K1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D"));
+ public static final BigInteger q = SecP224K1FieldElement.Q;
private static final int SECP224K1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP224K1_AFFINE_ZS = new ECFieldElement[] { new SecP224K1FieldElement(ECConstants.ONE) };
protected SecP224K1Point infinity;
@@ -27,7 +29,7 @@ public class SecP224K1Curve extends ECCurve.AbstractFp
this.a = fromBigInteger(ECConstants.ZERO);
this.b = fromBigInteger(BigInteger.valueOf(5));
- this.order = new BigInteger(1, Hex.decode("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7"));
+ this.order = new BigInteger(1, Hex.decodeStrict("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7"));
this.cofactor = BigInteger.valueOf(1);
this.coord = SECP224K1_DEFAULT_COORDS;
}
@@ -63,14 +65,14 @@ public class SecP224K1Curve extends ECCurve.AbstractFp
return new SecP224K1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP224K1Point(this, x, y, withCompression);
+ return new SecP224K1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP224K1Point(this, x, y, zs, withCompression);
+ return new SecP224K1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -93,7 +95,7 @@ public class SecP224K1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -118,8 +120,48 @@ public class SecP224K1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP224K1FieldElement(x), new SecP224K1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat224.create(), y = Nat224.create();
+ int pos = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ int MASK = ((i ^ index) - 1) >> 31;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] ^= table[pos + j] & MASK;
+ y[j] ^= table[pos + FE_INTS + j] & MASK;
+ }
+
+ pos += (FE_INTS * 2);
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP224K1FieldElement(x), new SecP224K1FieldElement(y), SECP224K1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat224.create();
+ SecP224K1Field.random(r, x);
+ return new SecP224K1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat224.create();
+ SecP224K1Field.randomMult(r, x);
+ return new SecP224K1FieldElement(x);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java
index 0146fec1..9427f934 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java
@@ -1,17 +1,20 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.math.raw.Nat224;
+import org.bouncycastle.util.Pack;
public class SecP224K1Field
{
// 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1
static final int[] P = new int[]{ 0xFFFFE56D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF };
- static final int[] PExt = new int[]{ 0x02C23069, 0x00003526, 0x00000001, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0xFFFFCADA, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x02C23069, 0x00003526, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xFFFFCADA, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
private static final int[] PExtInv = new int[]{ 0xFD3DCF97, 0xFFFFCAD9, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0x00003525, 0x00000002 };
private static final int P6 = 0xFFFFFFFF;
@@ -71,6 +74,22 @@ public class SecP224K1Field
}
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 7; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat224.createExt();
@@ -92,9 +111,9 @@ public class SecP224K1Field
public static void negate(int[] x, int[] z)
{
- if (Nat224.isZero(x))
+ if (0 != isZero(x))
{
- Nat224.zero(z);
+ Nat224.sub(P, P, z);
}
else
{
@@ -102,6 +121,26 @@ public class SecP224K1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[7 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 7);
+ }
+ while (0 == Nat.lessThan(7, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
long cc = Nat224.mul33Add(PInv33, xx, 7, xx, 0, z, 0);
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java
index 2093a061..e4cb310f 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java
@@ -3,13 +3,14 @@ package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
import org.bouncycastle.math.ec.ECFieldElement;
-import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat224;
import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.encoders.Hex;
public class SecP224K1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP224K1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D"));
// Calculated as ECConstants.TWO.modPow(Q.shiftRight(2), Q)
private static final int[] PRECOMP_POW2 = new int[]{ 0x33bfd202, 0xdcfad133, 0x2287624a, 0xc3811ba8,
@@ -99,7 +100,7 @@ public class SecP224K1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat224.create();
- Mod.invert(SecP224K1Field.P, ((SecP224K1FieldElement)b).x, z);
+ SecP224K1Field.inv(((SecP224K1FieldElement)b).x, z);
SecP224K1Field.multiply(z, x, z);
return new SecP224K1FieldElement(z);
}
@@ -122,7 +123,7 @@ public class SecP224K1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP224K1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat224.create();
- Mod.invert(SecP224K1Field.P, x, z);
+ SecP224K1Field.inv(x, z);
return new SecP224K1FieldElement(z);
}
@@ -139,7 +140,7 @@ public class SecP224K1FieldElement extends ECFieldElement.AbstractFp
* First, raise this element to the exponent 2^221 - 2^29 - 2^9 - 2^8 - 2^6 - 2^4 - 2^1 (i.e. m + 1)
*
* Breaking up the exponent's binary representation into "repunits", we get:
- * { 191 1s } { 1 0s } { 19 1s } { 2 0s } { 1 1s } { 1 0s} { 1 1s } { 1 0s} { 3 1s } { 1 0s}
+ * { 191 1s } { 1 0s } { 19 1s } { 2 0s } { 1 1s } { 1 0s } { 1 1s } { 1 0s } { 3 1s } { 1 0s }
*
* Therefore we need an addition chain containing 1, 3, 19, 191 (the lengths of the repunits)
* We use: [1], 2, [3], 4, 8, 11, [19], 23, 42, 84, 107, [191]
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java
index a4d37b5f..9fda6a20 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java
@@ -8,56 +8,14 @@ import org.bouncycastle.math.raw.Nat224;
public class SecP224K1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs,
- boolean withCompression)
+ SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -188,7 +146,7 @@ public class SecP224K1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
- return new SecP224K1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP224K1Point(curve, X3, Y3, zs);
}
// B.3 pg 62
@@ -248,7 +206,7 @@ public class SecP224K1Point extends ECPoint.AbstractFp
SecP224K1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP224K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, this.withCompression);
+ return new SecP224K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -293,6 +251,6 @@ public class SecP224K1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP224K1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP224K1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java
index febb323c..97df08c9 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java
@@ -1,7 +1,10 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.ec.AbstractECLookupTable;
+import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECLookupTable;
@@ -11,10 +14,10 @@ import org.bouncycastle.util.encoders.Hex;
public class SecP224R1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"));
+ public static final BigInteger q = SecP224R1FieldElement.Q;
- private static final int SecP224R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final int SECP224R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP224R1_AFFINE_ZS = new ECFieldElement[] { new SecP224R1FieldElement(ECConstants.ONE) };
protected SecP224R1Point infinity;
@@ -25,13 +28,13 @@ public class SecP224R1Curve extends ECCurve.AbstractFp
this.infinity = new SecP224R1Point(this, null, null);
this.a = fromBigInteger(new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")));
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")));
this.b = fromBigInteger(new BigInteger(1,
- Hex.decode("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")));
- this.order = new BigInteger(1, Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"));
+ Hex.decodeStrict("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"));
this.cofactor = BigInteger.valueOf(1);
- this.coord = SecP224R1_DEFAULT_COORDS;
+ this.coord = SECP224R1_DEFAULT_COORDS;
}
protected ECCurve cloneCurve()
@@ -65,14 +68,14 @@ public class SecP224R1Curve extends ECCurve.AbstractFp
return new SecP224R1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP224R1Point(this, x, y, withCompression);
+ return new SecP224R1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP224R1Point(this, x, y, zs, withCompression);
+ return new SecP224R1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -95,7 +98,7 @@ public class SecP224R1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -120,8 +123,41 @@ public class SecP224R1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP224R1FieldElement(x), new SecP224R1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat224.create(), y = Nat224.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP224R1FieldElement(x), new SecP224R1FieldElement(y), SECP224R1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat224.create();
+ SecP224R1Field.random(r, x);
+ return new SecP224R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat224.create();
+ SecP224R1Field.randomMult(r, x);
+ return new SecP224R1FieldElement(x);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java
index e05f6775..6ffc6275 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java
@@ -1,18 +1,22 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.math.raw.Nat224;
+import org.bouncycastle.util.Pack;
public class SecP224R1Field
{
private static final long M = 0xFFFFFFFFL;
// 2^224 - 2^96 + 1
- static final int[] P = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
- 0xFFFFFFFF, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ static final int[] P = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0x00000000,
0x00000000, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001 };
private static final int P6 = 0xFFFFFFFF;
@@ -71,6 +75,22 @@ public class SecP224R1Field
}
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 7; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat224.createExt();
@@ -92,9 +112,9 @@ public class SecP224R1Field
public static void negate(int[] x, int[] z)
{
- if (Nat224.isZero(x))
+ if (0 != isZero(x))
{
- Nat224.zero(z);
+ Nat224.sub(P, P, z);
}
else
{
@@ -102,6 +122,26 @@ public class SecP224R1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[7 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 7);
+ }
+ while (0 == Nat.lessThan(7, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
long xx10 = xx[10] & M, xx11 = xx[11] & M, xx12 = xx[12] & M, xx13 = xx[13] & M;
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java
index ed2334a7..351e69f8 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java
@@ -7,10 +7,12 @@ import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.math.raw.Nat224;
import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.encoders.Hex;
public class SecP224R1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP224R1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"));
protected int[] x;
@@ -96,7 +98,7 @@ public class SecP224R1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat224.create();
- Mod.invert(SecP224R1Field.P, ((SecP224R1FieldElement)b).x, z);
+ SecP224R1Field.inv(((SecP224R1FieldElement)b).x, z);
SecP224R1Field.multiply(z, x, z);
return new SecP224R1FieldElement(z);
}
@@ -119,7 +121,7 @@ public class SecP224R1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP224R1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat224.create();
- Mod.invert(SecP224R1Field.P, x, z);
+ SecP224R1Field.inv(x, z);
return new SecP224R1FieldElement(z);
}
@@ -262,7 +264,7 @@ public class SecP224R1FieldElement extends ECFieldElement.AbstractFp
if (Nat224.isZero(d1))
{
- Mod.invert(SecP224R1Field.P, e0, t);
+ SecP224R1Field.inv(e0, t);
SecP224R1Field.multiply(t, d0, t);
return true;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java
index 31da6f60..6472bb21 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java
@@ -8,55 +8,14 @@ import org.bouncycastle.math.raw.Nat224;
public class SecP224R1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -186,7 +145,7 @@ public class SecP224R1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
- return new SecP224R1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP224R1Point(curve, X3, Y3, zs);
}
public ECPoint twice()
@@ -258,7 +217,7 @@ public class SecP224R1Point extends ECPoint.AbstractFp
SecP224R1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP224R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new SecP224R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -303,6 +262,6 @@ public class SecP224R1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP224R1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP224R1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java
index 6235381e..46a7f0e7 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java
@@ -1,7 +1,9 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.ec.AbstractECLookupTable;
import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
@@ -12,10 +14,10 @@ import org.bouncycastle.util.encoders.Hex;
public class SecP256K1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"));
+ public static final BigInteger q = SecP256K1FieldElement.Q;
private static final int SECP256K1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP256K1_AFFINE_ZS = new ECFieldElement[] { new SecP256K1FieldElement(ECConstants.ONE) };
protected SecP256K1Point infinity;
@@ -27,7 +29,7 @@ public class SecP256K1Curve extends ECCurve.AbstractFp
this.a = fromBigInteger(ECConstants.ZERO);
this.b = fromBigInteger(BigInteger.valueOf(7));
- this.order = new BigInteger(1, Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"));
this.cofactor = BigInteger.valueOf(1);
this.coord = SECP256K1_DEFAULT_COORDS;
}
@@ -63,14 +65,14 @@ public class SecP256K1Curve extends ECCurve.AbstractFp
return new SecP256K1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP256K1Point(this, x, y, withCompression);
+ return new SecP256K1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP256K1Point(this, x, y, zs, withCompression);
+ return new SecP256K1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -93,7 +95,7 @@ public class SecP256K1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -118,8 +120,41 @@ public class SecP256K1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP256K1FieldElement(x), new SecP256K1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat256.create(), y = Nat256.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP256K1FieldElement(x), new SecP256K1FieldElement(y), SECP256K1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat256.create();
+ SecP256K1Field.random(r, x);
+ return new SecP256K1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat256.create();
+ SecP256K1Field.randomMult(r, x);
+ return new SecP256K1FieldElement(x);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
index c7b4def1..8afbb310 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
@@ -1,18 +1,21 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.math.raw.Nat256;
+import org.bouncycastle.util.Pack;
public class SecP256K1Field
{
// 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
static final int[] P = new int[]{ 0xFFFFFC2F, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF };
- static final int[] PExt = new int[]{ 0x000E90A1, 0x000007A2, 0x00000001, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0xFFFFF85E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x000E90A1, 0x000007A2, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xFFFFF85E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF };
private static final int[] PExtInv = new int[]{ 0xFFF16F5F, 0xFFFFF85D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000007A1, 0x00000002 };
private static final int P7 = 0xFFFFFFFF;
@@ -72,6 +75,22 @@ public class SecP256K1Field
}
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 8; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat256.createExt();
@@ -93,9 +112,9 @@ public class SecP256K1Field
public static void negate(int[] x, int[] z)
{
- if (Nat256.isZero(x))
+ if (0 != isZero(x))
{
- Nat256.zero(z);
+ Nat256.sub(P, P, z);
}
else
{
@@ -103,6 +122,26 @@ public class SecP256K1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[8 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 8);
+ }
+ while (0 == Nat.lessThan(8, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
long cc = Nat256.mul33Add(PInv33, xx, 8, xx, 0, z, 0);
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
index 30bca2e3..c04ce878 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
@@ -3,13 +3,14 @@ package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
import org.bouncycastle.math.ec.ECFieldElement;
-import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat256;
import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.encoders.Hex;
public class SecP256K1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP256K1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"));
protected int[] x;
@@ -95,7 +96,7 @@ public class SecP256K1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat256.create();
- Mod.invert(SecP256K1Field.P, ((SecP256K1FieldElement)b).x, z);
+ SecP256K1Field.inv(((SecP256K1FieldElement)b).x, z);
SecP256K1Field.multiply(z, x, z);
return new SecP256K1FieldElement(z);
}
@@ -118,7 +119,7 @@ public class SecP256K1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP256K1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat256.create();
- Mod.invert(SecP256K1Field.P, x, z);
+ SecP256K1Field.inv(x, z);
return new SecP256K1FieldElement(z);
}
@@ -133,7 +134,7 @@ public class SecP256K1FieldElement extends ECFieldElement.AbstractFp
* Raise this element to the exponent 2^254 - 2^30 - 2^7 - 2^6 - 2^5 - 2^4 - 2^2
*
* Breaking up the exponent's binary representation into "repunits", we get:
- * { 223 1s } { 1 0s } { 22 1s } { 4 0s } { 2 1s } { 2 0s}
+ * { 223 1s } { 1 0s } { 22 1s } { 4 0s } { 2 1s } { 2 0s }
*
* Therefore we need an addition chain containing 2, 22, 223 (the lengths of the repunits)
* We use: 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223]
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
index 43c9c558..0ec55e09 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
@@ -8,56 +8,14 @@ import org.bouncycastle.math.raw.Nat256;
public class SecP256K1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs,
- boolean withCompression)
+ SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -188,7 +146,7 @@ public class SecP256K1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
- return new SecP256K1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP256K1Point(curve, X3, Y3, zs);
}
// B.3 pg 62
@@ -248,7 +206,7 @@ public class SecP256K1Point extends ECPoint.AbstractFp
SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP256K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, this.withCompression);
+ return new SecP256K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -293,6 +251,6 @@ public class SecP256K1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP256K1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP256K1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java
index 7d7b51d5..26f3cb6f 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java
@@ -1,7 +1,10 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.ec.AbstractECLookupTable;
+import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECLookupTable;
@@ -11,10 +14,10 @@ import org.bouncycastle.util.encoders.Hex;
public class SecP256R1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"));
+ public static final BigInteger q = SecP256R1FieldElement.Q;
- private static final int SecP256R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final int SECP256R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP256R1_AFFINE_ZS = new ECFieldElement[] { new SecP256R1FieldElement(ECConstants.ONE) };
protected SecP256R1Point infinity;
@@ -25,13 +28,13 @@ public class SecP256R1Curve extends ECCurve.AbstractFp
this.infinity = new SecP256R1Point(this, null, null);
this.a = fromBigInteger(new BigInteger(1,
- Hex.decode("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")));
+ Hex.decodeStrict("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")));
this.b = fromBigInteger(new BigInteger(1,
- Hex.decode("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")));
- this.order = new BigInteger(1, Hex.decode("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"));
+ Hex.decodeStrict("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"));
this.cofactor = BigInteger.valueOf(1);
- this.coord = SecP256R1_DEFAULT_COORDS;
+ this.coord = SECP256R1_DEFAULT_COORDS;
}
protected ECCurve cloneCurve()
@@ -65,14 +68,14 @@ public class SecP256R1Curve extends ECCurve.AbstractFp
return new SecP256R1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP256R1Point(this, x, y, withCompression);
+ return new SecP256R1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP256R1Point(this, x, y, zs, withCompression);
+ return new SecP256R1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -95,7 +98,7 @@ public class SecP256R1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -120,8 +123,41 @@ public class SecP256R1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP256R1FieldElement(x), new SecP256R1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat256.create(), y = Nat256.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP256R1FieldElement(x), new SecP256R1FieldElement(y), SECP256R1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat256.create();
+ SecP256R1Field.random(r, x);
+ return new SecP256R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat256.create();
+ SecP256R1Field.randomMult(r, x);
+ return new SecP256R1FieldElement(x);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
index cea1af78..6b780fde 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
@@ -1,9 +1,12 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.math.raw.Nat256;
+import org.bouncycastle.util.Pack;
public class SecP256R1Field
{
@@ -12,9 +15,9 @@ public class SecP256R1Field
// 2^256 - 2^224 + 2^192 + 2^96 - 1
static final int[] P = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,
0x00000001, 0xFFFFFFFF };
- static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0x00000001, 0xFFFFFFFE,
- 0x00000002, 0xFFFFFFFE };
+ private static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0x00000001, 0xFFFFFFFE, 0x00000002,
+ 0xFFFFFFFE };
private static final int P7 = 0xFFFFFFFF;
private static final int PExt15s1 = 0xFFFFFFFE >>> 1;
@@ -68,6 +71,22 @@ public class SecP256R1Field
}
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 8; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat256.createExt();
@@ -86,9 +105,9 @@ public class SecP256R1Field
public static void negate(int[] x, int[] z)
{
- if (Nat256.isZero(x))
+ if (0 != isZero(x))
{
- Nat256.zero(z);
+ Nat256.sub(P, P, z);
}
else
{
@@ -96,6 +115,26 @@ public class SecP256R1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[8 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 8);
+ }
+ while (0 == Nat.lessThan(8, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
long xx08 = xx[8] & M, xx09 = xx[9] & M, xx10 = xx[10] & M, xx11 = xx[11] & M;
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
index 6be46f24..f2ad7851 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
@@ -3,13 +3,14 @@ package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
import org.bouncycastle.math.ec.ECFieldElement;
-import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat256;
import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.encoders.Hex;
public class SecP256R1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP256R1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"));
protected int[] x;
@@ -95,7 +96,7 @@ public class SecP256R1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat256.create();
- Mod.invert(SecP256R1Field.P, ((SecP256R1FieldElement)b).x, z);
+ SecP256R1Field.inv(((SecP256R1FieldElement)b).x, z);
SecP256R1Field.multiply(z, x, z);
return new SecP256R1FieldElement(z);
}
@@ -118,7 +119,7 @@ public class SecP256R1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP256R1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat256.create();
- Mod.invert(SecP256R1Field.P, x, z);
+ SecP256R1Field.inv(x, z);
return new SecP256R1FieldElement(z);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
index 78b5ff8f..7f39a4eb 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
@@ -8,55 +8,14 @@ import org.bouncycastle.math.raw.Nat256;
public class SecP256R1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -186,7 +145,7 @@ public class SecP256R1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
- return new SecP256R1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP256R1Point(curve, X3, Y3, zs);
}
public ECPoint twice()
@@ -258,7 +217,7 @@ public class SecP256R1Point extends ECPoint.AbstractFp
SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP256R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new SecP256R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -303,6 +262,6 @@ public class SecP256R1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP256R1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP256R1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java
index 7a5603d2..31012303 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java
@@ -1,7 +1,10 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.ec.AbstractECLookupTable;
+import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECLookupTable;
@@ -11,10 +14,10 @@ import org.bouncycastle.util.encoders.Hex;
public class SecP384R1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"));
+ public static final BigInteger q = SecP384R1FieldElement.Q;
- private static final int SecP384R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final int SECP384R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP384R1_AFFINE_ZS = new ECFieldElement[] { new SecP384R1FieldElement(ECConstants.ONE) };
protected SecP384R1Point infinity;
@@ -25,13 +28,13 @@ public class SecP384R1Curve extends ECCurve.AbstractFp
this.infinity = new SecP384R1Point(this, null, null);
this.a = fromBigInteger(new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")));
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")));
this.b = fromBigInteger(new BigInteger(1,
- Hex.decode("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")));
- this.order = new BigInteger(1, Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"));
+ Hex.decodeStrict("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"));
this.cofactor = BigInteger.valueOf(1);
- this.coord = SecP384R1_DEFAULT_COORDS;
+ this.coord = SECP384R1_DEFAULT_COORDS;
}
protected ECCurve cloneCurve()
@@ -65,14 +68,14 @@ public class SecP384R1Curve extends ECCurve.AbstractFp
return new SecP384R1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP384R1Point(this, x, y, withCompression);
+ return new SecP384R1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP384R1Point(this, x, y, zs, withCompression);
+ return new SecP384R1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -95,7 +98,7 @@ public class SecP384R1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -120,8 +123,41 @@ public class SecP384R1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP384R1FieldElement(x), new SecP384R1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat.create(FE_INTS), y = Nat.create(FE_INTS);
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP384R1FieldElement(x), new SecP384R1FieldElement(y), SECP384R1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat.create(12);
+ SecP384R1Field.random(r, x);
+ return new SecP384R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat.create(12);
+ SecP384R1Field.randomMult(r, x);
+ return new SecP384R1FieldElement(x);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
index 164a7957..83852e8d 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
@@ -1,9 +1,12 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.math.raw.Nat384;
+import org.bouncycastle.util.Pack;
public class SecP384R1Field
{
@@ -12,12 +15,12 @@ public class SecP384R1Field
// 2^384 - 2^128 - 2^96 + 2^32 - 1
static final int[] P = new int[]{ 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- static final int[] PExt = new int[]{ 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE,
+ private static final int[] PExt = new int[]{ 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE,
0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x00000001, 0x00000000,
0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0x00000001,
- 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0xFFFFFFFE, 0xFFFFFFFF,
- 0x00000001, 0x00000002 };
+ private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF,
+ 0x00000001, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0xFFFFFFFE,
+ 0xFFFFFFFF, 0x00000001, 0x00000002 };
private static final int P11 = 0xFFFFFFFF;
private static final int PExt23 = 0xFFFFFFFF;
@@ -74,6 +77,22 @@ public class SecP384R1Field
}
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 12; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat.create(24);
@@ -83,9 +102,9 @@ public class SecP384R1Field
public static void negate(int[] x, int[] z)
{
- if (Nat.isZero(12, x))
+ if (0 != isZero(x))
{
- Nat.zero(12, z);
+ Nat.sub(12, P, P, z);
}
else
{
@@ -93,6 +112,26 @@ public class SecP384R1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[12 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 12);
+ }
+ while (0 == Nat.lessThan(12, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
long xx16 = xx[16] & M, xx17 = xx[17] & M, xx18 = xx[18] & M, xx19 = xx[19] & M;
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
index 3116b443..77623c12 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
@@ -3,13 +3,14 @@ package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
import org.bouncycastle.math.ec.ECFieldElement;
-import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.encoders.Hex;
public class SecP384R1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP384R1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"));
protected int[] x;
@@ -95,7 +96,7 @@ public class SecP384R1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat.create(12);
- Mod.invert(SecP384R1Field.P, ((SecP384R1FieldElement)b).x, z);
+ SecP384R1Field.inv(((SecP384R1FieldElement)b).x, z);
SecP384R1Field.multiply(z, x, z);
return new SecP384R1FieldElement(z);
}
@@ -118,7 +119,7 @@ public class SecP384R1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP384R1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat.create(12);
- Mod.invert(SecP384R1Field.P, x, z);
+ SecP384R1Field.inv(x, z);
return new SecP384R1FieldElement(z);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
index 32c3b3f0..d234cb52 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
@@ -8,55 +8,14 @@ import org.bouncycastle.math.raw.Nat384;
public class SecP384R1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -187,7 +146,7 @@ public class SecP384R1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
- return new SecP384R1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP384R1Point(curve, X3, Y3, zs);
}
public ECPoint twice()
@@ -259,7 +218,7 @@ public class SecP384R1Point extends ECPoint.AbstractFp
SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP384R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new SecP384R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -304,6 +263,6 @@ public class SecP384R1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP384R1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP384R1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java
index 267defcf..720044b6 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java
@@ -1,7 +1,10 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.ec.AbstractECLookupTable;
+import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECLookupTable;
@@ -11,10 +14,10 @@ import org.bouncycastle.util.encoders.Hex;
public class SecP521R1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
+ public static final BigInteger q = SecP521R1FieldElement.Q;
- private static final int SecP521R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final int SECP521R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP521R1_AFFINE_ZS = new ECFieldElement[] { new SecP521R1FieldElement(ECConstants.ONE) };
protected SecP521R1Point infinity;
@@ -25,13 +28,13 @@ public class SecP521R1Curve extends ECCurve.AbstractFp
this.infinity = new SecP521R1Point(this, null, null);
this.a = fromBigInteger(new BigInteger(1,
- Hex.decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC")));
+ Hex.decodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC")));
this.b = fromBigInteger(new BigInteger(1,
- Hex.decode("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00")));
- this.order = new BigInteger(1, Hex.decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"));
+ Hex.decodeStrict("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00")));
+ this.order = new BigInteger(1, Hex.decodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"));
this.cofactor = BigInteger.valueOf(1);
- this.coord = SecP521R1_DEFAULT_COORDS;
+ this.coord = SECP521R1_DEFAULT_COORDS;
}
protected ECCurve cloneCurve()
@@ -65,14 +68,14 @@ public class SecP521R1Curve extends ECCurve.AbstractFp
return new SecP521R1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP521R1Point(this, x, y, withCompression);
+ return new SecP521R1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP521R1Point(this, x, y, zs, withCompression);
+ return new SecP521R1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -95,7 +98,7 @@ public class SecP521R1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -120,8 +123,41 @@ public class SecP521R1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP521R1FieldElement(x), new SecP521R1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat.create(FE_INTS), y = Nat.create(FE_INTS);
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] ^= table[pos + j];
+ y[j] ^= table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP521R1FieldElement(x), new SecP521R1FieldElement(y), SECP521R1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat.create(17);
+ SecP521R1Field.random(r, x);
+ return new SecP521R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat.create(17);
+ SecP521R1Field.randomMult(r, x);
+ return new SecP521R1FieldElement(x);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
index 00f10667..62f25917 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
@@ -1,9 +1,12 @@
package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.math.raw.Nat512;
+import org.bouncycastle.util.Pack;
public class SecP521R1Field
{
@@ -51,6 +54,22 @@ public class SecP521R1Field
z[16] = (x16 >>> 1) | (c >>> 23);
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 17; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat.create(33);
@@ -60,9 +79,9 @@ public class SecP521R1Field
public static void negate(int[] x, int[] z)
{
- if (Nat.isZero(17, x))
+ if (0 != isZero(x))
{
- Nat.zero(17, z);
+ Nat.sub(17, P, P, z);
}
else
{
@@ -70,6 +89,27 @@ public class SecP521R1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[17 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 17);
+ z[16] &= P16;
+ }
+ while (0 == Nat.lessThan(17, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
// assert xx[32] >>> 18 == 0;
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
index 5cf30fc0..be52b34b 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
@@ -3,13 +3,14 @@ package org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
import org.bouncycastle.math.ec.ECFieldElement;
-import org.bouncycastle.math.raw.Mod;
import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.encoders.Hex;
public class SecP521R1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP521R1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
protected int[] x;
@@ -95,7 +96,7 @@ public class SecP521R1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat.create(17);
- Mod.invert(SecP521R1Field.P, ((SecP521R1FieldElement)b).x, z);
+ SecP521R1Field.inv(((SecP521R1FieldElement)b).x, z);
SecP521R1Field.multiply(z, x, z);
return new SecP521R1FieldElement(z);
}
@@ -118,7 +119,7 @@ public class SecP521R1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP521R1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat.create(17);
- Mod.invert(SecP521R1Field.P, x, z);
+ SecP521R1Field.inv(x, z);
return new SecP521R1FieldElement(z);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
index d0445fa7..d695cda8 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
@@ -7,55 +7,14 @@ import org.bouncycastle.math.raw.Nat;
public class SecP521R1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -182,7 +141,7 @@ public class SecP521R1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
- return new SecP521R1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP521R1Point(curve, X3, Y3, zs);
}
public ECPoint twice()
@@ -253,7 +212,7 @@ public class SecP521R1Point extends ECPoint.AbstractFp
SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP521R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new SecP521R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -328,6 +287,6 @@ public class SecP521R1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP521R1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP521R1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/endo/EndoPreCompInfo.java b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/EndoPreCompInfo.java
new file mode 100644
index 00000000..1c9e184b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/EndoPreCompInfo.java
@@ -0,0 +1,31 @@
+package org.bouncycastle.math.ec.endo;
+
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.ec.PreCompInfo;
+
+public class EndoPreCompInfo implements PreCompInfo
+{
+ protected ECEndomorphism endomorphism;
+
+ protected ECPoint mappedPoint;
+
+ public ECEndomorphism getEndomorphism()
+ {
+ return endomorphism;
+ }
+
+ public void setEndomorphism(ECEndomorphism endomorphism)
+ {
+ this.endomorphism = endomorphism;
+ }
+
+ public ECPoint getMappedPoint()
+ {
+ return mappedPoint;
+ }
+
+ public void setMappedPoint(ECPoint mappedPoint)
+ {
+ this.mappedPoint = mappedPoint;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/endo/EndoUtil.java b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/EndoUtil.java
new file mode 100644
index 00000000..9cc24289
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/EndoUtil.java
@@ -0,0 +1,73 @@
+package org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.math.ec.ECConstants;
+import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.ec.PreCompCallback;
+import org.bouncycastle.math.ec.PreCompInfo;
+
+public abstract class EndoUtil
+{
+ public static final String PRECOMP_NAME = "bc_endo";
+
+ public static BigInteger[] decomposeScalar(ScalarSplitParameters p, BigInteger k)
+ {
+ int bits = p.getBits();
+ BigInteger b1 = calculateB(k, p.getG1(), bits);
+ BigInteger b2 = calculateB(k, p.getG2(), bits);
+
+ BigInteger a = k.subtract((b1.multiply(p.getV1A())).add(b2.multiply(p.getV2A())));
+ BigInteger b = (b1.multiply(p.getV1B())).add(b2.multiply(p.getV2B())).negate();
+
+ return new BigInteger[]{ a, b };
+ }
+
+ public static ECPoint mapPoint(final ECEndomorphism endomorphism, final ECPoint p)
+ {
+ final ECCurve c = p.getCurve();
+
+ EndoPreCompInfo precomp = (EndoPreCompInfo)c.precompute(p, PRECOMP_NAME, new PreCompCallback()
+ {
+ public PreCompInfo precompute(PreCompInfo existing)
+ {
+ EndoPreCompInfo existingEndo = (existing instanceof EndoPreCompInfo) ? (EndoPreCompInfo)existing : null;
+
+ if (checkExisting(existingEndo, endomorphism))
+ {
+ return existingEndo;
+ }
+
+ ECPoint mappedPoint = endomorphism.getPointMap().map(p);
+
+ EndoPreCompInfo result = new EndoPreCompInfo();
+ result.setEndomorphism(endomorphism);
+ result.setMappedPoint(mappedPoint);
+ return result;
+ }
+
+ private boolean checkExisting(EndoPreCompInfo existingEndo, ECEndomorphism endomorphism)
+ {
+ return null != existingEndo
+ && existingEndo.getEndomorphism() == endomorphism
+ && existingEndo.getMappedPoint() != null;
+ }
+ });
+
+ return precomp.getMappedPoint();
+ }
+
+ private static BigInteger calculateB(BigInteger k, BigInteger g, int t)
+ {
+ boolean negative = (g.signum() < 0);
+ BigInteger b = k.multiply(g.abs());
+ boolean extra = b.testBit(t - 1);
+ b = b.shiftRight(t);
+ if (extra)
+ {
+ b = b.add(ECConstants.ONE);
+ }
+ return negative ? b.negate() : b;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeAEndomorphism.java b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeAEndomorphism.java
new file mode 100644
index 00000000..32cf52a0
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeAEndomorphism.java
@@ -0,0 +1,40 @@
+package org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.ECPointMap;
+import org.bouncycastle.math.ec.ScaleYNegateXPointMap;
+
+public class GLVTypeAEndomorphism implements GLVEndomorphism
+{
+ protected final GLVTypeAParameters parameters;
+ protected final ECPointMap pointMap;
+
+ public GLVTypeAEndomorphism(ECCurve curve, GLVTypeAParameters parameters)
+ {
+ /*
+ * NOTE: 'curve' MUST only be used to create a suitable ECFieldElement. Due to the way
+ * ECCurve configuration works, 'curve' will not be the actual instance of ECCurve that the
+ * endomorphism is being used with.
+ */
+
+ this.parameters = parameters;
+ this.pointMap = new ScaleYNegateXPointMap(curve.fromBigInteger(parameters.getI()));
+ }
+
+ public BigInteger[] decomposeScalar(BigInteger k)
+ {
+ return EndoUtil.decomposeScalar(parameters.getSplitParams(), k);
+ }
+
+ public ECPointMap getPointMap()
+ {
+ return pointMap;
+ }
+
+ public boolean hasEfficientPointMap()
+ {
+ return true;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeAParameters.java b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeAParameters.java
new file mode 100644
index 00000000..c23f3ca4
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeAParameters.java
@@ -0,0 +1,31 @@
+package org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+public class GLVTypeAParameters
+{
+ protected final BigInteger i, lambda;
+ protected final ScalarSplitParameters splitParams;
+
+ public GLVTypeAParameters(BigInteger i, BigInteger lambda, ScalarSplitParameters splitParams)
+ {
+ this.i = i;
+ this.lambda = lambda;
+ this.splitParams = splitParams;
+ }
+
+ public BigInteger getI()
+ {
+ return i;
+ }
+
+ public BigInteger getLambda()
+ {
+ return lambda;
+ }
+
+ public ScalarSplitParameters getSplitParams()
+ {
+ return splitParams;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java
index 38591c05..e9c25337 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java
@@ -2,35 +2,30 @@ package org.bouncycastle.math.ec.endo;
import java.math.BigInteger;
-import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPointMap;
import org.bouncycastle.math.ec.ScaleXPointMap;
public class GLVTypeBEndomorphism implements GLVEndomorphism
{
- protected final ECCurve curve;
protected final GLVTypeBParameters parameters;
protected final ECPointMap pointMap;
public GLVTypeBEndomorphism(ECCurve curve, GLVTypeBParameters parameters)
{
- this.curve = curve;
+ /*
+ * NOTE: 'curve' MUST only be used to create a suitable ECFieldElement. Due to the way
+ * ECCurve configuration works, 'curve' will not be the actual instance of ECCurve that the
+ * endomorphism is being used with.
+ */
+
this.parameters = parameters;
this.pointMap = new ScaleXPointMap(curve.fromBigInteger(parameters.getBeta()));
}
public BigInteger[] decomposeScalar(BigInteger k)
{
- int bits = parameters.getBits();
- BigInteger b1 = calculateB(k, parameters.getG1(), bits);
- BigInteger b2 = calculateB(k, parameters.getG2(), bits);
-
- GLVTypeBParameters p = parameters;
- BigInteger a = k.subtract((b1.multiply(p.getV1A())).add(b2.multiply(p.getV2A())));
- BigInteger b = (b1.multiply(p.getV1B())).add(b2.multiply(p.getV2B())).negate();
-
- return new BigInteger[]{ a, b };
+ return EndoUtil.decomposeScalar(parameters.getSplitParams(), k);
}
public ECPointMap getPointMap()
@@ -42,17 +37,4 @@ public class GLVTypeBEndomorphism implements GLVEndomorphism
{
return true;
}
-
- protected BigInteger calculateB(BigInteger k, BigInteger g, int t)
- {
- boolean negative = (g.signum() < 0);
- BigInteger b = k.multiply(g.abs());
- boolean extra = b.testBit(t - 1);
- b = b.shiftRight(t);
- if (extra)
- {
- b = b.add(ECConstants.ONE);
- }
- return negative ? b.negate() : b;
- }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
index 92c175ab..55cc4c88 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
@@ -4,35 +4,25 @@ import java.math.BigInteger;
public class GLVTypeBParameters
{
- private static void checkVector(BigInteger[] v, String name)
- {
- if (v == null || v.length != 2 || v[0] == null || v[1] == null)
- {
- throw new IllegalArgumentException("'" + name + "' must consist of exactly 2 (non-null) values");
- }
- }
-
- protected final BigInteger beta;
- protected final BigInteger lambda;
- protected final BigInteger v1A, v1B, v2A, v2B;
- protected final BigInteger g1, g2;
- protected final int bits;
+ protected final BigInteger beta, lambda;
+ protected final ScalarSplitParameters splitParams;
+ /**
+ * @deprecated Use constructor taking a {@link ScalarSplitParameters} instead.
+ */
public GLVTypeBParameters(BigInteger beta, BigInteger lambda, BigInteger[] v1, BigInteger[] v2, BigInteger g1,
BigInteger g2, int bits)
{
- checkVector(v1, "v1");
- checkVector(v2, "v2");
+ this.beta = beta;
+ this.lambda = lambda;
+ this.splitParams = new ScalarSplitParameters(v1, v2, g1, g2, bits);
+ }
+ public GLVTypeBParameters(BigInteger beta, BigInteger lambda, ScalarSplitParameters splitParams)
+ {
this.beta = beta;
this.lambda = lambda;
- this.v1A = v1[0];
- this.v1B = v1[1];
- this.v2A = v2[0];
- this.v2B = v2[1];
- this.g1 = g1;
- this.g2 = g2;
- this.bits = bits;
+ this.splitParams = splitParams;
}
public BigInteger getBeta()
@@ -45,54 +35,64 @@ public class GLVTypeBParameters
return lambda;
}
- /**
- * @deprecated Use {@link #getV1A()} and {@link #getV1B()} instead.
- */
- public BigInteger[] getV1()
+ public ScalarSplitParameters getSplitParams()
{
- return new BigInteger[]{ v1A, v1B };
+ return splitParams;
}
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
public BigInteger getV1A()
{
- return v1A;
+ return getSplitParams().getV1A();
}
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
public BigInteger getV1B()
{
- return v1B;
+ return getSplitParams().getV1B();
}
/**
- * @deprecated Use {@link #getV2A()} and {@link #getV2B()} instead.
+ * @deprecated Access via {@link #getSplitParams()} instead.
*/
- public BigInteger[] getV2()
- {
- return new BigInteger[]{ v2A, v2B };
- }
-
public BigInteger getV2A()
{
- return v2A;
+ return getSplitParams().getV2A();
}
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
public BigInteger getV2B()
{
- return v2B;
+ return getSplitParams().getV2B();
}
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
public BigInteger getG1()
{
- return g1;
+ return getSplitParams().getG1();
}
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
public BigInteger getG2()
{
- return g2;
+ return getSplitParams().getG2();
}
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
public int getBits()
{
- return bits;
+ return getSplitParams().getBits();
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/endo/ScalarSplitParameters.java b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/ScalarSplitParameters.java
new file mode 100644
index 00000000..5004eed7
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/endo/ScalarSplitParameters.java
@@ -0,0 +1,68 @@
+package org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+public class ScalarSplitParameters
+{
+ private static void checkVector(BigInteger[] v, String name)
+ {
+ if (v == null || v.length != 2 || v[0] == null || v[1] == null)
+ {
+ throw new IllegalArgumentException("'" + name + "' must consist of exactly 2 (non-null) values");
+ }
+ }
+
+ protected final BigInteger v1A, v1B, v2A, v2B;
+ protected final BigInteger g1, g2;
+ protected final int bits;
+
+ public ScalarSplitParameters(BigInteger[] v1, BigInteger[] v2, BigInteger g1,
+ BigInteger g2, int bits)
+ {
+ checkVector(v1, "v1");
+ checkVector(v2, "v2");
+
+ this.v1A = v1[0];
+ this.v1B = v1[1];
+ this.v2A = v2[0];
+ this.v2B = v2[1];
+ this.g1 = g1;
+ this.g2 = g2;
+ this.bits = bits;
+ }
+
+ public BigInteger getV1A()
+ {
+ return v1A;
+ }
+
+ public BigInteger getV1B()
+ {
+ return v1B;
+ }
+
+ public BigInteger getV2A()
+ {
+ return v2A;
+ }
+
+ public BigInteger getV2B()
+ {
+ return v2B;
+ }
+
+ public BigInteger getG1()
+ {
+ return g1;
+ }
+
+ public BigInteger getG2()
+ {
+ return g2;
+ }
+
+ public int getBits()
+ {
+ return bits;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/field/FiniteFields.java b/bcprov/src/main/java/org/bouncycastle/math/field/FiniteFields.java
index 7197ffd0..c71eda7f 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/field/FiniteFields.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/field/FiniteFields.java
@@ -17,7 +17,7 @@ public abstract class FiniteFields
{
if (exponents[i] <= exponents[i - 1])
{
- throw new IllegalArgumentException("Polynomial exponents must be montonically increasing");
+ throw new IllegalArgumentException("Polynomial exponents must be monotonically increasing");
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/raw/Bits.java b/bcprov/src/main/java/org/bouncycastle/math/raw/Bits.java
new file mode 100644
index 00000000..322a73cf
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Bits.java
@@ -0,0 +1,26 @@
+package org.bouncycastle.math.raw;
+
+public abstract class Bits
+{
+ public static int bitPermuteStep(int x, int m, int s)
+ {
+ int t = (x ^ (x >>> s)) & m;
+ return (t ^ (t << s)) ^ x;
+ }
+
+ public static long bitPermuteStep(long x, long m, int s)
+ {
+ long t = (x ^ (x >>> s)) & m;
+ return (t ^ (t << s)) ^ x;
+ }
+
+ public static int bitPermuteStepSimple(int x, int m, int s)
+ {
+ return ((x & m) << s) | ((x >>> s) & m);
+ }
+
+ public static long bitPermuteStepSimple(long x, long m, int s)
+ {
+ return ((x & m) << s) | ((x >>> s) & m);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/raw/Interleave.java b/bcprov/src/main/java/org/bouncycastle/math/raw/Interleave.java
index 85f4f6d6..0f693a55 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Interleave.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Interleave.java
@@ -70,11 +70,10 @@ public class Interleave
public static long expand32to64(int x)
{
// "shuffle" low half to even bits and high half to odd bits
- int t;
- t = (x ^ (x >>> 8)) & 0x0000FF00; x ^= (t ^ (t << 8));
- t = (x ^ (x >>> 4)) & 0x00F000F0; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 2)) & 0x0C0C0C0C; x ^= (t ^ (t << 2));
- t = (x ^ (x >>> 1)) & 0x22222222; x ^= (t ^ (t << 1));
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C, 2);
+ x = Bits.bitPermuteStep(x, 0x22222222, 1);
return ((x >>> 1) & M32) << 32 | (x & M32);
}
@@ -82,26 +81,33 @@ public class Interleave
public static void expand64To128(long x, long[] z, int zOff)
{
// "shuffle" low half to even bits and high half to odd bits
- long t;
- t = (x ^ (x >>> 16)) & 0x00000000FFFF0000L; x ^= (t ^ (t << 16));
- t = (x ^ (x >>> 8)) & 0x0000FF000000FF00L; x ^= (t ^ (t << 8));
- t = (x ^ (x >>> 4)) & 0x00F000F000F000F0L; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 2)) & 0x0C0C0C0C0C0C0C0CL; x ^= (t ^ (t << 2));
- t = (x ^ (x >>> 1)) & 0x2222222222222222L; x ^= (t ^ (t << 1));
+ x = Bits.bitPermuteStep(x, 0x00000000FFFF0000L, 16);
+ x = Bits.bitPermuteStep(x, 0x0000FF000000FF00L, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F000F000F0L, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C0C0C0C0CL, 2);
+ x = Bits.bitPermuteStep(x, 0x2222222222222222L, 1);
z[zOff ] = (x ) & M64;
z[zOff + 1] = (x >>> 1) & M64;
}
+ public static void expand64To128(long[] xs, int xsOff, int xsLen, long[] zs, int zsOff)
+ {
+ for (int i = 0; i < xsLen; ++i)
+ {
+ expand64To128(xs[xsOff + i], zs, zsOff);
+ zsOff += 2;
+ }
+ }
+
public static void expand64To128Rev(long x, long[] z, int zOff)
{
// "shuffle" low half to even bits and high half to odd bits
- long t;
- t = (x ^ (x >>> 16)) & 0x00000000FFFF0000L; x ^= (t ^ (t << 16));
- t = (x ^ (x >>> 8)) & 0x0000FF000000FF00L; x ^= (t ^ (t << 8));
- t = (x ^ (x >>> 4)) & 0x00F000F000F000F0L; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 2)) & 0x0C0C0C0C0C0C0C0CL; x ^= (t ^ (t << 2));
- t = (x ^ (x >>> 1)) & 0x2222222222222222L; x ^= (t ^ (t << 1));
+ x = Bits.bitPermuteStep(x, 0x00000000FFFF0000L, 16);
+ x = Bits.bitPermuteStep(x, 0x0000FF000000FF00L, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F000F000F0L, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C0C0C0C0CL, 2);
+ x = Bits.bitPermuteStep(x, 0x2222222222222222L, 1);
z[zOff ] = (x ) & M64R;
z[zOff + 1] = (x << 1) & M64R;
@@ -110,68 +116,97 @@ public class Interleave
public static int shuffle(int x)
{
// "shuffle" low half to even bits and high half to odd bits
- int t;
- t = (x ^ (x >>> 8)) & 0x0000FF00; x ^= (t ^ (t << 8));
- t = (x ^ (x >>> 4)) & 0x00F000F0; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 2)) & 0x0C0C0C0C; x ^= (t ^ (t << 2));
- t = (x ^ (x >>> 1)) & 0x22222222; x ^= (t ^ (t << 1));
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C, 2);
+ x = Bits.bitPermuteStep(x, 0x22222222, 1);
return x;
}
public static long shuffle(long x)
{
// "shuffle" low half to even bits and high half to odd bits
- long t;
- t = (x ^ (x >>> 16)) & 0x00000000FFFF0000L; x ^= (t ^ (t << 16));
- t = (x ^ (x >>> 8)) & 0x0000FF000000FF00L; x ^= (t ^ (t << 8));
- t = (x ^ (x >>> 4)) & 0x00F000F000F000F0L; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 2)) & 0x0C0C0C0C0C0C0C0CL; x ^= (t ^ (t << 2));
- t = (x ^ (x >>> 1)) & 0x2222222222222222L; x ^= (t ^ (t << 1));
+ x = Bits.bitPermuteStep(x, 0x00000000FFFF0000L, 16);
+ x = Bits.bitPermuteStep(x, 0x0000FF000000FF00L, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F000F000F0L, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C0C0C0C0CL, 2);
+ x = Bits.bitPermuteStep(x, 0x2222222222222222L, 1);
return x;
}
public static int shuffle2(int x)
{
// "shuffle" (twice) low half to even bits and high half to odd bits
- int t;
- t = (x ^ (x >>> 7)) & 0x00AA00AA; x ^= (t ^ (t << 7));
- t = (x ^ (x >>> 14)) & 0x0000CCCC; x ^= (t ^ (t << 14));
- t = (x ^ (x >>> 4)) & 0x00F000F0; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 8)) & 0x0000FF00; x ^= (t ^ (t << 8));
+ x = Bits.bitPermuteStep(x, 0x00AA00AA, 7);
+ x = Bits.bitPermuteStep(x, 0x0000CCCC, 14);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
+ return x;
+ }
+
+ public static long shuffle2(long x)
+ {
+ // "shuffle" (twice) low half to even bits and high half to odd bits
+ x = Bits.bitPermuteStep(x, 0x00000000FF00FF00L, 24);
+ x = Bits.bitPermuteStep(x, 0x00CC00CC00CC00CCL, 6);
+ x = Bits.bitPermuteStep(x, 0x0000F0F00000F0F0L, 12);
+ x = Bits.bitPermuteStep(x, 0x0A0A0A0A0A0A0A0AL, 3);
+ return x;
+ }
+
+ public static long shuffle3(long x)
+ {
+ // "shuffle" (thrice) low half to even bits and high half to odd bits
+ x = Bits.bitPermuteStep(x, 0x00AA00AA00AA00AAL, 7);
+ x = Bits.bitPermuteStep(x, 0x0000CCCC0000CCCCL, 14);
+ x = Bits.bitPermuteStep(x, 0x00000000F0F0F0F0L, 28);
return x;
}
public static int unshuffle(int x)
{
// "unshuffle" even bits to low half and odd bits to high half
- int t;
- t = (x ^ (x >>> 1)) & 0x22222222; x ^= (t ^ (t << 1));
- t = (x ^ (x >>> 2)) & 0x0C0C0C0C; x ^= (t ^ (t << 2));
- t = (x ^ (x >>> 4)) & 0x00F000F0; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 8)) & 0x0000FF00; x ^= (t ^ (t << 8));
+ x = Bits.bitPermuteStep(x, 0x22222222, 1);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C, 2);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
return x;
}
public static long unshuffle(long x)
{
// "unshuffle" even bits to low half and odd bits to high half
- long t;
- t = (x ^ (x >>> 1)) & 0x2222222222222222L; x ^= (t ^ (t << 1));
- t = (x ^ (x >>> 2)) & 0x0C0C0C0C0C0C0C0CL; x ^= (t ^ (t << 2));
- t = (x ^ (x >>> 4)) & 0x00F000F000F000F0L; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 8)) & 0x0000FF000000FF00L; x ^= (t ^ (t << 8));
- t = (x ^ (x >>> 16)) & 0x00000000FFFF0000L; x ^= (t ^ (t << 16));
+ x = Bits.bitPermuteStep(x, 0x2222222222222222L, 1);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C0C0C0C0CL, 2);
+ x = Bits.bitPermuteStep(x, 0x00F000F000F000F0L, 4);
+ x = Bits.bitPermuteStep(x, 0x0000FF000000FF00L, 8);
+ x = Bits.bitPermuteStep(x, 0x00000000FFFF0000L, 16);
return x;
}
public static int unshuffle2(int x)
{
// "unshuffle" (twice) even bits to low half and odd bits to high half
- int t;
- t = (x ^ (x >>> 8)) & 0x0000FF00; x ^= (t ^ (t << 8));
- t = (x ^ (x >>> 4)) & 0x00F000F0; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 14)) & 0x0000CCCC; x ^= (t ^ (t << 14));
- t = (x ^ (x >>> 7)) & 0x00AA00AA; x ^= (t ^ (t << 7));
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0000CCCC, 14);
+ x = Bits.bitPermuteStep(x, 0x00AA00AA, 7);
+ return x;
+ }
+
+ public static long unshuffle2(long x)
+ {
+ // "unshuffle" (twice) even bits to low half and odd bits to high half
+ x = Bits.bitPermuteStep(x, 0x0A0A0A0A0A0A0A0AL, 3);
+ x = Bits.bitPermuteStep(x, 0x0000F0F00000F0F0L, 12);
+ x = Bits.bitPermuteStep(x, 0x00CC00CC00CC00CCL, 6);
+ x = Bits.bitPermuteStep(x, 0x00000000FF00FF00L, 24);
return x;
}
+
+ public static long unshuffle3(long x)
+ {
+ // "unshuffle" (thrice) even bits to low half and odd bits to high half
+ return shuffle3(x);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/raw/Mod.java b/bcprov/src/main/java/org/bouncycastle/math/raw/Mod.java
index 47e6d8c6..fc8f3c87 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Mod.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Mod.java
@@ -2,12 +2,48 @@ package org.bouncycastle.math.raw;
import java.util.Random;
-import org.bouncycastle.util.Pack;
+import org.bouncycastle.util.Integers;
+
+/*
+ * Modular inversion as implemented in this class is based on the paper "Fast constant-time gcd
+ * computation and modular inversion" by Daniel J. Bernstein and Bo-Yin Yang.
+ */
public abstract class Mod
{
+ private static final int M30 = 0x3FFFFFFF;
+ private static final long M32L = 0xFFFFFFFFL;
+
+ /** @deprecated Will be removed. */
+ public static void add(int[] p, int[] x, int[] y, int[] z)
+ {
+ int len = p.length;
+ int c = Nat.add(len, x, y, z);
+ if (c != 0)
+ {
+ Nat.subFrom(len, p, z);
+ }
+ }
+
+ public static void checkedModOddInverse(int[] m, int[] x, int[] z)
+ {
+ if (0 == modOddInverse(m, x, z))
+ {
+ throw new ArithmeticException("Inverse does not exist.");
+ }
+ }
+
+ public static void checkedModOddInverseVar(int[] m, int[] x, int[] z)
+ {
+ if (!modOddInverseVar(m, x, z))
+ {
+ throw new ArithmeticException("Inverse does not exist.");
+ }
+ }
+
public static int inverse32(int d)
{
+// assert (d & 1) == 1;
// int x = d + (((d + 1) & 4) << 1); // d.x == 1 mod 2**4
int x = d; // d.x == 1 mod 2**3
x *= 2 - d * x; // d.x == 1 mod 2**6
@@ -18,72 +54,152 @@ public abstract class Mod
return x;
}
- public static void invert(int[] p, int[] x, int[] z)
+ /** @deprecated Use {@link #checkedModOddInverseVar(int[], int[], int[])} instead. */
+ public static void invert(int[] m, int[] x, int[] z)
{
- int len = p.length;
- if (Nat.isZero(len, x))
- {
- throw new IllegalArgumentException("'x' cannot be 0");
- }
- if (Nat.isOne(len, x))
- {
- System.arraycopy(x, 0, z, 0, len);
- return;
- }
+ checkedModOddInverseVar(m, x, z);
+ }
- int[] u = Nat.copy(len, x);
- int[] a = Nat.create(len);
- a[0] = 1;
- int ac = 0;
+ public static int modOddInverse(int[] m, int[] x, int[] z)
+ {
+ int len32 = m.length;
+// assert len32 > 0;
+// assert (m[0] & 1) != 0;
+// assert m[len32 - 1] != 0;
- if ((u[0] & 1) == 0)
- {
- ac = inversionStep(p, u, len, a, ac);
- }
- if (Nat.isOne(len, u))
+ int bits = (len32 << 5) - Integers.numberOfLeadingZeros(m[len32 - 1]);
+ int len30 = (bits + 29) / 30;
+
+ int[] t = new int[4];
+ int[] D = new int[len30];
+ int[] E = new int[len30];
+ int[] F = new int[len30];
+ int[] G = new int[len30];
+ int[] M = new int[len30];
+
+ E[0] = 1;
+ encode30(bits, x, 0, G, 0);
+ encode30(bits, m, 0, M, 0);
+ System.arraycopy(M, 0, F, 0, len30);
+
+ int eta = -1;
+ int m0Inv32 = inverse32(M[0]);
+ int maxDivsteps = getMaximumDivsteps(bits);
+
+ for (int divSteps = 0; divSteps < maxDivsteps; divSteps += 30)
{
- inversionResult(p, ac, a, z);
- return;
+ eta = divsteps30(eta, F[0], G[0], t);
+ updateDE30(len30, D, E, t, m0Inv32, M);
+ updateFG30(len30, F, G, t);
}
- int[] v = Nat.copy(len, p);
- int[] b = Nat.create(len);
- int bc = 0;
+ int signF = F[len30 - 1] >> 31;
+ cnegate30(len30, signF, F);
- int uvLen = len;
+ /*
+ * D is in the range (-2.M, M). First, conditionally add M if D is negative, to bring it
+ * into the range (-M, M). Then normalize by conditionally negating (according to signF)
+ * and/or then adding M, to bring it into the range [0, M).
+ */
+ cnormalize30(len30, signF, D, M);
- for (;;)
+ decode30(bits, D, 0, z, 0);
+// assert 0 != Nat.lessThan(len32, z, m);
+
+ return Nat.equalTo(len30, F, 1) & Nat.equalToZero(len30, G);
+ }
+
+ public static boolean modOddInverseVar(int[] m, int[] x, int[] z)
+ {
+ int len32 = m.length;
+// assert len32 > 0;
+// assert (m[0] & 1) != 0;
+// assert m[len32 - 1] != 0;
+
+ int bits = (len32 << 5) - Integers.numberOfLeadingZeros(m[len32 - 1]);
+ int len30 = (bits + 29) / 30;
+
+ int[] t = new int[4];
+ int[] D = new int[len30];
+ int[] E = new int[len30];
+ int[] F = new int[len30];
+ int[] G = new int[len30];
+ int[] M = new int[len30];
+
+ E[0] = 1;
+ encode30(bits, x, 0, G, 0);
+ encode30(bits, m, 0, M, 0);
+ System.arraycopy(M, 0, F, 0, len30);
+
+ int clzG = Integers.numberOfLeadingZeros(G[len30 - 1] | 1) - (len30 * 30 + 2 - bits);
+ int eta = -1 - clzG;
+ int lenDE = len30, lenFG = len30;
+ int m0Inv32 = inverse32(M[0]);
+ int maxDivsteps = getMaximumDivsteps(bits);
+
+ int divsteps = 0;
+ while (!Nat.isZero(lenFG, G))
{
- while (u[uvLen - 1] == 0 && v[uvLen - 1] == 0)
+ if (divsteps >= maxDivsteps)
{
- --uvLen;
+ return false;
}
- if (Nat.gte(uvLen, u, v))
- {
- Nat.subFrom(uvLen, v, u);
-// assert (u[0] & 1) == 0;
- ac += Nat.subFrom(len, b, a) - bc;
- ac = inversionStep(p, u, uvLen, a, ac);
- if (Nat.isOne(uvLen, u))
- {
- inversionResult(p, ac, a, z);
- return;
- }
- }
- else
+ divsteps += 30;
+
+ eta = divsteps30Var(eta, F[0], G[0], t);
+ updateDE30(lenDE, D, E, t, m0Inv32, M);
+ updateFG30(lenFG, F, G, t);
+
+ int fn = F[lenFG - 1];
+ int gn = G[lenFG - 1];
+
+ int cond = (lenFG - 2) >> 31;
+ cond |= fn ^ (fn >> 31);
+ cond |= gn ^ (gn >> 31);
+
+ if (cond == 0)
{
- Nat.subFrom(uvLen, u, v);
-// assert (v[0] & 1) == 0;
- bc += Nat.subFrom(len, a, b) - ac;
- bc = inversionStep(p, v, uvLen, b, bc);
- if (Nat.isOne(uvLen, v))
- {
- inversionResult(p, bc, b, z);
- return;
- }
+ F[lenFG - 2] |= fn << 30;
+ G[lenFG - 2] |= gn << 30;
+ --lenFG;
}
}
+
+ int signF = F[lenFG - 1] >> 31;
+
+ /*
+ * D is in the range (-2.M, M). First, conditionally add M if D is negative, to bring it
+ * into the range (-M, M). Then normalize by conditionally negating (according to signF)
+ * and/or then adding M, to bring it into the range [0, M).
+ */
+ int signD = D[lenDE - 1] >> 31;
+ if (signD < 0)
+ {
+ signD = add30(lenDE, D, M);
+ }
+ if (signF < 0)
+ {
+ signD = negate30(lenDE, D);
+ signF = negate30(lenFG, F);
+ }
+// assert 0 == signF;
+
+ if (!Nat.isOne(lenFG, F))
+ {
+ return false;
+ }
+
+ if (signD < 0)
+ {
+ signD = add30(lenDE, D, M);
+ }
+// assert 0 == signD;
+
+ decode30(bits, D, 0, z, 0);
+// assert !Nat.gte(len32, z, m);
+
+ return true;
}
public static int[] random(int[] p)
@@ -112,88 +228,358 @@ public abstract class Mod
return s;
}
- public static void add(int[] p, int[] x, int[] y, int[] z)
+ /** @deprecated Will be removed. */
+ public static void subtract(int[] p, int[] x, int[] y, int[] z)
{
int len = p.length;
- int c = Nat.add(len, x, y, z);
+ int c = Nat.sub(len, x, y, z);
if (c != 0)
{
- Nat.subFrom(len, p, z);
+ Nat.addTo(len, p, z);
}
}
- public static void subtract(int[] p, int[] x, int[] y, int[] z)
+ private static int add30(int len30, int[] D, int[] M)
{
- int len = p.length;
- int c = Nat.sub(len, x, y, z);
- if (c != 0)
+// assert len30 > 0;
+// assert D.length >= len30;
+// assert M.length >= len30;
+
+ int c = 0, last = len30 - 1;
+ for (int i = 0; i < last; ++i)
{
- Nat.addTo(len, p, z);
+ c += D[i] + M[i];
+ D[i] = c & M30; c >>= 30;
+ }
+ c += D[last] + M[last];
+ D[last] = c; c >>= 30;
+ return c;
+ }
+
+ private static void cnegate30(int len30, int cond, int[] D)
+ {
+// assert len30 > 0;
+// assert D.length >= len30;
+
+ int c = 0, last = len30 - 1;
+ for (int i = 0; i < last; ++i)
+ {
+ c += (D[i] ^ cond) - cond;
+ D[i] = c & M30; c >>= 30;
}
+ c += (D[last] ^ cond) - cond;
+ D[last] = c;
}
- private static void inversionResult(int[] p, int ac, int[] a, int[] z)
+ private static void cnormalize30(int len30, int condNegate, int[] D, int[] M)
{
- if (ac < 0)
+// assert len30 > 0;
+// assert D.length >= len30;
+// assert M.length >= len30;
+
+ int last = len30 - 1;
+
+ {
+ int c = 0, condAdd = D[last] >> 31;
+ for (int i = 0; i < last; ++i)
+ {
+ int di = D[i] + (M[i] & condAdd);
+ di = (di ^ condNegate) - condNegate;
+ c += di; D[i] = c & M30; c >>= 30;
+ }
+ {
+ int di = D[last] + (M[last] & condAdd);
+ di = (di ^ condNegate) - condNegate;
+ c += di; D[last] = c;
+ }
+ }
+
{
- Nat.add(p.length, a, p, z);
+ int c = 0, condAdd = D[last] >> 31;
+ for (int i = 0; i < last; ++i)
+ {
+ int di = D[i] + (M[i] & condAdd);
+ c += di; D[i] = c & M30; c >>= 30;
+ }
+ {
+ int di = D[last] + (M[last] & condAdd);
+ c += di; D[last] = c;
+ }
+// assert c >> 30 == 0;
}
- else
+ }
+
+ private static void decode30(int bits, int[] x, int xOff, int[] z, int zOff)
+ {
+// assert bits > 0;
+// assert x != z;
+
+ int avail = 0;
+ long data = 0L;
+
+ while (bits > 0)
{
- System.arraycopy(a, 0, z, 0, p.length);
+ while (avail < Math.min(32, bits))
+ {
+ data |= (long)x[xOff++] << avail;
+ avail += 30;
+ }
+
+ z[zOff++] = (int)data; data >>>= 32;
+ avail -= 32;
+ bits -= 32;
}
}
- private static int inversionStep(int[] p, int[] u, int uLen, int[] x, int xc)
+ private static int divsteps30(int eta, int f0, int g0, int[] t)
{
- int len = p.length;
- int count = 0;
- while (u[0] == 0)
+ int u = 1, v = 0, q = 0, r = 1;
+ int f = f0, g = g0;
+
+ for (int i = 0; i < 30; ++i)
{
- Nat.shiftDownWord(uLen, u, 0);
- count += 32;
+// assert (f & 1) == 1;
+// assert (u * f0 + v * g0) == f << i;
+// assert (q * f0 + r * g0) == g << i;
+
+ int c1 = eta >> 31;
+ int c2 = -(g & 1);
+
+ int x = (f ^ c1) - c1;
+ int y = (u ^ c1) - c1;
+ int z = (v ^ c1) - c1;
+
+ g += x & c2;
+ q += y & c2;
+ r += z & c2;
+
+ c1 &= c2;
+ eta = (eta ^ c1) - (c1 + 1);
+
+ f += g & c1;
+ u += q & c1;
+ v += r & c1;
+
+ g >>= 1;
+ u <<= 1;
+ v <<= 1;
}
+ t[0] = u;
+ t[1] = v;
+ t[2] = q;
+ t[3] = r;
+
+ return eta;
+ }
+
+ private static int divsteps30Var(int eta, int f0, int g0, int[] t)
+ {
+ int u = 1, v = 0, q = 0, r = 1;
+ int f = f0, g = g0, m, w, x, y, z;
+ int i = 30, limit, zeros;
+
+ for (;;)
{
- int zeroes = getTrailingZeroes(u[0]);
- if (zeroes > 0)
+ // Use a sentinel bit to count zeros only up to i.
+ zeros = Integers.numberOfTrailingZeros(g | (-1 << i));
+
+ g >>= zeros;
+ u <<= zeros;
+ v <<= zeros;
+ eta -= zeros;
+ i -= zeros;
+
+ if (i <= 0)
+ {
+ break;
+ }
+
+// assert (f & 1) == 1;
+// assert (g & 1) == 1;
+// assert (u * f0 + v * g0) == f << (30 - i);
+// assert (q * f0 + r * g0) == g << (30 - i);
+
+ if (eta < 0)
{
- Nat.shiftDownBits(uLen, u, zeroes, 0);
- count += zeroes;
+ eta = -eta;
+ x = f; f = g; g = -x;
+ y = u; u = q; q = -y;
+ z = v; v = r; r = -z;
+
+ // Handle up to 6 divsteps at once, subject to eta and i.
+ limit = (eta + 1) > i ? i : (eta + 1);
+ m = (-1 >>> (32 - limit)) & 63;
+
+ w = (f * g * (f * f - 2)) & m;
+ }
+ else
+ {
+ // Handle up to 4 divsteps at once, subject to eta and i.
+ limit = (eta + 1) > i ? i : (eta + 1);
+ m = (-1 >>> (32 - limit)) & 15;
+
+ w = f + (((f + 1) & 4) << 1);
+ w = (-w * g) & m;
}
+
+ g += f * w;
+ q += u * w;
+ r += v * w;
+
+// assert (g & m) == 0;
}
- for (int i = 0; i < count; ++i)
+ t[0] = u;
+ t[1] = v;
+ t[2] = q;
+ t[3] = r;
+
+ return eta;
+ }
+
+ private static void encode30(int bits, int[] x, int xOff, int[] z, int zOff)
+ {
+// assert bits > 0;
+// assert x != z;
+
+ int avail = 0;
+ long data = 0L;
+
+ while (bits > 0)
{
- if ((x[0] & 1) != 0)
+ if (avail < Math.min(30, bits))
{
- if (xc < 0)
- {
- xc += Nat.addTo(len, p, x);
- }
- else
- {
- xc += Nat.subFrom(len, p, x);
- }
+ data |= (x[xOff++] & M32L) << avail;
+ avail += 32;
}
-// assert xc == 0 || xc == 1;
- Nat.shiftDownBit(len, x, xc);
+ z[zOff++] = (int)data & M30; data >>>= 30;
+ avail -= 30;
+ bits -= 30;
}
-
- return xc;
}
- private static int getTrailingZeroes(int x)
+ private static int getMaximumDivsteps(int bits)
+ {
+ return (49 * bits + (bits < 46 ? 80 : 47)) / 17;
+ }
+
+ private static int negate30(int len30, int[] D)
{
-// assert x != 0;
+// assert len30 > 0;
+// assert D.length >= len30;
- int count = 0;
- while ((x & 1) == 0)
+ int c = 0, last = len30 - 1;
+ for (int i = 0; i < last; ++i)
{
- x >>>= 1;
- ++count;
+ c -= D[i];
+ D[i] = c & M30; c >>= 30;
}
- return count;
+ c -= D[last];
+ D[last] = c; c >>= 30;
+ return c;
+ }
+
+ private static void updateDE30(int len30, int[] D, int[] E, int[] t, int m0Inv32, int[] M)
+ {
+// assert len30 > 0;
+// assert D.length >= len30;
+// assert E.length >= len30;
+// assert M.length >= len30;
+// assert m0Inv32 * M[0] == 1;
+
+ final int u = t[0], v = t[1], q = t[2], r = t[3];
+ int di, ei, i, md, me, mi, sd, se;
+ long cd, ce;
+
+ /*
+ * We accept D (E) in the range (-2.M, M) and conceptually add the modulus to the input
+ * value if it is initially negative. Instead of adding it explicitly, we add u and/or v (q
+ * and/or r) to md (me).
+ */
+ sd = D[len30 - 1] >> 31;
+ se = E[len30 - 1] >> 31;
+
+ md = (u & sd) + (v & se);
+ me = (q & sd) + (r & se);
+
+ mi = M[0];
+ di = D[0];
+ ei = E[0];
+
+ cd = (long)u * di + (long)v * ei;
+ ce = (long)q * di + (long)r * ei;
+
+ /*
+ * Subtract from md/me an extra term in the range [0, 2^30) such that the low 30 bits of the
+ * intermediate D/E values will be 0, allowing clean division by 2^30. The final D/E are
+ * thus in the range (-2.M, M), consistent with the input constraint.
+ */
+ md -= (m0Inv32 * (int)cd + md) & M30;
+ me -= (m0Inv32 * (int)ce + me) & M30;
+
+ cd += (long)mi * md;
+ ce += (long)mi * me;
+
+// assert ((int)cd & M30) == 0;
+// assert ((int)ce & M30) == 0;
+
+ cd >>= 30;
+ ce >>= 30;
+
+ for (i = 1; i < len30; ++i)
+ {
+ mi = M[i];
+ di = D[i];
+ ei = E[i];
+
+ cd += (long)u * di + (long)v * ei + (long)mi * md;
+ ce += (long)q * di + (long)r * ei + (long)mi * me;
+
+ D[i - 1] = (int)cd & M30; cd >>= 30;
+ E[i - 1] = (int)ce & M30; ce >>= 30;
+ }
+
+ D[len30 - 1] = (int)cd;
+ E[len30 - 1] = (int)ce;
+ }
+
+ private static void updateFG30(int len30, int[] F, int[] G, int[] t)
+ {
+// assert len30 > 0;
+// assert F.length >= len30;
+// assert G.length >= len30;
+
+ final int u = t[0], v = t[1], q = t[2], r = t[3];
+ int fi, gi, i;
+ long cf, cg;
+
+ fi = F[0];
+ gi = G[0];
+
+ cf = (long)u * fi + (long)v * gi;
+ cg = (long)q * fi + (long)r * gi;
+
+// assert ((int)cf & M30) == 0;
+// assert ((int)cg & M30) == 0;
+
+ cf >>= 30;
+ cg >>= 30;
+
+ for (i = 1; i < len30; ++i)
+ {
+ fi = F[i];
+ gi = G[i];
+
+ cf += (long)u * fi + (long)v * gi;
+ cg += (long)q * fi + (long)r * gi;
+
+ F[i - 1] = (int)cf & M30; cf >>= 30;
+ G[i - 1] = (int)cg & M30; cg >>= 30;
+ }
+
+ F[len30 - 1] = (int)cf;
+ G[len30 - 1] = (int)cg;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat.java b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat.java
index d9482cf7..28745df3 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat.java
@@ -160,6 +160,31 @@ public abstract class Nat
return (int)c;
}
+ public static int addTo(int len, int[] x, int xOff, int[] z, int zOff, int cIn)
+ {
+ long c = cIn & M;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[xOff + i] & M) + (z[zOff + i] & M);
+ z[zOff + i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int addToEachOther(int len, int[] u, int uOff, int[] v, int vOff)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (u[uOff + i] & M) + (v[vOff + i] & M);
+ u[uOff + i] = (int)c;
+ v[vOff + i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
public static int addWordAt(int len, int x, int[] z, int zPos)
{
// assert zPos <= (len - 1);
@@ -229,6 +254,34 @@ public abstract class Nat
// }
}
+ public static int compare(int len, int[] x, int[] y)
+ {
+ for (int i = len - 1; i >= 0; --i)
+ {
+ int x_i = x[i] ^ Integer.MIN_VALUE;
+ int y_i = y[i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return -1;
+ if (x_i > y_i)
+ return 1;
+ }
+ return 0;
+ }
+
+ public static int compare(int len, int[] x, int xOff, int[] y, int yOff)
+ {
+ for (int i = len - 1; i >= 0; --i)
+ {
+ int x_i = x[xOff + i] ^ Integer.MIN_VALUE;
+ int y_i = y[yOff + i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return -1;
+ if (x_i > y_i)
+ return 1;
+ }
+ return 0;
+ }
+
public static int[] copy(int len, int[] x)
{
int[] z = new int[len];
@@ -246,6 +299,23 @@ public abstract class Nat
System.arraycopy(x, xOff, z, zOff, len);
}
+ public static long[] copy64(int len, long[] x)
+ {
+ long[] z = new long[len];
+ System.arraycopy(x, 0, z, 0, len);
+ return z;
+ }
+
+ public static void copy64(int len, long[] x, long[] z)
+ {
+ System.arraycopy(x, 0, z, 0, len);
+ }
+
+ public static void copy64(int len, long[] x, int xOff, long[] z, int zOff)
+ {
+ System.arraycopy(x, xOff, z, zOff, len);
+ }
+
public static int[] create(int len)
{
return new int[len];
@@ -269,6 +339,19 @@ public abstract class Nat
return (int)c;
}
+ public static int csub(int len, int mask, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long MASK = -(mask & 1) & M;
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[xOff + i] & M) - (y[yOff + i] & MASK);
+ z[zOff + i] = (int)c;
+ c >>= 32;
+ }
+ return (int)c;
+ }
+
public static int dec(int len, int[] z)
{
for (int i = 0; i < len; ++i)
@@ -328,6 +411,20 @@ public abstract class Nat
return -1;
}
+ public static boolean diff(int len, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ boolean pos = gte(len, x, xOff, y, yOff);
+ if (pos)
+ {
+ sub(len, x, xOff, y, yOff, z, zOff);
+ }
+ else
+ {
+ sub(len, y, yOff, x, xOff, z, zOff);
+ }
+ return pos;
+ }
+
public static boolean eq(int len, int[] x, int[] y)
{
for (int i = len - 1; i >= 0; --i)
@@ -340,6 +437,72 @@ public abstract class Nat
return true;
}
+ public static int equalTo(int len, int[] x, int y)
+ {
+ int d = x[0] ^ y;
+ for (int i = 1; i < len; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalTo(int len, int[] x, int xOff, int y)
+ {
+ int d = x[xOff] ^ y;
+ for (int i = 1; i < len; ++i)
+ {
+ d |= x[xOff + i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalTo(int len, int[] x, int[] y)
+ {
+ int d = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ d |= x[i] ^ y[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalTo(int len, int[] x, int xOff, int[] y, int yOff)
+ {
+ int d = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ d |= x[xOff + i] ^ y[yOff + i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalToZero(int len, int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalToZero(int len, int[] x, int xOff)
+ {
+ int d = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ d |= x[xOff + i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static int[] fromBigInteger(int bits, BigInteger x)
{
if (x.signum() < 0 || x.bitLength() > bits)
@@ -349,15 +512,35 @@ public abstract class Nat
int len = (bits + 31) >> 5;
int[] z = create(len);
- int i = 0;
- while (x.signum() != 0)
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < len; ++i)
{
- z[i++] = x.intValue();
+ z[i] = x.intValue();
x = x.shiftRight(32);
}
return z;
}
+ public static long[] fromBigInteger64(int bits, BigInteger x)
+ {
+ if (x.signum() < 0 || x.bitLength() > bits)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ int len = (bits + 63) >> 6;
+ long[] z = create64(len);
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < len; ++i)
+ {
+ z[i] = x.longValue();
+ x = x.shiftRight(64);
+ }
+ return z;
+ }
+
public static int getBit(int[] x, int bit)
{
if (bit == 0)
@@ -387,6 +570,20 @@ public abstract class Nat
return true;
}
+ public static boolean gte(int len, int[] x, int xOff, int[] y, int yOff)
+ {
+ for (int i = len - 1; i >= 0; --i)
+ {
+ int x_i = x[xOff + i] ^ Integer.MIN_VALUE;
+ int y_i = y[yOff + i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return false;
+ if (x_i > y_i)
+ return true;
+ }
+ return true;
+ }
+
public static int inc(int len, int[] z)
{
for (int i = 0; i < len; ++i)
@@ -474,6 +671,30 @@ public abstract class Nat
return true;
}
+ public static int lessThan(int len, int[] x, int[] y)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[i] & M) - (y[i] & M);
+ c >>= 32;
+ }
+// assert c == 0L || c == -1L;
+ return (int)c;
+ }
+
+ public static int lessThan(int len, int[] x, int xOff, int[] y, int yOff)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[xOff + i] & M) - (y[yOff + i] & M);
+ c >>= 32;
+ }
+// assert c == 0L || c == -1L;
+ return (int)c;
+ }
+
public static void mul(int len, int[] x, int[] y, int[] zz)
{
zz[len] = mulWord(len, x[0], y, zz);
@@ -509,10 +730,10 @@ public abstract class Nat
long zc = 0;
for (int i = 0; i < len; ++i)
{
- long c = mulWordAddTo(len, x[i], y, 0, zz, i) & M;
- c += zc + (zz[i + len] & M);
- zz[i + len] = (int)c;
- zc = c >>> 32;
+ zc += mulWordAddTo(len, x[i], y, 0, zz, i) & M;
+ zc += zz[i + len] & M;
+ zz[i + len] = (int)zc;
+ zc >>>= 32;
}
return (int)zc;
}
@@ -522,10 +743,10 @@ public abstract class Nat
long zc = 0;
for (int i = 0; i < len; ++i)
{
- long c = mulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff) & M;
- c += zc + (zz[zzOff + len] & M);
- zz[zzOff + len] = (int)c;
- zc = c >>> 32;
+ zc += mulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff) & M;
+ zc += zz[zzOff + len] & M;
+ zz[zzOff + len] = (int)zc;
+ zc >>>= 32;
++zzOff;
}
return (int)zc;
@@ -857,11 +1078,18 @@ public abstract class Nat
}
while (j > 0);
+ long d = 0L;
+ int zzPos = 2;
+
for (int i = 1; i < len; ++i)
{
- c = squareWordAdd(x, i, zz);
- addWordAt(extLen, c, zz, i << 1);
+ d += squareWordAddTo(x, i, zz) & M;
+ d += zz[zzPos] & M;
+ zz[zzPos++] = (int)d; d >>>= 32;
+ d += zz[zzPos] & M;
+ zz[zzPos++] = (int)d; d >>>= 32;
}
+// assert 0L == d;
shiftUpBit(extLen, zz, x[0] << 31);
}
@@ -881,15 +1109,25 @@ public abstract class Nat
}
while (j > 0);
+ long d = 0L;
+ int zzPos = zzOff + 2;
+
for (int i = 1; i < len; ++i)
{
- c = squareWordAdd(x, xOff, i, zz, zzOff);
- addWordAt(extLen, c, zz, zzOff, i << 1);
+ d += squareWordAddTo(x, xOff, i, zz, zzOff) & M;
+ d += zz[zzPos] & M;
+ zz[zzPos++] = (int)d; d >>>= 32;
+ d += zz[zzPos] & M;
+ zz[zzPos++] = (int)d; d >>>= 32;
}
+// assert 0L == d;
shiftUpBit(extLen, zz, zzOff, x[xOff] << 31);
}
+ /**
+ * @deprecated Use {@link #squareWordAddTo(int[], int, int[])} instead.
+ */
public static int squareWordAdd(int[] x, int xPos, int[] z)
{
long c = 0, xVal = x[xPos] & M;
@@ -904,6 +1142,9 @@ public abstract class Nat
return (int)c;
}
+ /**
+ * @deprecated Use {@link #squareWordAddTo(int[], int, int, int[], int)} instead.
+ */
public static int squareWordAdd(int[] x, int xOff, int xPos, int[] z, int zOff)
{
long c = 0, xVal = x[xOff + xPos] & M;
@@ -919,6 +1160,35 @@ public abstract class Nat
return (int)c;
}
+ public static int squareWordAddTo(int[] x, int xPos, int[] z)
+ {
+ long c = 0, xVal = x[xPos] & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (x[i] & M) + (z[xPos + i] & M);
+ z[xPos + i] = (int)c;
+ c >>>= 32;
+ }
+ while (++i < xPos);
+ return (int)c;
+ }
+
+ public static int squareWordAddTo(int[] x, int xOff, int xPos, int[] z, int zOff)
+ {
+ long c = 0, xVal = x[xOff + xPos] & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M);
+ z[xPos + zOff] = (int)c;
+ c >>>= 32;
+ ++zOff;
+ }
+ while (++i < xPos);
+ return (int)c;
+ }
+
public static int sub(int len, int[] x, int[] y, int[] z)
{
long c = 0;
@@ -1139,6 +1409,14 @@ public abstract class Nat
}
}
+ public static void zero(int len, int[] z, int zOff)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[zOff + i] = 0;
+ }
+ }
+
public static void zero64(int len, long[] z)
{
for (int i = 0; i < len; ++i)
diff --git a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat192.java b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat192.java
index ffe74d70..9a84e6a3 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat192.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat192.java
@@ -234,10 +234,11 @@ public abstract class Nat192
}
int[] z = create();
- int i = 0;
- while (x.signum() != 0)
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 6; ++i)
{
- z[i++] = x.intValue();
+ z[i] = x.intValue();
x = x.shiftRight(32);
}
return z;
@@ -251,10 +252,11 @@ public abstract class Nat192
}
long[] z = create64();
- int i = 0;
- while (x.signum() != 0)
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 3; ++i)
{
- z[i++] = x.longValue();
+ z[i] = x.longValue();
x = x.shiftRight(64);
}
return z;
@@ -505,9 +507,10 @@ public abstract class Nat192
c += x_i * y_5 + (zz[i + 5] & M);
zz[i + 5] = (int)c;
c >>>= 32;
- c += zc + (zz[i + 6] & M);
- zz[i + 6] = (int)c;
- zc = c >>> 32;
+
+ zc += c + (zz[i + 6] & M);
+ zz[i + 6] = (int)zc;
+ zc >>>= 32;
}
return (int)zc;
}
@@ -543,9 +546,10 @@ public abstract class Nat192
c += x_i * y_5 + (zz[zzOff + 5] & M);
zz[zzOff + 5] = (int)c;
c >>>= 32;
- c += zc + (zz[zzOff + 6] & M);
- zz[zzOff + 6] = (int)c;
- zc = c >>> 32;
+
+ zc += c + (zz[zzOff + 6] & M);
+ zz[zzOff + 6] = (int)zc;
+ zc >>>= 32;
++zzOff;
}
return (int)zc;
diff --git a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat224.java b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat224.java
index 59be1f51..e4b7d5ee 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat224.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat224.java
@@ -270,10 +270,11 @@ public abstract class Nat224
}
int[] z = create();
- int i = 0;
- while (x.signum() != 0)
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 7; ++i)
{
- z[i++] = x.intValue();
+ z[i] = x.intValue();
x = x.shiftRight(32);
}
return z;
@@ -514,9 +515,10 @@ public abstract class Nat224
c += x_i * y_6 + (zz[i + 6] & M);
zz[i + 6] = (int)c;
c >>>= 32;
- c += zc + (zz[i + 7] & M);
- zz[i + 7] = (int)c;
- zc = c >>> 32;
+
+ zc += c + (zz[i + 7] & M);
+ zz[i + 7] = (int)zc;
+ zc >>>= 32;
}
return (int)zc;
}
@@ -556,9 +558,10 @@ public abstract class Nat224
c += x_i * y_6 + (zz[zzOff + 6] & M);
zz[zzOff + 6] = (int)c;
c >>>= 32;
- c += zc + (zz[zzOff + 7] & M);
- zz[zzOff + 7] = (int)c;
- zc = c >>> 32;
+
+ zc += c + (zz[zzOff + 7] & M);
+ zz[zzOff + 7] = (int)zc;
+ zc >>>= 32;
++zzOff;
}
return (int)zc;
diff --git a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java
index f7d80b3a..20b17cd0 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java
@@ -332,10 +332,11 @@ public abstract class Nat256
}
int[] z = create();
- int i = 0;
- while (x.signum() != 0)
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 8; ++i)
{
- z[i++] = x.intValue();
+ z[i] = x.intValue();
x = x.shiftRight(32);
}
return z;
@@ -349,10 +350,11 @@ public abstract class Nat256
}
long[] z = create64();
- int i = 0;
- while (x.signum() != 0)
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 4; ++i)
{
- z[i++] = x.longValue();
+ z[i] = x.longValue();
x = x.shiftRight(64);
}
return z;
@@ -639,9 +641,10 @@ public abstract class Nat256
c += x_i * y_7 + (zz[i + 7] & M);
zz[i + 7] = (int)c;
c >>>= 32;
- c += zc + (zz[i + 8] & M);
- zz[i + 8] = (int)c;
- zc = c >>> 32;
+
+ zc += c + (zz[i + 8] & M);
+ zz[i + 8] = (int)zc;
+ zc >>>= 32;
}
return (int)zc;
}
@@ -685,9 +688,10 @@ public abstract class Nat256
c += x_i * y_7 + (zz[zzOff + 7] & M);
zz[zzOff + 7] = (int)c;
c >>>= 32;
- c += zc + (zz[zzOff + 8] & M);
- zz[zzOff + 8] = (int)c;
- zc = c >>> 32;
+
+ zc += c + (zz[zzOff + 8] & M);
+ zz[zzOff + 8] = (int)zc;
+ zc >>>= 32;
++zzOff;
}
return (int)zc;
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Arrays.java b/bcprov/src/main/java/org/bouncycastle/util/Arrays.java
index c48ae757..6e52c367 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Arrays.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Arrays.java
@@ -23,88 +23,29 @@ public final class Arrays
return bits == 0;
}
- public static boolean areEqual(
- boolean[] a,
- boolean[] b)
+ public static boolean areEqual(boolean[] a, boolean[] b)
{
- if (a == b)
- {
- return true;
- }
-
- if (a == null || b == null)
- {
- return false;
- }
-
- if (a.length != b.length)
- {
- return false;
- }
-
- for (int i = 0; i != a.length; i++)
- {
- if (a[i] != b[i])
- {
- return false;
- }
- }
-
- return true;
+ return java.util.Arrays.equals(a, b);
}
- public static boolean areEqual(
- char[] a,
- char[] b)
+ public static boolean areEqual(byte[] a, byte[] b)
{
- if (a == b)
- {
- return true;
- }
-
- if (a == null || b == null)
- {
- return false;
- }
-
- if (a.length != b.length)
- {
- return false;
- }
-
- for (int i = 0; i != a.length; i++)
- {
- if (a[i] != b[i])
- {
- return false;
- }
- }
-
- return true;
+ return java.util.Arrays.equals(a, b);
}
- public static boolean areEqual(
- byte[] a,
- byte[] b)
+ public static boolean areEqual(byte[] a, int aFromIndex, int aToIndex, byte[] b, int bFromIndex, int bToIndex)
{
- if (a == b)
- {
- return true;
- }
-
- if (a == null || b == null)
- {
- return false;
- }
+ int aLength = aToIndex - aFromIndex;
+ int bLength = bToIndex - bFromIndex;
- if (a.length != b.length)
+ if (aLength != bLength)
{
return false;
}
- for (int i = 0; i != a.length; i++)
+ for (int i = 0; i < aLength; ++i)
{
- if (a[i] != b[i])
+ if (a[aFromIndex + i] != b[bFromIndex + i])
{
return false;
}
@@ -113,34 +54,29 @@ public final class Arrays
return true;
}
- public static boolean areEqual(
- short[] a,
- short[] b)
+ public static boolean areEqual(char[] a, char[] b)
{
- if (a == b)
- {
- return true;
- }
+ return java.util.Arrays.equals(a, b);
+ }
- if (a == null || b == null)
- {
- return false;
- }
+ public static boolean areEqual(int[] a, int[] b)
+ {
+ return java.util.Arrays.equals(a, b);
+ }
- if (a.length != b.length)
- {
- return false;
- }
+ public static boolean areEqual(long[] a, long[] b)
+ {
+ return java.util.Arrays.equals(a, b);
+ }
- for (int i = 0; i != a.length; i++)
- {
- if (a[i] != b[i])
- {
- return false;
- }
- }
+ public static boolean areEqual(Object[] a, Object[] b)
+ {
+ return java.util.Arrays.equals(a, b);
+ }
- return true;
+ public static boolean areEqual(short[] a, short[] b)
+ {
+ return java.util.Arrays.equals(a, b);
}
/**
@@ -156,121 +92,61 @@ public final class Arrays
byte[] expected,
byte[] supplied)
{
- if (expected == supplied)
- {
- return true;
- }
-
if (expected == null || supplied == null)
{
return false;
}
- if (expected.length != supplied.length)
- {
- return !Arrays.constantTimeAreEqual(expected, expected);
- }
-
- int nonEqual = 0;
-
- for (int i = 0; i != expected.length; i++)
- {
- nonEqual |= (expected[i] ^ supplied[i]);
- }
-
- return nonEqual == 0;
- }
-
- public static boolean areEqual(
- int[] a,
- int[] b)
- {
- if (a == b)
+ if (expected == supplied)
{
return true;
}
- if (a == null || b == null)
- {
- return false;
- }
+ int len = (expected.length < supplied.length) ? expected.length : supplied.length;
- if (a.length != b.length)
+ int nonEqual = expected.length ^ supplied.length;
+
+ for (int i = 0; i != len; i++)
{
- return false;
+ nonEqual |= (expected[i] ^ supplied[i]);
}
-
- for (int i = 0; i != a.length; i++)
+ for (int i = len; i < supplied.length; i++)
{
- if (a[i] != b[i])
- {
- return false;
- }
+ nonEqual |= (supplied[i] ^ ~supplied[i]);
}
- return true;
+ return nonEqual == 0;
}
- public static boolean areEqual(
- long[] a,
- long[] b)
+ public static boolean constantTimeAreEqual(int len, byte[] a, int aOff, byte[] b, int bOff)
{
- if (a == b)
+ if (null == a)
{
- return true;
+ throw new NullPointerException("'a' cannot be null");
}
-
- if (a == null || b == null)
+ if (null == b)
{
- return false;
+ throw new NullPointerException("'b' cannot be null");
}
-
- if (a.length != b.length)
+ if (len < 0)
{
- return false;
+ throw new IllegalArgumentException("'len' cannot be negative");
}
-
- for (int i = 0; i != a.length; i++)
+ if (aOff > (a.length - len))
{
- if (a[i] != b[i])
- {
- return false;
- }
+ throw new IndexOutOfBoundsException("'aOff' value invalid for specified length");
}
-
- return true;
- }
-
- public static boolean areEqual(Object[] a, Object[] b)
- {
- if (a == b)
+ if (bOff > (b.length - len))
{
- return true;
+ throw new IndexOutOfBoundsException("'bOff' value invalid for specified length");
}
- if (a == null || b == null)
- {
- return false;
- }
- if (a.length != b.length)
- {
- return false;
- }
- for (int i = 0; i != a.length; i++)
+
+ int d = 0;
+ for (int i = 0; i < len; ++i)
{
- Object objA = a[i], objB = b[i];
- if (objA == null)
- {
- if (objB != null)
- {
- return false;
- }
- }
- else if (!objA.equals(objB))
- {
- return false;
- }
+ d |= (a[aOff + i] ^ b[bOff + i]);
}
- return true;
+ return 0 == d;
}
public static int compareUnsigned(byte[] a, byte[] b)
@@ -311,11 +187,11 @@ public final class Arrays
return 0;
}
- public static boolean contains(short[] a, short n)
+ public static boolean contains(boolean[] a, boolean val)
{
for (int i = 0; i < a.length; ++i)
{
- if (a[i] == n)
+ if (a[i] == val)
{
return true;
}
@@ -323,11 +199,11 @@ public final class Arrays
return false;
}
- public static boolean contains(int[] a, int n)
+ public static boolean contains(byte[] a, byte val)
{
for (int i = 0; i < a.length; ++i)
{
- if (a[i] == n)
+ if (a[i] == val)
{
return true;
}
@@ -335,122 +211,154 @@ public final class Arrays
return false;
}
- public static void fill(
- byte[] array,
- byte value)
+ public static boolean contains(char[] a, char val)
{
- for (int i = 0; i < array.length; i++)
+ for (int i = 0; i < a.length; ++i)
{
- array[i] = value;
+ if (a[i] == val)
+ {
+ return true;
+ }
}
+ return false;
}
- public static void fill(
- byte[] array,
- int start,
- int finish,
- byte value)
+ public static boolean contains(int[] a, int val)
{
- for (int i = start; i < finish; i++)
+ for (int i = 0; i < a.length; ++i)
{
- array[i] = value;
+ if (a[i] == val)
+ {
+ return true;
+ }
}
+ return false;
}
- public static void fill(
- char[] array,
- char value)
+ public static boolean contains(long[] a, long val)
{
- for (int i = 0; i < array.length; i++)
+ for (int i = 0; i < a.length; ++i)
{
- array[i] = value;
+ if (a[i] == val)
+ {
+ return true;
+ }
}
+ return false;
}
- public static void fill(
- long[] array,
- long value)
+ public static boolean contains(short[] a, short val)
{
- for (int i = 0; i < array.length; i++)
+ for (int i = 0; i < a.length; ++i)
{
- array[i] = value;
+ if (a[i] == val)
+ {
+ return true;
+ }
}
+ return false;
}
- public static void fill(
- short[] array,
- short value)
+ public static void fill(boolean[] a, boolean val)
{
- for (int i = 0; i < array.length; i++)
- {
- array[i] = value;
- }
+ java.util.Arrays.fill(a, val);
}
- public static void fill(
- int[] array,
- int value)
+ public static void fill(boolean[] a, int fromIndex, int toIndex, boolean val)
{
- for (int i = 0; i < array.length; i++)
- {
- array[i] = value;
- }
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
}
- public static void fill(
- byte[] array,
- int out,
- byte value)
+ public static void fill(byte[] a, byte val)
{
- if(out < array.length)
- {
- for (int i = out; i < array.length; i++)
- {
- array[i] = value;
- }
- }
+ java.util.Arrays.fill(a, val);
}
- public static void fill(
- int[] array,
- int out,
- int value)
+ /**
+ * @deprecated Use {@link #fill(byte[], int, int, byte)} instead.
+ */
+ public static void fill(byte[] a, int fromIndex, byte val)
{
- if(out < array.length)
- {
- for (int i = out; i < array.length; i++)
- {
- array[i] = value;
- }
- }
+ fill(a, fromIndex, a.length, val);
}
- public static void fill(
- short[] array,
- int out,
- short value)
+ public static void fill(byte[] a, int fromIndex, int toIndex, byte val)
{
- if(out < array.length)
- {
- for (int i = out; i < array.length; i++)
- {
- array[i] = value;
- }
- }
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
}
- public static void fill(
- long[] array,
- int out,
- long value)
+ public static void fill(char[] a, char val)
{
- if(out < array.length)
- {
- for (int i = out; i < array.length; i++)
- {
- array[i] = value;
- }
- }
+ java.util.Arrays.fill(a, val);
+ }
+
+ public static void fill(char[] a, int fromIndex, int toIndex, char val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static void fill(int[] a, int val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ /**
+ * @deprecated Use {@link #fill(int[], int, int, int)} instead.
+ */
+ public static void fill(int[] a, int fromIndex, int val)
+ {
+ java.util.Arrays.fill(a, fromIndex, a.length, val);
+ }
+
+ public static void fill(int[] a, int fromIndex, int toIndex, int val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static void fill(long[] a, long val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ /**
+ * @deprecated Use {@link #fill(long[], int, int, long)} instead.
+ */
+ public static void fill(long[] a, int fromIndex, long val)
+ {
+ java.util.Arrays.fill(a, fromIndex, a.length, val);
+ }
+
+ public static void fill(long[] a, int fromIndex, int toIndex, long val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static void fill(Object[] a, Object val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ public static void fill(Object[] a, int fromIndex, int toIndex, Object val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static void fill(short[] a, short val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ /**
+ * @deprecated Use {@link #fill(short[], int, int, short)} instead.
+ */
+ public static void fill(short[] a, int fromIndex, short val)
+ {
+ java.util.Arrays.fill(a, fromIndex, a.length, val);
+ }
+
+ public static void fill(short[] a, int fromIndex, int toIndex, short val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
}
public static int hashCode(byte[] data)
@@ -660,36 +568,45 @@ public final class Arrays
while (--i >= 0)
{
hc *= 257;
- hc ^= data[i].hashCode();
+ hc ^= Objects.hashCode(data[i]);
}
return hc;
}
+ public static boolean[] clone(boolean[] data)
+ {
+ return null == data ? null : data.clone();
+ }
+
public static byte[] clone(byte[] data)
{
- if (data == null)
- {
- return null;
- }
- byte[] copy = new byte[data.length];
+ return null == data ? null : data.clone();
+ }
- System.arraycopy(data, 0, copy, 0, data.length);
+ public static char[] clone(char[] data)
+ {
+ return null == data ? null : data.clone();
+ }
- return copy;
+ public static int[] clone(int[] data)
+ {
+ return null == data ? null : data.clone();
}
- public static char[] clone(char[] data)
+ public static long[] clone(long[] data)
{
- if (data == null)
- {
- return null;
- }
- char[] copy = new char[data.length];
+ return null == data ? null : data.clone();
+ }
- System.arraycopy(data, 0, copy, 0, data.length);
+ public static short[] clone(short[] data)
+ {
+ return null == data ? null : data.clone();
+ }
- return copy;
+ public static BigInteger[] clone(BigInteger[] data)
+ {
+ return null == data ? null : data.clone();
}
public static byte[] clone(byte[] data, byte[] existing)
@@ -706,31 +623,28 @@ public final class Arrays
return existing;
}
- public static byte[][] clone(byte[][] data)
+ public static long[] clone(long[] data, long[] existing)
{
if (data == null)
{
return null;
}
-
- byte[][] copy = new byte[data.length][];
-
- for (int i = 0; i != copy.length; i++)
+ if ((existing == null) || (existing.length != data.length))
{
- copy[i] = clone(data[i]);
+ return clone(data);
}
-
- return copy;
+ System.arraycopy(data, 0, existing, 0, existing.length);
+ return existing;
}
- public static byte[][][] clone(byte[][][] data)
+ public static byte[][] clone(byte[][] data)
{
if (data == null)
{
return null;
}
- byte[][][] copy = new byte[data.length][][];
+ byte[][] copy = new byte[data.length][];
for (int i = 0; i != copy.length; i++)
{
@@ -740,233 +654,139 @@ public final class Arrays
return copy;
}
- public static int[] clone(int[] data)
+ public static byte[][][] clone(byte[][][] data)
{
if (data == null)
{
return null;
}
- int[] copy = new int[data.length];
- System.arraycopy(data, 0, copy, 0, data.length);
-
- return copy;
- }
+ byte[][][] copy = new byte[data.length][][];
- public static long[] clone(long[] data)
- {
- if (data == null)
+ for (int i = 0; i != copy.length; i++)
{
- return null;
+ copy[i] = clone(data[i]);
}
- long[] copy = new long[data.length];
-
- System.arraycopy(data, 0, copy, 0, data.length);
return copy;
}
- public static long[] clone(long[] data, long[] existing)
+ public static boolean[] copyOf(boolean[] original, int newLength)
{
- if (data == null)
- {
- return null;
- }
- if ((existing == null) || (existing.length != data.length))
- {
- return clone(data);
- }
- System.arraycopy(data, 0, existing, 0, existing.length);
- return existing;
+ boolean[] copy = new boolean[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
}
- public static short[] clone(short[] data)
+ public static byte[] copyOf(byte[] original, int newLength)
{
- if (data == null)
- {
- return null;
- }
- short[] copy = new short[data.length];
-
- System.arraycopy(data, 0, copy, 0, data.length);
-
+ byte[] copy = new byte[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
return copy;
}
- public static BigInteger[] clone(BigInteger[] data)
+ public static char[] copyOf(char[] original, int newLength)
{
- if (data == null)
- {
- return null;
- }
- BigInteger[] copy = new BigInteger[data.length];
-
- System.arraycopy(data, 0, copy, 0, data.length);
-
+ char[] copy = new char[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
return copy;
}
- public static byte[] copyOf(byte[] data, int newLength)
+ public static int[] copyOf(int[] original, int newLength)
{
- byte[] tmp = new byte[newLength];
-
- if (newLength < data.length)
- {
- System.arraycopy(data, 0, tmp, 0, newLength);
- }
- else
- {
- System.arraycopy(data, 0, tmp, 0, data.length);
- }
-
- return tmp;
+ int[] copy = new int[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
}
- public static char[] copyOf(char[] data, int newLength)
+ public static long[] copyOf(long[] original, int newLength)
{
- char[] tmp = new char[newLength];
-
- if (newLength < data.length)
- {
- System.arraycopy(data, 0, tmp, 0, newLength);
- }
- else
- {
- System.arraycopy(data, 0, tmp, 0, data.length);
- }
-
- return tmp;
+ long[] copy = new long[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
}
- public static int[] copyOf(int[] data, int newLength)
+ public static short[] copyOf(short[] original, int newLength)
{
- int[] tmp = new int[newLength];
-
- if (newLength < data.length)
- {
- System.arraycopy(data, 0, tmp, 0, newLength);
- }
- else
- {
- System.arraycopy(data, 0, tmp, 0, data.length);
- }
-
- return tmp;
+ short[] copy = new short[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
}
- public static long[] copyOf(long[] data, int newLength)
+ public static BigInteger[] copyOf(BigInteger[] original, int newLength)
{
- long[] tmp = new long[newLength];
-
- if (newLength < data.length)
- {
- System.arraycopy(data, 0, tmp, 0, newLength);
- }
- else
- {
- System.arraycopy(data, 0, tmp, 0, data.length);
- }
-
- return tmp;
+ BigInteger[] copy = new BigInteger[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
}
- public static BigInteger[] copyOf(BigInteger[] data, int newLength)
+ public static boolean[] copyOfRange(boolean[] original, int from, int to)
{
- BigInteger[] tmp = new BigInteger[newLength];
-
- if (newLength < data.length)
- {
- System.arraycopy(data, 0, tmp, 0, newLength);
- }
- else
- {
- System.arraycopy(data, 0, tmp, 0, data.length);
- }
-
- return tmp;
+ int newLength = getLength(from, to);
+ boolean[] copy = new boolean[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
}
/**
- * Make a copy of a range of bytes from the passed in data array. The range can
- * extend beyond the end of the input array, in which case the return array will
- * be padded with zeroes.
+ * Make a copy of a range of bytes from the passed in array. The range can extend beyond the end
+ * of the input array, in which case the returned array will be padded with zeroes.
*
- * @param data the array from which the data is to be copied.
- * @param from the start index at which the copying should take place.
- * @param to the final index of the range (exclusive).
+ * @param original
+ * the array from which the data is to be copied.
+ * @param from
+ * the start index at which the copying should take place.
+ * @param to
+ * the final index of the range (exclusive).
*
* @return a new byte array containing the range given.
*/
- public static byte[] copyOfRange(byte[] data, int from, int to)
+ public static byte[] copyOfRange(byte[] original, int from, int to)
{
int newLength = getLength(from, to);
-
- byte[] tmp = new byte[newLength];
-
- if (data.length - from < newLength)
- {
- System.arraycopy(data, from, tmp, 0, data.length - from);
- }
- else
- {
- System.arraycopy(data, from, tmp, 0, newLength);
- }
-
- return tmp;
+ byte[] copy = new byte[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
}
- public static int[] copyOfRange(int[] data, int from, int to)
+ public static char[] copyOfRange(char[] original, int from, int to)
{
int newLength = getLength(from, to);
-
- int[] tmp = new int[newLength];
-
- if (data.length - from < newLength)
- {
- System.arraycopy(data, from, tmp, 0, data.length - from);
- }
- else
- {
- System.arraycopy(data, from, tmp, 0, newLength);
- }
-
- return tmp;
+ char[] copy = new char[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
}
- public static long[] copyOfRange(long[] data, int from, int to)
+ public static int[] copyOfRange(int[] original, int from, int to)
{
int newLength = getLength(from, to);
-
- long[] tmp = new long[newLength];
-
- if (data.length - from < newLength)
- {
- System.arraycopy(data, from, tmp, 0, data.length - from);
- }
- else
- {
- System.arraycopy(data, from, tmp, 0, newLength);
- }
-
- return tmp;
+ int[] copy = new int[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
}
- public static BigInteger[] copyOfRange(BigInteger[] data, int from, int to)
+ public static long[] copyOfRange(long[] original, int from, int to)
{
int newLength = getLength(from, to);
+ long[] copy = new long[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
+ }
- BigInteger[] tmp = new BigInteger[newLength];
-
- if (data.length - from < newLength)
- {
- System.arraycopy(data, from, tmp, 0, data.length - from);
- }
- else
- {
- System.arraycopy(data, from, tmp, 0, newLength);
- }
+ public static short[] copyOfRange(short[] original, int from, int to)
+ {
+ int newLength = getLength(from, to);
+ short[] copy = new short[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
+ }
- return tmp;
+ public static BigInteger[] copyOfRange(BigInteger[] original, int from, int to)
+ {
+ int newLength = getLength(from, to);
+ BigInteger[] copy = new BigInteger[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
}
private static int getLength(int from, int to)
@@ -1037,84 +857,93 @@ public final class Arrays
return result;
}
-
-
public static byte[] concatenate(byte[] a, byte[] b)
{
- if (a != null && b != null)
+ if (null == a)
{
- byte[] rv = new byte[a.length + b.length];
+ // b might also be null
+ return clone(b);
+ }
+ if (null == b)
+ {
+ // a might also be null
+ return clone(a);
+ }
- System.arraycopy(a, 0, rv, 0, a.length);
- System.arraycopy(b, 0, rv, a.length, b.length);
+ byte[] r = new byte[a.length + b.length];
+ System.arraycopy(a, 0, r, 0, a.length);
+ System.arraycopy(b, 0, r, a.length, b.length);
+ return r;
+ }
- return rv;
- }
- else if (b != null)
+ public static short[] concatenate(short[] a, short[] b)
+ {
+ if (null == a)
{
+ // b might also be null
return clone(b);
}
- else
+ if (null == b)
{
+ // a might also be null
return clone(a);
}
+
+ short[] r = new short[a.length + b.length];
+ System.arraycopy(a, 0, r, 0, a.length);
+ System.arraycopy(b, 0, r, a.length, b.length);
+ return r;
}
public static byte[] concatenate(byte[] a, byte[] b, byte[] c)
{
- if (a != null && b != null && c != null)
- {
- byte[] rv = new byte[a.length + b.length + c.length];
-
- System.arraycopy(a, 0, rv, 0, a.length);
- System.arraycopy(b, 0, rv, a.length, b.length);
- System.arraycopy(c, 0, rv, a.length + b.length, c.length);
-
- return rv;
- }
- else if (a == null)
+ if (null == a)
{
return concatenate(b, c);
}
- else if (b == null)
+ if (null == b)
{
return concatenate(a, c);
}
- else
+ if (null == c)
{
return concatenate(a, b);
}
+
+ byte[] r = new byte[a.length + b.length + c.length];
+ int pos = 0;
+ System.arraycopy(a, 0, r, pos, a.length); pos += a.length;
+ System.arraycopy(b, 0, r, pos, b.length); pos += b.length;
+ System.arraycopy(c, 0, r, pos, c.length);
+ return r;
}
public static byte[] concatenate(byte[] a, byte[] b, byte[] c, byte[] d)
{
- if (a != null && b != null && c != null && d != null)
+ if (null == a)
{
- byte[] rv = new byte[a.length + b.length + c.length + d.length];
-
- System.arraycopy(a, 0, rv, 0, a.length);
- System.arraycopy(b, 0, rv, a.length, b.length);
- System.arraycopy(c, 0, rv, a.length + b.length, c.length);
- System.arraycopy(d, 0, rv, a.length + b.length + c.length, d.length);
-
- return rv;
+ return concatenate(b, c, d);
}
- else if (d == null)
+ if (null == b)
{
- return concatenate(a, b, c);
+ return concatenate(a, c, d);
}
- else if (c == null)
+ if (null == c)
{
return concatenate(a, b, d);
}
- else if (b == null)
+ if (null == d)
{
- return concatenate(a, c, d);
- }
- else
- {
- return concatenate(b, c, d);
+ return concatenate(a, b, c);
}
+
+ byte[] r = new byte[a.length + b.length + c.length + d.length];
+ int pos = 0;
+ System.arraycopy(a, 0, r, pos, a.length); pos += a.length;
+ System.arraycopy(b, 0, r, pos, b.length); pos += b.length;
+ System.arraycopy(c, 0, r, pos, c.length); pos += c.length;
+ System.arraycopy(d, 0, r, pos, d.length);
+ return r;
}
public static byte[] concatenate(byte[][] arrays)
@@ -1139,19 +968,21 @@ public final class Arrays
public static int[] concatenate(int[] a, int[] b)
{
- if (a == null)
+ if (null == a)
{
+ // b might also be null
return clone(b);
}
- if (b == null)
+ if (null == b)
{
+ // a might also be null
return clone(a);
}
- int[] c = new int[a.length + b.length];
- System.arraycopy(a, 0, c, 0, a.length);
- System.arraycopy(b, 0, c, a.length, b.length);
- return c;
+ int[] r = new int[a.length + b.length];
+ System.arraycopy(a, 0, r, 0, a.length);
+ System.arraycopy(b, 0, r, a.length, b.length);
+ return r;
}
public static byte[] prepend(byte[] a, byte b)
@@ -1279,16 +1110,53 @@ public final class Arrays
/**
* Fill input array by zeros
*
- * @param array input array
+ * @param data input array
*/
- public static void clear(byte[] array)
+ public static void clear(byte[] data)
+ {
+ if (null != data)
+ {
+ java.util.Arrays.fill(data, (byte)0x00);
+ }
+ }
+
+ public static void clear(int[] data)
{
- if (array != null)
+ if (null != data)
+ {
+ java.util.Arrays.fill(data, 0);
+ }
+ }
+
+ public static boolean isNullOrContainsNull(Object[] array)
+ {
+ if (null == array)
+ {
+ return true;
+ }
+ int count = array.length;
+ for (int i = 0; i < count; ++i)
{
- for (int i = 0; i < array.length; i++)
+ if (null == array[i])
{
- array[i] = 0;
+ return true;
}
}
+ return false;
+ }
+
+ public static boolean isNullOrEmpty(byte[] array)
+ {
+ return null == array || array.length < 1;
+ }
+
+ public static boolean isNullOrEmpty(int[] array)
+ {
+ return null == array || array.length < 1;
+ }
+
+ public static boolean isNullOrEmpty(Object[] array)
+ {
+ return null == array || array.length < 1;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/BigIntegers.java b/bcprov/src/main/java/org/bouncycastle/util/BigIntegers.java
index 62be36ec..46e2bb02 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/BigIntegers.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/BigIntegers.java
@@ -3,6 +3,9 @@ package org.bouncycastle.util;
import java.math.BigInteger;
import java.security.SecureRandom;
+import org.bouncycastle.math.raw.Mod;
+import org.bouncycastle.math.raw.Nat;
+
/**
* BigInteger utilities.
*/
@@ -10,8 +13,8 @@ public final class BigIntegers
{
public static final BigInteger ZERO = BigInteger.valueOf(0);
public static final BigInteger ONE = BigInteger.valueOf(1);
+ public static final BigInteger TWO = BigInteger.valueOf(2);
- private static final BigInteger TWO = BigInteger.valueOf(2);
private static final BigInteger THREE = BigInteger.valueOf(3);
private static final int MAX_ITERATIONS = 1000;
@@ -19,7 +22,7 @@ public final class BigIntegers
/**
* Return the passed in value as an unsigned byte array.
*
- * @param value value to be converted.
+ * @param value the value to be converted.
* @return a byte array without a leading zero byte if present in the signed encoding.
*/
public static byte[] asUnsignedByteArray(
@@ -27,7 +30,7 @@ public final class BigIntegers
{
byte[] bytes = value.toByteArray();
- if (bytes[0] == 0)
+ if (bytes[0] == 0 && bytes.length != 1)
{
byte[] tmp = new byte[bytes.length - 1];
@@ -40,10 +43,14 @@ public final class BigIntegers
}
/**
- * Return the passed in value as an unsigned byte array.
+ * Return the passed in value as an unsigned byte array of the specified length, padded with
+ * leading zeros as necessary..
*
- * @param value value to be converted.
- * @return a byte array without a leading zero byte if present in the signed encoding.
+ * @param length
+ * the fixed length of the result
+ * @param value
+ * the value to be converted.
+ * @return a byte array padded to a fixed length with leading zeros.
*/
public static byte[] asUnsignedByteArray(int length, BigInteger value)
{
@@ -53,7 +60,7 @@ public final class BigIntegers
return bytes;
}
- int start = bytes[0] == 0 ? 1 : 0;
+ int start = (bytes[0] == 0 && bytes.length != 1) ? 1 : 0;
int count = bytes.length - start;
if (count > length)
@@ -67,6 +74,41 @@ public final class BigIntegers
}
/**
+ * Write the passed in value as unsigned bytes to the specified buffer range, padded with
+ * leading zeros as necessary.
+ *
+ * @param value
+ * the value to be converted.
+ * @param buf
+ * the buffer to which the value is written.
+ * @param off
+ * the start offset in array <code>buf</code> at which the data is written.
+ * @param len
+ * the fixed length of data written (possibly padded with leading zeros).
+ */
+ public static void asUnsignedByteArray(BigInteger value, byte[] buf, int off, int len)
+ {
+ byte[] bytes = value.toByteArray();
+ if (bytes.length == len)
+ {
+ System.arraycopy(bytes, 0, buf, off, len);
+ return;
+ }
+
+ int start = (bytes[0] == 0 && bytes.length != 1) ? 1 : 0;
+ int count = bytes.length - start;
+
+ if (count > len)
+ {
+ throw new IllegalArgumentException("standard length exceeded for value");
+ }
+
+ int padLen = len - count;
+ Arrays.fill(buf, off, off + padLen, (byte)0x00);
+ System.arraycopy(bytes, start, buf, off + padLen, count);
+ }
+
+ /**
* Return a random BigInteger not less than 'min' and not greater than 'max'
*
* @param min the least value that may be generated
@@ -124,8 +166,97 @@ public final class BigIntegers
return new BigInteger(1, mag);
}
+ public static int intValueExact(BigInteger x)
+ {
+ // Since Java 1.8 could use BigInteger.intValueExact instead
+ if (x.bitLength() > 31)
+ {
+ throw new ArithmeticException("BigInteger out of int range");
+ }
+
+ return x.intValue();
+ }
+
+ public static long longValueExact(BigInteger x)
+ {
+ // Since Java 1.8 could use BigInteger.longValueExact instead
+ if (x.bitLength() > 63)
+ {
+ throw new ArithmeticException("BigInteger out of long range");
+ }
+
+ return x.longValue();
+ }
+
+ public static BigInteger modOddInverse(BigInteger M, BigInteger X)
+ {
+ if (!M.testBit(0))
+ {
+ throw new IllegalArgumentException("'M' must be odd");
+ }
+ if (M.signum() != 1)
+ {
+ throw new ArithmeticException("BigInteger: modulus not positive");
+ }
+ if (X.signum() < 0 || X.compareTo(M) >= 0)
+ {
+ X = X.mod(M);
+ }
+
+ int bits = M.bitLength();
+ int[] m = Nat.fromBigInteger(bits, M);
+ int[] x = Nat.fromBigInteger(bits, X);
+ int len = m.length;
+ int[] z = Nat.create(len);
+ if (0 == Mod.modOddInverse(m, x, z))
+ {
+ throw new ArithmeticException("BigInteger not invertible.");
+ }
+ return Nat.toBigInteger(len, z);
+ }
+
+ public static BigInteger modOddInverseVar(BigInteger M, BigInteger X)
+ {
+ if (!M.testBit(0))
+ {
+ throw new IllegalArgumentException("'M' must be odd");
+ }
+ if (M.signum() != 1)
+ {
+ throw new ArithmeticException("BigInteger: modulus not positive");
+ }
+ if (M.equals(ONE))
+ {
+ return ZERO;
+ }
+ if (X.signum() < 0 || X.compareTo(M) >= 0)
+ {
+ X = X.mod(M);
+ }
+ if (X.equals(ONE))
+ {
+ return ONE;
+ }
+
+ int bits = M.bitLength();
+ int[] m = Nat.fromBigInteger(bits, M);
+ int[] x = Nat.fromBigInteger(bits, X);
+ int len = m.length;
+ int[] z = Nat.create(len);
+ if (!Mod.modOddInverseVar(m, x, z))
+ {
+ throw new ArithmeticException("BigInteger not invertible.");
+ }
+ return Nat.toBigInteger(len, z);
+ }
+
public static int getUnsignedByteLength(BigInteger n)
{
+ if (n.equals(ZERO))
+ {
+ return 1;
+ }
+
return (n.bitLength() + 7) / 8;
}
@@ -148,7 +279,7 @@ public final class BigIntegers
+ "ce86165a978d719ebf647f362d33fca29cd179fb42401cbaf3df0c614056f9c8"
+ "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f",
16);
- private static final int SQR_MAX_SMALL = 20; // bitlength of 743 * 743
+ private static final int MAX_SMALL = BigInteger.valueOf(743).bitLength(); // bitlength of 743 * 743
/**
* Return a prime number candidate of the specified bit length.
@@ -183,7 +314,7 @@ public final class BigIntegers
base[base.length - 1] |= 0x01;
rv = new BigInteger(1, base);
- if (bitLength > SQR_MAX_SMALL)
+ if (bitLength > MAX_SMALL)
{
while (!rv.gcd(SMALL_PRIMES_PRODUCT).equals(ONE))
{
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Doubles.java b/bcprov/src/main/java/org/bouncycastle/util/Doubles.java
new file mode 100644
index 00000000..d72bc57b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/util/Doubles.java
@@ -0,0 +1,9 @@
+package org.bouncycastle.util;
+
+public class Doubles
+{
+ public static Double valueOf(double value)
+ {
+ return Double.valueOf(value);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Integers.java b/bcprov/src/main/java/org/bouncycastle/util/Integers.java
index cbae4a37..fdacb51f 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Integers.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Integers.java
@@ -5,6 +5,26 @@ package org.bouncycastle.util;
*/
public class Integers
{
+ public static int numberOfLeadingZeros(int i)
+ {
+ return Integer.numberOfLeadingZeros(i);
+ }
+
+ public static int numberOfTrailingZeros(int i)
+ {
+ return Integer.numberOfTrailingZeros(i);
+ }
+
+ public static int reverse(int i)
+ {
+ return Integer.reverse(i);
+ }
+
+ public static int reverseBytes(int i)
+ {
+ return Integer.reverseBytes(i);
+ }
+
public static int rotateLeft(int i, int distance)
{
return Integer.rotateLeft(i, distance);
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Longs.java b/bcprov/src/main/java/org/bouncycastle/util/Longs.java
new file mode 100644
index 00000000..2e502105
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/util/Longs.java
@@ -0,0 +1,29 @@
+package org.bouncycastle.util;
+
+public class Longs
+{
+ public static long reverse(long i)
+ {
+ return Long.reverse(i);
+ }
+
+ public static long reverseBytes(long i)
+ {
+ return Long.reverseBytes(i);
+ }
+
+ public static long rotateLeft(long i, int distance)
+ {
+ return Long.rotateLeft(i, distance);
+ }
+
+ public static long rotateRight(long i, int distance)
+ {
+ return Long.rotateRight(i, distance);
+ }
+
+ public static Long valueOf(long value)
+ {
+ return Long.valueOf(value);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Objects.java b/bcprov/src/main/java/org/bouncycastle/util/Objects.java
new file mode 100644
index 00000000..9ea2ff36
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/util/Objects.java
@@ -0,0 +1,14 @@
+package org.bouncycastle.util;
+
+public class Objects
+{
+ public static boolean areEqual(Object a, Object b)
+ {
+ return a == b || (null != a && null != b && a.equals(b));
+ }
+
+ public static int hashCode(Object obj)
+ {
+ return null == obj ? 0 : obj.hashCode();
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Pack.java b/bcprov/src/main/java/org/bouncycastle/util/Pack.java
index 44b0b278..d0eeef47 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Pack.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Pack.java
@@ -7,14 +7,14 @@ public abstract class Pack
{
public static short bigEndianToShort(byte[] bs, int off)
{
- int n = (bs[ off] & 0xff) << 8;
+ int n = (bs[off] & 0xff) << 8;
n |= (bs[++off] & 0xff);
return (short)n;
}
public static int bigEndianToInt(byte[] bs, int off)
{
- int n = bs[ off] << 24;
+ int n = bs[off] << 24;
n |= (bs[++off] & 0xff) << 16;
n |= (bs[++off] & 0xff) << 8;
n |= (bs[++off] & 0xff);
@@ -30,6 +30,15 @@ public abstract class Pack
}
}
+ public static void bigEndianToInt(byte[] bs, int off, int[] ns, int nsOff, int nsLen)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ ns[nsOff + i] = bigEndianToInt(bs, off);
+ off += 4;
+ }
+ }
+
public static byte[] intToBigEndian(int n)
{
byte[] bs = new byte[4];
@@ -39,10 +48,10 @@ public abstract class Pack
public static void intToBigEndian(int n, byte[] bs, int off)
{
- bs[ off] = (byte)(n >>> 24);
+ bs[off] = (byte)(n >>> 24);
bs[++off] = (byte)(n >>> 16);
- bs[++off] = (byte)(n >>> 8);
- bs[++off] = (byte)(n );
+ bs[++off] = (byte)(n >>> 8);
+ bs[++off] = (byte)(n);
}
public static byte[] intToBigEndian(int[] ns)
@@ -61,6 +70,15 @@ public abstract class Pack
}
}
+ public static void intToBigEndian(int[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ intToBigEndian(ns[nsOff + i], bs, bsOff);
+ bsOff += 4;
+ }
+ }
+
public static long bigEndianToLong(byte[] bs, int off)
{
int hi = bigEndianToInt(bs, off);
@@ -77,6 +95,15 @@ public abstract class Pack
}
}
+ public static void bigEndianToLong(byte[] bs, int bsOff, long[] ns, int nsOff, int nsLen)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ ns[nsOff + i] = bigEndianToLong(bs, bsOff);
+ bsOff += 8;
+ }
+ }
+
public static byte[] longToBigEndian(long n)
{
byte[] bs = new byte[8];
@@ -106,16 +133,42 @@ public abstract class Pack
}
}
+ public static void longToBigEndian(long[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ longToBigEndian(ns[nsOff + i], bs, bsOff);
+ bsOff += 8;
+ }
+ }
+
+ /**
+ * @param value The number
+ * @param bs The target.
+ * @param off Position in target to start.
+ * @param bytes number of bytes to write.
+ *
+ * @deprecated Will be removed
+ */
+ public static void longToBigEndian(long value, byte[] bs, int off, int bytes)
+ {
+ for (int i = bytes - 1; i >= 0; i--)
+ {
+ bs[i + off] = (byte)(value & 0xff);
+ value >>>= 8;
+ }
+ }
+
public static short littleEndianToShort(byte[] bs, int off)
{
- int n = bs[ off] & 0xff;
+ int n = bs[off] & 0xff;
n |= (bs[++off] & 0xff) << 8;
return (short)n;
}
public static int littleEndianToInt(byte[] bs, int off)
{
- int n = bs[ off] & 0xff;
+ int n = bs[off] & 0xff;
n |= (bs[++off] & 0xff) << 8;
n |= (bs[++off] & 0xff) << 16;
n |= bs[++off] << 24;
@@ -160,10 +213,25 @@ public abstract class Pack
public static void shortToLittleEndian(short n, byte[] bs, int off)
{
- bs[ off] = (byte)(n );
- bs[++off] = (byte)(n >>> 8);
+ bs[off] = (byte)(n);
+ bs[++off] = (byte)(n >>> 8);
}
+
+ public static byte[] shortToBigEndian(short n)
+ {
+ byte[] r = new byte[2];
+ shortToBigEndian(n, r, 0);
+ return r;
+ }
+
+ public static void shortToBigEndian(short n, byte[] bs, int off)
+ {
+ bs[off] = (byte)(n >>> 8);
+ bs[++off] = (byte)(n);
+ }
+
+
public static byte[] intToLittleEndian(int n)
{
byte[] bs = new byte[4];
@@ -173,8 +241,8 @@ public abstract class Pack
public static void intToLittleEndian(int n, byte[] bs, int off)
{
- bs[ off] = (byte)(n );
- bs[++off] = (byte)(n >>> 8);
+ bs[off] = (byte)(n);
+ bs[++off] = (byte)(n >>> 8);
bs[++off] = (byte)(n >>> 16);
bs[++off] = (byte)(n >>> 24);
}
@@ -195,6 +263,15 @@ public abstract class Pack
}
}
+ public static void intToLittleEndian(int[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ intToLittleEndian(ns[nsOff + i], bs, bsOff);
+ bsOff += 4;
+ }
+ }
+
public static long littleEndianToLong(byte[] bs, int off)
{
int lo = littleEndianToInt(bs, off);
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Properties.java b/bcprov/src/main/java/org/bouncycastle/util/Properties.java
index c472d187..b87d3ac3 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Properties.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Properties.java
@@ -4,6 +4,7 @@ import java.math.BigInteger;
import java.security.AccessControlException;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.security.Security;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -18,11 +19,10 @@ public class Properties
{
private Properties()
{
-
}
private static final ThreadLocal threadProperties = new ThreadLocal();
-
+
/**
* Return whether a particular override has been set to true.
*
@@ -33,14 +33,31 @@ public class Properties
{
try
{
- String p = fetchProperty(propertyName);
+ return isSetTrue(getPropertyValue(propertyName));
+ }
+ catch (AccessControlException e)
+ {
+ return false;
+ }
+ }
- if (p != null)
+ /**
+ * Return whether a particular override has been set to false.
+ *
+ * @param propertyName the property name for the override.
+ * @param isTrue true if the override should be true, false otherwise.
+ * @return true if the property is set to the value of isTrue, false otherwise.
+ */
+ public static boolean isOverrideSetTo(String propertyName, boolean isTrue)
+ {
+ try
+ {
+ String propertyValue = getPropertyValue(propertyName);
+ if (isTrue)
{
- return "true".equals(Strings.toLowerCase(p));
+ return isSetTrue(propertyValue);
}
-
- return false;
+ return isSetFalse(propertyValue);
}
catch (AccessControlException e)
{
@@ -53,7 +70,7 @@ public class Properties
*
* @param propertyName the property name for the override.
* @param enable true if the override should be enabled, false if it should be disabled.
- * @return true if the override was already set, false otherwise.
+ * @return true if the override was already set true, false otherwise.
*/
public static boolean setThreadOverride(String propertyName, boolean enable)
{
@@ -63,48 +80,44 @@ public class Properties
if (localProps == null)
{
localProps = new HashMap();
+
+ threadProperties.set(localProps);
}
localProps.put(propertyName, enable ? "true" : "false");
- threadProperties.set(localProps);
-
return isSet;
}
/**
- * Enable the specified override property in the current thread only.
+ * Remove any value for the specified override property for the current thread only.
*
* @param propertyName the property name for the override.
- * @return true if the override set true in thread local, false otherwise.
+ * @return true if the override was already set true in thread local, false otherwise.
*/
public static boolean removeThreadOverride(String propertyName)
{
- boolean isSet = isOverrideSet(propertyName);
-
Map localProps = (Map)threadProperties.get();
- if (localProps == null)
+ if (localProps != null)
{
- return false;
- }
-
- localProps.remove(propertyName);
+ String p = (String)localProps.remove(propertyName);
+ if (p != null)
+ {
+ if (localProps.isEmpty())
+ {
+ threadProperties.remove();
+ }
- if (localProps.isEmpty())
- {
- threadProperties.remove();
- }
- else
- {
- threadProperties.set(localProps);
+ return "true".equals(Strings.toLowerCase(p));
+ }
}
- return isSet;
+ return false;
}
public static BigInteger asBigInteger(String propertyName)
{
- String p = fetchProperty(propertyName);
+ String p = getPropertyValue(propertyName);
if (p != null)
{
@@ -118,7 +131,7 @@ public class Properties
{
Set<String> set = new HashSet<String>();
- String p = fetchProperty(propertyName);
+ String p = getPropertyValue(propertyName);
if (p != null)
{
@@ -132,20 +145,63 @@ public class Properties
return Collections.unmodifiableSet(set);
}
- private static String fetchProperty(final String propertyName)
+ public static String getPropertyValue(final String propertyName)
{
- return (String)AccessController.doPrivileged(new PrivilegedAction()
+ String val = (String)AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
- Map localProps = (Map)threadProperties.get();
- if (localProps != null)
- {
- return localProps.get(propertyName);
- }
+ return Security.getProperty(propertyName);
+ }
+ });
+ if (val != null)
+ {
+ return val;
+ }
+ Map localProps = (Map)threadProperties.get();
+ if (localProps != null)
+ {
+ String p = (String)localProps.get(propertyName);
+ if (p != null)
+ {
+ return p;
+ }
+ }
+
+ return (String)AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
return System.getProperty(propertyName);
}
});
}
+
+ private static boolean isSetFalse(String p)
+ {
+ if (p == null || p.length() != 5)
+ {
+ return false;
+ }
+
+ return (p.charAt(0) == 'f' || p.charAt(0) == 'F')
+ && (p.charAt(1) == 'a' || p.charAt(1) == 'A')
+ && (p.charAt(2) == 'l' || p.charAt(2) == 'L')
+ && (p.charAt(3) == 's' || p.charAt(3) == 'S')
+ && (p.charAt(4) == 'e' || p.charAt(4) == 'E');
+ }
+
+ private static boolean isSetTrue(String p)
+ {
+ if (p == null || p.length() != 4)
+ {
+ return false;
+ }
+
+ return (p.charAt(0) == 't' || p.charAt(0) == 'T')
+ && (p.charAt(1) == 'r' || p.charAt(1) == 'R')
+ && (p.charAt(2) == 'u' || p.charAt(2) == 'U')
+ && (p.charAt(3) == 'e' || p.charAt(3) == 'E');
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java b/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java
index 645b151c..1af48607 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java
@@ -49,71 +49,71 @@ public class Base64Encoder
{
initialiseDecodingTable();
}
-
- /**
- * encode the input data producing a base 64 output stream.
- *
- * @return the number of bytes produced.
- */
- public int encode(
- byte[] data,
- int off,
- int length,
- OutputStream out)
- throws IOException
+
+ public int encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) throws IOException
{
- int modulus = length % 3;
- int dataLength = (length - modulus);
- int a1, a2, a3;
-
- for (int i = off; i < off + dataLength; i += 3)
+ int inPos = inOff;
+ int inEnd = inOff + inLen - 2;
+ int outPos = outOff;
+
+ while (inPos < inEnd)
{
- a1 = data[i] & 0xff;
- a2 = data[i + 1] & 0xff;
- a3 = data[i + 2] & 0xff;
-
- out.write(encodingTable[(a1 >>> 2) & 0x3f]);
- out.write(encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f]);
- out.write(encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f]);
- out.write(encodingTable[a3 & 0x3f]);
+ int a1 = inBuf[inPos++];
+ int a2 = inBuf[inPos++] & 0xFF;
+ int a3 = inBuf[inPos++] & 0xFF;
+
+ outBuf[outPos++] = encodingTable[(a1 >>> 2) & 0x3F];
+ outBuf[outPos++] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3F];
+ outBuf[outPos++] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3F];
+ outBuf[outPos++] = encodingTable[a3 & 0x3F];
}
- /*
- * process the tail end.
- */
- int b1, b2, b3;
- int d1, d2;
-
- switch (modulus)
+ switch (inLen - (inPos - inOff))
{
- case 0: /* nothing left to do */
- break;
case 1:
- d1 = data[off + dataLength] & 0xff;
- b1 = (d1 >>> 2) & 0x3f;
- b2 = (d1 << 4) & 0x3f;
-
- out.write(encodingTable[b1]);
- out.write(encodingTable[b2]);
- out.write(padding);
- out.write(padding);
+ {
+ int a1 = inBuf[inPos++] & 0xFF;
+
+ outBuf[outPos++] = encodingTable[(a1 >>> 2) & 0x3F];
+ outBuf[outPos++] = encodingTable[(a1 << 4) & 0x3F];
+ outBuf[outPos++] = padding;
+ outBuf[outPos++] = padding;
break;
+ }
case 2:
- d1 = data[off + dataLength] & 0xff;
- d2 = data[off + dataLength + 1] & 0xff;
-
- b1 = (d1 >>> 2) & 0x3f;
- b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
- b3 = (d2 << 2) & 0x3f;
+ {
+ int a1 = inBuf[inPos++] & 0xFF;
+ int a2 = inBuf[inPos++] & 0xFF;
- out.write(encodingTable[b1]);
- out.write(encodingTable[b2]);
- out.write(encodingTable[b3]);
- out.write(padding);
+ outBuf[outPos++] = encodingTable[(a1 >>> 2) & 0x3F];
+ outBuf[outPos++] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3F];
+ outBuf[outPos++] = encodingTable[(a2 << 2) & 0x3F];
+ outBuf[outPos++] = padding;
break;
}
+ }
- return (dataLength / 3) * 4 + ((modulus == 0) ? 0 : 4);
+ return outPos - outOff;
+ }
+
+ /**
+ * encode the input data producing a base 64 output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public int encode(byte[] buf, int off, int len, OutputStream out)
+ throws IOException
+ {
+ byte[] tmp = new byte[72];
+ while (len > 0)
+ {
+ int inLen = Math.min(54, len);
+ int outLen = encode(buf, off, inLen, tmp, 0);
+ out.write(tmp, 0, outLen);
+ off += inLen;
+ len -= inLen;
+ }
+ return ((len + 2) / 3) * 4;
}
private boolean ignore(
@@ -136,6 +136,8 @@ public class Base64Encoder
throws IOException
{
byte b1, b2, b3, b4;
+ byte[] outBuffer = new byte[54]; // S/MIME standard
+ int bufOff = 0;
int outLen = 0;
int end = off + length;
@@ -191,16 +193,27 @@ public class Base64Encoder
{
throw new IOException("invalid characters encountered in base64 data");
}
+
+ outBuffer[bufOff++] = (byte)((b1 << 2) | (b2 >> 4));
+ outBuffer[bufOff++] = (byte)((b2 << 4) | (b3 >> 2));
+ outBuffer[bufOff++] = (byte)((b3 << 6) | b4);
- out.write((b1 << 2) | (b2 >> 4));
- out.write((b2 << 4) | (b3 >> 2));
- out.write((b3 << 6) | b4);
+ if (bufOff == outBuffer.length)
+ {
+ out.write(outBuffer);
+ bufOff = 0;
+ }
outLen += 3;
i = nextI(data, i, finish);
}
+ if (bufOff > 0)
+ {
+ out.write(outBuffer, 0, bufOff);
+ }
+
int e0 = nextI(data, i, end);
int e1 = nextI(data, e0 + 1, end);
int e2 = nextI(data, e1 + 1, end);
@@ -232,6 +245,8 @@ public class Base64Encoder
throws IOException
{
byte b1, b2, b3, b4;
+ byte[] outBuffer = new byte[54]; // S/MIME standard
+ int bufOff = 0;
int length = 0;
int end = data.length();
@@ -288,15 +303,25 @@ public class Base64Encoder
throw new IOException("invalid characters encountered in base64 data");
}
- out.write((b1 << 2) | (b2 >> 4));
- out.write((b2 << 4) | (b3 >> 2));
- out.write((b3 << 6) | b4);
+ outBuffer[bufOff++] = (byte)((b1 << 2) | (b2 >> 4));
+ outBuffer[bufOff++] = (byte)((b2 << 4) | (b3 >> 2));
+ outBuffer[bufOff++] = (byte)((b3 << 6) | b4);
length += 3;
-
+ if (bufOff == outBuffer.length)
+ {
+ out.write(outBuffer);
+ bufOff = 0;
+ }
+
i = nextI(data, i, finish);
}
+ if (bufOff > 0)
+ {
+ out.write(outBuffer, 0, bufOff);
+ }
+
int e0 = nextI(data, i, end);
int e1 = nextI(data, e0 + 1, end);
int e2 = nextI(data, e1 + 1, end);
diff --git a/bcprov/src/main/java/org/bouncycastle/util/encoders/Hex.java b/bcprov/src/main/java/org/bouncycastle/util/encoders/Hex.java
index 63e9c713..b51c879a 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/encoders/Hex.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/Hex.java
@@ -11,8 +11,8 @@ import org.bouncycastle.util.Strings;
*/
public class Hex
{
- private static final Encoder encoder = new HexEncoder();
-
+ private static final HexEncoder encoder = new HexEncoder();
+
public static String toHexString(
byte[] data)
{
@@ -38,7 +38,7 @@ public class Hex
{
return encode(data, 0, data.length);
}
-
+
/**
* encode the input data producing a Hex encoded byte array.
*
@@ -50,7 +50,7 @@ public class Hex
int length)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
+
try
{
encoder.encode(data, off, length, bOut);
@@ -59,7 +59,7 @@ public class Hex
{
throw new EncoderException("exception encoding Hex string: " + e.getMessage(), e);
}
-
+
return bOut.toByteArray();
}
@@ -75,7 +75,7 @@ public class Hex
{
return encoder.encode(data, 0, data.length, out);
}
-
+
/**
* Hex encode the byte data writing it to the given output stream.
*
@@ -90,7 +90,7 @@ public class Hex
{
return encoder.encode(data, off, length, out);
}
-
+
/**
* decode the Hex encoded input data. It is assumed the input data is valid.
*
@@ -100,7 +100,7 @@ public class Hex
byte[] data)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
+
try
{
encoder.decode(data, 0, data.length, bOut);
@@ -112,7 +112,7 @@ public class Hex
return bOut.toByteArray();
}
-
+
/**
* decode the Hex encoded String data - whitespace will be ignored.
*
@@ -122,7 +122,7 @@ public class Hex
String data)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
+
try
{
encoder.decode(data, bOut);
@@ -131,10 +131,10 @@ public class Hex
{
throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e);
}
-
+
return bOut.toByteArray();
}
-
+
/**
* decode the Hex encoded String data writing it to the given output stream,
* whitespace characters will be ignored.
@@ -148,4 +148,40 @@ public class Hex
{
return encoder.decode(data, out);
}
+
+ /**
+ * Decode the hexadecimal-encoded string strictly i.e. any non-hexadecimal characters will be
+ * considered an error.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decodeStrict(String str)
+ {
+ try
+ {
+ return encoder.decodeStrict(str, 0, str.length());
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Decode the hexadecimal-encoded string strictly i.e. any non-hexadecimal characters will be
+ * considered an error.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decodeStrict(String str, int off, int len)
+ {
+ try
+ {
+ return encoder.decodeStrict(str, off, len);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e);
+ }
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java b/bcprov/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java
index 52f8fa6d..6bdafaf3 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java
@@ -31,7 +31,7 @@ public class HexEncoder
{
decodingTable[encodingTable[i]] = (byte)i;
}
-
+
decodingTable['A'] = decodingTable['a'];
decodingTable['B'] = decodingTable['b'];
decodingTable['C'] = decodingTable['c'];
@@ -39,33 +39,47 @@ public class HexEncoder
decodingTable['E'] = decodingTable['e'];
decodingTable['F'] = decodingTable['f'];
}
-
+
public HexEncoder()
{
initialiseDecodingTable();
}
-
+
+ public int encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) throws IOException
+ {
+ int inPos = inOff;
+ int inEnd = inOff + inLen;
+ int outPos = outOff;
+
+ while (inPos < inEnd)
+ {
+ int b = inBuf[inPos++] & 0xFF;
+
+ outBuf[outPos++] = encodingTable[b >>> 4];
+ outBuf[outPos++] = encodingTable[b & 0xF];
+ }
+
+ return outPos - outOff;
+ }
+
/**
* encode the input data producing a Hex output stream.
*
* @return the number of bytes produced.
*/
- public int encode(
- byte[] data,
- int off,
- int length,
- OutputStream out)
+ public int encode(byte[] buf, int off, int len, OutputStream out)
throws IOException
- {
- for (int i = off; i < (off + length); i++)
+ {
+ byte[] tmp = new byte[72];
+ while (len > 0)
{
- int v = data[i] & 0xff;
-
- out.write(encodingTable[(v >>> 4)]);
- out.write(encodingTable[v & 0xf]);
+ int inLen = Math.min(36, len);
+ int outLen = encode(buf, off, inLen, tmp, 0);
+ out.write(tmp, 0, outLen);
+ off += inLen;
+ len -= inLen;
}
-
- return length * 2;
+ return len * 2;
}
private static boolean ignore(
@@ -89,19 +103,21 @@ public class HexEncoder
{
byte b1, b2;
int outLen = 0;
-
+ byte[] buf = new byte[36];
+ int bufOff = 0;
+
int end = off + length;
-
+
while (end > off)
{
if (!ignore((char)data[end - 1]))
{
break;
}
-
+
end--;
}
-
+
int i = off;
while (i < end)
{
@@ -109,14 +125,14 @@ public class HexEncoder
{
i++;
}
-
+
b1 = decodingTable[data[i++]];
-
+
while (i < end && ignore((char)data[i]))
{
i++;
}
-
+
b2 = decodingTable[data[i++]];
if ((b1 | b2) < 0)
@@ -124,14 +140,24 @@ public class HexEncoder
throw new IOException("invalid characters encountered in Hex data");
}
- out.write((b1 << 4) | b2);
-
+ buf[bufOff++] = (byte)((b1 << 4) | b2);
+
+ if (bufOff == buf.length)
+ {
+ out.write(buf);
+ bufOff = 0;
+ }
outLen++;
}
+ if (bufOff > 0)
+ {
+ out.write(buf, 0, bufOff);
+ }
+
return outLen;
}
-
+
/**
* decode the Hex encoded String data writing it to the given output stream,
* whitespace characters will be ignored.
@@ -145,19 +171,21 @@ public class HexEncoder
{
byte b1, b2;
int length = 0;
+ byte[] buf = new byte[36];
+ int bufOff = 0;
int end = data.length();
-
+
while (end > 0)
{
if (!ignore(data.charAt(end - 1)))
{
break;
}
-
+
end--;
}
-
+
int i = 0;
while (i < end)
{
@@ -165,14 +193,14 @@ public class HexEncoder
{
i++;
}
-
+
b1 = decodingTable[data.charAt(i++)];
-
+
while (i < end && ignore(data.charAt(i)))
{
i++;
}
-
+
b2 = decodingTable[data.charAt(i++)];
if ((b1 | b2) < 0)
@@ -180,11 +208,57 @@ public class HexEncoder
throw new IOException("invalid characters encountered in Hex string");
}
- out.write((b1 << 4) | b2);
-
+ buf[bufOff++] = (byte)((b1 << 4) | b2);
+
+ if (bufOff == buf.length)
+ {
+ out.write(buf);
+ bufOff = 0;
+ }
+
length++;
}
+ if (bufOff > 0)
+ {
+ out.write(buf, 0, bufOff);
+ }
+
return length;
}
+
+ byte[] decodeStrict(String str, int off, int len) throws IOException
+ {
+ if (null == str)
+ {
+ throw new NullPointerException("'str' cannot be null");
+ }
+ if (off < 0 || len < 0 || off > (str.length() - len))
+ {
+ throw new IndexOutOfBoundsException("invalid offset and/or length specified");
+ }
+ if (0 != (len & 1))
+ {
+ throw new IOException("a hexadecimal encoding must have an even number of characters");
+ }
+
+ int resultLen = len >>> 1;
+ byte[] result = new byte[resultLen];
+
+ int strPos = off;
+ for (int i = 0; i < resultLen; ++i)
+ {
+ byte b1 = decodingTable[str.charAt(strPos++)];
+ byte b2 = decodingTable[str.charAt(strPos++)];
+
+ int n = (b1 << 4) | b2;
+ if (n < 0)
+ {
+ throw new IOException("invalid characters encountered in Hex string");
+ }
+
+ result[i] = (byte)n;
+ }
+ return result;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/io/TeeInputStream.java b/bcprov/src/main/java/org/bouncycastle/util/io/TeeInputStream.java
index 96da1694..c59881cc 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/io/TeeInputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/io/TeeInputStream.java
@@ -25,6 +25,11 @@ public class TeeInputStream
this.output = output;
}
+ public int available() throws IOException
+ {
+ return input.available();
+ }
+
public int read(byte[] buf)
throws IOException
{
diff --git a/bcprov/src/main/java/org/bouncycastle/util/io/pem/PemReader.java b/bcprov/src/main/java/org/bouncycastle/util/io/pem/PemReader.java
index be9090d9..6616feca 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/io/pem/PemReader.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/io/pem/PemReader.java
@@ -42,10 +42,11 @@ public class PemReader
{
line = line.substring(BEGIN.length());
int index = line.indexOf('-');
- String type = line.substring(0, index);
- if (index > 0)
+ if (index > 0 && line.endsWith("-----") && (line.length() - index) == 5)
{
+ String type = line.substring(0, index);
+
return loadObject(type);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateHolder.java b/bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateHolder.java
index 15375ab1..c072ba50 100644
--- a/bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateHolder.java
+++ b/bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateHolder.java
@@ -148,8 +148,7 @@ public class AttributeCertificateHolder
{
if (holder.getObjectDigestInfo() != null)
{
- return holder.getObjectDigestInfo().getDigestedObjectType()
- .getValue().intValue();
+ return holder.getObjectDigestInfo().getDigestedObjectType().intValueExact();
}
return -1;
}
@@ -338,7 +337,7 @@ public class AttributeCertificateHolder
{
if (holder.getBaseCertificateID() != null)
{
- return holder.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber())
+ return holder.getBaseCertificateID().getSerial().hasValue(x509Cert.getSerialNumber())
&& matchesDN(PrincipalUtil.getIssuerX509Principal(x509Cert), holder.getBaseCertificateID().getIssuer());
}
diff --git a/bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateIssuer.java b/bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateIssuer.java
index 3a342082..c6078672 100644
--- a/bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateIssuer.java
+++ b/bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateIssuer.java
@@ -152,7 +152,7 @@ public class AttributeCertificateIssuer
V2Form issuer = (V2Form)form;
if (issuer.getBaseCertificateID() != null)
{
- return issuer.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber())
+ return issuer.getBaseCertificateID().getSerial().hasValue(x509Cert.getSerialNumber())
&& matchesDN(x509Cert.getIssuerX500Principal(), issuer.getBaseCertificateID().getIssuer());
}
diff --git a/bcprov/src/main/java/org/bouncycastle/x509/CertPathReviewerMessages.properties b/bcprov/src/main/java/org/bouncycastle/x509/CertPathReviewerMessages.properties
index 6843d2c3..7749f3c6 100644
--- a/bcprov/src/main/java/org/bouncycastle/x509/CertPathReviewerMessages.properties
+++ b/bcprov/src/main/java/org/bouncycastle/x509/CertPathReviewerMessages.properties
@@ -74,10 +74,10 @@ CertPathReviewer.ncSubjectNameError.details = Name constraint checking failed: t
## path length errors
# max path length extended
-CertPathReviewer.pathLenghtExtended.title = Maximum path length extended
-CertPathReviewer.pathLenghtExtended.text = Certificate path invalid: Maximum path length extended.
-CertPathReviewer.pathLenghtExtended.summary = Certificate path invalid: Maximum path length extended.
-CertPathReviewer.pathLenghtExtended.details = Certificate path invalid: Maximum path length extended.
+CertPathReviewer.pathLengthExtended.title = Maximum path length extended
+CertPathReviewer.pathLengthExtended.text = Certificate path invalid: Maximum path length extended.
+CertPathReviewer.pathLengthExtended.summary = Certificate path invalid: Maximum path length extended.
+CertPathReviewer.pathLengthExtended.details = Certificate path invalid: Maximum path length extended.
# error reading length constraint from basic constraint extension
CertPathReviewer.processLengthConstError.title = Path length checking failed
diff --git a/bcprov/src/main/java/org/bouncycastle/x509/X509Util.java b/bcprov/src/main/java/org/bouncycastle/x509/X509Util.java
index 4762ec52..2effc5f7 100644
--- a/bcprov/src/main/java/org/bouncycastle/x509/X509Util.java
+++ b/bcprov/src/main/java/org/bouncycastle/x509/X509Util.java
@@ -105,11 +105,13 @@ class X509Util
noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384);
noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512);
noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1);
+ // BEGIN Android-removed:
+ // noParams.add(OIWObjectIdentifiers.dsaWithSHA1);
noParams.add(NISTObjectIdentifiers.dsa_with_sha224);
noParams.add(NISTObjectIdentifiers.dsa_with_sha256);
noParams.add(NISTObjectIdentifiers.dsa_with_sha384);
noParams.add(NISTObjectIdentifiers.dsa_with_sha512);
-
+
//
// RFC 4491
//
diff --git a/bcprov/src/main/java/org/bouncycastle/x509/X509V2AttributeCertificate.java b/bcprov/src/main/java/org/bouncycastle/x509/X509V2AttributeCertificate.java
index 61319a85..96a899bb 100644
--- a/bcprov/src/main/java/org/bouncycastle/x509/X509V2AttributeCertificate.java
+++ b/bcprov/src/main/java/org/bouncycastle/x509/X509V2AttributeCertificate.java
@@ -93,7 +93,7 @@ public class X509V2AttributeCertificate
public int getVersion()
{
- return cert.getAcinfo().getVersion().getValue().intValue() + 1;
+ return cert.getAcinfo().getVersion().intValueExact() + 1;
}
public BigInteger getSerialNumber()
diff --git a/bouncycastle.version b/bouncycastle.version
index 24734c83..bab63ae6 100644
--- a/bouncycastle.version
+++ b/bouncycastle.version
@@ -1,2 +1,2 @@
BOUNCYCASTLE_JDK=15on
-BOUNCYCASTLE_VERSION=161
+BOUNCYCASTLE_VERSION=168
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ApplicationSpecific.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
index 6a6c5119..60cc2336 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
@@ -156,17 +156,17 @@ public abstract class ASN1ApplicationSpecific
/* (non-Javadoc)
* @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
*/
- void encode(ASN1OutputStream out) throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- int classBits = BERTags.APPLICATION;
+ int flags = BERTags.APPLICATION;
if (isConstructed)
{
- classBits |= BERTags.CONSTRUCTED;
+ flags |= BERTags.CONSTRUCTED;
}
- out.writeEncoded(classBits, tag, octets);
+ out.writeEncoded(withTag, flags, tag, octets);
}
-
+
boolean asn1Equals(
ASN1Primitive o)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BitString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BitString.java
index 9975e8fa..38b6b462 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BitString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1BitString.java
@@ -1,7 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
@@ -13,7 +12,6 @@ import com.android.org.bouncycastle.util.io.Streams;
* Base class for BIT STRING objects
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public abstract class ASN1BitString
extends ASN1Primitive
implements ASN1String
@@ -103,6 +101,17 @@ public abstract class ASN1BitString
return result;
}
+ protected ASN1BitString(byte data, int padBits)
+ {
+ if (padBits > 7 || padBits < 0)
+ {
+ throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
+ }
+
+ this.data = new byte[]{ data };
+ this.padBits = padBits;
+ }
+
/**
* Base constructor.
*
@@ -115,7 +124,7 @@ public abstract class ASN1BitString
{
if (data == null)
{
- throw new NullPointerException("data cannot be null");
+ throw new NullPointerException("'data' cannot be null");
}
if (data.length == 0 && padBits != 0)
{
@@ -137,21 +146,18 @@ public abstract class ASN1BitString
*/
public String getString()
{
- StringBuffer buf = new StringBuffer("#");
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
+ StringBuffer buf = new StringBuffer("#");
+ byte[] string;
try
{
- aOut.writeObject(this);
+ string = getEncoded();
}
catch (IOException e)
{
throw new ASN1ParsingException("Internal error encoding BitString: " + e.getMessage(), e);
}
- byte[] string = bOut.toByteArray();
-
for (int i = 0; i != string.length; i++)
{
buf.append(table[(string[i] >>> 4) & 0xf]);
@@ -167,18 +173,16 @@ public abstract class ASN1BitString
public int intValue()
{
int value = 0;
- byte[] string = data;
-
- if (padBits > 0 && data.length <= 4)
+ int end = Math.min(4, data.length - 1);
+ for (int i = 0; i < end; ++i)
{
- string = derForm(data, padBits);
+ value |= (data[i] & 0xFF) << (8 * i);
}
-
- for (int i = 0; i != string.length && i != 4; i++)
+ if (0 <= end && end < 4)
{
- value |= (string[i] & 0xff) << (8 * i);
+ byte der = (byte)(data[end] & (0xFF << padBits));
+ value |= (der & 0xFF) << (8 * end);
}
-
return value;
}
@@ -201,7 +205,15 @@ public abstract class ASN1BitString
public byte[] getBytes()
{
- return derForm(data, padBits);
+ if (0 == data.length)
+ {
+ return data;
+ }
+
+ byte[] rv = Arrays.clone(data);
+ // DER requires pad bits be zero
+ rv[data.length - 1] &= (0xFF << padBits);
+ return rv;
}
public int getPadBits()
@@ -214,13 +226,23 @@ public abstract class ASN1BitString
return getString();
}
- @libcore.api.CorePlatformApi
public int hashCode()
{
- return padBits ^ Arrays.hashCode(this.getBytes());
+ int end = data.length;
+ if (--end < 0)
+ {
+ return 1;
+ }
+
+ byte der = (byte)(data[end] & (0xFF << padBits));
+
+ int hc = Arrays.hashCode(data, 0, end);
+ hc *= 257;
+ hc ^= der;
+ return hc ^ padBits;
}
- protected boolean asn1Equals(
+ boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof ASN1BitString))
@@ -229,21 +251,32 @@ public abstract class ASN1BitString
}
ASN1BitString other = (ASN1BitString)o;
-
- return this.padBits == other.padBits
- && Arrays.areEqual(this.getBytes(), other.getBytes());
- }
-
- protected static byte[] derForm(byte[] data, int padBits)
- {
- byte[] rv = Arrays.clone(data);
- // DER requires pad bits be zero
- if (padBits > 0)
+ if (padBits != other.padBits)
+ {
+ return false;
+ }
+ byte[] a = data, b = other.data;
+ int end = a.length;
+ if (end != b.length)
+ {
+ return false;
+ }
+ if (--end < 0)
+ {
+ return true;
+ }
+ for (int i = 0; i < end; ++i)
{
- rv[data.length - 1] &= 0xff << padBits;
+ if (a[i] != b[i])
+ {
+ return false;
+ }
}
- return rv;
+ byte derA = (byte)(a[end] & (0xFF << padBits));
+ byte derB = (byte)(b[end] & (0xFF << padBits));
+
+ return derA == derB;
}
static ASN1BitString fromInputStream(int length, InputStream stream)
@@ -266,7 +299,7 @@ public abstract class ASN1BitString
if (padBits > 0 && padBits < 8)
{
- if (data[data.length - 1] != (byte)(data[data.length - 1] & (0xff << padBits)))
+ if (data[data.length - 1] != (byte)(data[data.length - 1] & (0xFF << padBits)))
{
return new DLBitString(data, padBits);
}
@@ -291,6 +324,5 @@ public abstract class ASN1BitString
return new DLBitString(data, padBits);
}
- abstract void encode(ASN1OutputStream out)
- throws IOException;
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Boolean.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Boolean.java
index 5390b328..afb0cad1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Boolean.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Boolean.java
@@ -3,12 +3,10 @@ package com.android.org.bouncycastle.asn1;
import java.io.IOException;
-import com.android.org.bouncycastle.util.Arrays;
-
/**
* Public facade of ASN.1 Boolean data.
* <p>
- * Use following to place a new instance of ASN.1 Boolean in your dataset:
+ * Use following to place a new instance of ASN.1 Boolean in your data:
* <ul>
* <li> ASN1Boolean.TRUE literal</li>
* <li> ASN1Boolean.FALSE literal</li>
@@ -20,13 +18,13 @@ import com.android.org.bouncycastle.util.Arrays;
public class ASN1Boolean
extends ASN1Primitive
{
- private static final byte[] TRUE_VALUE = new byte[] { (byte)0xff };
- private static final byte[] FALSE_VALUE = new byte[] { 0 };
+ private static final byte FALSE_VALUE = 0x00;
+ private static final byte TRUE_VALUE = (byte)0xFF;
- private final byte[] value;
+ public static final ASN1Boolean FALSE = new ASN1Boolean(FALSE_VALUE);
+ public static final ASN1Boolean TRUE = new ASN1Boolean(TRUE_VALUE);
- public static final ASN1Boolean FALSE = new ASN1Boolean(false);
- public static final ASN1Boolean TRUE = new ASN1Boolean(true);
+ private final byte value;
/**
* Return a boolean from the passed in object.
@@ -64,10 +62,9 @@ public class ASN1Boolean
* @param value true or false depending on the ASN1Boolean wanted.
* @return an ASN1Boolean instance.
*/
- public static ASN1Boolean getInstance(
- boolean value)
+ public static ASN1Boolean getInstance(boolean value)
{
- return (value ? TRUE : FALSE);
+ return value ? TRUE : FALSE;
}
/**
@@ -75,10 +72,9 @@ public class ASN1Boolean
* @param value non-zero (true) or zero (false) depending on the ASN1Boolean wanted.
* @return an ASN1Boolean instance.
*/
- public static ASN1Boolean getInstance(
- int value)
+ public static ASN1Boolean getInstance(int value)
{
- return (value != 0 ? TRUE : FALSE);
+ return value != 0 ? TRUE : FALSE;
}
// BEGIN Android-added: Unknown reason
@@ -102,9 +98,7 @@ public class ASN1Boolean
* be converted.
* @return an ASN1Boolean instance.
*/
- public static ASN1Boolean getInstance(
- ASN1TaggedObject obj,
- boolean explicit)
+ public static ASN1Boolean getInstance(ASN1TaggedObject obj, boolean explicit)
{
ASN1Primitive o = obj.getObject();
@@ -114,46 +108,18 @@ public class ASN1Boolean
}
else
{
- return ASN1Boolean.fromOctetString(((ASN1OctetString)o).getOctets());
+ return ASN1Boolean.fromOctetString(ASN1OctetString.getInstance(o).getOctets());
}
}
- ASN1Boolean(
- byte[] value)
+ private ASN1Boolean(byte value)
{
- if (value.length != 1)
- {
- throw new IllegalArgumentException("byte value should have 1 byte in it");
- }
-
- if (value[0] == 0)
- {
- this.value = FALSE_VALUE;
- }
- else if ((value[0] & 0xff) == 0xff)
- {
- this.value = TRUE_VALUE;
- }
- else
- {
- this.value = Arrays.clone(value);
- }
- }
-
- /**
- * @deprecated use getInstance(boolean) method.
- * @param value true or false.
- */
- // Android-changed: Reduce visibility to protected
- protected ASN1Boolean(
- boolean value)
- {
- this.value = (value) ? TRUE_VALUE : FALSE_VALUE;
+ this.value = value;
}
public boolean isTrue()
{
- return (value[0] != 0);
+ return value != FALSE_VALUE;
}
boolean isConstructed()
@@ -166,33 +132,36 @@ public class ASN1Boolean
return 3;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.BOOLEAN, value);
+ out.writeEncoded(withTag, BERTags.BOOLEAN, value);
}
- protected boolean asn1Equals(
- ASN1Primitive o)
+ boolean asn1Equals(ASN1Primitive other)
{
- if (o instanceof ASN1Boolean)
+ if (!(other instanceof ASN1Boolean))
{
- return (value[0] == ((ASN1Boolean)o).value[0]);
+ return false;
}
- return false;
+ ASN1Boolean that = (ASN1Boolean)other;
+
+ return this.isTrue() == that.isTrue();
}
public int hashCode()
{
- return value[0];
+ return isTrue() ? 1 : 0;
}
+ ASN1Primitive toDERObject()
+ {
+ return isTrue() ? TRUE : FALSE;
+ }
public String toString()
{
- return (value[0] != 0) ? "TRUE" : "FALSE";
+ return isTrue() ? "TRUE" : "FALSE";
}
static ASN1Boolean fromOctetString(byte[] value)
@@ -202,17 +171,12 @@ public class ASN1Boolean
throw new IllegalArgumentException("BOOLEAN value should have 1 byte in it");
}
- if (value[0] == 0)
- {
- return FALSE;
- }
- else if ((value[0] & 0xff) == 0xff)
- {
- return TRUE;
- }
- else
+ byte b = value[0];
+ switch (b)
{
- return new ASN1Boolean(value);
+ case FALSE_VALUE: return FALSE;
+ case TRUE_VALUE: return TRUE;
+ default: return new ASN1Boolean(b);
}
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Encodable.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Encodable.java
index aa0f2a18..9c9eceac 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Encodable.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Encodable.java
@@ -5,7 +5,6 @@ package com.android.org.bouncycastle.asn1;
* Basic interface to produce serialisers for ASN.1 encodings.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public interface ASN1Encodable
{
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1EncodableVector.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1EncodableVector.java
index 3715a948..7dbd82d3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1EncodableVector.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1EncodableVector.java
@@ -1,50 +1,91 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.util.Enumeration;
-import java.util.Vector;
-
/**
* Mutable class for building ASN.1 constructed objects such as SETs or SEQUENCEs.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class ASN1EncodableVector
{
- private final Vector v = new Vector();
+ static final ASN1Encodable[] EMPTY_ELEMENTS = new ASN1Encodable[0];
+
+ private static final int DEFAULT_CAPACITY = 10;
+
+ private ASN1Encodable[] elements;
+ private int elementCount;
+ private boolean copyOnWrite;
- /**
- * Base constructor.
- */
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public ASN1EncodableVector()
{
+ this(DEFAULT_CAPACITY);
+ }
+
+ public ASN1EncodableVector(int initialCapacity)
+ {
+ if (initialCapacity < 0)
+ {
+ throw new IllegalArgumentException("'initialCapacity' must not be negative");
+ }
+
+ this.elements = (initialCapacity == 0) ? EMPTY_ELEMENTS : new ASN1Encodable[initialCapacity];
+ this.elementCount = 0;
+ this.copyOnWrite = false;
}
- /**
- * Add an encodable to the vector.
- *
- * @param obj the encodable to add.
- */
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
- public void add(ASN1Encodable obj)
+ public void add(ASN1Encodable element)
{
- v.addElement(obj);
+ if (null == element)
+ {
+ throw new NullPointerException("'element' cannot be null");
+ }
+
+ int capacity = elements.length;
+ int minCapacity = elementCount + 1;
+ if ((minCapacity > capacity) | copyOnWrite)
+ {
+ reallocate(minCapacity);
+ }
+
+ this.elements[elementCount] = element;
+ this.elementCount = minCapacity;
}
- /**
- * Add the contents of another vector.
- *
- * @param other the vector to add.
- */
public void addAll(ASN1EncodableVector other)
{
- for (Enumeration en = other.v.elements(); en.hasMoreElements();)
+ if (null == other)
+ {
+ throw new NullPointerException("'other' cannot be null");
+ }
+
+ int otherElementCount = other.size();
+ if (otherElementCount < 1)
+ {
+ return;
+ }
+
+ int capacity = elements.length;
+ int minCapacity = elementCount + otherElementCount;
+ if ((minCapacity > capacity) | copyOnWrite)
+ {
+ reallocate(minCapacity);
+ }
+
+ int i = 0;
+ do
{
- v.addElement(en.nextElement());
+ ASN1Encodable otherElement = other.get(i);
+ if (null == otherElement)
+ {
+ throw new NullPointerException("'other' elements cannot be null");
+ }
+
+ this.elements[elementCount + i] = otherElement;
}
+ while (++i < otherElementCount);
+
+ this.elementCount = minCapacity;
}
/**
@@ -55,7 +96,12 @@ public class ASN1EncodableVector
*/
public ASN1Encodable get(int i)
{
- return (ASN1Encodable)v.elementAt(i);
+ if (i >= elementCount)
+ {
+ throw new ArrayIndexOutOfBoundsException(i + " >= " + elementCount);
+ }
+
+ return elements[i];
}
/**
@@ -65,6 +111,53 @@ public class ASN1EncodableVector
*/
public int size()
{
- return v.size();
+ return elementCount;
+ }
+
+ ASN1Encodable[] copyElements()
+ {
+ if (0 == elementCount)
+ {
+ return EMPTY_ELEMENTS;
+ }
+
+ ASN1Encodable[] copy = new ASN1Encodable[elementCount];
+ System.arraycopy(elements, 0, copy, 0, elementCount);
+ return copy;
+ }
+
+ ASN1Encodable[] takeElements()
+ {
+ if (0 == elementCount)
+ {
+ return EMPTY_ELEMENTS;
+ }
+
+ if (elements.length == elementCount)
+ {
+ this.copyOnWrite = true;
+ return elements;
+ }
+
+ ASN1Encodable[] copy = new ASN1Encodable[elementCount];
+ System.arraycopy(elements, 0, copy, 0, elementCount);
+ return copy;
+ }
+
+ private void reallocate(int minCapacity)
+ {
+ int oldCapacity = elements.length;
+ int newCapacity = Math.max(oldCapacity, minCapacity + (minCapacity >> 1));
+
+ ASN1Encodable[] copy = new ASN1Encodable[newCapacity];
+ System.arraycopy(elements, 0, copy, 0, elementCount);
+
+ this.elements = copy;
+ this.copyOnWrite = false;
+ }
+
+ static ASN1Encodable[] cloneElements(ASN1Encodable[] elements)
+ {
+ return elements.length < 1 ? EMPTY_ELEMENTS : (ASN1Encodable[])elements.clone();
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Enumerated.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Enumerated.java
index 3695b9eb..e67e1746 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Enumerated.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Enumerated.java
@@ -5,7 +5,6 @@ import java.io.IOException;
import java.math.BigInteger;
import com.android.org.bouncycastle.util.Arrays;
-import com.android.org.bouncycastle.util.Properties;
/**
* Class representing the ASN.1 ENUMERATED type.
@@ -15,6 +14,7 @@ public class ASN1Enumerated
extends ASN1Primitive
{
private final byte[] bytes;
+ private final int start;
/**
* return an enumerated from the passed in object
@@ -68,7 +68,7 @@ public class ASN1Enumerated
}
else
{
- return fromOctetString(((ASN1OctetString)o).getOctets());
+ return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -77,10 +77,15 @@ public class ASN1Enumerated
*
* @param value the value of this enumerated.
*/
- public ASN1Enumerated(
- int value)
+ public ASN1Enumerated(int value)
{
- bytes = BigInteger.valueOf(value).toByteArray();
+ if (value < 0)
+ {
+ throw new IllegalArgumentException("enumerated must be non-negative");
+ }
+
+ this.bytes = BigInteger.valueOf(value).toByteArray();
+ this.start = 0;
}
/**
@@ -88,10 +93,15 @@ public class ASN1Enumerated
*
* @param value the value of this enumerated.
*/
- public ASN1Enumerated(
- BigInteger value)
+ public ASN1Enumerated(BigInteger value)
{
- bytes = value.toByteArray();
+ if (value.signum() < 0)
+ {
+ throw new IllegalArgumentException("enumerated must be non-negative");
+ }
+
+ this.bytes = value.toByteArray();
+ this.start = 0;
}
/**
@@ -99,17 +109,19 @@ public class ASN1Enumerated
*
* @param bytes the value of this enumerated as an encoded BigInteger (signed).
*/
- public ASN1Enumerated(
- byte[] bytes)
+ public ASN1Enumerated(byte[] bytes)
{
- if (!Properties.isOverrideSet("com.android.org.bouncycastle.asn1.allow_unsafe_integer"))
+ if (ASN1Integer.isMalformed(bytes))
{
- if (ASN1Integer.isMalformed(bytes))
- {
- throw new IllegalArgumentException("malformed enumerated");
- }
+ throw new IllegalArgumentException("malformed enumerated");
}
+ if (0 != (bytes[0] & 0x80))
+ {
+ throw new IllegalArgumentException("enumerated must be non-negative");
+ }
+
this.bytes = Arrays.clone(bytes);
+ this.start = ASN1Integer.signBytesToSkip(bytes);
}
public BigInteger getValue()
@@ -117,6 +129,25 @@ public class ASN1Enumerated
return new BigInteger(bytes);
}
+ public boolean hasValue(BigInteger x)
+ {
+ return null != x
+ // Fast check to avoid allocation
+ && ASN1Integer.intValue(bytes, start, ASN1Integer.SIGN_EXT_SIGNED) == x.intValue()
+ && getValue().equals(x);
+ }
+
+ public int intValueExact()
+ {
+ int count = bytes.length - start;
+ if (count > 4)
+ {
+ throw new ArithmeticException("ASN.1 Enumerated out of int range");
+ }
+
+ return ASN1Integer.intValue(bytes, start, ASN1Integer.SIGN_EXT_SIGNED);
+ }
+
boolean isConstructed()
{
return false;
@@ -127,13 +158,11 @@ public class ASN1Enumerated
return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.ENUMERATED, bytes);
+ out.writeEncoded(withTag, BERTags.ENUMERATED, bytes);
}
-
+
boolean asn1Equals(
ASN1Primitive o)
{
@@ -169,14 +198,14 @@ public class ASN1Enumerated
if (value >= cache.length)
{
- return new ASN1Enumerated(Arrays.clone(enc));
+ return new ASN1Enumerated(enc);
}
ASN1Enumerated possibleMatch = cache[value];
if (possibleMatch == null)
{
- possibleMatch = cache[value] = new ASN1Enumerated(Arrays.clone(enc));
+ possibleMatch = cache[value] = new ASN1Enumerated(enc);
}
return possibleMatch;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1External.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1External.java
index df55fa53..dee1198f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1External.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1External.java
@@ -108,14 +108,14 @@ public abstract class ASN1External
}
ASN1Primitive toDERObject()
- {
- if (this instanceof DERExternal)
- {
- return this;
- }
+ {
+ return new DERExternal(directReference, indirectReference, dataValueDescriptor, encoding, externalContent);
+ }
- return new DERExternal(directReference, indirectReference, dataValueDescriptor, encoding, externalContent);
- }
+ ASN1Primitive toDLObject()
+ {
+ return new DLExternal(directReference, indirectReference, dataValueDescriptor, encoding, externalContent);
+ }
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GeneralizedTime.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GeneralizedTime.java
index 4c0eb25d..319c9bc9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GeneralizedTime.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1GeneralizedTime.java
@@ -102,7 +102,7 @@ public class ASN1GeneralizedTime
}
else
{
- return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets());
+ return new ASN1GeneralizedTime(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -171,7 +171,16 @@ public class ASN1GeneralizedTime
ASN1GeneralizedTime(
byte[] bytes)
{
+ if (bytes.length < 4)
+ {
+ throw new IllegalArgumentException("GeneralizedTime string too short");
+ }
this.time = bytes;
+
+ if (!(isDigit(0) && isDigit(1) && isDigit(2) && isDigit(3)))
+ {
+ throw new IllegalArgumentException("illegal characters in GeneralizedTime string");
+ }
}
/**
@@ -210,8 +219,16 @@ public class ASN1GeneralizedTime
}
else
{
- int signPos = stime.length() - 5;
+ int signPos = stime.length() - 6;
char sign = stime.charAt(signPos);
+ if ((sign == '-' || sign == '+') && stime.indexOf("GMT") == signPos - 3)
+ {
+ // already a GMT string!
+ return stime;
+ }
+
+ signPos = stime.length() - 5;
+ sign = stime.charAt(signPos);
if (sign == '-' || sign == '+')
{
return stime.substring(0, signPos)
@@ -220,23 +237,21 @@ public class ASN1GeneralizedTime
+ ":"
+ stime.substring(signPos + 3);
}
- else
+
+ signPos = stime.length() - 3;
+ sign = stime.charAt(signPos);
+ if (sign == '-' || sign == '+')
{
- signPos = stime.length() - 3;
- sign = stime.charAt(signPos);
- if (sign == '-' || sign == '+')
- {
- return stime.substring(0, signPos)
- + "GMT"
- + stime.substring(signPos)
- + ":00";
- }
+ return stime.substring(0, signPos)
+ + "GMT"
+ + stime.substring(signPos)
+ + ":00";
}
}
- return stime + calculateGMTOffset();
+ return stime + calculateGMTOffset(stime);
}
- private String calculateGMTOffset()
+ private String calculateGMTOffset(String stime)
{
String sign = "+";
TimeZone timeZone = TimeZone.getDefault();
@@ -251,9 +266,18 @@ public class ASN1GeneralizedTime
try
{
- if (timeZone.useDaylightTime() && timeZone.inDaylightTime(this.getDate()))
+ if (timeZone.useDaylightTime())
{
- hours += sign.equals("+") ? 1 : -1;
+ if (hasFractionalSeconds())
+ {
+ stime = pruneFractionalSeconds(stime);
+ }
+ SimpleDateFormat dateF = calculateGMTDateFormat();
+ if (timeZone.inDaylightTime(
+ dateF.parse(stime + "GMT" + sign + convert(hours) + ":" + convert(minutes))))
+ {
+ hours += sign.equals("+") ? 1 : -1;
+ }
}
}
catch (ParseException e)
@@ -264,6 +288,64 @@ public class ASN1GeneralizedTime
return "GMT" + sign + convert(hours) + ":" + convert(minutes);
}
+ private SimpleDateFormat calculateGMTDateFormat()
+ {
+ SimpleDateFormat dateF;
+
+ if (hasFractionalSeconds())
+ {
+ dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz");
+ }
+ else if (hasSeconds())
+ {
+ dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
+ }
+ else if (hasMinutes())
+ {
+ dateF = new SimpleDateFormat("yyyyMMddHHmmz");
+ }
+ else
+ {
+ dateF = new SimpleDateFormat("yyyyMMddHHz");
+ }
+
+ dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
+ return dateF;
+ }
+
+ private String pruneFractionalSeconds(String origTime)
+ {
+ // java misinterprets extra digits as being milliseconds...
+ String frac = origTime.substring(14);
+ int index;
+ for (index = 1; index < frac.length(); index++)
+ {
+ char ch = frac.charAt(index);
+ if (!('0' <= ch && ch <= '9'))
+ {
+ break;
+ }
+ }
+
+ if (index - 1 > 3)
+ {
+ frac = frac.substring(0, 4) + frac.substring(index);
+ origTime = origTime.substring(0, 14) + frac;
+ }
+ else if (index - 1 == 1)
+ {
+ frac = frac.substring(0, index) + "00" + frac.substring(index);
+ origTime = origTime.substring(0, 14) + frac;
+ }
+ else if (index - 1 == 2)
+ {
+ frac = frac.substring(0, index) + "0" + frac.substring(index);
+ origTime = origTime.substring(0, 14) + frac;
+ }
+
+ return origTime;
+ }
+
private String convert(int time)
{
if (time < 10)
@@ -313,32 +395,7 @@ public class ASN1GeneralizedTime
else if (stime.indexOf('-') > 0 || stime.indexOf('+') > 0)
{
d = this.getTime();
- if (hasFractionalSeconds())
- {
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz");
- dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz", Locale.US);
- }
- else if (hasSeconds())
- {
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
- dateF = new SimpleDateFormat("yyyyMMddHHmmssz", Locale.US);
- }
- else if (hasMinutes())
- {
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHmmz");
- dateF = new SimpleDateFormat("yyyyMMddHHmmz", Locale.US);
- }
- else
- {
- // Android-changed: Use localized version
- // dateF = new SimpleDateFormat("yyyyMMddHHz");
- dateF = new SimpleDateFormat("yyyyMMddHHz", Locale.US);
- }
-
- dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
+ dateF = calculateGMTDateFormat();
}
else
{
@@ -372,35 +429,9 @@ public class ASN1GeneralizedTime
if (hasFractionalSeconds())
{
- // java misinterprets extra digits as being milliseconds...
- String frac = d.substring(14);
- int index;
- for (index = 1; index < frac.length(); index++)
- {
- char ch = frac.charAt(index);
- if (!('0' <= ch && ch <= '9'))
- {
- break;
- }
- }
-
- if (index - 1 > 3)
- {
- frac = frac.substring(0, 4) + frac.substring(index);
- d = d.substring(0, 14) + frac;
- }
- else if (index - 1 == 1)
- {
- frac = frac.substring(0, index) + "00" + frac.substring(index);
- d = d.substring(0, 14) + frac;
- }
- else if (index - 1 == 2)
- {
- frac = frac.substring(0, index) + "0" + frac.substring(index);
- d = d.substring(0, 14) + frac;
- }
+ d = pruneFractionalSeconds(d);
}
-
+
return DateUtil.epochAdjust(dateF.parse(d));
}
@@ -446,11 +477,9 @@ public class ASN1GeneralizedTime
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.GENERALIZED_TIME, time);
+ out.writeEncoded(withTag, BERTags.GENERALIZED_TIME, time);
}
ASN1Primitive toDERObject()
@@ -458,6 +487,11 @@ public class ASN1GeneralizedTime
return new DERGeneralizedTime(time);
}
+ ASN1Primitive toDLObject()
+ {
+ return new DERGeneralizedTime(time);
+ }
+
boolean asn1Equals(
ASN1Primitive o)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Generator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Generator.java
index 3799c6ff..f651d9b6 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Generator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Generator.java
@@ -9,12 +9,14 @@ import java.io.OutputStream;
*/
public abstract class ASN1Generator
{
+ // TODO This is problematic if we want an isolating buffer for all ASN.1 writes
protected OutputStream _out;
/**
* Base constructor.
*
- * @param out the end output stream that object encodings are written to.
+ * @param out
+ * the end output stream that object encodings are written to.
*/
public ASN1Generator(OutputStream out)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1InputStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1InputStream.java
index 229881cc..dbe0e1a5 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1InputStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1InputStream.java
@@ -16,7 +16,6 @@ import com.android.org.bouncycastle.util.io.Streams;
* returned.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class ASN1InputStream
extends FilterInputStream
implements BERTags
@@ -26,8 +25,7 @@ public class ASN1InputStream
private final byte[][] tmpBuffers;
- @android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
+ @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
public ASN1InputStream(
InputStream is)
{
@@ -41,7 +39,6 @@ public class ASN1InputStream
* @param input array containing ASN.1 encoded data.
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public ASN1InputStream(
byte[] input)
{
@@ -116,7 +113,7 @@ public class ASN1InputStream
protected int readLength()
throws IOException
{
- return readLength(this, limit);
+ return readLength(this, limit, false);
}
protected void readFully(
@@ -146,7 +143,7 @@ public class ASN1InputStream
{
boolean isConstructed = (tag & CONSTRUCTED) != 0;
- DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length);
+ DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length, limit);
if ((tag & APPLICATION) != 0)
{
@@ -167,12 +164,20 @@ public class ASN1InputStream
//
// yes, people actually do this...
//
- ASN1EncodableVector v = buildDEREncodableVector(defIn);
+ ASN1EncodableVector v = readVector(defIn);
ASN1OctetString[] strings = new ASN1OctetString[v.size()];
for (int i = 0; i != strings.length; i++)
{
- strings[i] = (ASN1OctetString)v.get(i);
+ ASN1Encodable asn1Obj = v.get(i);
+ if (asn1Obj instanceof ASN1OctetString)
+ {
+ strings[i] = (ASN1OctetString)asn1Obj;
+ }
+ else
+ {
+ throw new ASN1Exception("unknown object encountered in constructed OCTET STRING: " + asn1Obj.getClass());
+ }
}
return new BEROctetString(strings);
@@ -183,12 +188,12 @@ public class ASN1InputStream
}
else
{
- return DERFactory.createSequence(buildDEREncodableVector(defIn));
+ return DLFactory.createSequence(readVector(defIn));
}
case SET:
- return DERFactory.createSet(buildDEREncodableVector(defIn));
+ return DLFactory.createSet(readVector(defIn));
case EXTERNAL:
- return new DLExternal(buildDEREncodableVector(defIn));
+ return new DLExternal(readVector(defIn));
default:
throw new IOException("unknown tag " + tagNo + " encountered");
}
@@ -197,28 +202,24 @@ public class ASN1InputStream
return createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
}
- ASN1EncodableVector buildEncodableVector()
- throws IOException
+ ASN1EncodableVector readVector(DefiniteLengthInputStream dIn) throws IOException
{
- ASN1EncodableVector v = new ASN1EncodableVector();
- ASN1Primitive o;
-
- while ((o = readObject()) != null)
+ if (dIn.getRemaining() < 1)
{
- v.add(o);
+ return new ASN1EncodableVector(0);
}
+ ASN1InputStream subStream = new ASN1InputStream(dIn);
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1Primitive p;
+ while ((p = subStream.readObject()) != null)
+ {
+ v.add(p);
+ }
return v;
}
- ASN1EncodableVector buildDEREncodableVector(
- DefiniteLengthInputStream dIn) throws IOException
- {
- return new ASN1InputStream(dIn).buildEncodableVector();
- }
-
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public ASN1Primitive readObject()
throws IOException
{
@@ -332,7 +333,7 @@ public class ASN1InputStream
return tagNo;
}
- static int readLength(InputStream s, int limit)
+ static int readLength(InputStream s, int limit, boolean isParsing)
throws IOException
{
int length = s.read();
@@ -374,9 +375,9 @@ public class ASN1InputStream
throw new IOException("corrupted stream - negative length found");
}
- if (length >= limit) // after all we must have read at least 1 byte
+ if (length >= limit && !isParsing) // after all we must have read at least 1 byte
{
- throw new IOException("corrupted stream - out of bounds length found");
+ throw new IOException("corrupted stream - out of bounds length found: " + length + " >= " + limit);
}
}
@@ -387,47 +388,72 @@ public class ASN1InputStream
throws IOException
{
int len = defIn.getRemaining();
- if (defIn.getRemaining() < tmpBuffers.length)
+ if (len >= tmpBuffers.length)
{
- byte[] buf = tmpBuffers[len];
-
- if (buf == null)
- {
- buf = tmpBuffers[len] = new byte[len];
- }
-
- Streams.readFully(defIn, buf);
-
- return buf;
+ return defIn.toByteArray();
}
- else
+
+ byte[] buf = tmpBuffers[len];
+ if (buf == null)
{
- return defIn.toByteArray();
+ buf = tmpBuffers[len] = new byte[len];
}
+
+ defIn.readAllIntoByteArray(buf);
+
+ return buf;
}
private static char[] getBMPCharBuffer(DefiniteLengthInputStream defIn)
throws IOException
{
- int len = defIn.getRemaining() / 2;
- char[] buf = new char[len];
- int totalRead = 0;
- while (totalRead < len)
+ int remainingBytes = defIn.getRemaining();
+ if (0 != (remainingBytes & 1))
+ {
+ throw new IOException("malformed BMPString encoding encountered");
+ }
+
+ char[] string = new char[remainingBytes / 2];
+ int stringPos = 0;
+
+ byte[] buf = new byte[8];
+ while (remainingBytes >= 8)
+ {
+ if (Streams.readFully(defIn, buf, 0, 8) != 8)
+ {
+ throw new EOFException("EOF encountered in middle of BMPString");
+ }
+
+ string[stringPos ] = (char)((buf[0] << 8) | (buf[1] & 0xFF));
+ string[stringPos + 1] = (char)((buf[2] << 8) | (buf[3] & 0xFF));
+ string[stringPos + 2] = (char)((buf[4] << 8) | (buf[5] & 0xFF));
+ string[stringPos + 3] = (char)((buf[6] << 8) | (buf[7] & 0xFF));
+ stringPos += 4;
+ remainingBytes -= 8;
+ }
+ if (remainingBytes > 0)
{
- int ch1 = defIn.read();
- if (ch1 < 0)
+ if (Streams.readFully(defIn, buf, 0, remainingBytes) != remainingBytes)
{
- break;
+ throw new EOFException("EOF encountered in middle of BMPString");
}
- int ch2 = defIn.read();
- if (ch2 < 0)
+
+ int bufPos = 0;
+ do
{
- break;
+ int b1 = buf[bufPos++] << 8;
+ int b2 = buf[bufPos++] & 0xFF;
+ string[stringPos++] = (char)(b1 | b2);
}
- buf[totalRead++] = (char)((ch1 << 8) | (ch2 & 0xff));
+ while (bufPos < remainingBytes);
}
- return buf;
+ if (0 != defIn.getRemaining() || string.length != stringPos)
+ {
+ throw new IllegalStateException();
+ }
+
+ return string;
}
static ASN1Primitive createPrimitiveDERObject(
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Integer.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Integer.java
index 07919e07..4e2d68e2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Integer.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Integer.java
@@ -11,11 +11,14 @@ import com.android.org.bouncycastle.util.Properties;
* Class representing the ASN.1 INTEGER type.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class ASN1Integer
extends ASN1Primitive
{
+ static final int SIGN_EXT_SIGNED = 0xFFFFFFFF;
+ static final int SIGN_EXT_UNSIGNED = 0xFF;
+
private final byte[] bytes;
+ private final int start;
/**
* Return an integer from the passed in object.
@@ -78,10 +81,10 @@ public class ASN1Integer
*
* @param value the long representing the value desired.
*/
- public ASN1Integer(
- long value)
+ public ASN1Integer(long value)
{
- bytes = BigInteger.valueOf(value).toByteArray();
+ this.bytes = BigInteger.valueOf(value).toByteArray();
+ this.start = 0;
}
/**
@@ -90,11 +93,10 @@ public class ASN1Integer
* @param value the BigInteger representing the value desired.
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
- public ASN1Integer(
- BigInteger value)
+ public ASN1Integer(BigInteger value)
{
- bytes = value.toByteArray();
+ this.bytes = value.toByteArray();
+ this.start = 0;
}
/**
@@ -119,62 +121,77 @@ public class ASN1Integer
*
* @param bytes the byte array representing a 2's complement encoding of a BigInteger.
*/
- public ASN1Integer(
- byte[] bytes)
+ public ASN1Integer(byte[] bytes)
{
this(bytes, true);
}
ASN1Integer(byte[] bytes, boolean clone)
{
- // Apply loose validation, see note in public constructor ANS1Integer(byte[])
- if (!Properties.isOverrideSet("com.android.org.bouncycastle.asn1.allow_unsafe_integer"))
- {
- if (isMalformed(bytes))
- {
- throw new IllegalArgumentException("malformed integer");
- }
+ if (isMalformed(bytes))
+ {
+ throw new IllegalArgumentException("malformed integer");
}
- this.bytes = (clone) ? Arrays.clone(bytes) : bytes;
+
+ this.bytes = clone ? Arrays.clone(bytes) : bytes;
+ this.start = signBytesToSkip(bytes);
}
/**
- * Apply the correct validation for an INTEGER primitive following the BER rules.
+ * in some cases positive values get crammed into a space,
+ * that's not quite big enough...
*
- * @param bytes The raw encoding of the integer.
- * @return true if the (in)put fails this validation.
+ * @return the BigInteger that results from treating this ASN.1 INTEGER as unsigned.
*/
- static boolean isMalformed(byte[] bytes)
+ public BigInteger getPositiveValue()
+ {
+ return new BigInteger(1, bytes);
+ }
+
+ public BigInteger getValue()
{
- if (bytes.length > 1)
+ return new BigInteger(bytes);
+ }
+
+ public boolean hasValue(BigInteger x)
+ {
+ return null != x
+ // Fast check to avoid allocation
+ && intValue(bytes, start, SIGN_EXT_SIGNED) == x.intValue()
+ && getValue().equals(x);
+ }
+
+ public int intPositiveValueExact()
+ {
+ int count = bytes.length - start;
+ if (count > 4 || (count == 4 && 0 != (bytes[start] & 0x80)))
{
- if (bytes[0] == 0 && (bytes[1] & 0x80) == 0)
- {
- return true;
- }
- if (bytes[0] == (byte)0xff && (bytes[1] & 0x80) != 0)
- {
- return true;
- }
+ throw new ArithmeticException("ASN.1 Integer out of positive int range");
}
- return false;
+ return intValue(bytes, start, SIGN_EXT_UNSIGNED);
}
- public BigInteger getValue()
+ public int intValueExact()
{
- return new BigInteger(bytes);
+ int count = bytes.length - start;
+ if (count > 4)
+ {
+ throw new ArithmeticException("ASN.1 Integer out of int range");
+ }
+
+ return intValue(bytes, start, SIGN_EXT_SIGNED);
}
- /**
- * in some cases positive values get crammed into a space,
- * that's not quite big enough...
- *
- * @return the BigInteger that results from treating this ASN.1 INTEGER as unsigned.
- */
- public BigInteger getPositiveValue()
+ public long longValueExact()
{
- return new BigInteger(1, bytes);
+ int count = bytes.length - start;
+ if (count > 8)
+ {
+ throw new ArithmeticException("ASN.1 Integer out of long range");
+ }
+
+ return longValue(bytes, start, SIGN_EXT_SIGNED);
}
boolean isConstructed()
@@ -187,27 +204,17 @@ public class ASN1Integer
return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.INTEGER, bytes);
+ out.writeEncoded(withTag, BERTags.INTEGER, bytes);
}
public int hashCode()
{
- int value = 0;
-
- for (int i = 0; i != bytes.length; i++)
- {
- value ^= (bytes[i] & 0xff) << (i % 4);
- }
-
- return value;
+ return Arrays.hashCode(bytes);
}
- boolean asn1Equals(
- ASN1Primitive o)
+ boolean asn1Equals(ASN1Primitive o)
{
if (!(o instanceof ASN1Integer))
{
@@ -216,7 +223,7 @@ public class ASN1Integer
ASN1Integer other = (ASN1Integer)o;
- return Arrays.areEqual(bytes, other.bytes);
+ return Arrays.areEqual(this.bytes, other.bytes);
}
public String toString()
@@ -224,4 +231,61 @@ public class ASN1Integer
return getValue().toString();
}
+ static int intValue(byte[] bytes, int start, int signExt)
+ {
+ int length = bytes.length;
+ int pos = Math.max(start, length - 4);
+
+ int val = bytes[pos] & signExt;
+ while (++pos < length)
+ {
+ val = (val << 8) | (bytes[pos] & SIGN_EXT_UNSIGNED);
+ }
+ return val;
+ }
+
+ static long longValue(byte[] bytes, int start, int signExt)
+ {
+ int length = bytes.length;
+ int pos = Math.max(start, length - 8);
+
+ long val = bytes[pos] & signExt;
+ while (++pos < length)
+ {
+ val = (val << 8) | (bytes[pos] & SIGN_EXT_UNSIGNED);
+ }
+ return val;
+ }
+
+ /**
+ * Apply the correct validation for an INTEGER primitive following the BER rules.
+ *
+ * @param bytes The raw encoding of the integer.
+ * @return true if the (in)put fails this validation.
+ */
+ static boolean isMalformed(byte[] bytes)
+ {
+ switch (bytes.length)
+ {
+ case 0:
+ return true;
+ case 1:
+ return false;
+ default:
+ return bytes[0] == (bytes[1] >> 7)
+ // Apply loose validation, see note in public constructor ASN1Integer(byte[])
+ && !Properties.isOverrideSet("com.android.org.bouncycastle.asn1.allow_unsafe_integer");
+ }
+ }
+
+ static int signBytesToSkip(byte[] bytes)
+ {
+ int pos = 0, last = bytes.length - 1;
+ while (pos < last
+ && bytes[pos] == (bytes[pos + 1] >> 7))
+ {
+ ++pos;
+ }
+ return pos;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Null.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Null.java
index a0876fc7..6737fd57 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Null.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Null.java
@@ -10,7 +10,6 @@ import java.io.IOException;
* A NULL object - use DERNull.INSTANCE for populating structures.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public abstract class ASN1Null
extends ASN1Primitive
{
@@ -60,7 +59,6 @@ public abstract class ASN1Null
return null;
}
- @libcore.api.CorePlatformApi
public int hashCode()
{
return -1;
@@ -77,8 +75,7 @@ public abstract class ASN1Null
return true;
}
- abstract void encode(ASN1OutputStream out)
- throws IOException;
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
public String toString()
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Object.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Object.java
index c8afd018..d582aa8e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Object.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Object.java
@@ -3,6 +3,7 @@ package com.android.org.bouncycastle.asn1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import com.android.org.bouncycastle.util.Encodable;
@@ -10,29 +11,32 @@ import com.android.org.bouncycastle.util.Encodable;
* Base class for defining an ASN.1 object.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public abstract class ASN1Object
implements ASN1Encodable, Encodable
{
- @libcore.api.CorePlatformApi
public ASN1Object() {
}
+ public void encodeTo(OutputStream output) throws IOException
+ {
+ ASN1OutputStream.create(output).writeObject(this);
+ }
+
+ public void encodeTo(OutputStream output, String encoding) throws IOException
+ {
+ ASN1OutputStream.create(output, encoding).writeObject(this);
+ }
+
/**
* Return the default BER or DER encoding for this object.
*
* @return BER/DER byte encoded object.
* @throws java.io.IOException on encoding error.
*/
- @libcore.api.CorePlatformApi
- public byte[] getEncoded()
- throws IOException
+ public byte[] getEncoded() throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
- aOut.writeObject(this);
-
+ encodeTo(bOut);
return bOut.toByteArray();
}
@@ -43,31 +47,11 @@ public abstract class ASN1Object
* @return byte encoded object.
* @throws IOException on encoding error.
*/
- @libcore.api.CorePlatformApi
- public byte[] getEncoded(
- String encoding)
- throws IOException
+ public byte[] getEncoded(String encoding) throws IOException
{
- if (encoding.equals(ASN1Encoding.DER))
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- DEROutputStream dOut = new DEROutputStream(bOut);
-
- dOut.writeObject(this);
-
- return bOut.toByteArray();
- }
- else if (encoding.equals(ASN1Encoding.DL))
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- DLOutputStream dOut = new DLOutputStream(bOut);
-
- dOut.writeObject(this);
-
- return bOut.toByteArray();
- }
-
- return this.getEncoded();
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ encodeTo(bOut, encoding);
+ return bOut.toByteArray();
}
public int hashCode()
@@ -93,6 +77,8 @@ public abstract class ASN1Object
return this.toASN1Primitive().equals(other.toASN1Primitive());
}
+ // BEGIN Android-changed: Was removed in upstream.
+ // Used by https://source.corp.google.com/android/cts/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
/**
* @deprecated use toASN1Primitive()
* @return the underlying primitive type.
@@ -101,6 +87,7 @@ public abstract class ASN1Object
{
return this.toASN1Primitive();
}
+ // END Android-changed
/**
* Return true if obj is a byte array and represents an object with the given tag value.
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ObjectIdentifier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
index d49d4c80..452a3a0a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
@@ -13,7 +13,6 @@ import com.android.org.bouncycastle.util.Arrays;
* Class representing the ASN.1 OBJECT IDENTIFIER type.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class ASN1ObjectIdentifier
extends ASN1Primitive
{
@@ -28,7 +27,6 @@ public class ASN1ObjectIdentifier
* @return an ASN1ObjectIdentifier instance, or null.
* @throws IllegalArgumentException if the object cannot be converted.
*/
- @libcore.api.CorePlatformApi
public static ASN1ObjectIdentifier getInstance(
Object obj)
{
@@ -174,13 +172,12 @@ public class ASN1ObjectIdentifier
*
* @param identifier a string representation of an OID.
*/
- @libcore.api.CorePlatformApi
public ASN1ObjectIdentifier(
String identifier)
{
if (identifier == null)
{
- throw new IllegalArgumentException("'identifier' cannot be null");
+ throw new NullPointerException("'identifier' cannot be null");
}
if (!isValidIdentifier(identifier))
{
@@ -212,7 +209,6 @@ public class ASN1ObjectIdentifier
*
* @return the string representation of the OID carried by this object.
*/
- @libcore.api.CorePlatformApi
public String getId()
{
return identifier;
@@ -335,15 +331,9 @@ public class ASN1ObjectIdentifier
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- byte[] enc = getBody();
-
- out.write(BERTags.OBJECT_IDENTIFIER);
- out.writeLength(enc.length);
- out.write(enc);
+ out.writeEncoded(withTag, BERTags.OBJECT_IDENTIFIER, getBody());
}
public int hashCode()
@@ -375,35 +365,40 @@ public class ASN1ObjectIdentifier
private static boolean isValidBranchID(
String branchID, int start)
{
- boolean periodAllowed = false;
+ int digitCount = 0;
int pos = branchID.length();
while (--pos >= start)
{
char ch = branchID.charAt(pos);
- // TODO Leading zeroes?
- if ('0' <= ch && ch <= '9')
- {
- periodAllowed = true;
- continue;
- }
-
if (ch == '.')
{
- if (!periodAllowed)
+ if (0 == digitCount
+ || (digitCount > 1 && branchID.charAt(pos + 1) == '0'))
{
return false;
}
- periodAllowed = false;
- continue;
+ digitCount = 0;
+ }
+ else if ('0' <= ch && ch <= '9')
+ {
+ ++digitCount;
+ }
+ else
+ {
+ return false;
}
+ }
+ if (0 == digitCount
+ || (digitCount > 1 && branchID.charAt(pos + 1) == '0'))
+ {
return false;
}
- return periodAllowed;
+ return true;
}
private static boolean isValidIdentifier(
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OctetString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OctetString.java
index ded2e140..30351c2d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OctetString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OctetString.java
@@ -98,7 +98,6 @@ import com.android.org.bouncycastle.util.encoders.Hex;
* (Contrast with 8.21.6.)
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public abstract class ASN1OctetString
extends ASN1Primitive
implements ASN1OctetStringParser
@@ -108,28 +107,78 @@ public abstract class ASN1OctetString
/**
* return an Octet String from a tagged object.
*
- * @param obj the tagged object holding the object we want.
+ * @param taggedObject the tagged object holding the object we want.
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
*/
public static ASN1OctetString getInstance(
- ASN1TaggedObject obj,
+ ASN1TaggedObject taggedObject,
boolean explicit)
{
- ASN1Primitive o = obj.getObject();
+ if (explicit)
+ {
+ if (!taggedObject.isExplicit())
+ {
+ throw new IllegalArgumentException("object implicit - explicit expected.");
+ }
+
+ return getInstance(taggedObject.getObject());
+ }
+
+ ASN1Primitive o = taggedObject.getObject();
+
+ /*
+ * constructed object which appears to be explicitly tagged and it's really implicit means
+ * we have to add the surrounding octet string.
+ */
+ if (taggedObject.isExplicit())
+ {
+ ASN1OctetString singleSegment = getInstance(o);
+
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return new BEROctetString(new ASN1OctetString[]{ singleSegment });
+ }
+
+ // TODO Should really be similar to the BERTaggedObject case above:
+// return new DLOctetString(new ASN1OctetString[]{ singleSegment });
+ return (ASN1OctetString)new BEROctetString(new ASN1OctetString[]{ singleSegment }).toDLObject();
+ }
- if (explicit || o instanceof ASN1OctetString)
+ if (o instanceof ASN1OctetString)
{
- return getInstance(o);
+ ASN1OctetString s = (ASN1OctetString)o;
+
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return s;
+ }
+
+ return (ASN1OctetString)s.toDLObject();
}
- else
+
+ /*
+ * in this case the parser returns a sequence, convert it into an octet string.
+ */
+ if (o instanceof ASN1Sequence)
{
- return BEROctetString.fromSequence(ASN1Sequence.getInstance(o));
+ ASN1Sequence s = (ASN1Sequence)o;
+
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return BEROctetString.fromSequence(s);
+ }
+
+ // TODO Should really be similar to the BERTaggedObject case above:
+// return DLOctetString.fromSequence(s);
+ return (ASN1OctetString)BEROctetString.fromSequence(s).toDLObject();
}
+
+ throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
}
-
+
/**
* return an Octet String from the given object.
*
@@ -147,7 +196,7 @@ public abstract class ASN1OctetString
{
try
{
- return ASN1OctetString.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
+ return getInstance(fromByteArray((byte[])obj));
}
catch (IOException e)
{
@@ -177,7 +226,7 @@ public abstract class ASN1OctetString
{
if (string == null)
{
- throw new NullPointerException("string cannot be null");
+ throw new NullPointerException("'string' cannot be null");
}
this.string = string;
}
@@ -207,13 +256,11 @@ public abstract class ASN1OctetString
*
* @return the byte[] representing the OCTET STRING's content.
*/
- @libcore.api.CorePlatformApi
public byte[] getOctets()
{
return string;
}
- @libcore.api.CorePlatformApi
public int hashCode()
{
return Arrays.hashCode(this.getOctets());
@@ -247,8 +294,7 @@ public abstract class ASN1OctetString
return new DEROctetString(string);
}
- abstract void encode(ASN1OutputStream out)
- throws IOException;
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
public String toString()
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OutputStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OutputStream.java
index 34f5ba7b..0c2c931d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OutputStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OutputStream.java
@@ -3,6 +3,7 @@ package com.android.org.bouncycastle.asn1;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.Enumeration;
/**
* Stream that produces output based on the default encoding for the passed in objects.
@@ -10,15 +11,38 @@ import java.io.OutputStream;
*/
public class ASN1OutputStream
{
+ public static ASN1OutputStream create(OutputStream out)
+ {
+ return new ASN1OutputStream(out);
+ }
+
+ public static ASN1OutputStream create(OutputStream out, String encoding)
+ {
+ if (encoding.equals(ASN1Encoding.DER))
+ {
+ return new DEROutputStream(out);
+ }
+ else if (encoding.equals(ASN1Encoding.DL))
+ {
+ return new DLOutputStream(out);
+ }
+ else
+ {
+ return new ASN1OutputStream(out);
+ }
+ }
+
private OutputStream os;
- public ASN1OutputStream(
- OutputStream os)
+ /**
+ * @deprecated Use {@link ASN1OutputStream#create(OutputStream)} instead.
+ */
+ public ASN1OutputStream(OutputStream os)
{
this.os = os;
}
- void writeLength(
+ final void writeLength(
int length)
throws IOException
{
@@ -45,37 +69,173 @@ public class ASN1OutputStream
}
}
- void write(int b)
+ final void write(int b)
throws IOException
{
os.write(b);
}
- void write(byte[] bytes)
+ final void write(byte[] bytes, int off, int len)
throws IOException
{
- os.write(bytes);
+ os.write(bytes, off, len);
}
- void write(byte[] bytes, int off, int len)
+ final void writeElements(ASN1Encodable[] elements)
throws IOException
{
- os.write(bytes, off, len);
+ int count = elements.length;
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive primitive = elements[i].toASN1Primitive();
+
+ writePrimitive(primitive, true);
+ }
+ }
+
+ final void writeElements(Enumeration elements)
+ throws IOException
+ {
+ while (elements.hasMoreElements())
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)elements.nextElement()).toASN1Primitive();
+
+ writePrimitive(primitive, true);
+ }
+ }
+
+ final void writeEncoded(
+ boolean withTag,
+ int tag,
+ byte contents)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(1);
+ write(contents);
}
- void writeEncoded(
+ final void writeEncoded(
+ boolean withTag,
int tag,
- byte[] bytes)
+ byte[] contents)
throws IOException
{
- write(tag);
- writeLength(bytes.length);
- write(bytes);
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(contents.length);
+ write(contents, 0, contents.length);
}
- void writeTag(int flags, int tagNo)
+ final void writeEncoded(
+ boolean withTag,
+ int tag,
+ byte[] contents,
+ int contentsOff,
+ int contentsLen)
throws IOException
{
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(contentsLen);
+ write(contents, contentsOff, contentsLen);
+ }
+
+ final void writeEncoded(
+ boolean withTag,
+ int tag,
+ byte headByte,
+ byte[] tailBytes)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(1 + tailBytes.length);
+ write(headByte);
+ write(tailBytes, 0, tailBytes.length);
+ }
+
+ final void writeEncoded(
+ boolean withTag,
+ int tag,
+ byte headByte,
+ byte[] body,
+ int bodyOff,
+ int bodyLen,
+ byte tailByte)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(2 + bodyLen);
+ write(headByte);
+ write(body, bodyOff, bodyLen);
+ write(tailByte);
+ }
+
+ final void writeEncoded(boolean withTag, int flags, int tagNo, byte[] contents)
+ throws IOException
+ {
+ writeTag(withTag, flags, tagNo);
+ writeLength(contents.length);
+ write(contents, 0, contents.length);
+ }
+
+ final void writeEncodedIndef(boolean withTag, int flags, int tagNo, byte[] contents)
+ throws IOException
+ {
+ writeTag(withTag, flags, tagNo);
+ write(0x80);
+ write(contents, 0, contents.length);
+ write(0x00);
+ write(0x00);
+ }
+
+ final void writeEncodedIndef(boolean withTag, int tag, ASN1Encodable[] elements)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ write(0x80);
+ writeElements(elements);
+ write(0x00);
+ write(0x00);
+ }
+
+ final void writeEncodedIndef(boolean withTag, int tag, Enumeration elements)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ write(0x80);
+ writeElements(elements);
+ write(0x00);
+ write(0x00);
+ }
+
+ final void writeTag(boolean withTag, int flags, int tagNo)
+ throws IOException
+ {
+ if (!withTag)
+ {
+ return;
+ }
+
if (tagNo < 31)
{
write(flags | tagNo);
@@ -106,46 +266,31 @@ public class ASN1OutputStream
}
}
- void writeEncoded(int flags, int tagNo, byte[] bytes)
- throws IOException
+ public void writeObject(ASN1Encodable obj) throws IOException
{
- writeTag(flags, tagNo);
- writeLength(bytes.length);
- write(bytes);
- }
+ if (null == obj)
+ {
+ throw new IOException("null object detected");
+ }
- protected void writeNull()
- throws IOException
- {
- os.write(BERTags.NULL);
- os.write(0x00);
+ writePrimitive(obj.toASN1Primitive(), true);
+ flushInternal();
}
- public void writeObject(
- ASN1Encodable obj)
- throws IOException
+ public void writeObject(ASN1Primitive primitive) throws IOException
{
- if (obj != null)
- {
- obj.toASN1Primitive().encode(this);
- }
- else
+ if (null == primitive)
{
throw new IOException("null object detected");
}
+
+ writePrimitive(primitive, true);
+ flushInternal();
}
- void writeImplicitObject(ASN1Primitive obj)
- throws IOException
+ void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
{
- if (obj != null)
- {
- obj.encode(new ImplicitOutputStream(os));
- }
- else
- {
- throw new IOException("null object detected");
- }
+ primitive.encode(this, withTag);
}
public void close()
@@ -160,37 +305,19 @@ public class ASN1OutputStream
os.flush();
}
- ASN1OutputStream getDERSubStream()
+ void flushInternal()
+ throws IOException
{
- return new DEROutputStream(os);
+ // Placeholder to support future internal buffering
}
- ASN1OutputStream getDLSubStream()
+ DEROutputStream getDERSubStream()
{
- return new DLOutputStream(os);
+ return new DEROutputStream(os);
}
- private class ImplicitOutputStream
- extends ASN1OutputStream
+ ASN1OutputStream getDLSubStream()
{
- private boolean first = true;
-
- public ImplicitOutputStream(OutputStream os)
- {
- super(os);
- }
-
- public void write(int b)
- throws IOException
- {
- if (first)
- {
- first = false;
- }
- else
- {
- super.write(b);
- }
- }
+ return new DLOutputStream(os);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Primitive.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Primitive.java
index 8ad3a8b2..c3b423b9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Primitive.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Primitive.java
@@ -2,18 +2,27 @@
package com.android.org.bouncycastle.asn1;
import java.io.IOException;
+import java.io.OutputStream;
/**
* Base class for ASN.1 primitive objects. These are the actual objects used to generate byte encodings.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public abstract class ASN1Primitive
extends ASN1Object
{
ASN1Primitive()
{
+ }
+
+ public void encodeTo(OutputStream output) throws IOException
+ {
+ ASN1OutputStream.create(output).writeObject(this);
+ }
+ public void encodeTo(OutputStream output, String encoding) throws IOException
+ {
+ ASN1OutputStream.create(output, encoding).writeObject(this);
}
/**
@@ -23,7 +32,6 @@ public abstract class ASN1Primitive
* @return the base ASN.1 object represented by the byte stream.
* @exception IOException if there is a problem parsing the data, or parsing the stream did not exhaust the available data.
*/
- @libcore.api.CorePlatformApi
public static ASN1Primitive fromByteArray(byte[] data)
throws IOException
{
@@ -56,8 +64,17 @@ public abstract class ASN1Primitive
return (o instanceof ASN1Encodable) && asn1Equals(((ASN1Encodable)o).toASN1Primitive());
}
- @libcore.api.CorePlatformApi
- public ASN1Primitive toASN1Primitive()
+ public final boolean equals(ASN1Encodable other)
+ {
+ return this == other || (null != other && asn1Equals(other.toASN1Primitive()));
+ }
+
+ public final boolean equals(ASN1Primitive other)
+ {
+ return this == other || asn1Equals(other);
+ }
+
+ public final ASN1Primitive toASN1Primitive()
{
return this;
}
@@ -97,7 +114,7 @@ public abstract class ASN1Primitive
*/
abstract int encodedLength() throws IOException;
- abstract void encode(ASN1OutputStream out) throws IOException;
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
/**
* Equality (similarity) comparison for two ASN1Primitive objects.
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Sequence.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Sequence.java
index e84992f7..6984a50d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Sequence.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Sequence.java
@@ -4,7 +4,7 @@ package com.android.org.bouncycastle.asn1;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
-import java.util.Vector;
+import java.util.NoSuchElementException;
import com.android.org.bouncycastle.util.Arrays;
@@ -58,12 +58,12 @@ import com.android.org.bouncycastle.util.Arrays;
* </p>
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public abstract class ASN1Sequence
extends ASN1Primitive
implements com.android.org.bouncycastle.util.Iterable<ASN1Encodable>
{
- protected Vector seq = new Vector();
+ // NOTE: Only non-final to support LazyEncodedSequence
+ ASN1Encodable[] elements;
/**
* Return an ASN1Sequence from the given object.
@@ -117,7 +117,7 @@ public abstract class ASN1Sequence
* dealing with implicitly tagged sequences you really <b>should</b>
* be using this method.
*
- * @param obj the tagged object.
+ * @param taggedObject the tagged object.
* @param explicit true if the object is meant to be explicitly tagged,
* false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
@@ -125,48 +125,48 @@ public abstract class ASN1Sequence
* @return an ASN1Sequence instance.
*/
public static ASN1Sequence getInstance(
- ASN1TaggedObject obj,
+ ASN1TaggedObject taggedObject,
boolean explicit)
{
if (explicit)
{
- if (!obj.isExplicit())
+ if (!taggedObject.isExplicit())
{
throw new IllegalArgumentException("object implicit - explicit expected.");
}
- return ASN1Sequence.getInstance(obj.getObject().toASN1Primitive());
+ return getInstance(taggedObject.getObject());
}
- else
+
+ ASN1Primitive o = taggedObject.getObject();
+
+ /*
+ * constructed object which appears to be explicitly tagged when it should be implicit means
+ * we have to add the surrounding sequence.
+ */
+ if (taggedObject.isExplicit())
{
- ASN1Primitive o = obj.getObject();
-
- //
- // constructed object which appears to be explicitly tagged
- // when it should be implicit means we have to add the
- // surrounding sequence.
- //
- if (obj.isExplicit())
+ if (taggedObject instanceof BERTaggedObject)
{
- if (obj instanceof BERTaggedObject)
- {
- return new BERSequence(o);
- }
- else
- {
- return new DLSequence(o);
- }
+ return new BERSequence(o);
}
- else
+
+ return new DLSequence(o);
+ }
+
+ if (o instanceof ASN1Sequence)
+ {
+ ASN1Sequence s = (ASN1Sequence)o;
+
+ if (taggedObject instanceof BERTaggedObject)
{
- if (o instanceof ASN1Sequence)
- {
- return (ASN1Sequence)o;
- }
+ return s;
}
+
+ return (ASN1Sequence)s.toDLObject();
}
- throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
+ throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
}
/**
@@ -174,79 +174,105 @@ public abstract class ASN1Sequence
*/
protected ASN1Sequence()
{
+ this.elements = ASN1EncodableVector.EMPTY_ELEMENTS;
}
/**
* Create a SEQUENCE containing one object.
- * @param obj the object to be put in the SEQUENCE.
+ * @param element the object to be put in the SEQUENCE.
*/
- protected ASN1Sequence(
- ASN1Encodable obj)
+ protected ASN1Sequence(ASN1Encodable element)
{
- seq.addElement(obj);
+ if (null == element)
+ {
+ throw new NullPointerException("'element' cannot be null");
+ }
+
+ this.elements = new ASN1Encodable[]{ element };
}
/**
* Create a SEQUENCE containing a vector of objects.
- * @param v the vector of objects to be put in the SEQUENCE.
+ * @param elementVector the vector of objects to be put in the SEQUENCE.
*/
- protected ASN1Sequence(
- ASN1EncodableVector v)
+ protected ASN1Sequence(ASN1EncodableVector elementVector)
{
- for (int i = 0; i != v.size(); i++)
+ if (null == elementVector)
{
- seq.addElement(v.get(i));
+ throw new NullPointerException("'elementVector' cannot be null");
}
+
+ this.elements = elementVector.takeElements();
}
/**
* Create a SEQUENCE containing an array of objects.
- * @param array the array of objects to be put in the SEQUENCE.
+ * @param elements the array of objects to be put in the SEQUENCE.
*/
- protected ASN1Sequence(
- ASN1Encodable[] array)
+ protected ASN1Sequence(ASN1Encodable[] elements)
{
- for (int i = 0; i != array.length; i++)
+ if (Arrays.isNullOrContainsNull(elements))
{
- seq.addElement(array[i]);
+ throw new NullPointerException("'elements' cannot be null, or contain null");
}
+
+ this.elements = ASN1EncodableVector.cloneElements(elements);
}
- public ASN1Encodable[] toArray()
+ ASN1Sequence(ASN1Encodable[] elements, boolean clone)
{
- ASN1Encodable[] values = new ASN1Encodable[this.size()];
+ this.elements = clone ? ASN1EncodableVector.cloneElements(elements) : elements;
+ }
- for (int i = 0; i != this.size(); i++)
- {
- values[i] = this.getObjectAt(i);
- }
+ public ASN1Encodable[] toArray()
+ {
+ return ASN1EncodableVector.cloneElements(elements);
+ }
- return values;
+ ASN1Encodable[] toArrayInternal()
+ {
+ return elements;
}
public Enumeration getObjects()
{
- return seq.elements();
+ return new Enumeration()
+ {
+ private int pos = 0;
+
+ public boolean hasMoreElements()
+ {
+ return pos < elements.length;
+ }
+
+ public Object nextElement()
+ {
+ if (pos < elements.length)
+ {
+ return elements[pos++];
+ }
+ throw new NoSuchElementException();
+ }
+ };
}
public ASN1SequenceParser parser()
{
- final ASN1Sequence outer = this;
+ // NOTE: Call size() here to 'force' a LazyEncodedSequence
+ final int count = size();
return new ASN1SequenceParser()
{
- private final int max = size();
-
- private int index;
+ private int pos = 0;
public ASN1Encodable readObject() throws IOException
{
- if (index == max)
+ if (count == pos)
{
return null;
}
-
- ASN1Encodable obj = getObjectAt(index++);
+
+ ASN1Encodable obj = elements[pos++];
if (obj instanceof ASN1Sequence)
{
return ((ASN1Sequence)obj).parser();
@@ -261,12 +287,12 @@ public abstract class ASN1Sequence
public ASN1Primitive getLoadedObject()
{
- return outer;
+ return ASN1Sequence.this;
}
-
+
public ASN1Primitive toASN1Primitive()
{
- return outer;
+ return ASN1Sequence.this;
}
};
}
@@ -277,11 +303,9 @@ public abstract class ASN1Sequence
* @param index the sequence number (starting at zero) of the object
* @return the object at the sequence position indicated by index.
*/
- @libcore.api.CorePlatformApi
- public ASN1Encodable getObjectAt(
- int index)
+ public ASN1Encodable getObjectAt(int index)
{
- return (ASN1Encodable)seq.elementAt(index);
+ return elements[index];
}
/**
@@ -289,84 +313,62 @@ public abstract class ASN1Sequence
*
* @return the number of objects in this sequence.
*/
- @libcore.api.CorePlatformApi
public int size()
{
- return seq.size();
+ return elements.length;
}
- @libcore.api.CorePlatformApi
public int hashCode()
{
- Enumeration e = this.getObjects();
- int hashCode = size();
+// return Arrays.hashCode(elements);
+ int i = elements.length;
+ int hc = i + 1;
- while (e.hasMoreElements())
+ while (--i >= 0)
{
- Object o = getNext(e);
- hashCode *= 17;
-
- hashCode ^= o.hashCode();
+ hc *= 257;
+ hc ^= elements[i].toASN1Primitive().hashCode();
}
- return hashCode;
+ return hc;
}
- boolean asn1Equals(
- ASN1Primitive o)
+ boolean asn1Equals(ASN1Primitive other)
{
- if (!(o instanceof ASN1Sequence))
+ if (!(other instanceof ASN1Sequence))
{
return false;
}
-
- ASN1Sequence other = (ASN1Sequence)o;
- if (this.size() != other.size())
+ ASN1Sequence that = (ASN1Sequence)other;
+
+ int count = this.size();
+ if (that.size() != count)
{
return false;
}
- Enumeration s1 = this.getObjects();
- Enumeration s2 = other.getObjects();
-
- while (s1.hasMoreElements())
+ for (int i = 0; i < count; ++i)
{
- ASN1Encodable obj1 = getNext(s1);
- ASN1Encodable obj2 = getNext(s2);
-
- ASN1Primitive o1 = obj1.toASN1Primitive();
- ASN1Primitive o2 = obj2.toASN1Primitive();
+ ASN1Primitive p1 = this.elements[i].toASN1Primitive();
+ ASN1Primitive p2 = that.elements[i].toASN1Primitive();
- if (o1 == o2 || o1.equals(o2))
+ if (p1 != p2 && !p1.asn1Equals(p2))
{
- continue;
+ return false;
}
-
- return false;
}
return true;
}
- private ASN1Encodable getNext(Enumeration e)
- {
- ASN1Encodable encObj = (ASN1Encodable)e.nextElement();
-
- return encObj;
- }
-
/**
* Change current SEQUENCE object to be encoded as {@link DERSequence}.
* This is part of Distinguished Encoding Rules form serialization.
*/
ASN1Primitive toDERObject()
{
- ASN1Sequence derSeq = new DERSequence();
-
- derSeq.seq = this.seq;
-
- return derSeq;
+ return new DERSequence(elements, false);
}
/**
@@ -375,11 +377,7 @@ public abstract class ASN1Sequence
*/
ASN1Primitive toDLObject()
{
- ASN1Sequence dlSeq = new DLSequence();
-
- dlSeq.seq = this.seq;
-
- return dlSeq;
+ return new DLSequence(elements, false);
}
boolean isConstructed()
@@ -387,16 +385,34 @@ public abstract class ASN1Sequence
return true;
}
- abstract void encode(ASN1OutputStream out)
- throws IOException;
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
public String toString()
{
- return seq.toString();
+ // NOTE: Call size() here to 'force' a LazyEncodedSequence
+ int count = size();
+ if (0 == count)
+ {
+ return "[]";
+ }
+
+ StringBuffer sb = new StringBuffer();
+ sb.append('[');
+ for (int i = 0;;)
+ {
+ sb.append(elements[i]);
+ if (++i >= count)
+ {
+ break;
+ }
+ sb.append(", ");
+ }
+ sb.append(']');
+ return sb.toString();
}
public Iterator<ASN1Encodable> iterator()
{
- return new Arrays.Iterator<ASN1Encodable>(toArray());
+ return new Arrays.Iterator<ASN1Encodable>(elements);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Set.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Set.java
index a9541aa1..564d151b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Set.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Set.java
@@ -4,7 +4,7 @@ package com.android.org.bouncycastle.asn1;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
-import java.util.Vector;
+import java.util.NoSuchElementException;
import com.android.org.bouncycastle.util.Arrays;
@@ -100,8 +100,8 @@ public abstract class ASN1Set
extends ASN1Primitive
implements com.android.org.bouncycastle.util.Iterable<ASN1Encodable>
{
- private Vector set = new Vector();
- private boolean isSorted = false;
+ protected final ASN1Encodable[] elements;
+ protected final boolean isSorted;
/**
* return an ASN1Set from the given object.
@@ -155,7 +155,7 @@ public abstract class ASN1Set
* dealing with implicitly tagged sets you really <b>should</b>
* be using this method.
*
- * @param obj the tagged object.
+ * @param taggedObject the tagged object.
* @param explicit true if the object is meant to be explicitly tagged
* false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
@@ -163,125 +163,164 @@ public abstract class ASN1Set
* @return an ASN1Set instance.
*/
public static ASN1Set getInstance(
- ASN1TaggedObject obj,
+ ASN1TaggedObject taggedObject,
boolean explicit)
{
if (explicit)
{
- if (!obj.isExplicit())
+ if (!taggedObject.isExplicit())
{
throw new IllegalArgumentException("object implicit - explicit expected.");
}
- return (ASN1Set)obj.getObject();
+ return getInstance(taggedObject.getObject());
}
- else
+
+ ASN1Primitive o = taggedObject.getObject();
+
+ /*
+ * constructed object which appears to be explicitly tagged and it's really implicit means
+ * we have to add the surrounding set.
+ */
+ if (taggedObject.isExplicit())
{
- ASN1Primitive o = obj.getObject();
-
- //
- // constructed object which appears to be explicitly tagged
- // and it's really implicit means we have to add the
- // surrounding set.
- //
- if (obj.isExplicit())
+ if (taggedObject instanceof BERTaggedObject)
{
- if (obj instanceof BERTaggedObject)
- {
- return new BERSet(o);
- }
- else
- {
- return new DLSet(o);
- }
+ return new BERSet(o);
}
- else
+
+ return new DLSet(o);
+ }
+
+ if (o instanceof ASN1Set)
+ {
+ ASN1Set s = (ASN1Set)o;
+
+ if (taggedObject instanceof BERTaggedObject)
{
- if (o instanceof ASN1Set)
- {
- return (ASN1Set)o;
- }
+ return s;
+ }
- //
- // in this case the parser returns a sequence, convert it
- // into a set.
- //
- if (o instanceof ASN1Sequence)
- {
- ASN1Sequence s = (ASN1Sequence)o;
-
- if (obj instanceof BERTaggedObject)
- {
- return new BERSet(s.toArray());
- }
- else
- {
- return new DLSet(s.toArray());
- }
- }
+ return (ASN1Set)s.toDLObject();
+ }
+
+ /*
+ * in this case the parser returns a sequence, convert it into a set.
+ */
+ if (o instanceof ASN1Sequence)
+ {
+ ASN1Sequence s = (ASN1Sequence)o;
+
+ // NOTE: Will force() a LazyEncodedSequence
+ ASN1Encodable[] elements = s.toArrayInternal();
+
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return new BERSet(false, elements);
}
+
+ return new DLSet(false, elements);
}
- throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
+ throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
}
protected ASN1Set()
{
+ this.elements = ASN1EncodableVector.EMPTY_ELEMENTS;
+ this.isSorted = true;
}
/**
* Create a SET containing one object
- * @param obj object to be added to the SET.
+ * @param element object to be added to the SET.
*/
- protected ASN1Set(
- ASN1Encodable obj)
+ protected ASN1Set(ASN1Encodable element)
{
- set.addElement(obj);
+ if (null == element)
+ {
+ throw new NullPointerException("'element' cannot be null");
+ }
+
+ this.elements = new ASN1Encodable[]{ element };
+ this.isSorted = true;
}
/**
* Create a SET containing a vector of objects.
- * @param v a vector of objects to make up the SET.
+ * @param elementVector a vector of objects to make up the SET.
* @param doSort true if should be sorted DER style, false otherwise.
*/
- protected ASN1Set(
- ASN1EncodableVector v,
- boolean doSort)
+ protected ASN1Set(ASN1EncodableVector elementVector, boolean doSort)
{
- for (int i = 0; i != v.size(); i++)
+ if (null == elementVector)
{
- set.addElement(v.get(i));
+ throw new NullPointerException("'elementVector' cannot be null");
}
- if (doSort)
+ ASN1Encodable[] tmp;
+ if (doSort && elementVector.size() >= 2)
{
- this.sort();
+ tmp = elementVector.copyElements();
+ sort(tmp);
}
+ else
+ {
+ tmp = elementVector.takeElements();
+ }
+
+ this.elements = tmp;
+ this.isSorted = doSort || tmp.length < 2;
}
/**
* Create a SET containing an array of objects.
- * @param array an array of objects to make up the SET.
+ * @param elements an array of objects to make up the SET.
* @param doSort true if should be sorted DER style, false otherwise.
*/
- protected ASN1Set(
- ASN1Encodable[] array,
- boolean doSort)
+ protected ASN1Set(ASN1Encodable[] elements, boolean doSort)
{
- for (int i = 0; i != array.length; i++)
+ if (Arrays.isNullOrContainsNull(elements))
{
- set.addElement(array[i]);
+ throw new NullPointerException("'elements' cannot be null, or contain null");
}
- if (doSort)
+ ASN1Encodable[] tmp = ASN1EncodableVector.cloneElements(elements);
+ if (doSort && tmp.length >= 2)
{
- this.sort();
+ sort(tmp);
}
+
+ this.elements = tmp;
+ this.isSorted = doSort || tmp.length < 2;
+ }
+
+ ASN1Set(boolean isSorted, ASN1Encodable[] elements)
+ {
+ this.elements = elements;
+ this.isSorted = isSorted || elements.length < 2;
}
public Enumeration getObjects()
{
- return set.elements();
+ return new Enumeration()
+ {
+ private int pos = 0;
+
+ public boolean hasMoreElements()
+ {
+ return pos < elements.length;
+ }
+
+ public Object nextElement()
+ {
+ if (pos < elements.length)
+ {
+ return elements[pos++];
+ }
+ throw new NoSuchElementException();
+ }
+ };
}
/**
@@ -290,10 +329,9 @@ public abstract class ASN1Set
* @param index the set number (starting at zero) of the object
* @return the object at the set position indicated by index.
*/
- public ASN1Encodable getObjectAt(
- int index)
+ public ASN1Encodable getObjectAt(int index)
{
- return (ASN1Encodable)set.elementAt(index);
+ return elements[index];
}
/**
@@ -303,39 +341,30 @@ public abstract class ASN1Set
*/
public int size()
{
- return set.size();
+ return elements.length;
}
public ASN1Encodable[] toArray()
{
- ASN1Encodable[] values = new ASN1Encodable[this.size()];
-
- for (int i = 0; i != this.size(); i++)
- {
- values[i] = this.getObjectAt(i);
- }
-
- return values;
+ return ASN1EncodableVector.cloneElements(elements);
}
public ASN1SetParser parser()
{
- final ASN1Set outer = this;
+ final int count = size();
return new ASN1SetParser()
{
- private final int max = size();
-
- private int index;
+ private int pos = 0;
public ASN1Encodable readObject() throws IOException
{
- if (index == max)
+ if (count == pos)
{
return null;
}
- ASN1Encodable obj = getObjectAt(index++);
+ ASN1Encodable obj = elements[pos++];
if (obj instanceof ASN1Sequence)
{
return ((ASN1Sequence)obj).parser();
@@ -350,30 +379,29 @@ public abstract class ASN1Set
public ASN1Primitive getLoadedObject()
{
- return outer;
+ return ASN1Set.this;
}
public ASN1Primitive toASN1Primitive()
{
- return outer;
+ return ASN1Set.this;
}
};
}
public int hashCode()
{
- Enumeration e = this.getObjects();
- int hashCode = size();
+// return Arrays.hashCode(elements);
+ int i = elements.length;
+ int hc = i + 1;
- while (e.hasMoreElements())
+ // NOTE: Order-independent contribution of elements to avoid sorting
+ while (--i >= 0)
{
- Object o = getNext(e);
- hashCode *= 17;
-
- hashCode ^= o.hashCode();
+ hc += elements[i].toASN1Primitive().hashCode();
}
- return hashCode;
+ return hc;
}
/**
@@ -382,31 +410,18 @@ public abstract class ASN1Set
*/
ASN1Primitive toDERObject()
{
+ ASN1Encodable[] tmp;
if (isSorted)
{
- ASN1Set derSet = new DERSet();
-
- derSet.set = this.set;
-
- return derSet;
+ tmp = elements;
}
else
{
- Vector v = new Vector();
-
- for (int i = 0; i != set.size(); i++)
- {
- v.addElement(set.elementAt(i));
- }
-
- ASN1Set derSet = new DERSet();
-
- derSet.set = v;
-
- derSet.sort();
-
- return derSet;
+ tmp = (ASN1Encodable[])elements.clone();
+ sort(tmp);
}
+
+ return new DERSet(true, tmp);
}
/**
@@ -415,83 +430,77 @@ public abstract class ASN1Set
*/
ASN1Primitive toDLObject()
{
- ASN1Set derSet = new DLSet();
-
- derSet.set = this.set;
-
- return derSet;
+ return new DLSet(isSorted, elements);
}
- boolean asn1Equals(
- ASN1Primitive o)
+ boolean asn1Equals(ASN1Primitive other)
{
- if (!(o instanceof ASN1Set))
+ if (!(other instanceof ASN1Set))
{
return false;
}
- ASN1Set other = (ASN1Set)o;
+ ASN1Set that = (ASN1Set)other;
- if (this.size() != other.size())
+ int count = this.size();
+ if (that.size() != count)
{
return false;
}
- Enumeration s1 = this.getObjects();
- Enumeration s2 = other.getObjects();
+ DERSet dis = (DERSet)this.toDERObject();
+ DERSet dat = (DERSet)that.toDERObject();
- while (s1.hasMoreElements())
+ for (int i = 0; i < count; ++i)
{
- ASN1Encodable obj1 = getNext(s1);
- ASN1Encodable obj2 = getNext(s2);
+ ASN1Primitive p1 = dis.elements[i].toASN1Primitive();
+ ASN1Primitive p2 = dat.elements[i].toASN1Primitive();
- ASN1Primitive o1 = obj1.toASN1Primitive();
- ASN1Primitive o2 = obj2.toASN1Primitive();
-
- if (o1 == o2 || o1.equals(o2))
+ if (p1 != p2 && !p1.asn1Equals(p2))
{
- continue;
+ return false;
}
-
- return false;
}
return true;
}
- private ASN1Encodable getNext(Enumeration e)
+ boolean isConstructed()
{
- ASN1Encodable encObj = (ASN1Encodable)e.nextElement();
+ return true;
+ }
+
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
- // unfortunately null was allowed as a substitute for DER null
- if (encObj == null)
+ public String toString()
+ {
+ int count = size();
+ if (0 == count)
{
- return DERNull.INSTANCE;
+ return "[]";
}
- return encObj;
- }
-
- /**
- * return true if a <= b (arrays are assumed padded with zeros).
- */
- private boolean lessThanOrEqual(
- byte[] a,
- byte[] b)
- {
- int len = Math.min(a.length, b.length);
- for (int i = 0; i != len; ++i)
+ StringBuffer sb = new StringBuffer();
+ sb.append('[');
+ for (int i = 0;;)
{
- if (a[i] != b[i])
+ sb.append(elements[i]);
+ if (++i >= count)
{
- return (a[i] & 0xff) < (b[i] & 0xff);
+ break;
}
+ sb.append(", ");
}
- return len == a.length;
+ sb.append(']');
+ return sb.toString();
+ }
+
+ public Iterator<ASN1Encodable> iterator()
+ {
+ return new Arrays.Iterator<ASN1Encodable>(toArray());
}
- private byte[] getDEREncoded(
- ASN1Encodable obj)
+ private static byte[] getDEREncoded(ASN1Encodable obj)
{
try
{
@@ -503,67 +512,98 @@ public abstract class ASN1Set
}
}
- protected void sort()
+ /**
+ * return true if a <= b (arrays are assumed padded with zeros).
+ */
+ private static boolean lessThanOrEqual(byte[] a, byte[] b)
{
- if (!isSorted)
+// assert a.length >= 2 && b.length >= 2;
+
+ /*
+ * NOTE: Set elements in DER encodings are ordered first according to their tags (class and
+ * number); the CONSTRUCTED bit is not part of the tag.
+ *
+ * For SET-OF, this is unimportant. All elements have the same tag and DER requires them to
+ * either all be in constructed form or all in primitive form, according to that tag. The
+ * elements are effectively ordered according to their content octets.
+ *
+ * For SET, the elements will have distinct tags, and each will be in constructed or
+ * primitive form accordingly. Failing to ignore the CONSTRUCTED bit could therefore lead to
+ * ordering inversions.
+ */
+ int a0 = a[0] & ~BERTags.CONSTRUCTED;
+ int b0 = b[0] & ~BERTags.CONSTRUCTED;
+ if (a0 != b0)
+ {
+ return a0 < b0;
+ }
+
+ int last = Math.min(a.length, b.length) - 1;
+ for (int i = 1; i < last; ++i)
{
- isSorted = true;
- if (set.size() > 1)
+ if (a[i] != b[i])
{
- boolean swapped = true;
- int lastSwap = set.size() - 1;
+ return (a[i] & 0xFF) < (b[i] & 0xFF);
+ }
+ }
+ return (a[last] & 0xFF) <= (b[last] & 0xFF);
+ }
- while (swapped)
- {
- int index = 0;
- int swapIndex = 0;
- byte[] a = getDEREncoded((ASN1Encodable)set.elementAt(0));
+ private static void sort(ASN1Encodable[] t)
+ {
+ int count = t.length;
+ if (count < 2)
+ {
+ return;
+ }
- swapped = false;
+ ASN1Encodable eh = t[0], ei = t[1];
+ byte[] bh = getDEREncoded(eh), bi = getDEREncoded(ei);;
- while (index != lastSwap)
- {
- byte[] b = getDEREncoded((ASN1Encodable)set.elementAt(index + 1));
+ if (lessThanOrEqual(bi, bh))
+ {
+ ASN1Encodable et = ei; ei = eh; eh = et;
+ byte[] bt = bi; bi = bh; bh = bt;
+ }
- if (lessThanOrEqual(a, b))
- {
- a = b;
- }
- else
- {
- Object o = set.elementAt(index);
+ for (int i = 2; i < count; ++i)
+ {
+ ASN1Encodable e2 = t[i];
+ byte[] b2 = getDEREncoded(e2);
- set.setElementAt(set.elementAt(index + 1), index);
- set.setElementAt(o, index + 1);
+ if (lessThanOrEqual(bi, b2))
+ {
+ t[i - 2] = eh;
+ eh = ei; bh = bi;
+ ei = e2; bi = b2;
+ continue;
+ }
- swapped = true;
- swapIndex = index;
- }
+ if (lessThanOrEqual(bh, b2))
+ {
+ t[i - 2] = eh;
+ eh = e2; bh = b2;
+ continue;
+ }
- index++;
- }
+ int j = i - 1;
+ while (--j > 0)
+ {
+ ASN1Encodable e1 = t[j - 1];
+ byte[] b1 = getDEREncoded(e1);
- lastSwap = swapIndex;
+ if (lessThanOrEqual(b1, b2))
+ {
+ break;
}
- }
- }
- }
-
- boolean isConstructed()
- {
- return true;
- }
- abstract void encode(ASN1OutputStream out)
- throws IOException;
+ t[j] = e1;
+ }
- public String toString()
- {
- return set.toString();
- }
+ t[j] = e2;
+ }
- public Iterator<ASN1Encodable> iterator()
- {
- return new Arrays.Iterator<ASN1Encodable>(toArray());
+ t[count - 2] = eh;
+ t[count - 1] = ei;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1StreamParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1StreamParser.java
index fe704c8c..2ae9ca77 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1StreamParser.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1StreamParser.java
@@ -74,9 +74,9 @@ public class ASN1StreamParser
switch (tag)
{
case BERTags.SET:
- return new DERSetParser(this);
+ return new DLSetParser(this);
case BERTags.SEQUENCE:
- return new DERSequenceParser(this);
+ return new DLSequenceParser(this);
case BERTags.OCTET_STRING:
return new BEROctetStringParser(this);
}
@@ -103,7 +103,7 @@ public class ASN1StreamParser
{
// Note: !CONSTRUCTED => IMPLICIT
DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in;
- return new DERTaggedObject(false, tag, new DEROctetString(defIn.toByteArray()));
+ return new DLTaggedObject(false, tag, new DEROctetString(defIn.toByteArray()));
}
ASN1EncodableVector v = readVector();
@@ -116,8 +116,8 @@ public class ASN1StreamParser
}
return v.size() == 1
- ? new DERTaggedObject(true, tag, v.get(0))
- : new DERTaggedObject(false, tag, DERFactory.createSequence(v));
+ ? new DLTaggedObject(true, tag, v.get(0))
+ : new DLTaggedObject(false, tag, DLFactory.createSequence(v));
}
public ASN1Encodable readObject()
@@ -144,7 +144,8 @@ public class ASN1StreamParser
//
// calculate length
//
- int length = ASN1InputStream.readLength(_in, _limit);
+ int length = ASN1InputStream.readLength(_in, _limit,
+ tagNo == BERTags.OCTET_STRING || tagNo == BERTags.SEQUENCE || tagNo == BERTags.SET || tagNo == BERTags.EXTERNAL);
if (length < 0) // indefinite-length method
{
@@ -170,7 +171,7 @@ public class ASN1StreamParser
}
else
{
- DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length);
+ DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length, _limit);
if ((tag & BERTags.APPLICATION) != 0)
{
@@ -193,9 +194,9 @@ public class ASN1StreamParser
//
return new BEROctetStringParser(new ASN1StreamParser(defIn));
case BERTags.SEQUENCE:
- return new DERSequenceParser(new ASN1StreamParser(defIn));
+ return new DLSequenceParser(new ASN1StreamParser(defIn));
case BERTags.SET:
- return new DERSetParser(new ASN1StreamParser(defIn));
+ return new DLSetParser(new ASN1StreamParser(defIn));
case BERTags.EXTERNAL:
return new DERExternalParser(new ASN1StreamParser(defIn));
default:
@@ -231,10 +232,14 @@ public class ASN1StreamParser
ASN1EncodableVector readVector() throws IOException
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1Encodable obj = readObject();
+ if (null == obj)
+ {
+ return new ASN1EncodableVector(0);
+ }
- ASN1Encodable obj;
- while ((obj = readObject()) != null)
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ do
{
if (obj instanceof InMemoryRepresentable)
{
@@ -245,7 +250,7 @@ public class ASN1StreamParser
v.add(obj.toASN1Primitive());
}
}
-
+ while ((obj = readObject()) != null);
return v;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1TaggedObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1TaggedObject.java
index 809173bd..bbf65548 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1TaggedObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1TaggedObject.java
@@ -9,15 +9,13 @@ import java.io.IOException;
* rules (as with sequences).
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public abstract class ASN1TaggedObject
extends ASN1Primitive
implements ASN1TaggedObjectParser
{
- int tagNo;
- boolean empty = false;
- boolean explicit = true;
- ASN1Encodable obj = null;
+ final int tagNo;
+ final boolean explicit;
+ final ASN1Encodable obj;
static public ASN1TaggedObject getInstance(
ASN1TaggedObject obj,
@@ -25,7 +23,7 @@ public abstract class ASN1TaggedObject
{
if (explicit)
{
- return (ASN1TaggedObject)obj.getObject();
+ return getInstance(obj.getObject());
}
throw new IllegalArgumentException("implicitly tagged tagged object");
@@ -36,7 +34,7 @@ public abstract class ASN1TaggedObject
{
if (obj == null || obj instanceof ASN1TaggedObject)
{
- return (ASN1TaggedObject)obj;
+ return (ASN1TaggedObject)obj;
}
else if (obj instanceof byte[])
{
@@ -68,83 +66,39 @@ public abstract class ASN1TaggedObject
int tagNo,
ASN1Encodable obj)
{
- if (obj instanceof ASN1Choice)
+ if (null == obj)
{
- this.explicit = true;
+ throw new NullPointerException("'obj' cannot be null");
}
- else
- {
- this.explicit = explicit;
- }
-
- this.tagNo = tagNo;
-
- if (this.explicit)
- {
- this.obj = obj;
- }
- else
- {
- ASN1Primitive prim = obj.toASN1Primitive();
-
- if (prim instanceof ASN1Set)
- {
- ASN1Set s = null;
- }
- this.obj = obj;
- }
+ this.tagNo = tagNo;
+ this.explicit = explicit || (obj instanceof ASN1Choice);
+ this.obj = obj;
}
-
- boolean asn1Equals(
- ASN1Primitive o)
+
+ boolean asn1Equals(ASN1Primitive other)
{
- if (!(o instanceof ASN1TaggedObject))
+ if (!(other instanceof ASN1TaggedObject))
{
return false;
}
-
- ASN1TaggedObject other = (ASN1TaggedObject)o;
-
- if (tagNo != other.tagNo || empty != other.empty || explicit != other.explicit)
+
+ ASN1TaggedObject that = (ASN1TaggedObject)other;
+
+ if (this.tagNo != that.tagNo || this.explicit != that.explicit)
{
return false;
}
-
- if(obj == null)
- {
- if (other.obj != null)
- {
- return false;
- }
- }
- else
- {
- if (!(obj.toASN1Primitive().equals(other.obj.toASN1Primitive())))
- {
- return false;
- }
- }
-
- return true;
+
+ ASN1Primitive p1 = this.obj.toASN1Primitive();
+ ASN1Primitive p2 = that.obj.toASN1Primitive();
+
+ return p1 == p2 || p1.asn1Equals(p2);
}
-
- @libcore.api.CorePlatformApi
+
public int hashCode()
{
- int code = tagNo;
-
- // TODO: actually this is wrong - the problem is that a re-encoded
- // object may end up with a different hashCode due to implicit
- // tagging. As implicit tagging is ambiguous if a sequence is involved
- // it seems the only correct method for both equals and hashCode is to
- // compare the encodings...
- if (obj != null)
- {
- code ^= obj.hashCode();
- }
-
- return code;
+ return tagNo ^ (explicit ? 0x0F : 0xF0) ^ obj.toASN1Primitive().hashCode();
}
/**
@@ -171,11 +125,6 @@ public abstract class ASN1TaggedObject
return explicit;
}
- public boolean isEmpty()
- {
- return empty;
- }
-
/**
* Return whatever was following the tag.
* <p>
@@ -183,15 +132,9 @@ public abstract class ASN1TaggedObject
* trying to extract a tagged object you should be going via the
* appropriate getInstance method.
*/
- @libcore.api.CorePlatformApi
public ASN1Primitive getObject()
{
- if (obj != null)
- {
- return obj.toASN1Primitive();
- }
-
- return null;
+ return obj.toASN1Primitive();
}
/**
@@ -237,8 +180,7 @@ public abstract class ASN1TaggedObject
return new DLTaggedObject(explicit, tagNo, obj);
}
- abstract void encode(ASN1OutputStream out)
- throws IOException;
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
public String toString()
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UTCTime.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UTCTime.java
index 2c173f39..e49ce013 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UTCTime.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1UTCTime.java
@@ -92,7 +92,7 @@ public class ASN1UTCTime
}
else
{
- return new ASN1UTCTime(((ASN1OctetString)o).getOctets());
+ return new ASN1UTCTime(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -161,7 +161,15 @@ public class ASN1UTCTime
ASN1UTCTime(
byte[] time)
{
+ if (time.length < 2)
+ {
+ throw new IllegalArgumentException("UTCTime string too short");
+ }
this.time = time;
+ if (!(isDigit(0) && isDigit(1)))
+ {
+ throw new IllegalArgumentException("illegal characters in UTCTime string");
+ }
}
/**
@@ -277,6 +285,11 @@ public class ASN1UTCTime
}
}
+ private boolean isDigit(int pos)
+ {
+ return time.length > pos && time[pos] >= '0' && time[pos] <= '9';
+ }
+
boolean isConstructed()
{
return false;
@@ -289,20 +302,9 @@ public class ASN1UTCTime
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.write(BERTags.UTC_TIME);
-
- int length = time.length;
-
- out.writeLength(length);
-
- for (int i = 0; i != length; i++)
- {
- out.write((byte)time[i]);
- }
+ out.writeEncoded(withTag, BERTags.UTC_TIME, time);
}
boolean asn1Equals(
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERApplicationSpecific.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERApplicationSpecific.java
index f2d136c7..ae0d363c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERApplicationSpecific.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERApplicationSpecific.java
@@ -99,18 +99,14 @@ public class BERApplicationSpecific
/* (non-Javadoc)
* @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
*/
- void encode(ASN1OutputStream out) throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- int classBits = BERTags.APPLICATION;
+ int flags = BERTags.APPLICATION;
if (isConstructed)
{
- classBits |= BERTags.CONSTRUCTED;
+ flags |= BERTags.CONSTRUCTED;
}
- out.writeTag(classBits, tag);
- out.write(0x80);
- out.write(octets);
- out.write(0x00);
- out.write(0x00);
+ out.writeEncodedIndef(withTag, flags, tag, octets);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERFactory.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERFactory.java
index 4021d189..4f8a2600 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERFactory.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERFactory.java
@@ -8,11 +8,21 @@ class BERFactory
static BERSequence createSequence(ASN1EncodableVector v)
{
- return v.size() < 1 ? EMPTY_SEQUENCE : new BERSequence(v);
+ if (v.size() < 1)
+ {
+ return EMPTY_SEQUENCE;
+ }
+
+ return new BERSequence(v);
}
static BERSet createSet(ASN1EncodableVector v)
{
- return v.size() < 1 ? EMPTY_SET : new BERSet(v);
+ if (v.size() < 1)
+ {
+ return EMPTY_SET;
+ }
+
+ return new BERSet(v);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERGenerator.java
index 880d9543..af27f8a8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERGenerator.java
@@ -11,23 +11,20 @@ import java.io.OutputStream;
public class BERGenerator
extends ASN1Generator
{
- private boolean _tagged = false;
- private boolean _isExplicit;
- private int _tagNo;
+ private boolean _tagged = false;
+ private boolean _isExplicit;
+ private int _tagNo;
- protected BERGenerator(
- OutputStream out)
+ protected BERGenerator(OutputStream out)
{
super(out);
}
- protected BERGenerator(
- OutputStream out,
- int tagNo,
- boolean isExplicit)
+ protected BERGenerator(OutputStream out, int tagNo, boolean isExplicit)
{
super(out);
-
+
+ // TODO Check proper handling of implicit tagging
_tagged = true;
_isExplicit = isExplicit;
_tagNo = tagNo;
@@ -37,18 +34,14 @@ public class BERGenerator
{
return _out;
}
-
- private void writeHdr(
- int tag)
- throws IOException
+
+ private void writeHdr(int tag) throws IOException
{
_out.write(tag);
_out.write(0x80);
}
-
- protected void writeBERHeader(
- int tag)
- throws IOException
+
+ protected void writeBERHeader(int tag) throws IOException
{
if (_tagged)
{
@@ -60,7 +53,7 @@ public class BERGenerator
writeHdr(tag);
}
else
- {
+ {
if ((tag & BERTags.CONSTRUCTED) != 0)
{
writeHdr(tagNum | BERTags.CONSTRUCTED);
@@ -77,12 +70,11 @@ public class BERGenerator
}
}
- protected void writeBEREnd()
- throws IOException
+ protected void writeBEREnd() throws IOException
{
_out.write(0x00);
_out.write(0x00);
-
+
if (_tagged && _isExplicit) // write extra end for tag header
{
_out.write(0x00);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetString.java
index 41a906c6..04c1fada 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetString.java
@@ -4,7 +4,7 @@ package com.android.org.bouncycastle.asn1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Enumeration;
-import java.util.Vector;
+import java.util.NoSuchElementException;
/**
* ASN.1 OctetStrings, with indefinite length rules, and <i>constructed form</i> support.
@@ -24,7 +24,7 @@ import java.util.Vector;
public class BEROctetString
extends ASN1OctetString
{
- private static final int DEFAULT_LENGTH = 1000;
+ private static final int DEFAULT_CHUNK_SIZE = 1000;
private final int chunkSize;
private final ASN1OctetString[] octs;
@@ -41,13 +41,7 @@ public class BEROctetString
{
try
{
- DEROctetString o = (DEROctetString)octs[i];
-
- bOut.write(o.getOctets());
- }
- catch (ClassCastException e)
- {
- throw new IllegalArgumentException(octs[i].getClass().getName() + " found in input should only contain DEROctetString");
+ bOut.write(octs[i].getOctets());
}
catch (IOException e)
{
@@ -65,7 +59,7 @@ public class BEROctetString
public BEROctetString(
byte[] string)
{
- this(string, DEFAULT_LENGTH);
+ this(string, DEFAULT_CHUNK_SIZE);
}
/**
@@ -77,7 +71,7 @@ public class BEROctetString
public BEROctetString(
ASN1OctetString[] octs)
{
- this(octs, DEFAULT_LENGTH);
+ this(octs, DEFAULT_CHUNK_SIZE);
}
/**
@@ -114,15 +108,6 @@ public class BEROctetString
}
/**
- * Return a concatenated byte array of all the octets making up the constructed OCTET STRING
- * @return the full OCTET STRING.
- */
- public byte[] getOctets()
- {
- return string;
- }
-
- /**
* Return the OCTET STRINGs that make up this string.
*
* @return an Enumeration of the component OCTET STRINGs.
@@ -131,7 +116,28 @@ public class BEROctetString
{
if (octs == null)
{
- return generateOcts().elements();
+ return new Enumeration()
+ {
+ int pos = 0;
+
+ public boolean hasMoreElements()
+ {
+ return pos < string.length;
+ }
+
+ public Object nextElement()
+ {
+ if (pos < string.length)
+ {
+ int length = Math.min(string.length - pos, chunkSize);
+ byte[] chunk = new byte[length];
+ System.arraycopy(string, pos, chunk, 0, length);
+ pos += length;
+ return new DEROctetString(chunk);
+ }
+ throw new NoSuchElementException();
+ }
+ };
}
return new Enumeration()
@@ -145,37 +151,15 @@ public class BEROctetString
public Object nextElement()
{
- return octs[counter++];
+ if (counter < octs.length)
+ {
+ return octs[counter++];
+ }
+ throw new NoSuchElementException();
}
};
}
- private Vector generateOcts()
- {
- Vector vec = new Vector();
- for (int i = 0; i < string.length; i += chunkSize)
- {
- int end;
-
- if (i + chunkSize > string.length)
- {
- end = string.length;
- }
- else
- {
- end = i + chunkSize;
- }
-
- byte[] nStr = new byte[end - i];
-
- System.arraycopy(string, i, nStr, 0, nStr.length);
-
- vec.addElement(new DEROctetString(nStr));
- }
-
- return vec;
- }
-
boolean isConstructed()
{
return true;
@@ -193,37 +177,19 @@ public class BEROctetString
return 2 + length + 2;
}
- public void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.write(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
-
- out.write(0x80);
-
- //
- // write out the octet array
- //
- for (Enumeration e = getObjects(); e.hasMoreElements();)
- {
- out.writeObject((ASN1Encodable)e.nextElement());
- }
-
- out.write(0x00);
- out.write(0x00);
+ out.writeEncodedIndef(withTag, BERTags.CONSTRUCTED | BERTags.OCTET_STRING, getObjects());
}
static BEROctetString fromSequence(ASN1Sequence seq)
{
- ASN1OctetString[] v = new ASN1OctetString[seq.size()];
- Enumeration e = seq.getObjects();
- int index = 0;
-
- while (e.hasMoreElements())
+ int count = seq.size();
+ ASN1OctetString[] v = new ASN1OctetString[count];
+ for (int i = 0; i < count; ++i)
{
- v[index++] = (ASN1OctetString)e.nextElement();
+ v[i] = ASN1OctetString.getInstance(seq.getObjectAt(i));
}
-
return new BEROctetString(v);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetStringGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetStringGenerator.java
index 1fb1e579..6d21f9c1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetStringGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROctetStringGenerator.java
@@ -22,7 +22,7 @@ public class BEROctetStringGenerator
throws IOException
{
super(out);
-
+
writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
}
@@ -42,7 +42,7 @@ public class BEROctetStringGenerator
throws IOException
{
super(out, tagNo, isExplicit);
-
+
writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
}
@@ -67,7 +67,7 @@ public class BEROctetStringGenerator
{
return new BufferedBEROctetStream(buf);
}
-
+
private class BufferedBEROctetStream
extends OutputStream
{
@@ -82,7 +82,7 @@ public class BEROctetStringGenerator
_off = 0;
_derOut = new DEROutputStream(_out);
}
-
+
public void write(
int b)
throws IOException
@@ -91,7 +91,7 @@ public class BEROctetStringGenerator
if (_off == _buf.length)
{
- DEROctetString.encode(_derOut, _buf);
+ DEROctetString.encode(_derOut, true, _buf, 0, _buf.length);
_off = 0;
}
}
@@ -109,7 +109,7 @@ public class BEROctetStringGenerator
break;
}
- DEROctetString.encode(_derOut, _buf);
+ DEROctetString.encode(_derOut, true, _buf, 0, _buf.length);
_off = 0;
off += numToCopy;
@@ -117,17 +117,16 @@ public class BEROctetStringGenerator
}
}
- public void close()
+ public void close()
throws IOException
{
if (_off != 0)
{
- byte[] bytes = new byte[_off];
- System.arraycopy(_buf, 0, bytes, 0, _off);
-
- DEROctetString.encode(_derOut, bytes);
+ DEROctetString.encode(_derOut, true, _buf, 0, _off);
}
-
+
+ _derOut.flushInternal();
+
writeBEREnd();
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROutputStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROutputStream.java
index 7b36fffd..b2e27bb6 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROutputStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BEROutputStream.java
@@ -1,53 +1,23 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.IOException;
import java.io.OutputStream;
/**
- * A class which writes indefinite and definite length objects. Objects which specify DER will be encoded accordingly, but DL or BER
- * objects will be encoded as defined.
- * @hide This class is not part of the Android public SDK API
+ * A class which writes indefinite and definite length objects. Objects which specify DER will be
+ * encoded accordingly, but DL or BER objects will be encoded as defined.
*/
-public class BEROutputStream
- extends DEROutputStream
+class BEROutputStream
+ extends ASN1OutputStream
{
/**
* Base constructor.
*
- * @param os target output stream.
+ * @param os
+ * target output stream.
*/
- public BEROutputStream(
- OutputStream os)
+ BEROutputStream(OutputStream os)
{
super(os);
}
-
- /**
- * Write out an ASN.1 object.
- *
- * @param obj the object to be encoded.
- * @throws IOException if there is an issue on encoding or output of the object.
- */
- public void writeObject(
- Object obj)
- throws IOException
- {
- if (obj == null)
- {
- writeNull();
- }
- else if (obj instanceof ASN1Primitive)
- {
- ((ASN1Primitive)obj).encode(this);
- }
- else if (obj instanceof ASN1Encodable)
- {
- ((ASN1Encodable)obj).toASN1Primitive().encode(this);
- }
- else
- {
- throw new IOException("object not BEREncodable");
- }
- }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSequence.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSequence.java
index 32611b68..c4531d27 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSequence.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSequence.java
@@ -2,7 +2,6 @@
package com.android.org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* Indefinite length SEQUENCE of objects.
@@ -26,56 +25,43 @@ public class BERSequence
/**
* Create a sequence containing one object
*/
- public BERSequence(
- ASN1Encodable obj)
+ public BERSequence(ASN1Encodable element)
{
- super(obj);
+ super(element);
}
/**
* Create a sequence containing a vector of objects.
*/
- public BERSequence(
- ASN1EncodableVector v)
+ public BERSequence(ASN1EncodableVector elementVector)
{
- super(v);
+ super(elementVector);
}
/**
* Create a sequence containing an array of objects.
*/
- public BERSequence(
- ASN1Encodable[] array)
+ public BERSequence(ASN1Encodable[] elements)
{
- super(array);
+ super(elements);
}
- int encodedLength()
- throws IOException
+ int encodedLength() throws IOException
{
- int length = 0;
- for (Enumeration e = getObjects(); e.hasMoreElements();)
+ int count = elements.length;
+ int totalLength = 0;
+
+ for (int i = 0; i < count; ++i)
{
- length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
+ ASN1Primitive p = elements[i].toASN1Primitive();
+ totalLength += p.encodedLength();
}
- return 2 + length + 2;
+ return 2 + totalLength + 2;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
- out.write(0x80);
-
- Enumeration e = getObjects();
- while (e.hasMoreElements())
- {
- out.writeObject((ASN1Encodable)e.nextElement());
- }
-
- out.write(0x00);
- out.write(0x00);
+ out.writeEncodedIndef(withTag, BERTags.SEQUENCE | BERTags.CONSTRUCTED, elements);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSet.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSet.java
index 78bb56b8..041bdd25 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSet.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERSet.java
@@ -2,7 +2,6 @@
package com.android.org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* Indefinite length <code>SET</code> and <code>SET OF</code> constructs.
@@ -32,60 +31,52 @@ public class BERSet
/**
* Create a SET containing one object.
*
- * @param obj - a single object that makes up the set.
+ * @param element - a single object that makes up the set.
*/
- public BERSet(
- ASN1Encodable obj)
+ public BERSet(ASN1Encodable element)
{
- super(obj);
+ super(element);
}
/**
* Create a SET containing multiple objects.
- * @param v a vector of objects making up the set.
+ * @param elementVector a vector of objects making up the set.
*/
- public BERSet(
- ASN1EncodableVector v)
+ public BERSet(ASN1EncodableVector elementVector)
{
- super(v, false);
+ super(elementVector, false);
}
/**
* Create a SET from an array of objects.
- * @param a an array of ASN.1 objects.
+ * @param elements an array of ASN.1 objects.
*/
- public BERSet(
- ASN1Encodable[] a)
+ public BERSet(ASN1Encodable[] elements)
{
- super(a, false);
+ super(elements, false);
}
- int encodedLength()
- throws IOException
+ BERSet(boolean isSorted, ASN1Encodable[] elements)
{
- int length = 0;
- for (Enumeration e = getObjects(); e.hasMoreElements();)
- {
- length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
- }
-
- return 2 + length + 2;
+ super(isSorted, elements);
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ int encodedLength() throws IOException
{
- out.write(BERTags.SET | BERTags.CONSTRUCTED);
- out.write(0x80);
+ int count = elements.length;
+ int totalLength = 0;
- Enumeration e = getObjects();
- while (e.hasMoreElements())
+ for (int i = 0; i < count; ++i)
{
- out.writeObject((ASN1Encodable)e.nextElement());
+ ASN1Primitive p = elements[i].toASN1Primitive();
+ totalLength += p.encodedLength();
}
- out.write(0x00);
- out.write(0x00);
+ return 2 + totalLength + 2;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodedIndef(withTag, BERTags.SET | BERTags.CONSTRUCTED, elements);
}
-} \ No newline at end of file
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTaggedObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTaggedObject.java
index fae54886..0bdfc35e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTaggedObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/BERTaggedObject.java
@@ -49,101 +49,92 @@ public class BERTaggedObject
boolean isConstructed()
{
- if (!empty)
- {
- if (explicit)
- {
- return true;
- }
- else
- {
- ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
-
- return primitive.isConstructed();
- }
- }
- else
- {
- return true;
- }
+ return explicit || obj.toASN1Primitive().isConstructed();
}
int encodedLength()
throws IOException
{
- if (!empty)
- {
- ASN1Primitive primitive = obj.toASN1Primitive();
- int length = primitive.encodedLength();
+ ASN1Primitive primitive = obj.toASN1Primitive();
+ int length = primitive.encodedLength();
- if (explicit)
- {
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
- }
- else
- {
- // header length already in calculation
- length = length - 1;
-
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ if (explicit)
+ {
+ return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
}
else
{
- return StreamUtil.calculateTagLength(tagNo) + 1;
+ // header length already in calculation
+ length = length - 1;
+
+ return StreamUtil.calculateTagLength(tagNo) + length;
}
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
+ out.writeTag(withTag, BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
out.write(0x80);
- if (!empty)
+ if (!explicit)
{
- if (!explicit)
+ Enumeration e;
+ if (obj instanceof ASN1OctetString)
{
- Enumeration e;
- if (obj instanceof ASN1OctetString)
+ if (obj instanceof BEROctetString)
{
- if (obj instanceof BEROctetString)
- {
- e = ((BEROctetString)obj).getObjects();
- }
- else
- {
- ASN1OctetString octs = (ASN1OctetString)obj;
- BEROctetString berO = new BEROctetString(octs.getOctets());
- e = berO.getObjects();
- }
- }
- else if (obj instanceof ASN1Sequence)
- {
- e = ((ASN1Sequence)obj).getObjects();
- }
- else if (obj instanceof ASN1Set)
- {
- e = ((ASN1Set)obj).getObjects();
+ e = ((BEROctetString)obj).getObjects();
}
else
{
- throw new ASN1Exception("not implemented: " + obj.getClass().getName());
- }
-
- while (e.hasMoreElements())
- {
- out.writeObject((ASN1Encodable)e.nextElement());
+ ASN1OctetString octs = (ASN1OctetString)obj;
+ BEROctetString berO = new BEROctetString(octs.getOctets());
+ e = berO.getObjects();
}
}
+ else if (obj instanceof ASN1Sequence)
+ {
+ e = ((ASN1Sequence)obj).getObjects();
+ }
+ else if (obj instanceof ASN1Set)
+ {
+ e = ((ASN1Set)obj).getObjects();
+ }
else
{
- out.writeObject(obj);
+ throw new ASN1Exception("not implemented: " + obj.getClass().getName());
}
+
+ out.writeElements(e);
+ }
+ else
+ {
+ out.writePrimitive(obj.toASN1Primitive(), true);
}
out.write(0x00);
out.write(0x00);
+
+// ASN1Primitive primitive = obj.toASN1Primitive();
+//
+// int flags = BERTags.TAGGED;
+// if (explicit || primitive.isConstructed())
+// {
+// flags |= BERTags.CONSTRUCTED;
+// }
+//
+// out.writeTag(withTag, flags, tagNo);
+//
+// if (explicit)
+// {
+// out.write(0x80);
+// out.writePrimitive(obj.toASN1Primitive(), true);
+// out.write(0x00);
+// out.write(0x00);
+// }
+// else
+// {
+// out.writePrimitive(obj.toASN1Primitive(), false);
+// }
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ConstructedOctetStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ConstructedOctetStream.java
index 7ef280d1..f31cff26 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ConstructedOctetStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ConstructedOctetStream.java
@@ -27,15 +27,14 @@ class ConstructedOctetStream
return -1;
}
- ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
-
- if (s == null)
+ ASN1OctetStringParser next = getNextParser();
+ if (next == null)
{
return -1;
}
_first = false;
- _currentStream = s.getOctetStream();
+ _currentStream = next.getOctetStream();
}
int totalRead = 0;
@@ -55,15 +54,14 @@ class ConstructedOctetStream
}
else
{
- ASN1OctetStringParser aos = (ASN1OctetStringParser)_parser.readObject();
-
- if (aos == null)
+ ASN1OctetStringParser next = getNextParser();
+ if (next == null)
{
_currentStream = null;
return totalRead < 1 ? -1 : totalRead;
}
- _currentStream = aos.getOctetStream();
+ _currentStream = next.getOctetStream();
}
}
}
@@ -78,15 +76,14 @@ class ConstructedOctetStream
return -1;
}
- ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
-
- if (s == null)
+ ASN1OctetStringParser next = getNextParser();
+ if (next == null)
{
return -1;
}
-
+
_first = false;
- _currentStream = s.getOctetStream();
+ _currentStream = next.getOctetStream();
}
for (;;)
@@ -98,15 +95,30 @@ class ConstructedOctetStream
return b;
}
- ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
-
- if (s == null)
+ ASN1OctetStringParser next = getNextParser();
+ if (next == null)
{
_currentStream = null;
return -1;
}
- _currentStream = s.getOctetStream();
+ _currentStream = next.getOctetStream();
}
}
+
+ private ASN1OctetStringParser getNextParser() throws IOException
+ {
+ ASN1Encodable asn1Obj = _parser.readObject();
+ if (asn1Obj == null)
+ {
+ return null;
+ }
+
+ if (asn1Obj instanceof ASN1OctetStringParser)
+ {
+ return (ASN1OctetStringParser)asn1Obj;
+ }
+
+ throw new IOException("unknown object encountered: " + asn1Obj.getClass());
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERApplicationSpecific.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERApplicationSpecific.java
index 79698d48..b77373da 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERApplicationSpecific.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERApplicationSpecific.java
@@ -113,14 +113,14 @@ public class DERApplicationSpecific
/* (non-Javadoc)
* @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
*/
- void encode(ASN1OutputStream out) throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- int classBits = BERTags.APPLICATION;
+ int flags = BERTags.APPLICATION;
if (isConstructed)
{
- classBits |= BERTags.CONSTRUCTED;
+ flags |= BERTags.CONSTRUCTED;
}
- out.writeEncoded(classBits, tag, octets);
+ out.writeEncoded(withTag, flags, tag, octets);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBMPString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBMPString.java
index 5901af2e..3803c2b5 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBMPString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBMPString.java
@@ -83,9 +83,21 @@ public class DERBMPString
DERBMPString(
byte[] string)
{
- char[] cs = new char[string.length / 2];
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
+ int byteLen = string.length;
+ if (0 != (byteLen & 1))
+ {
+ throw new IllegalArgumentException("malformed BMPString encoding encountered");
+ }
- for (int i = 0; i != cs.length; i++)
+ int charLen = byteLen / 2;
+ char[] cs = new char[charLen];
+
+ for (int i = 0; i != charLen; i++)
{
cs[i] = (char)((string[2 * i] << 8) | (string[2 * i + 1] & 0xff));
}
@@ -95,6 +107,11 @@ public class DERBMPString
DERBMPString(char[] string)
{
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
this.string = string;
}
@@ -105,6 +122,11 @@ public class DERBMPString
public DERBMPString(
String string)
{
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
this.string = string.toCharArray();
}
@@ -147,18 +169,49 @@ public class DERBMPString
}
void encode(
- ASN1OutputStream out)
+ ASN1OutputStream out, boolean withTag)
throws IOException
{
- out.write(BERTags.BMP_STRING);
- out.writeLength(string.length * 2);
+ int count = string.length;
+ if (withTag)
+ {
+ out.write(BERTags.BMP_STRING);
+ }
+ out.writeLength(count * 2);
+
+ byte[] buf = new byte[8];
- for (int i = 0; i != string.length; i++)
+ int i = 0, limit = count & -4;
+ while (i < limit)
{
- char c = string[i];
+ char c0 = string[i], c1 = string[i + 1], c2 = string[i + 2], c3 = string[i + 3];
+ i += 4;
+
+ buf[0] = (byte)(c0 >> 8);
+ buf[1] = (byte)c0;
+ buf[2] = (byte)(c1 >> 8);
+ buf[3] = (byte)c1;
+ buf[4] = (byte)(c2 >> 8);
+ buf[5] = (byte)c2;
+ buf[6] = (byte)(c3 >> 8);
+ buf[7] = (byte)c3;
+
+ out.write(buf, 0, 8);
+ }
+ if (i < count)
+ {
+ int bufPos = 0;
+ do
+ {
+ char c0 = string[i];
+ i += 1;
+
+ buf[bufPos++] = (byte)(c0 >> 8);
+ buf[bufPos++] = (byte)c0;
+ }
+ while (i < count);
- out.write((byte)(c >> 8));
- out.write((byte)c);
+ out.write(buf, 0, bufPos);
}
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBitString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBitString.java
index ab740061..fbfb67c4 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBitString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBitString.java
@@ -7,7 +7,6 @@ import java.io.IOException;
* A BIT STRING with DER encoding - the first byte contains the count of padding bits included in the byte array's last byte.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class DERBitString
extends ASN1BitString
{
@@ -66,24 +65,13 @@ public class DERBitString
}
else
{
- return fromOctetString(((ASN1OctetString)o).getOctets());
+ return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
}
}
-
- protected DERBitString(
- byte data,
- int padBits)
- {
- this(toByteArray(data), padBits);
- }
- private static byte[] toByteArray(byte data)
+ protected DERBitString(byte data, int padBits)
{
- byte[] rv = new byte[1];
-
- rv[0] = data;
-
- return rv;
+ super(data, padBits);
}
/**
@@ -98,7 +86,6 @@ public class DERBitString
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public DERBitString(
byte[] data)
{
@@ -128,17 +115,30 @@ public class DERBitString
return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- byte[] string = derForm(data, padBits);
- byte[] bytes = new byte[string.length + 1];
+ int len = data.length;
+ if (0 == len
+ || 0 == padBits
+ || (data[len - 1] == (byte)(data[len - 1] & (0xFF << padBits))))
+ {
+ out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
+ }
+ else
+ {
+ byte der = (byte)(data[len - 1] & (0xFF << padBits));
+ out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data, 0, len - 1, der);
+ }
+ }
- bytes[0] = (byte)getPadBits();
- System.arraycopy(string, 0, bytes, 1, bytes.length - 1);
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
- out.writeEncoded(BERTags.BIT_STRING, bytes);
+ ASN1Primitive toDLObject()
+ {
+ return this;
}
static DERBitString fromOctetString(byte[] bytes)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBoolean.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBoolean.java
deleted file mode 100644
index f3b4fdc8..00000000
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERBoolean.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.bouncycastle.asn1;
-
-/**
- * @deprecated use ASN1Boolean
- * @hide This class is not part of the Android public SDK API
- */
-public class DERBoolean
- extends ASN1Boolean
-{
- /**
- * @deprecated use getInstance(boolean) method.
- * @param value
- */
- public DERBoolean(boolean value)
- {
- super(value);
- }
-
- DERBoolean(byte[] value)
- {
- super(value);
- }
-}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEREncodableVector.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEREncodableVector.java
index 5025adcb..c216ef29 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEREncodableVector.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEREncodableVector.java
@@ -13,7 +13,7 @@ public class DEREncodableVector
/**
* @deprecated use ASN1EncodableVector instead.
*/
- @android.compat.annotation.UnsupportedAppUsage
+ @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
public DEREncodableVector()
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERExternal.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERExternal.java
index d49f1992..018b8920 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERExternal.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERExternal.java
@@ -55,6 +55,16 @@ public class DERExternal
super(directReference, indirectReference, dataValueDescriptor, encoding, externalData);
}
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
int encodedLength()
throws IOException
{
@@ -64,8 +74,7 @@ public class DERExternal
/* (non-Javadoc)
* @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
*/
- void encode(ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (directReference != null)
@@ -82,6 +91,7 @@ public class DERExternal
}
DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent);
baos.write(obj.getEncoded(ASN1Encoding.DER));
- out.writeEncoded(BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
+
+ out.writeEncoded(withTag, BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERFactory.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERFactory.java
index dcd43aad..0c4f774a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERFactory.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERFactory.java
@@ -8,11 +8,21 @@ class DERFactory
static ASN1Sequence createSequence(ASN1EncodableVector v)
{
- return v.size() < 1 ? EMPTY_SEQUENCE : new DLSequence(v);
+ if (v.size() < 1)
+ {
+ return EMPTY_SEQUENCE;
+ }
+
+ return new DERSequence(v);
}
static ASN1Set createSet(ASN1EncodableVector v)
{
- return v.size() < 1 ? EMPTY_SET : new DLSet(v);
+ if (v.size() < 1)
+ {
+ return EMPTY_SET;
+ }
+
+ return new DERSet(v);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralString.java
index f1060f8c..67818396 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralString.java
@@ -73,7 +73,7 @@ public class DERGeneralString
}
else
{
- return new DERGeneralString(((ASN1OctetString)o).getOctets());
+ return new DERGeneralString(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -127,12 +127,11 @@ public class DERGeneralString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.GENERAL_STRING, string);
+ out.writeEncoded(withTag, BERTags.GENERAL_STRING, string);
}
-
+
public int hashCode()
{
return Arrays.hashCode(string);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralizedTime.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralizedTime.java
index 41fbfb69..b8f39693 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralizedTime.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGeneralizedTime.java
@@ -109,10 +109,18 @@ public class DERGeneralizedTime
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.GENERALIZED_TIME, getDERTime());
+ out.writeEncoded(withTag, BERTags.GENERALIZED_TIME, getDERTime());
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGraphicString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGraphicString.java
index a76ba801..1000928d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGraphicString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERGraphicString.java
@@ -67,7 +67,7 @@ public class DERGraphicString
}
else
{
- return new DERGraphicString(((ASN1OctetString)o).getOctets());
+ return new DERGraphicString(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -96,11 +96,9 @@ public class DERGraphicString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.GRAPHIC_STRING, string);
+ out.writeEncoded(withTag, BERTags.GRAPHIC_STRING, string);
}
public int hashCode()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERIA5String.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERIA5String.java
index b29aed25..b4364e3a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERIA5String.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERIA5String.java
@@ -71,7 +71,7 @@ public class DERIA5String
}
else
{
- return new DERIA5String(((ASN1OctetString)o).getOctets());
+ return new DERIA5String(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -109,11 +109,11 @@ public class DERIA5String
{
if (string == null)
{
- throw new NullPointerException("string cannot be null");
+ throw new NullPointerException("'string' cannot be null");
}
if (validate && !isIA5String(string))
{
- throw new IllegalArgumentException("string contains illegal characters");
+ throw new IllegalArgumentException("'string' contains illegal characters");
}
this.string = Strings.toByteArray(string);
@@ -144,11 +144,9 @@ public class DERIA5String
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.IA5_STRING, string);
+ out.writeEncoded(withTag, BERTags.IA5_STRING, string);
}
public int hashCode()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERInteger.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERInteger.java
index e81beeba..75e8aeaf 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERInteger.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERInteger.java
@@ -7,7 +7,6 @@ import java.math.BigInteger;
* @deprecated Use ASN1Integer instead of this,
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class DERInteger
extends ASN1Integer
{
@@ -21,14 +20,13 @@ public class DERInteger
super(bytes, true);
}
- @android.compat.annotation.UnsupportedAppUsage
+ @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
public DERInteger(BigInteger value)
{
super(value);
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public DERInteger(long value)
{
super(value);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNull.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNull.java
index a86a335b..b4de8aed 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNull.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNull.java
@@ -9,21 +9,15 @@ import java.io.IOException;
* Preferably use the constant: DERNull.INSTANCE.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class DERNull
extends ASN1Null
{
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public static final DERNull INSTANCE = new DERNull();
private static final byte[] zeroBytes = new byte[0];
- /**
- * @deprecated use DERNull.INSTANCE
- */
- // Android-changed: Reduce visibility to protected.
- protected DERNull()
+ private DERNull()
{
}
@@ -37,10 +31,8 @@ public class DERNull
return 2;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.NULL, zeroBytes);
+ out.writeEncoded(withTag, BERTags.NULL, zeroBytes);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNumericString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNumericString.java
index f5633f7a..1ff789cd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNumericString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNumericString.java
@@ -142,11 +142,9 @@ public class DERNumericString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.NUMERIC_STRING, string);
+ out.writeEncoded(withTag, BERTags.NUMERIC_STRING, string);
}
public int hashCode()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERObjectIdentifier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERObjectIdentifier.java
index fef16ea8..05c8380b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERObjectIdentifier.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERObjectIdentifier.java
@@ -9,7 +9,7 @@ package com.android.org.bouncycastle.asn1;
public class DERObjectIdentifier
extends ASN1ObjectIdentifier
{
- @android.compat.annotation.UnsupportedAppUsage
+ @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
public DERObjectIdentifier(String identifier)
{
super(identifier);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROctetString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROctetString.java
index 28fffe05..52cbfa4f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROctetString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROctetString.java
@@ -7,7 +7,6 @@ import java.io.IOException;
* Carrier class for a DER encoding OCTET STRING
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class DEROctetString
extends ASN1OctetString
{
@@ -16,8 +15,7 @@ public class DEROctetString
*
* @param string the octets making up the octet string.
*/
- @android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
+ @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
public DEROctetString(
byte[] string)
{
@@ -46,18 +44,23 @@ public class DEROctetString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.OCTET_STRING, string);
+ out.writeEncoded(withTag, BERTags.OCTET_STRING, string);
}
- static void encode(
- DEROutputStream derOut,
- byte[] bytes)
- throws IOException
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
+ static void encode(ASN1OutputStream derOut, boolean withTag, byte[] buf, int off, int len) throws IOException
{
- derOut.writeEncoded(BERTags.OCTET_STRING, bytes);
+ derOut.writeEncoded(withTag, BERTags.OCTET_STRING, buf, off, len);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROutputStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROutputStream.java
index 5ec0c931..2cae73bf 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROutputStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROutputStream.java
@@ -8,31 +8,23 @@ import java.io.OutputStream;
* Stream that outputs encoding based on distinguished encoding rules.
* @hide This class is not part of the Android public SDK API
*/
+// BEGIN Android-changed: Class is package-private in upstream.
+// Leaving as public as it's used by build/make/tools/signapk/src/com/android/signapk/SignApk.java
public class DEROutputStream
extends ASN1OutputStream
{
- @android.compat.annotation.UnsupportedAppUsage
- public DEROutputStream(
- OutputStream os)
+ @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
+ public DEROutputStream(OutputStream os)
{
super(os);
}
- public void writeObject(
- ASN1Encodable obj)
- throws IOException
+ void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
{
- if (obj != null)
- {
- obj.toASN1Primitive().toDERObject().encode(this);
- }
- else
- {
- throw new IOException("null object detected");
- }
+ primitive.toDERObject().encode(this, withTag);
}
- ASN1OutputStream getDERSubStream()
+ DEROutputStream getDERSubStream()
{
return this;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERPrintableString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERPrintableString.java
index 7ecdda28..f32ecff1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERPrintableString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERPrintableString.java
@@ -153,11 +153,9 @@ public class DERPrintableString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.PRINTABLE_STRING, string);
+ out.writeEncoded(withTag, BERTags.PRINTABLE_STRING, string);
}
public int hashCode()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequence.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequence.java
index 92697c91..9e8b6e51 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequence.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequence.java
@@ -2,7 +2,6 @@
package com.android.org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* Definite length SEQUENCE, encoding tells explicit number of bytes
@@ -11,75 +10,77 @@ import java.util.Enumeration;
* For X.690 syntax rules, see {@link ASN1Sequence}.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class DERSequence
extends ASN1Sequence
{
+ public static DERSequence convert(ASN1Sequence seq)
+ {
+ return (DERSequence)seq.toDERObject();
+ }
+
private int bodyLength = -1;
/**
* Create an empty sequence
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public DERSequence()
{
}
/**
* Create a sequence containing one object
- * @param obj the object to go in the sequence.
+ * @param element the object to go in the sequence.
*/
- public DERSequence(
- ASN1Encodable obj)
+ public DERSequence(ASN1Encodable element)
{
- super(obj);
+ super(element);
}
/**
* Create a sequence containing a vector of objects.
- * @param v the vector of objects to make up the sequence.
+ * @param elementVector the vector of objects to make up the sequence.
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
- public DERSequence(
- ASN1EncodableVector v)
+ public DERSequence(ASN1EncodableVector elementVector)
{
- super(v);
+ super(elementVector);
}
/**
* Create a sequence containing an array of objects.
- * @param array the array of objects to make up the sequence.
+ * @param elements the array of objects to make up the sequence.
*/
- public DERSequence(
- ASN1Encodable[] array)
+ public DERSequence(ASN1Encodable[] elements)
{
- super(array);
+ super(elements);
}
- private int getBodyLength()
- throws IOException
+ DERSequence(ASN1Encodable[] elements, boolean clone)
+ {
+ super(elements, clone);
+ }
+
+ private int getBodyLength() throws IOException
{
if (bodyLength < 0)
{
- int length = 0;
+ int count = elements.length;
+ int totalLength = 0;
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ for (int i = 0; i < count; ++i)
{
- Object obj = e.nextElement();
-
- length += ((ASN1Encodable)obj).toASN1Primitive().toDERObject().encodedLength();
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ totalLength += derObject.encodedLength();
}
- bodyLength = length;
+ this.bodyLength = totalLength;
}
return bodyLength;
}
- int encodedLength()
- throws IOException
+ int encodedLength() throws IOException
{
int length = getBodyLength();
@@ -94,21 +95,55 @@ public class DERSequence
* ASN.1 descriptions given. Rather than just outputting SEQUENCE,
* we also have to specify CONSTRUCTED, and the objects length.
*/
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- ASN1OutputStream dOut = out.getDERSubStream();
- int length = getBodyLength();
+ if (withTag)
+ {
+ out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
+ }
+
+ DEROutputStream derOut = out.getDERSubStream();
- out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
- out.writeLength(length);
+ int count = elements.length;
+ if (bodyLength >= 0 || count > 16)
+ {
+ out.writeLength(getBodyLength());
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ derObject.encode(derOut, true);
+ }
+ }
+ else
{
- Object obj = e.nextElement();
+ int totalLength = 0;
+
+ ASN1Primitive[] derObjects = new ASN1Primitive[count];
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ derObjects[i] = derObject;
+ totalLength += derObject.encodedLength();
+ }
- dOut.writeObject((ASN1Encodable)obj);
+ this.bodyLength = totalLength;
+ out.writeLength(totalLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ derObjects[i].encode(derOut, true);
+ }
}
}
+
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequenceParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequenceParser.java
index 8958d7da..918db1fd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequenceParser.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSequenceParser.java
@@ -4,7 +4,7 @@ package com.android.org.bouncycastle.asn1;
import java.io.IOException;
/**
- * Parser class for DER SEQUENCEs.
+ * @deprecated Use DLSequenceParser instead
* @hide This class is not part of the Android public SDK API
*/
public class DERSequenceParser
@@ -38,7 +38,7 @@ public class DERSequenceParser
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new DERSequence(_parser.readVector());
+ return new DLSequence(_parser.readVector());
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSet.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSet.java
index 069c8336..bacdb688 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSet.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSet.java
@@ -2,7 +2,6 @@
package com.android.org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* A DER encoded SET object
@@ -18,6 +17,11 @@ import java.util.Enumeration;
public class DERSet
extends ASN1Set
{
+ public static DERSet convert(ASN1Set set)
+ {
+ return (DERSet)set.toDERObject();
+ }
+
private int bodyLength = -1;
/**
@@ -29,64 +33,57 @@ public class DERSet
/**
* create a set containing one object
- * @param obj the object to go in the set
+ * @param element the object to go in the set
*/
- public DERSet(
- ASN1Encodable obj)
+ public DERSet(ASN1Encodable element)
{
- super(obj);
+ super(element);
}
/**
* create a set containing a vector of objects.
- * @param v the vector of objects to make up the set.
+ * @param elementVector the vector of objects to make up the set.
*/
- @android.compat.annotation.UnsupportedAppUsage
- public DERSet(
- ASN1EncodableVector v)
+ @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
+ public DERSet(ASN1EncodableVector elementVector)
{
- super(v, true);
+ super(elementVector, true);
}
-
+
/**
* create a set containing an array of objects.
- * @param a the array of objects to make up the set.
+ * @param elements the array of objects to make up the set.
*/
- public DERSet(
- ASN1Encodable[] a)
+ public DERSet(ASN1Encodable[] elements)
{
- super(a, true);
+ super(elements, true);
}
- DERSet(
- ASN1EncodableVector v,
- boolean doSort)
+ DERSet(boolean isSorted, ASN1Encodable[] elements)
{
- super(v, doSort);
+ super(checkSorted(isSorted), elements);
}
- private int getBodyLength()
- throws IOException
+ private int getBodyLength() throws IOException
{
if (bodyLength < 0)
{
- int length = 0;
+ int count = elements.length;
+ int totalLength = 0;
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ for (int i = 0; i < count; ++i)
{
- Object obj = e.nextElement();
-
- length += ((ASN1Encodable)obj).toASN1Primitive().toDERObject().encodedLength();
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ totalLength += derObject.encodedLength();
}
- bodyLength = length;
+ this.bodyLength = totalLength;
}
return bodyLength;
}
- int encodedLength()
- throws IOException
+ int encodedLength() throws IOException
{
int length = getBodyLength();
@@ -101,21 +98,64 @@ public class DERSet
* ASN.1 descriptions given. Rather than just outputting SET,
* we also have to specify CONSTRUCTED, and the objects length.
*/
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- ASN1OutputStream dOut = out.getDERSubStream();
- int length = getBodyLength();
+ if (withTag)
+ {
+ out.write(BERTags.SET | BERTags.CONSTRUCTED);
+ }
- out.write(BERTags.SET | BERTags.CONSTRUCTED);
- out.writeLength(length);
+ DEROutputStream derOut = out.getDERSubStream();
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ int count = elements.length;
+ if (bodyLength >= 0 || count > 16)
{
- Object obj = e.nextElement();
+ out.writeLength(getBodyLength());
+
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ derObject.encode(derOut, true);
+ }
+ }
+ else
+ {
+ int totalLength = 0;
+
+ ASN1Primitive[] derObjects = new ASN1Primitive[count];
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ derObjects[i] = derObject;
+ totalLength += derObject.encodedLength();
+ }
- dOut.writeObject((ASN1Encodable)obj);
+ this.bodyLength = totalLength;
+ out.writeLength(totalLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ derObjects[i].encode(derOut, true);
+ }
+ }
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return isSorted ? this : super.toDERObject();
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
+ private static boolean checkSorted(boolean isSorted)
+ {
+ if (!isSorted)
+ {
+ throw new IllegalStateException("DERSet elements should always be in sorted order");
}
+ return isSorted;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSetParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSetParser.java
index 253ef531..31b15776 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSetParser.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERSetParser.java
@@ -4,7 +4,7 @@ package com.android.org.bouncycastle.asn1;
import java.io.IOException;
/**
- * Parser class for DER SETs.
+ * @deprecated Use DLSetParser instead
* @hide This class is not part of the Android public SDK API
*/
public class DERSetParser
@@ -38,7 +38,7 @@ public class DERSetParser
public ASN1Primitive getLoadedObject()
throws IOException
{
- return new DERSet(_parser.readVector(), false);
+ return new DLSet(_parser.readVector());
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERT61String.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERT61String.java
index 61bc1f17..a0a7b3cb 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERT61String.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERT61String.java
@@ -119,11 +119,9 @@ public class DERT61String
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.T61_STRING, string);
+ out.writeEncoded(withTag, BERTags.T61_STRING, string);
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERTaggedObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERTaggedObject.java
index 8f78e310..2aaf86aa 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERTaggedObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERTaggedObject.java
@@ -9,12 +9,9 @@ import java.io.IOException;
* rules (as with sequences).
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class DERTaggedObject
extends ASN1TaggedObject
{
- private static final byte[] ZERO_BYTES = new byte[0];
-
/**
* @param explicit true if an explicitly tagged object.
* @param tagNo the tag number for this object.
@@ -28,7 +25,6 @@ public class DERTaggedObject
super(explicit, tagNo, obj);
}
- @libcore.api.CorePlatformApi
public DERTaggedObject(int tagNo, ASN1Encodable encodable)
{
super(true, tagNo, encodable);
@@ -36,87 +32,55 @@ public class DERTaggedObject
boolean isConstructed()
{
- if (!empty)
- {
- if (explicit)
- {
- return true;
- }
- else
- {
- ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
-
- return primitive.isConstructed();
- }
- }
- else
- {
- return true;
- }
+ return explicit || obj.toASN1Primitive().toDERObject().isConstructed();
}
int encodedLength()
throws IOException
{
- if (!empty)
- {
- ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
- int length = primitive.encodedLength();
-
- if (explicit)
- {
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
- }
- else
- {
- // header length already in calculation
- length = length - 1;
+ ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
+ int length = primitive.encodedLength();
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ if (explicit)
+ {
+ return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
}
else
{
- return StreamUtil.calculateTagLength(tagNo) + 1;
+ // header length already in calculation
+ length = length - 1;
+
+ return StreamUtil.calculateTagLength(tagNo) + length;
}
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (!empty)
+ ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
+
+ int flags = BERTags.TAGGED;
+ if (explicit || primitive.isConstructed())
{
- ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
+ flags |= BERTags.CONSTRUCTED;
+ }
- if (explicit)
- {
- out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
- out.writeLength(primitive.encodedLength());
- out.writeObject(primitive);
- }
- else
- {
- //
- // need to mark constructed types...
- //
- int flags;
- if (primitive.isConstructed())
- {
- flags = BERTags.CONSTRUCTED | BERTags.TAGGED;
- }
- else
- {
- flags = BERTags.TAGGED;
- }
+ out.writeTag(withTag, flags, tagNo);
- out.writeTag(flags, tagNo);
- out.writeImplicitObject(primitive);
- }
- }
- else
+ if (explicit)
{
- out.writeEncoded(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo, ZERO_BYTES);
+ out.writeLength(primitive.encodedLength());
}
+
+ primitive.encode(out.getDERSubStream(), explicit);
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUTF8String.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUTF8String.java
index d4f15bf9..8136d458 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUTF8String.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUTF8String.java
@@ -10,7 +10,6 @@ import com.android.org.bouncycastle.util.Strings;
* DER UTF8String object.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class DERUTF8String
extends ASN1Primitive
implements ASN1String
@@ -89,13 +88,11 @@ public class DERUTF8String
*
* @param string the string to be carried in the UTF8String object,
*/
- @libcore.api.CorePlatformApi
public DERUTF8String(String string)
{
this.string = Strings.toUTF8ByteArray(string);
}
- @libcore.api.CorePlatformApi
public String getString()
{
return Strings.fromUTF8ByteArray(string);
@@ -134,9 +131,8 @@ public class DERUTF8String
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.UTF8_STRING, string);
+ out.writeEncoded(withTag, BERTags.UTF8_STRING, string);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUniversalString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUniversalString.java
index 03b27fa3..0aaef1ea 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUniversalString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUniversalString.java
@@ -1,7 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import com.android.org.bouncycastle.util.Arrays;
@@ -70,7 +69,7 @@ public class DERUniversalString
}
else
{
- return new DERUniversalString(((ASN1OctetString)o).getOctets());
+ return new DERUniversalString(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -87,21 +86,18 @@ public class DERUniversalString
public String getString()
{
- StringBuffer buf = new StringBuffer("#");
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
+ StringBuffer buf = new StringBuffer("#");
+
+ byte[] string;
try
{
- aOut.writeObject(this);
+ string = getEncoded();
}
catch (IOException e)
{
throw new ASN1ParsingException("internal error encoding UniversalString");
}
-
- byte[] string = bOut.toByteArray();
-
+
for (int i = 0; i != string.length; i++)
{
buf.append(table[(string[i] >>> 4) & 0xf]);
@@ -131,13 +127,11 @@ public class DERUniversalString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.UNIVERSAL_STRING, this.getOctets());
+ out.writeEncoded(withTag, BERTags.UNIVERSAL_STRING, string);
}
-
+
boolean asn1Equals(
ASN1Primitive o)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVideotexString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVideotexString.java
index a53230c3..505072ff 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVideotexString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVideotexString.java
@@ -67,7 +67,7 @@ public class DERVideotexString
}
else
{
- return new DERVideotexString(((ASN1OctetString)o).getOctets());
+ return new DERVideotexString(ASN1OctetString.getInstance(o).getOctets());
}
}
@@ -96,11 +96,9 @@ public class DERVideotexString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.VIDEOTEX_STRING, string);
+ out.writeEncoded(withTag, BERTags.VIDEOTEX_STRING, string);
}
public int hashCode()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVisibleString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVisibleString.java
index a7f4199d..dbfb1182 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVisibleString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERVisibleString.java
@@ -120,13 +120,11 @@ public class DERVisibleString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- out.writeEncoded(BERTags.VISIBLE_STRING, this.string);
+ out.writeEncoded(withTag, BERTags.VISIBLE_STRING, this.string);
}
-
+
boolean asn1Equals(
ASN1Primitive o)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLApplicationSpecific.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLApplicationSpecific.java
index 1af00e33..53bf2d7e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLApplicationSpecific.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLApplicationSpecific.java
@@ -113,14 +113,14 @@ public class DLApplicationSpecific
/* (non-Javadoc)
* @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
*/
- void encode(ASN1OutputStream out) throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- int classBits = BERTags.APPLICATION;
+ int flags = BERTags.APPLICATION;
if (isConstructed)
{
- classBits |= BERTags.CONSTRUCTED;
+ flags |= BERTags.CONSTRUCTED;
}
- out.writeEncoded(classBits, tag, octets);
+ out.writeEncoded(withTag, flags, tag, octets);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLBitString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLBitString.java
index 3d911ac4..7ee84e40 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLBitString.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLBitString.java
@@ -65,24 +65,13 @@ public class DLBitString
}
else
{
- return fromOctetString(((ASN1OctetString)o).getOctets());
+ return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
}
}
- protected DLBitString(
- byte data,
- int padBits)
- {
- this(toByteArray(data), padBits);
- }
-
- private static byte[] toByteArray(byte data)
+ protected DLBitString(byte data, int padBits)
{
- byte[] rv = new byte[1];
-
- rv[0] = data;
-
- return rv;
+ super(data, padBits);
}
/**
@@ -125,17 +114,14 @@ public class DLBitString
return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- byte[] string = data;
- byte[] bytes = new byte[string.length + 1];
-
- bytes[0] = (byte)getPadBits();
- System.arraycopy(string, 0, bytes, 1, bytes.length - 1);
+ out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
+ }
- out.writeEncoded(BERTags.BIT_STRING, bytes);
+ ASN1Primitive toDLObject()
+ {
+ return this;
}
static DLBitString fromOctetString(byte[] bytes)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLExternal.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLExternal.java
index 76ae0645..0945a86d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLExternal.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLExternal.java
@@ -55,6 +55,11 @@ public class DLExternal
super(directReference, indirectReference, dataValueDescriptor, encoding, externalData);
}
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
int encodedLength()
throws IOException
{
@@ -64,8 +69,7 @@ public class DLExternal
/* (non-Javadoc)
* @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
*/
- void encode(ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (directReference != null)
@@ -80,8 +84,9 @@ public class DLExternal
{
baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DL));
}
- DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent);
+ ASN1TaggedObject obj = new DLTaggedObject(true, encoding, externalContent);
baos.write(obj.getEncoded(ASN1Encoding.DL));
- out.writeEncoded(BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
+
+ out.writeEncoded(withTag, BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLFactory.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLFactory.java
new file mode 100644
index 00000000..ad993d18
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLFactory.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+class DLFactory
+{
+ static final ASN1Sequence EMPTY_SEQUENCE = new DLSequence();
+ static final ASN1Set EMPTY_SET = new DLSet();
+
+ static ASN1Sequence createSequence(ASN1EncodableVector v)
+ {
+ if (v.size() < 1)
+ {
+ return EMPTY_SEQUENCE;
+ }
+
+ return new DLSequence(v);
+ }
+
+ static ASN1Set createSet(ASN1EncodableVector v)
+ {
+ if (v.size() < 1)
+ {
+ return EMPTY_SET;
+ }
+
+ return new DLSet(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLOutputStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLOutputStream.java
index ff3614ec..1ab6e157 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLOutputStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLOutputStream.java
@@ -6,28 +6,22 @@ import java.io.OutputStream;
/**
* Stream that outputs encoding based on definite length.
- * @hide This class is not part of the Android public SDK API
*/
-public class DLOutputStream
+class DLOutputStream
extends ASN1OutputStream
{
- public DLOutputStream(
- OutputStream os)
+ DLOutputStream(OutputStream os)
{
super(os);
}
- public void writeObject(
- ASN1Encodable obj)
- throws IOException
+ void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
{
- if (obj != null)
- {
- obj.toASN1Primitive().toDLObject().encode(this);
- }
- else
- {
- throw new IOException("null object detected");
- }
+ primitive.toDLObject().encode(this, withTag);
+ }
+
+ ASN1OutputStream getDLSubStream()
+ {
+ return this;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequence.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequence.java
index d826994a..1255e333 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequence.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequence.java
@@ -2,7 +2,6 @@
package com.android.org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* The DLSequence encodes a SEQUENCE using definite length form.
@@ -22,56 +21,56 @@ public class DLSequence
/**
* create a sequence containing one object
- * @param obj the object to go in the sequence.
+ * @param element the object to go in the sequence.
*/
- public DLSequence(
- ASN1Encodable obj)
+ public DLSequence(ASN1Encodable element)
{
- super(obj);
+ super(element);
}
/**
* create a sequence containing a vector of objects.
- * @param v the vector of objects to make up the sequence.
+ * @param elementVector the vector of objects to make up the sequence.
*/
- public DLSequence(
- ASN1EncodableVector v)
+ public DLSequence(ASN1EncodableVector elementVector)
{
- super(v);
+ super(elementVector);
}
/**
* create a sequence containing an array of objects.
- * @param array the array of objects to make up the sequence.
+ * @param elements the array of objects to make up the sequence.
*/
- public DLSequence(
- ASN1Encodable[] array)
+ public DLSequence(ASN1Encodable[] elements)
{
- super(array);
+ super(elements);
}
- private int getBodyLength()
- throws IOException
+ DLSequence(ASN1Encodable[] elements, boolean clone)
+ {
+ super(elements, clone);
+ }
+
+ private int getBodyLength() throws IOException
{
if (bodyLength < 0)
{
- int length = 0;
+ int count = elements.length;
+ int totalLength = 0;
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ for (int i = 0; i < count; ++i)
{
- Object obj = e.nextElement();
-
- length += ((ASN1Encodable)obj).toASN1Primitive().toDLObject().encodedLength();
+ ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
+ totalLength += dlObject.encodedLength();
}
- bodyLength = length;
+ this.bodyLength = totalLength;
}
return bodyLength;
}
- int encodedLength()
- throws IOException
+ int encodedLength() throws IOException
{
int length = getBodyLength();
@@ -86,21 +85,49 @@ public class DLSequence
* ASN.1 descriptions given. Rather than just outputting SEQUENCE,
* we also have to specify CONSTRUCTED, and the objects length.
*/
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- ASN1OutputStream dOut = out.getDLSubStream();
- int length = getBodyLength();
+ if (withTag)
+ {
+ out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
+ }
- out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
- out.writeLength(length);
+ ASN1OutputStream dlOut = out.getDLSubStream();
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ int count = elements.length;
+ if (bodyLength >= 0 || count > 16)
{
- Object obj = e.nextElement();
+ out.writeLength(getBodyLength());
- dOut.writeObject((ASN1Encodable)obj);
+ for (int i = 0; i < count; ++i)
+ {
+ dlOut.writePrimitive(elements[i].toASN1Primitive(), true);
+ }
}
+ else
+ {
+ int totalLength = 0;
+
+ ASN1Primitive[] dlObjects = new ASN1Primitive[count];
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
+ dlObjects[i] = dlObject;
+ totalLength += dlObject.encodedLength();
+ }
+
+ this.bodyLength = totalLength;
+ out.writeLength(totalLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ dlOut.writePrimitive(dlObjects[i], true);
+ }
+ }
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
}
} \ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequenceParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequenceParser.java
new file mode 100644
index 00000000..e5c17f68
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSequenceParser.java
@@ -0,0 +1,62 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Parser class for DL SEQUENCEs.
+ *
+ * TODO The class is only publicly visible to support 'instanceof' checks; provide an alternative
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DLSequenceParser
+ implements ASN1SequenceParser
+{
+ private ASN1StreamParser _parser;
+
+ DLSequenceParser(ASN1StreamParser parser)
+ {
+ this._parser = parser;
+ }
+
+ /**
+ * Return the next object in the SEQUENCE.
+ *
+ * @return next object in SEQUENCE.
+ * @throws IOException if there is an issue loading the object.
+ */
+ public ASN1Encodable readObject()
+ throws IOException
+ {
+ return _parser.readObject();
+ }
+
+ /**
+ * Return an in memory, encodable, representation of the SEQUENCE.
+ *
+ * @return a DLSequence.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return new DLSequence(_parser.readVector());
+ }
+
+ /**
+ * Return a DLSequence representing this parser and its contents.
+ *
+ * @return a DLSequence.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException(e.getMessage());
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSet.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSet.java
index 3a01b8f2..85b71a89 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSet.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSet.java
@@ -2,7 +2,6 @@
package com.android.org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* The DLSet encodes ASN.1 SET value without element ordering,
@@ -66,54 +65,54 @@ public class DLSet
}
/**
- * @param obj - a single object that makes up the set.
+ * @param element - a single object that makes up the set.
*/
- public DLSet(
- ASN1Encodable obj)
+ public DLSet(ASN1Encodable element)
{
- super(obj);
+ super(element);
}
/**
- * @param v - a vector of objects making up the set.
+ * @param elementVector - a vector of objects making up the set.
*/
- public DLSet(
- ASN1EncodableVector v)
+ public DLSet(ASN1EncodableVector elementVector)
{
- super(v, false);
+ super(elementVector, false);
}
/**
* create a set from an array of objects.
*/
- public DLSet(
- ASN1Encodable[] a)
+ public DLSet(ASN1Encodable[] elements)
{
- super(a, false);
+ super(elements, false);
}
- private int getBodyLength()
- throws IOException
+ DLSet(boolean isSorted, ASN1Encodable[] elements)
+ {
+ super(isSorted, elements);
+ }
+
+ private int getBodyLength() throws IOException
{
if (bodyLength < 0)
{
- int length = 0;
+ int count = elements.length;
+ int totalLength = 0;
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ for (int i = 0; i < count; ++i)
{
- Object obj = e.nextElement();
-
- length += ((ASN1Encodable)obj).toASN1Primitive().toDLObject().encodedLength();
+ ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
+ totalLength += dlObject.encodedLength();
}
- bodyLength = length;
+ this.bodyLength = totalLength;
}
return bodyLength;
}
- int encodedLength()
- throws IOException
+ int encodedLength() throws IOException
{
int length = getBodyLength();
@@ -128,21 +127,49 @@ public class DLSet
* ASN.1 descriptions given. Rather than just outputting SET,
* we also have to specify CONSTRUCTED, and the objects length.
*/
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- ASN1OutputStream dOut = out.getDLSubStream();
- int length = getBodyLength();
+ if (withTag)
+ {
+ out.write(BERTags.SET | BERTags.CONSTRUCTED);
+ }
- out.write(BERTags.SET | BERTags.CONSTRUCTED);
- out.writeLength(length);
+ ASN1OutputStream dlOut = out.getDLSubStream();
- for (Enumeration e = this.getObjects(); e.hasMoreElements();)
+ int count = elements.length;
+ if (bodyLength >= 0 || count > 16)
{
- Object obj = e.nextElement();
+ out.writeLength(getBodyLength());
- dOut.writeObject((ASN1Encodable)obj);
+ for (int i = 0; i < count; ++i)
+ {
+ dlOut.writePrimitive(elements[i].toASN1Primitive(), true);
+ }
}
+ else
+ {
+ int totalLength = 0;
+
+ ASN1Primitive[] dlObjects = new ASN1Primitive[count];
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
+ dlObjects[i] = dlObject;
+ totalLength += dlObject.encodedLength();
+ }
+
+ this.bodyLength = totalLength;
+ out.writeLength(totalLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ dlOut.writePrimitive(dlObjects[i], true);
+ }
+ }
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
}
} \ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSetParser.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSetParser.java
new file mode 100644
index 00000000..6d2ef114
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLSetParser.java
@@ -0,0 +1,62 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Parser class for DL SETs.
+ *
+ * TODO The class is only publicly visible to support 'instanceof' checks; provide an alternative
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DLSetParser
+ implements ASN1SetParser
+{
+ private ASN1StreamParser _parser;
+
+ DLSetParser(ASN1StreamParser parser)
+ {
+ this._parser = parser;
+ }
+
+ /**
+ * Return the next object in the SET.
+ *
+ * @return next object in SET.
+ * @throws IOException if there is an issue loading the object.
+ */
+ public ASN1Encodable readObject()
+ throws IOException
+ {
+ return _parser.readObject();
+ }
+
+ /**
+ * Return an in memory, encodable, representation of the SET.
+ *
+ * @return a DLSet.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return new DLSet(_parser.readVector());
+ }
+
+ /**
+ * Return a DLSet representing this parser and its contents.
+ *
+ * @return a DLSet
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException(e.getMessage(), e);
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLTaggedObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLTaggedObject.java
index d9e1ed17..e9f7479f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLTaggedObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DLTaggedObject.java
@@ -12,8 +12,6 @@ import java.io.IOException;
public class DLTaggedObject
extends ASN1TaggedObject
{
- private static final byte[] ZERO_BYTES = new byte[0];
-
/**
* @param explicit true if an explicitly tagged object.
* @param tagNo the tag number for this object.
@@ -29,86 +27,49 @@ public class DLTaggedObject
boolean isConstructed()
{
- if (!empty)
- {
- if (explicit)
- {
- return true;
- }
- else
- {
- ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
-
- return primitive.isConstructed();
- }
- }
- else
- {
- return true;
- }
+ return explicit || obj.toASN1Primitive().toDLObject().isConstructed();
}
int encodedLength()
throws IOException
{
- if (!empty)
- {
- int length = obj.toASN1Primitive().toDLObject().encodedLength();
+ int length = obj.toASN1Primitive().toDLObject().encodedLength();
- if (explicit)
- {
- return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
- }
- else
- {
- // header length already in calculation
- length = length - 1;
-
- return StreamUtil.calculateTagLength(tagNo) + length;
- }
+ if (explicit)
+ {
+ return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
}
else
{
- return StreamUtil.calculateTagLength(tagNo) + 1;
+ // header length already in calculation
+ length = length - 1;
+
+ return StreamUtil.calculateTagLength(tagNo) + length;
}
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (!empty)
+ ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
+
+ int flags = BERTags.TAGGED;
+ if (explicit || primitive.isConstructed())
{
- ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
+ flags |= BERTags.CONSTRUCTED;
+ }
- if (explicit)
- {
- out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
- out.writeLength(primitive.encodedLength());
- out.writeObject(primitive);
- }
- else
- {
- //
- // need to mark constructed types...
- //
- int flags;
- if (primitive.isConstructed())
- {
- flags = BERTags.CONSTRUCTED | BERTags.TAGGED;
- }
- else
- {
- flags = BERTags.TAGGED;
- }
+ out.writeTag(withTag, flags, tagNo);
- out.writeTag(flags, tagNo);
- out.writeImplicitObject(primitive);
- }
- }
- else
+ if (explicit)
{
- out.writeEncoded(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo, ZERO_BYTES);
+ out.writeLength(primitive.encodedLength());
}
+
+ out.getDLSubStream().writePrimitive(primitive, explicit);
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DefiniteLengthInputStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DefiniteLengthInputStream.java
index af9ca634..5ab6e113 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DefiniteLengthInputStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DefiniteLengthInputStream.java
@@ -16,13 +16,15 @@ class DefiniteLengthInputStream
private static final byte[] EMPTY_BYTES = new byte[0];
private final int _originalLength;
+
private int _remaining;
DefiniteLengthInputStream(
InputStream in,
- int length)
+ int length,
+ int limit)
{
- super(in, length);
+ super(in, limit);
if (length < 0)
{
@@ -90,6 +92,33 @@ class DefiniteLengthInputStream
return numRead;
}
+ void readAllIntoByteArray(byte[] buf)
+ throws IOException
+ {
+ if (_remaining != buf.length)
+ {
+ throw new IllegalArgumentException("buffer length not right for data");
+ }
+
+ if (_remaining == 0)
+ {
+ return;
+ }
+
+ // make sure it's safe to do this!
+ int limit = getLimit();
+ if (_remaining >= limit)
+ {
+ throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit);
+ }
+
+ if ((_remaining -= Streams.readFully(_in, buf)) != 0)
+ {
+ throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
+ }
+ setParentEofDetect(true);
+ }
+
byte[] toByteArray()
throws IOException
{
@@ -98,6 +127,13 @@ class DefiniteLengthInputStream
return EMPTY_BYTES;
}
+ // make sure it's safe to do this!
+ int limit = getLimit();
+ if (_remaining >= limit)
+ {
+ throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit);
+ }
+
byte[] bytes = new byte[_remaining];
if ((_remaining -= Streams.readFully(_in, bytes)) != 0)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyConstructionEnumeration.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyConstructionEnumeration.java
index bd258c25..ebda1a7e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyConstructionEnumeration.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyConstructionEnumeration.java
@@ -3,6 +3,7 @@ package com.android.org.bouncycastle.asn1;
import java.io.IOException;
import java.util.Enumeration;
+import java.util.NoSuchElementException;
class LazyConstructionEnumeration
implements Enumeration
@@ -23,11 +24,13 @@ class LazyConstructionEnumeration
public Object nextElement()
{
- Object o = nextObj;
-
- nextObj = readObject();
-
- return o;
+ if (nextObj != null)
+ {
+ Object o = nextObj;
+ nextObj = readObject();
+ return o;
+ }
+ throw new NoSuchElementException();
}
private Object readObject()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyEncodedSequence.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyEncodedSequence.java
index 6e9d42c3..8ec6478b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyEncodedSequence.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LazyEncodedSequence.java
@@ -3,6 +3,7 @@ package com.android.org.bouncycastle.asn1;
import java.io.IOException;
import java.util.Enumeration;
+import java.util.Iterator;
/**
* Note: this class is for processing DER/DL encoded sequences only.
@@ -12,99 +13,117 @@ class LazyEncodedSequence
{
private byte[] encoded;
- LazyEncodedSequence(
- byte[] encoded)
- throws IOException
+ LazyEncodedSequence(byte[] encoded) throws IOException
{
+ // NOTE: Initially, the actual 'elements' will be empty
+ super();
+
this.encoded = encoded;
}
- private void parse()
+ public synchronized ASN1Encodable getObjectAt(int index)
{
- Enumeration en = new LazyConstructionEnumeration(encoded);
+ force();
+
+ return super.getObjectAt(index);
+ }
- while (en.hasMoreElements())
+ public synchronized Enumeration getObjects()
+ {
+ if (null != encoded)
{
- seq.addElement(en.nextElement());
+ return new LazyConstructionEnumeration(encoded);
}
- encoded = null;
+ return super.getObjects();
}
- public synchronized ASN1Encodable getObjectAt(int index)
+ public synchronized int hashCode()
{
- if (encoded != null)
- {
- parse();
- }
+ force();
- return super.getObjectAt(index);
+ return super.hashCode();
}
- public synchronized Enumeration getObjects()
+ public synchronized Iterator<ASN1Encodable> iterator()
{
- if (encoded == null)
- {
- return super.getObjects();
- }
+ force();
- return new LazyConstructionEnumeration(encoded);
+ return super.iterator();
}
public synchronized int size()
{
- if (encoded != null)
- {
- parse();
- }
+ force();
return super.size();
}
- ASN1Primitive toDERObject()
+ public synchronized ASN1Encodable[] toArray()
{
- if (encoded != null)
- {
- parse();
- }
+ force();
- return super.toDERObject();
+ return super.toArray();
}
- ASN1Primitive toDLObject()
+ ASN1Encodable[] toArrayInternal()
{
- if (encoded != null)
- {
- parse();
- }
+ force();
- return super.toDLObject();
+ return super.toArrayInternal();
}
- int encodedLength()
+ synchronized int encodedLength()
throws IOException
{
- if (encoded != null)
+ if (null != encoded)
{
return 1 + StreamUtil.calculateBodyLength(encoded.length) + encoded.length;
}
- else
- {
- return super.toDLObject().encodedLength();
- }
+
+ return super.toDLObject().encodedLength();
}
- void encode(
- ASN1OutputStream out)
- throws IOException
+ synchronized void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
- if (encoded != null)
+ if (null != encoded)
{
- out.writeEncoded(BERTags.SEQUENCE | BERTags.CONSTRUCTED, encoded);
+ out.writeEncoded(withTag, BERTags.SEQUENCE | BERTags.CONSTRUCTED, encoded);
}
else
{
- super.toDLObject().encode(out);
+ super.toDLObject().encode(out, withTag);
+ }
+ }
+
+ synchronized ASN1Primitive toDERObject()
+ {
+ force();
+
+ return super.toDERObject();
+ }
+
+ synchronized ASN1Primitive toDLObject()
+ {
+ force();
+
+ return super.toDLObject();
+ }
+
+ private void force()
+ {
+ if (null != encoded)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ Enumeration en = new LazyConstructionEnumeration(encoded);
+ while (en.hasMoreElements())
+ {
+ v.add((ASN1Primitive)en.nextElement());
+ }
+
+ this.elements = v.takeElements();
+ this.encoded = null;
}
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LimitedInputStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LimitedInputStream.java
index e4c8db45..ce84e825 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LimitedInputStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/LimitedInputStream.java
@@ -20,12 +20,11 @@ abstract class LimitedInputStream
this._limit = limit;
}
- int getRemaining()
+ int getLimit()
{
- // TODO: maybe one day this can become more accurate
return _limit;
}
-
+
protected void setParentEofDetect(boolean on)
{
if (_in instanceof IndefiniteLengthInputStream)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/StreamUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/StreamUtil.java
index 46738322..21a875a0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/StreamUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/StreamUtil.java
@@ -13,7 +13,7 @@ class StreamUtil
// private static final long MAX_MEMORY = Runtime.getRuntime().maxMemory();
/**
- * Find out possible longest length...
+ * Find out possible longest length, capped by available memory.
*
* @param in input stream of interest
* @return length calculation or MAX_VALUE.
@@ -22,7 +22,7 @@ class StreamUtil
{
if (in instanceof LimitedInputStream)
{
- return ((LimitedInputStream)in).getRemaining();
+ return ((LimitedInputStream)in).getLimit();
}
else if (in instanceof ASN1InputStream)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
index 032216e5..74005e9b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
@@ -149,11 +149,16 @@ public interface BCObjectIdentifiers
* qTESLA
*/
public static final ASN1ObjectIdentifier qTESLA = bc_sig.branch("4");
- public static final ASN1ObjectIdentifier qTESLA_I = qTESLA.branch("1");
- public static final ASN1ObjectIdentifier qTESLA_III_size = qTESLA.branch("2");
- public static final ASN1ObjectIdentifier qTESLA_III_speed = qTESLA.branch("3");
- public static final ASN1ObjectIdentifier qTESLA_p_I = qTESLA.branch("4");
- public static final ASN1ObjectIdentifier qTESLA_p_III = qTESLA.branch("5");
+
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_I = qTESLA.branch("1");
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_III_size = qTESLA.branch("2");
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_III_speed = qTESLA.branch("3");
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_p_I = qTESLA.branch("4");
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_p_III = qTESLA.branch("5");
+
+
+ public static final ASN1ObjectIdentifier qTESLA_p_I = qTESLA.branch("11");
+ public static final ASN1ObjectIdentifier qTESLA_p_III = qTESLA.branch("12");
/**
* key_exchange(3) algorithms
@@ -166,4 +171,13 @@ public interface BCObjectIdentifiers
public static final ASN1ObjectIdentifier newHope = bc_exch.branch("1");
*/
// END Android-removed: Unsupported algorithms
+
+ /**
+ * X.509 extension(4) values
+ * <p>
+ * 1.3.6.1.4.1.22554.4
+ */
+ public static final ASN1ObjectIdentifier bc_ext = bc.branch("4");
+
+ public static final ASN1ObjectIdentifier linkedCertificate = bc_ext.branch("1");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Attribute.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Attribute.java
index 352198a9..5909dc94 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Attribute.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Attribute.java
@@ -11,7 +11,7 @@ import com.android.org.bouncycastle.asn1.ASN1Set;
import com.android.org.bouncycastle.asn1.DERSequence;
/**
- * <a href="http://tools.ietf.org/html/rfc5652#page-14">RFC 5652</a>:
+ * <a href="https://tools.ietf.org/html/rfc5652#page-14">RFC 5652</a>:
* Attribute is a pair of OID (as type identifier) + set of values.
* <p>
* <pre>
@@ -102,7 +102,7 @@ public class Attribute
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(attrType);
v.add(attrValues);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Attributes.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Attributes.java
index de1cf4ba..495c2f03 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Attributes.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Attributes.java
@@ -9,7 +9,7 @@ import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.org.bouncycastle.asn1.DLSet;
/**
- * <a href="http://tools.ietf.org/html/rfc5652">RFC 5652</a> defines
+ * <a href="https://tools.ietf.org/html/rfc5652">RFC 5652</a> defines
* 5 "SET OF Attribute" entities with 5 different names.
* This is common implementation for them all:
* <pre>
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java
index 34c16e33..1f9b475f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java
@@ -121,7 +121,7 @@ public class CMSAlgorithmProtection
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(digestAlgorithm);
if (signatureAlgorithm != null)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/CMSAttributes.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/CMSAttributes.java
index 87008543..ed5973e0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/CMSAttributes.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/CMSAttributes.java
@@ -6,8 +6,8 @@ import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
/**
- * <a href="http://tools.ietf.org/html/rfc5652">RFC 5652</a> CMS attribute OID constants.
- * and <a href="http://tools.ietf.org/html/rfc6211">RFC 6211</a> Algorithm Identifier Protection Attribute.
+ * <a href="https://tools.ietf.org/html/rfc5652">RFC 5652</a> CMS attribute OID constants.
+ * and <a href="https://tools.ietf.org/html/rfc6211">RFC 6211</a> Algorithm Identifier Protection Attribute.
* <pre>
* contentType ::= 1.2.840.113549.1.9.3
* messageDigest ::= 1.2.840.113549.1.9.4
@@ -30,7 +30,7 @@ public interface CMSAttributes
ASN1ObjectIdentifier signingTime = PKCSObjectIdentifiers.pkcs_9_at_signingTime;
/** PKCS#9: 1.2.840.113549.1.9.6 */
ASN1ObjectIdentifier counterSignature = PKCSObjectIdentifiers.pkcs_9_at_counterSignature;
- /** PKCS#9: 1.2.840.113549.1.9.16.6.2.4 - See <a href="http://tools.ietf.org/html/rfc2634">RFC 2634</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.6.2.4 - See <a href="https://tools.ietf.org/html/rfc2634">RFC 2634</a> */
ASN1ObjectIdentifier contentHint = PKCSObjectIdentifiers.id_aa_contentHint;
ASN1ObjectIdentifier cmsAlgorithmProtect = PKCSObjectIdentifiers.id_aa_cmsAlgorithmProtect;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/ContentInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/ContentInfo.java
index 1be16151..cbde2d35 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/ContentInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/ContentInfo.java
@@ -12,8 +12,8 @@ import com.android.org.bouncycastle.asn1.BERSequence;
import com.android.org.bouncycastle.asn1.BERTaggedObject;
/**
- * <a href="http://tools.ietf.org/html/rfc5652#section-3">RFC 5652</a> ContentInfo, and
- * <a href="http://tools.ietf.org/html/rfc5652#section-5.2">RFC 5652</a> EncapsulatedContentInfo objects.
+ * <a href="https://tools.ietf.org/html/rfc5652#section-3">RFC 5652</a> ContentInfo, and
+ * <a href="https://tools.ietf.org/html/rfc5652#section-5.2">RFC 5652</a> EncapsulatedContentInfo objects.
*
* <pre>
* ContentInfo ::= SEQUENCE {
@@ -118,7 +118,7 @@ public class ContentInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(contentType);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/GCMParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/GCMParameters.java
index faa2bbd3..17e3ba01 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/GCMParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/GCMParameters.java
@@ -12,7 +12,7 @@ import com.android.org.bouncycastle.asn1.DERSequence;
import com.android.org.bouncycastle.util.Arrays;
/**
- * <a href="http://tools.ietf.org/html/rfc5084">RFC 5084</a>: GCMParameters object.
+ * <a href="https://tools.ietf.org/html/rfc5084">RFC 5084</a>: GCMParameters object.
* <p>
* <pre>
GCMParameters ::= SEQUENCE {
@@ -62,7 +62,7 @@ public class GCMParameters
if (seq.size() == 2)
{
- this.icvLen = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue().intValue();
+ this.icvLen = ASN1Integer.getInstance(seq.getObjectAt(1)).intValueExact();
}
else
{
@@ -90,7 +90,7 @@ public class GCMParameters
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(new DEROctetString(nonce));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java
index 2c9d96bb..dd08f799 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java
@@ -15,7 +15,7 @@ import com.android.org.bouncycastle.asn1.x509.X509CertificateStructure;
import com.android.org.bouncycastle.asn1.x509.X509Name;
/**
- * <a href="http://tools.ietf.org/html/rfc5652#section-10.2.4">RFC 5652</a>: IssuerAndSerialNumber object.
+ * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.4">RFC 5652</a>: IssuerAndSerialNumber object.
* <p>
* <pre>
* IssuerAndSerialNumber ::= SEQUENCE {
@@ -130,7 +130,7 @@ public class IssuerAndSerialNumber
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(name);
v.add(serialNumber);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignedData.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignedData.java
index 19cf200e..70fa1ce2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignedData.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignedData.java
@@ -17,7 +17,7 @@ import com.android.org.bouncycastle.asn1.BERTaggedObject;
import com.android.org.bouncycastle.asn1.DERTaggedObject;
/**
- * <a href="http://tools.ietf.org/html/rfc5652#section-5.1">RFC 5652</a>:
+ * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">RFC 5652</a>:
* <p>
* A signed data object containing multitude of {@link SignerInfo}s.
* <pre>
@@ -208,7 +208,7 @@ public class SignedData
{
SignerInfo s = SignerInfo.getInstance(e.nextElement());
- if (s.getVersion().getValue().intValue() == 3)
+ if (s.getVersion().intValueExact() == 3)
{
return true;
}
@@ -295,7 +295,7 @@ public class SignedData
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(6);
v.add(version);
v.add(digestAlgorithms);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignerIdentifier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignerIdentifier.java
index 942f1d32..bbcb6c31 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignerIdentifier.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignerIdentifier.java
@@ -10,7 +10,7 @@ import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.org.bouncycastle.asn1.DERTaggedObject;
/**
- * <a href="http://tools.ietf.org/html/rfc5652#section-5.3">RFC 5652</a>:
+ * <a href="https://tools.ietf.org/html/rfc5652#section-5.3">RFC 5652</a>:
* Identify who signed the containing {@link SignerInfo} object.
* <p>
* The certificates referred to by this are at containing {@link SignedData} structure.
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignerInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignerInfo.java
index 9a0d9b53..0d419995 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignerInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/SignerInfo.java
@@ -17,7 +17,7 @@ import com.android.org.bouncycastle.asn1.DERTaggedObject;
import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
/**
- * <a href="http://tools.ietf.org/html/rfc5652#section-5.3">RFC 5652</a>:
+ * <a href="https://tools.ietf.org/html/rfc5652#section-5.3">RFC 5652</a>:
* Signature container per Signer, see {@link SignerIdentifier}.
* <pre>
* PKCS#7:
@@ -260,7 +260,7 @@ public class SignerInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(7);
v.add(version);
v.add(sid);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Time.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Time.java
index 612c6721..2f304a5f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Time.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/cms/Time.java
@@ -19,7 +19,7 @@ import com.android.org.bouncycastle.asn1.DERGeneralizedTime;
import com.android.org.bouncycastle.asn1.DERUTCTime;
/**
- * <a href="http://tools.ietf.org/html/rfc5652#section-11.3">RFC 5652</a>:
+ * <a href="https://tools.ietf.org/html/rfc5652#section-11.3">RFC 5652</a>:
* Dual-mode timestamp format producing either UTCTIme or GeneralizedTime.
* <p>
* <pre>
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java
index 8c3719e1..a437f4e8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java
@@ -6,7 +6,7 @@ import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
/**
* German Federal Office for Information Security
* (Bundesamt f&uuml;r Sicherheit in der Informationstechnik)
- * <a href="http://www.bsi.bund.de/">http://www.bsi.bund.de/</a>
+ * <a href="https://www.bsi.bund.de/">https://www.bsi.bund.de/</a>
* <p>
* <a href="https://www.bsi.bund.de/EN/Publications/TechnicalGuidelines/TR03110/BSITR03110.html">BSI TR-03110</a>
* Technical Guideline Advanced Security Mechanisms for Machine Readable Travel Documents
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java
index 2df49d6e..75c62d94 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java
@@ -7,10 +7,10 @@ import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
* Korea Information Security Agency (KISA)
* ({iso(1) member-body(2) kr(410) kisa(200004)})
* <p>
- * See <a href="http://tools.ietf.org/html/rfc4010">RFC 4010</a>
+ * See <a href="https://tools.ietf.org/html/rfc4010">RFC 4010</a>
* Use of the SEED Encryption Algorithm
* in Cryptographic Message Syntax (CMS),
- * and <a href="http://tools.ietf.org/html/rfc4269">RFC 4269</a>
+ * and <a href="https://tools.ietf.org/html/rfc4269">RFC 4269</a>
* The SEED Encryption Algorithm
* @hide This class is not part of the Android public SDK API
*/
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
index 59f0c86a..bbf5cd7e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
@@ -106,6 +106,12 @@ public interface MiscObjectIdentifiers
ASN1ObjectIdentifier cast5CBC = entrust.branch("66.10");
//
+ // HMAC-SHA1 hMAC-SHA1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
+ // dod(6) internet(1) security(5) mechanisms(5) 8 1 2 }
+ //
+ ASN1ObjectIdentifier hMAC_SHA1 = new ASN1ObjectIdentifier("1.3.6.1.5.5.8.1.2");
+
+ //
// Ascom
//
ASN1ObjectIdentifier as_sys_sec_alg_ideaCBC = new ASN1ObjectIdentifier("1.3.6.1.4.1.188.7.1.1.2");
@@ -139,4 +145,11 @@ public interface MiscObjectIdentifiers
//
// Scrypt
ASN1ObjectIdentifier id_scrypt = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.4.11");
+
+ // Composite key/signature oid - prototyping
+ //
+ // id-alg-composite OBJECT IDENTIFIER ::= {
+ // iso(1) identified-organization(3) dod(6) internet(1) private(4)
+ // enterprise(1) OpenCA(18227) Algorithms(2) id-alg-composite(1) }
+ ASN1ObjectIdentifier id_alg_composite = new ASN1ObjectIdentifier("1.3.6.1.4.1.18227.2.1");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
index fc5adab3..3a1609ea 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
@@ -53,6 +53,14 @@ public interface NISTObjectIdentifiers
static final ASN1ObjectIdentifier id_hmacWithSHA3_384 = hashAlgs.branch("15");
/** 2.16.840.1.101.3.4.2.16 */
static final ASN1ObjectIdentifier id_hmacWithSHA3_512 = hashAlgs.branch("16");
+ /** 2.16.840.1.101.3.4.2.17 */
+ static final ASN1ObjectIdentifier id_shake128_len = hashAlgs.branch("17");
+ /** 2.16.840.1.101.3.4.2.18 */
+ static final ASN1ObjectIdentifier id_shake256_len = hashAlgs.branch("18");
+ /** 2.16.840.1.101.3.4.2.19 */
+ static final ASN1ObjectIdentifier id_KmacWithSHAKE128 = hashAlgs.branch("19");
+ /** 2.16.840.1.101.3.4.2.20 */
+ static final ASN1ObjectIdentifier id_KmacWithSHAKE256 = hashAlgs.branch("20");
/** 2.16.840.1.101.3.4.1 */
static final ASN1ObjectIdentifier aes = nistAlgorithm.branch("1");
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java
index a6a81b71..72fbc5b2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java
@@ -4,7 +4,7 @@ package com.android.org.bouncycastle.asn1.ntt;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
/**
- * From <a href="http://tools.ietf.org/html/rfc3657">RFC 3657</a>
+ * From <a href="https://tools.ietf.org/html/rfc3657">RFC 3657</a>
* Use of the Camellia Encryption Algorithm
* in Cryptographic Message Syntax (CMS)
* @hide This class is not part of the Android public SDK API
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/Attribute.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/Attribute.java
index 2a3f3e95..86544187 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/Attribute.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/Attribute.java
@@ -82,7 +82,7 @@ public class Attribute
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(attrType);
v.add(attrValues);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java
index 9f567176..ed37fa11 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java
@@ -68,20 +68,13 @@ public class AuthenticatedSafe
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
-
- for (int i = 0; i != info.length; i++)
- {
- v.add(info[i]);
- }
-
if (isBer)
{
- return new BERSequence(v);
+ return new BERSequence(info);
}
else
{
- return new DLSequence(v);
+ return new DLSequence(info);
}
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CRLBag.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CRLBag.java
index e1239feb..441dfd11 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CRLBag.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CRLBag.java
@@ -78,7 +78,7 @@ public class CRLBag
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(crlId);
v.add(new DERTaggedObject(0, crlValue));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertBag.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertBag.java
index 7338256b..76fe51ab 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertBag.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertBag.java
@@ -7,6 +7,7 @@ import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.org.bouncycastle.asn1.DERSequence;
import com.android.org.bouncycastle.asn1.DERTaggedObject;
@@ -22,8 +23,8 @@ public class CertBag
private CertBag(
ASN1Sequence seq)
{
- this.certId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
- this.certValue = ((DERTaggedObject)seq.getObjectAt(1)).getObject();
+ this.certId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+ this.certValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getObject();
}
public static CertBag getInstance(Object o)
@@ -60,7 +61,7 @@ public class CertBag
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(certId);
v.add(new DERTaggedObject(0, certValue));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequest.java
index 034b63d2..b5e90911 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequest.java
@@ -85,7 +85,7 @@ public class CertificationRequest
public ASN1Primitive toASN1Primitive()
{
// Construct the CertificateRequest
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(reqInfo);
v.add(sigAlgId);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
index f97a3090..fc3e97c2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
@@ -150,7 +150,7 @@ public class CertificationRequestInfo
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(version);
v.add(subject);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/ContentInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/ContentInfo.java
index 8568cc52..2611ac7c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/ContentInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/ContentInfo.java
@@ -85,7 +85,7 @@ public class ContentInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(contentType);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/DHParameter.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/DHParameter.java
index d238173a..20e830f4 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/DHParameter.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/DHParameter.java
@@ -93,7 +93,7 @@ public class DHParameter
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(p);
v.add(g);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedData.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedData.java
index 108e5bfb..87d7d06a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedData.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedData.java
@@ -57,7 +57,7 @@ public class EncryptedData
private EncryptedData(
ASN1Sequence seq)
{
- int version = ((ASN1Integer)seq.getObjectAt(0)).getValue().intValue();
+ int version = ((ASN1Integer)seq.getObjectAt(0)).intValueExact();
if (version != 0)
{
@@ -72,7 +72,7 @@ public class EncryptedData
AlgorithmIdentifier encryptionAlgorithm,
ASN1Encodable content)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(contentType);
v.add(encryptionAlgorithm.toASN1Primitive());
@@ -105,7 +105,7 @@ public class EncryptedData
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(new ASN1Integer(0));
v.add(data);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
index fe92da58..1a723582 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
@@ -80,7 +80,7 @@ public class EncryptedPrivateKeyInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(algId);
v.add(data);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java
index e547468b..4cba8067 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java
@@ -79,7 +79,7 @@ public class IssuerAndSerialNumber
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(name);
v.add(certSerialNumber);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/MacData.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/MacData.java
index 0171ae83..b6912b1d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/MacData.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/MacData.java
@@ -96,7 +96,7 @@ public class MacData
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(digInfo);
v.add(new DEROctetString(salt));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBEParameter.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBEParameter.java
index f3c6766e..bfe2d6c3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBEParameter.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBEParameter.java
@@ -67,7 +67,7 @@ public class PBEParameter
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(salt);
v.add(iterations);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBES2Parameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBES2Parameters.java
index fb631f74..64ae11e0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBES2Parameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBES2Parameters.java
@@ -71,7 +71,7 @@ public class PBES2Parameters
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(func);
v.add(scheme);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBKDF2Params.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
index 50490772..082284e2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
@@ -245,7 +245,7 @@ public class PBKDF2Params
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(octStr);
v.add(iterationCount);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java
index 21664138..0df62f12 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java
@@ -63,7 +63,7 @@ public class PKCS12PBEParams
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(iv);
v.add(iterations);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
index 717c6f77..1e68d870 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
@@ -9,7 +9,6 @@ import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
* @hide This class is not part of the Android public SDK API
*
*/
-@libcore.api.CorePlatformApi
public interface PKCSObjectIdentifiers
{
/** PKCS#1: 1.2.840.113549.1.1 */
@@ -40,12 +39,10 @@ public interface PKCSObjectIdentifiers
ASN1ObjectIdentifier id_RSASSA_PSS = pkcs_1.branch("10");
/** PKCS#1: 1.2.840.113549.1.1.11 */
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
ASN1ObjectIdentifier sha256WithRSAEncryption = pkcs_1.branch("11");
/** PKCS#1: 1.2.840.113549.1.1.12 */
ASN1ObjectIdentifier sha384WithRSAEncryption = pkcs_1.branch("12");
/** PKCS#1: 1.2.840.113549.1.1.13 */
- @libcore.api.CorePlatformApi
ASN1ObjectIdentifier sha512WithRSAEncryption = pkcs_1.branch("13");
/** PKCS#1: 1.2.840.113549.1.1.14 */
ASN1ObjectIdentifier sha224WithRSAEncryption = pkcs_1.branch("14");
@@ -267,6 +264,49 @@ public interface PKCSObjectIdentifiers
*/
ASN1ObjectIdentifier id_rsa_KEM = id_alg.branch("14");
+
+ /**
+ * id-alg-hss-lms-hashsig OBJECT IDENTIFIER ::= { iso(1)
+ * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
+ * smime(16) alg(3) 17 }
+ */
+ public static final ASN1ObjectIdentifier id_alg_hss_lms_hashsig = id_alg.branch("17");
+
+ /**
+ * <pre>
+ * id-alg-AEADChaCha20Poly1305 OBJECT IDENTIFIER ::=
+ * { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+ * pkcs9(9) smime(16) alg(3) 18 }
+ *
+ * AEADChaCha20Poly1305Nonce ::= OCTET STRING (SIZE(12))
+ * </pre>
+ */
+ ASN1ObjectIdentifier id_alg_AEADChaCha20Poly1305 = id_alg.branch("18");
+
+ /**
+ * <pre>
+ * id-alg-hkdf-with-sha256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ * us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 28 }
+ * </pre>
+ */
+ ASN1ObjectIdentifier id_alg_hkdf_with_sha256 = id_alg.branch("28");
+
+ /**
+ * <pre>
+ * id-alg-hkdf-with-sha384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ * us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 29 }
+ * </pre>
+ */
+ ASN1ObjectIdentifier id_alg_hkdf_with_sha384 = id_alg.branch("29");
+
+ /**
+ * <pre>
+ * id-alg-hkdf-with-sha512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ * us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 30 }
+ * </pre>
+ */
+ ASN1ObjectIdentifier id_alg_hkdf_with_sha512 = id_alg.branch("30");
+
//
// id-cti OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
// rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) cti(6)}
@@ -298,7 +338,7 @@ public interface PKCSObjectIdentifiers
/** PKCS#9: 1.2.840.113549.1.9.16.2.1 -- smime attribute receiptRequest */
ASN1ObjectIdentifier id_aa_receiptRequest = id_aa.branch("1");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.4 - See <a href="http://tools.ietf.org/html/rfc2634">RFC 2634</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.4 - See <a href="https://tools.ietf.org/html/rfc2634">RFC 2634</a> */
ASN1ObjectIdentifier id_aa_contentHint = id_aa.branch("4"); // See RFC 2634
/** PKCS#9: 1.2.840.113549.1.9.16.2.5 */
ASN1ObjectIdentifier id_aa_msgSigDigest = id_aa.branch("5");
@@ -315,40 +355,40 @@ public interface PKCSObjectIdentifiers
/** PKCS#9: 1.2.840.113549.1.9.16.2.47 */
ASN1ObjectIdentifier id_aa_signingCertificateV2 = id_aa.branch("47");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.7 - See <a href="http://tools.ietf.org/html/rfc2634">RFC 2634</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.7 - See <a href="https://tools.ietf.org/html/rfc2634">RFC 2634</a> */
ASN1ObjectIdentifier id_aa_contentIdentifier = id_aa.branch("7"); // See RFC 2634
/*
* RFC 3126
*/
- /** PKCS#9: 1.2.840.113549.1.9.16.2.14 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.14 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_signatureTimeStampToken = id_aa.branch("14");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.15 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.15 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_sigPolicyId = id_aa.branch("15");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.16 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.16 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_commitmentType = id_aa.branch("16");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.17 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.17 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_signerLocation = id_aa.branch("17");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.18 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.18 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_signerAttr = id_aa.branch("18");
- /** PKCS#9: 1.2.840.113549.1.9.16.6.2.19 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.6.2.19 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_otherSigCert = id_aa.branch("19");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.20 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.20 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_contentTimestamp = id_aa.branch("20");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.21 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.21 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_certificateRefs = id_aa.branch("21");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.22 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.22 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_revocationRefs = id_aa.branch("22");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.23 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.23 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_certValues = id_aa.branch("23");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.24 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.24 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_revocationValues = id_aa.branch("24");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.25 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.25 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_escTimeStamp = id_aa.branch("25");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.26 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.26 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_certCRLTimestamp = id_aa.branch("26");
- /** PKCS#9: 1.2.840.113549.1.9.16.2.27 - <a href="http://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.27 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
ASN1ObjectIdentifier id_aa_ets_archiveTimestamp = id_aa.branch("27");
/** PKCS#9: 1.2.840.113549.1.9.16.2.37 - <a href="https://tools.ietf.org/html/rfc4108#section-2.2.5">RFC 4108</a> */
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/Pfx.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/Pfx.java
index 8cb94739..01241ccf 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/Pfx.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/Pfx.java
@@ -1,8 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.pkcs;
-import java.math.BigInteger;
-
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1Object;
@@ -24,8 +22,8 @@ public class Pfx
private Pfx(
ASN1Sequence seq)
{
- BigInteger version = ASN1Integer.getInstance(seq.getObjectAt(0)).getValue();
- if (version.intValue() != 3)
+ ASN1Integer version = ASN1Integer.getInstance(seq.getObjectAt(0));
+ if (version.intValueExact() != 3)
{
throw new IllegalArgumentException("wrong version for PFX PDU");
}
@@ -74,7 +72,7 @@ public class Pfx
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(new ASN1Integer(3));
v.add(contentInfo);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
index 56743253..c368321a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
@@ -2,7 +2,6 @@
package com.android.org.bouncycastle.asn1.pkcs;
import java.io.IOException;
-import java.math.BigInteger;
import java.util.Enumeration;
import com.android.org.bouncycastle.asn1.ASN1BitString;
@@ -60,7 +59,6 @@ import com.android.org.bouncycastle.util.BigIntegers;
* </pre>
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class PrivateKeyInfo
extends ASN1Object
{
@@ -75,7 +73,6 @@ public class PrivateKeyInfo
return getInstance(ASN1Sequence.getInstance(obj, explicit));
}
- @libcore.api.CorePlatformApi
public static PrivateKeyInfo getInstance(Object obj)
{
if (obj instanceof PrivateKeyInfo)
@@ -92,12 +89,12 @@ public class PrivateKeyInfo
private static int getVersionValue(ASN1Integer version)
{
- BigInteger bigValue = version.getValue();
- if (bigValue.compareTo(BigIntegers.ZERO) < 0 || bigValue.compareTo(BigIntegers.ONE) > 0)
+ int versionValue = version.intValueExact();
+ if (versionValue < 0 || versionValue > 1)
{
throw new IllegalArgumentException("invalid version for private key info");
}
- return bigValue.intValue();
+ return versionValue;
}
public PrivateKeyInfo(
@@ -180,18 +177,26 @@ public class PrivateKeyInfo
}
}
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
public ASN1Set getAttributes()
{
return attributes;
}
- @libcore.api.CorePlatformApi
public AlgorithmIdentifier getPrivateKeyAlgorithm()
{
return privateKeyAlgorithm;
}
- @libcore.api.CorePlatformApi
+ public ASN1OctetString getPrivateKey()
+ {
+ return new DEROctetString(privateKey.getOctets());
+ }
+
public ASN1Encodable parsePrivateKey()
throws IOException
{
@@ -234,7 +239,7 @@ public class PrivateKeyInfo
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
v.add(version);
v.add(privateKeyAlgorithm);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
index f47ccf85..2bdfbab0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
@@ -137,7 +137,7 @@ public class RSAESOAEPparams
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
if (!hashAlgorithm.equals(DEFAULT_HASH_ALGORITHM))
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java
index f3194440..68d8a242 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java
@@ -78,13 +78,14 @@ public class RSAPrivateKey
{
Enumeration e = seq.getObjects();
- BigInteger v = ((ASN1Integer)e.nextElement()).getValue();
- if (v.intValue() != 0 && v.intValue() != 1)
+ ASN1Integer v = (ASN1Integer)e.nextElement();
+ int versionValue = v.intValueExact();
+ if (versionValue < 0 || versionValue > 1)
{
throw new IllegalArgumentException("wrong version for RSA private key");
}
- version = v;
+ version = v.getValue();
modulus = ((ASN1Integer)e.nextElement()).getValue();
publicExponent = ((ASN1Integer)e.nextElement()).getValue();
privateExponent = ((ASN1Integer)e.nextElement()).getValue();
@@ -169,7 +170,7 @@ public class RSAPrivateKey
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(10);
v.add(new ASN1Integer(version)); // version
v.add(new ASN1Integer(getModulus()));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java
index 08e30086..13960ecb 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java
@@ -78,13 +78,14 @@ public class RSAPrivateKeyStructure
{
Enumeration e = seq.getObjects();
- BigInteger v = ((ASN1Integer)e.nextElement()).getValue();
- if (v.intValue() != 0 && v.intValue() != 1)
+ ASN1Integer v = (ASN1Integer)e.nextElement();
+ int versionValue = v.intValueExact();
+ if (versionValue < 0 || versionValue > 1)
{
throw new IllegalArgumentException("wrong version for RSA private key");
}
- version = v.intValue();
+ version = versionValue;
modulus = ((ASN1Integer)e.nextElement()).getValue();
publicExponent = ((ASN1Integer)e.nextElement()).getValue();
privateExponent = ((ASN1Integer)e.nextElement()).getValue();
@@ -169,7 +170,7 @@ public class RSAPrivateKeyStructure
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(10);
v.add(new ASN1Integer(version)); // version
v.add(new ASN1Integer(getModulus()));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPublicKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPublicKey.java
index 090763b9..4f98a174 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPublicKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSAPublicKey.java
@@ -89,7 +89,7 @@ public class RSAPublicKey
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(new ASN1Integer(getModulus()));
v.add(new ASN1Integer(getPublicExponent()));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java
index 59b93512..dd6885bb 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java
@@ -149,7 +149,7 @@ public class RSASSAPSSparams
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
if (!hashAlgorithm.equals(DEFAULT_HASH_ALGORITHM))
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/SafeBag.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/SafeBag.java
index d37078f7..b093f6c2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/SafeBag.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/SafeBag.java
@@ -85,7 +85,7 @@ public class SafeBag
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(bagId);
v.add(new DLTaggedObject(true, 0, bagValue));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/SignedData.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/SignedData.java
index 6ebfdff8..88d32b55 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/SignedData.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/pkcs/SignedData.java
@@ -146,7 +146,7 @@ public class SignedData
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(6);
v.add(version);
v.add(digestAlgorithms);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKey.java
index 6a84adeb..07f0439c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKey.java
@@ -70,7 +70,7 @@ public class ECPrivateKey
{
byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key);
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(new ASN1Integer(1));
v.add(new DEROctetString(bytes));
@@ -115,7 +115,7 @@ public class ECPrivateKey
{
byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key);
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(new ASN1Integer(1));
v.add(new DEROctetString(bytes));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
index 65bb3210..dbef9bdb 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
@@ -39,7 +39,7 @@ public class ECPrivateKeyStructure
{
byte[] bytes = BigIntegers.asUnsignedByteArray(key);
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(new ASN1Integer(1));
v.add(new DEROctetString(bytes));
@@ -61,7 +61,7 @@ public class ECPrivateKeyStructure
{
byte[] bytes = BigIntegers.asUnsignedByteArray(key);
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(new ASN1Integer(1));
v.add(new DEROctetString(bytes));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/SECNamedCurves.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/SECNamedCurves.java
index 145e08fb..2c67e252 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/SECNamedCurves.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/sec/SECNamedCurves.java
@@ -11,8 +11,10 @@ import com.android.org.bouncycastle.asn1.x9.X9ECParametersHolder;
import com.android.org.bouncycastle.asn1.x9.X9ECPoint;
import com.android.org.bouncycastle.math.ec.ECConstants;
import com.android.org.bouncycastle.math.ec.ECCurve;
+import com.android.org.bouncycastle.math.ec.WNafUtil;
import com.android.org.bouncycastle.math.ec.endo.GLVTypeBEndomorphism;
import com.android.org.bouncycastle.math.ec.endo.GLVTypeBParameters;
+import com.android.org.bouncycastle.math.ec.endo.ScalarSplitParameters;
import com.android.org.bouncycastle.util.Strings;
import com.android.org.bouncycastle.util.encoders.Hex;
@@ -21,6 +23,13 @@ import com.android.org.bouncycastle.util.encoders.Hex;
*/
public class SECNamedCurves
{
+ private static X9ECPoint configureBasepoint(ECCurve curve, String encoding)
+ {
+ X9ECPoint G = new X9ECPoint(curve, Hex.decodeStrict(encoding));
+ WNafUtil.configureBasepoint(G.getPoint());
+ return G;
+ }
+
private static ECCurve configureCurve(ECCurve curve)
{
return curve;
@@ -31,10 +40,9 @@ public class SECNamedCurves
return c.configure().setEndomorphism(new GLVTypeBEndomorphism(c, p)).create();
}
- private static BigInteger fromHex(
- String hex)
+ private static BigInteger fromHex(String hex)
{
- return new BigInteger(1, Hex.decode(hex));
+ return new BigInteger(1, Hex.decodeStrict(hex));
}
/*
@@ -48,16 +56,14 @@ public class SECNamedCurves
BigInteger p = fromHex("DB7C2ABF62E35E668076BEAD208B");
BigInteger a = fromHex("DB7C2ABF62E35E668076BEAD2088");
BigInteger b = fromHex("659EF8BA043916EEDE8911702B22");
- byte[] S = Hex.decode("00F50B028E4D696E676875615175290472783FB1");
+ byte[] S = Hex.decodeStrict("00F50B028E4D696E676875615175290472783FB1");
BigInteger n = fromHex("DB7C2ABF62E35E7628DFAC6561C5");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "09487239995A5EE76B55F9C2F098"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "09487239995A5EE76B55F9C2F098"
- + "A89CE5AF8724C0A23E0E0FF77500"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0FF77500");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -74,16 +80,14 @@ public class SECNamedCurves
BigInteger p = fromHex("DB7C2ABF62E35E668076BEAD208B");
BigInteger a = fromHex("6127C24C05F38A0AAAF65C0EF02C");
BigInteger b = fromHex("51DEF1815DB5ED74FCC34C85D709");
- byte[] S = Hex.decode("002757A1114D696E6768756151755316C05E0BD4");
+ byte[] S = Hex.decodeStrict("002757A1114D696E6768756151755316C05E0BD4");
BigInteger n = fromHex("36DF0AAFD8B8D7597CA10520D04B");
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "4BA30AB5E892B4E1649DD0928643"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "4BA30AB5E892B4E1649DD0928643"
- + "ADCD46F5882E3747DEF36E956E97"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -100,16 +104,14 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("E87579C11079F43DD824993C2CEE5ED3");
- byte[] S = Hex.decode("000E0D4D696E6768756151750CC03A4473D03679");
+ byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
BigInteger n = fromHex("FFFFFFFE0000000075A30D1B9038A115");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "161FF7528B899B2D0C28607CA52C5B86"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "161FF7528B899B2D0C28607CA52C5B86"
- + "CF5AC8395BAFEB13C02DA292DDED7A83"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -126,16 +128,14 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("D6031998D1B3BBFEBF59CC9BBFF9AEE1");
BigInteger b = fromHex("5EEEFCA380D02919DC2C6558BB6D8A5D");
- byte[] S = Hex.decode("004D696E67687561517512D8F03431FCE63B88F4");
+ byte[] S = Hex.decodeStrict("004D696E67687561517512D8F03431FCE63B88F4");
BigInteger n = fromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3");
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "7B6AA5D85E572983E6FB32A7CDEBC140"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "7B6AA5D85E572983E6FB32A7CDEBC140"
- + "27B6916A894D3AEE7106FE805FC34B44"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "047B6AA5D85E572983E6FB32A7CDEBC14027B6916A894D3AEE7106FE805FC34B44");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -159,22 +159,21 @@ public class SECNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16),
new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16),
- new BigInteger[]{
- new BigInteger("9162fbe73984472a0a9e", 16),
- new BigInteger("-96341f1138933bc2f505", 16) },
- new BigInteger[]{
- new BigInteger("127971af8721782ecffa3", 16),
- new BigInteger("9162fbe73984472a0a9e", 16) },
- new BigInteger("9162fbe73984472a0a9d0590", 16),
- new BigInteger("96341f1138933bc2f503fd44", 16),
- 176);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("9162fbe73984472a0a9e", 16),
+ new BigInteger("-96341f1138933bc2f505", 16) },
+ new BigInteger[]{
+ new BigInteger("127971af8721782ecffa3", 16),
+ new BigInteger("9162fbe73984472a0a9e", 16) },
+ new BigInteger("9162fbe73984472a0a9d0590", 16),
+ new BigInteger("96341f1138933bc2f503fd44", 16),
+ 176));
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
-// ECPoint G = curve.decodePoint(Hex.decode("02"
-// + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"
- + "938CF935318FDCED6BC28286531733C3F03C4FEE"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -191,16 +190,14 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC");
BigInteger b = fromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45");
- byte[] S = Hex.decode("1053CDE42C14D696E67687561517533BF3F83345");
+ byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
BigInteger n = fromHex("0100000000000000000001F4C8F927AED3CA752257");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "4A96B5688EF573284664698968C38BB913CBFC82"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "4A96B5688EF573284664698968C38BB913CBFC82"
- + "23A628553168947D59DCC912042351377AC5FB32"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -217,16 +214,14 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70");
BigInteger b = fromHex("B4E134D3FB59EB8BAB57274904664D5AF50388BA");
- byte[] S = Hex.decode("B99B99B099B323E02709A4D696E6768756151751");
+ byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
BigInteger n = fromHex("0100000000000000000000351EE786A818F3A1A16B");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "52DCB034293A117E1F4FF11B30F7199D3144CE6D"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "52DCB034293A117E1F4FF11B30F7199D3144CE6D"
- + "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -250,22 +245,21 @@ public class SECNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16),
new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16),
- new BigInteger[]{
- new BigInteger("71169be7330b3038edb025f1", 16),
- new BigInteger("-b3fb3400dec5c4adceb8655c", 16) },
- new BigInteger[]{
- new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
- new BigInteger("71169be7330b3038edb025f1", 16) },
- new BigInteger("71169be7330b3038edb025f1d0f9", 16),
- new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
- 208);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("71169be7330b3038edb025f1", 16),
+ new BigInteger("-b3fb3400dec5c4adceb8655c", 16) },
+ new BigInteger[]{
+ new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
+ new BigInteger("71169be7330b3038edb025f1", 16) },
+ new BigInteger("71169be7330b3038edb025f1d0f9", 16),
+ new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
+ 208));
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"
- + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -282,16 +276,14 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1");
- byte[] S = Hex.decode("3045AE6FC8422F64ED579528D38120EAE12196D5");
+ byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"
- + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -315,22 +307,21 @@ public class SECNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16),
new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16),
- new BigInteger[]{
- new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
- new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) },
- new BigInteger[]{
- new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
- new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) },
- new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
- new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
- 240);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
+ new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) },
+ new BigInteger[]{
+ new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) },
+ new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
+ new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
+ 240));
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"
- + "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -347,16 +338,14 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE");
BigInteger b = fromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4");
- byte[] S = Hex.decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
+ byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"
- + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -380,22 +369,21 @@ public class SECNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16),
new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16),
- new BigInteger[]{
- new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
- new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) },
- new BigInteger[]{
- new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
- new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) },
- new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
- new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
- 272);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
+ new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) },
+ new BigInteger[]{
+ new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) },
+ new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
+ new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
+ 272));
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
- + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -412,16 +400,14 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B");
- byte[] S = Hex.decode("C49D360886E704936A6678E1139D26B7819F7E90");
+ byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
BigInteger n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
- + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -438,16 +424,15 @@ public class SECNamedCurves
BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF");
BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC");
BigInteger b = fromHex("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF");
- byte[] S = Hex.decode("A335926AA319A27A1D00896A6773A4827ACDAC73");
+ byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
- + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"));
+ + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -464,17 +449,15 @@ public class SECNamedCurves
BigInteger p = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
BigInteger a = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC");
BigInteger b = fromHex("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00");
- byte[] S = Hex.decode("D09E8800291CB85396CC6717393284AAA0DA64BA");
+ byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
- + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"));
+ + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -492,16 +475,14 @@ public class SECNamedCurves
BigInteger a = fromHex("003088250CA6E7C7FE649CE85820F7");
BigInteger b = fromHex("00E8BEE4D3E2260744188BE0E9C723");
- byte[] S = Hex.decode("10E723AB14D696E6768756151756FEBF8FCB49A9");
+ byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
BigInteger n = fromHex("0100000000000000D9CCEC8A39E56F");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "009D73616F35F4AB1407D73562C10F"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "009D73616F35F4AB1407D73562C10F"
- + "00A52830277958EE84D1315ED31886"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -519,16 +500,14 @@ public class SECNamedCurves
BigInteger a = fromHex("00689918DBEC7E5A0DD6DFC0AA55C7");
BigInteger b = fromHex("0095E9A9EC9B297BD4BF36E059184F");
- byte[] S = Hex.decode("10C0FB15760860DEF1EEF4D696E676875615175D");
+ byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
BigInteger n = fromHex("010000000000000108789B2496AF93");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "01A57A6A7B26CA5EF52FCDB8164797"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "01A57A6A7B26CA5EF52FCDB8164797"
- + "00B3ADC94ED1FE674C06E695BABA1D"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -548,16 +527,14 @@ public class SECNamedCurves
BigInteger a = fromHex("07A11B09A76B562144418FF3FF8C2570B8");
BigInteger b = fromHex("0217C05610884B63B9C6C7291678F9D341");
- byte[] S = Hex.decode("4D696E676875615175985BD3ADBADA21B43A97E2");
+ byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
BigInteger n = fromHex("0400000000000000023123953A9464B54D");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "0081BAF91FDF9833C40F9C181343638399"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "0081BAF91FDF9833C40F9C181343638399"
- + "078C6E7EA38C001F73C8134B1B4EF9E150"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -577,16 +554,14 @@ public class SECNamedCurves
BigInteger a = fromHex("03E5A88919D7CAFCBF415F07C2176573B2");
BigInteger b = fromHex("04B8266A46C55657AC734CE38F018F2192");
- byte[] S = Hex.decode("985BD3ADBAD4D696E676875615175A21B43A97E3");
+ byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
BigInteger n = fromHex("0400000000000000016954A233049BA98F");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "0356DCD8F2F95031AD652D23951BB366A8"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "0356DCD8F2F95031AD652D23951BB366A8"
- + "0648F06D867940A5366D9E265DE9EB240F"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -611,11 +586,9 @@ public class SECNamedCurves
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8"
- + "0289070FB05D38FF58321F2E800536D538CCDAA3D9"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -635,16 +608,14 @@ public class SECNamedCurves
BigInteger a = fromHex("07B6882CAAEFA84F9554FF8428BD88E246D2782AE2");
BigInteger b = fromHex("0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9");
- byte[] S = Hex.decode("24B7B137C8A14D696E6768756151756FD0DA2E5C");
+ byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "0369979697AB43897789566789567F787A7876A654"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "0369979697AB43897789566789567F787A7876A654"
- + "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -664,16 +635,14 @@ public class SECNamedCurves
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("020A601907B8C953CA1481EB10512F78744A3205FD");
- byte[] S = Hex.decode("85E25BFE5C86226CDB12016F7553F9D0E693A268");
+ byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
BigInteger n = fromHex("040000000000000000000292FE77E70C12A4234C33");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "03F0EBA16286A2D57EA0991168D4994637E8343E36"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "03F0EBA16286A2D57EA0991168D4994637E8343E36"
- + "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -691,16 +660,14 @@ public class SECNamedCurves
BigInteger a = fromHex("0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01");
BigInteger b = fromHex("00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814");
- byte[] S = Hex.decode("103FAEC74D696E676875615175777FC5B191EF30");
+ byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
BigInteger n = fromHex("01000000000000000000000000C7F34A778F443ACC920EBA49");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1"
- + "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -718,16 +685,14 @@ public class SECNamedCurves
BigInteger a = fromHex("0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B");
BigInteger b = fromHex("00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE");
- byte[] S = Hex.decode("10B7B4D696E676875615175137C8A16FD0DA2211");
+ byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
BigInteger n = fromHex("010000000000000000000000015AAB561B005413CCD4EE99D5");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F"
- + "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -750,11 +715,9 @@ public class SECNamedCurves
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126"
- + "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -772,16 +735,14 @@ public class SECNamedCurves
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD");
- byte[] S = Hex.decode("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
+ byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
BigInteger n = fromHex("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B"
- + "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -804,11 +765,9 @@ public class SECNamedCurves
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC"
- + "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA"));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -833,11 +792,10 @@ public class SECNamedCurves
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
- + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259"));
+ + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -857,16 +815,15 @@ public class SECNamedCurves
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5");
- byte[] S = Hex.decode("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
+ byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
- + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4"));
+ + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -889,11 +846,10 @@ public class SECNamedCurves
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
- + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B"));
+ + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -911,16 +867,15 @@ public class SECNamedCurves
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F");
- byte[] S = Hex.decode("4099B5A457F9D69F79213D094C4BCD4D4262210B");
+ byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
BigInteger n = fromHex("010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
- + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706"));
+ + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -945,11 +900,10 @@ public class SECNamedCurves
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("02"
- //+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
- + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3"));
+ + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3");
return new X9ECParameters(curve, G, n, h, S);
}
@@ -969,16 +923,15 @@ public class SECNamedCurves
BigInteger a = BigInteger.valueOf(1);
BigInteger b = fromHex("02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A");
- byte[] S = Hex.decode("2AA058F73A0E33AB486B0F610410C53A7F132310");
+ byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47");
BigInteger h = BigInteger.valueOf(2);
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
- //ECPoint G = curve.decodePoint(Hex.decode("03"
- //+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"));
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
- + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B"));
+ + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B");
return new X9ECParameters(curve, G, n, h, S);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/util/ASN1Dump.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/util/ASN1Dump.java
index a20b16d8..91fd01f3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/util/ASN1Dump.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/util/ASN1Dump.java
@@ -129,16 +129,7 @@ public class ASN1Dump
buf.append(nl);
- if (o.isEmpty())
- {
- buf.append(tab);
- buf.append("EMPTY");
- buf.append(nl);
- }
- else
- {
- _dumpAsString(tab, verbose, o.getObject(), buf);
- }
+ _dumpAsString(tab, verbose, o.getObject(), buf);
}
else if (obj instanceof ASN1Set)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java
index eedf1170..47f1716b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java
@@ -67,7 +67,7 @@ public class AttributeTypeAndValue
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(type);
v.add(value);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/RDN.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/RDN.java
index 8af82b15..853c9edc 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/RDN.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/RDN.java
@@ -46,7 +46,7 @@ public class RDN
*/
public RDN(ASN1ObjectIdentifier oid, ASN1Encodable value)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(oid);
v.add(value);
@@ -106,6 +106,31 @@ public class RDN
return tmp;
}
+ int collectAttributeTypes(ASN1ObjectIdentifier[] oids, int oidsOff)
+ {
+ int count = values.size();
+ for (int i = 0; i < count; ++i)
+ {
+ AttributeTypeAndValue attr = AttributeTypeAndValue.getInstance(values.getObjectAt(i));
+ oids[oidsOff + i] = attr.getType();
+ }
+ return count;
+ }
+
+ boolean containsAttributeType(ASN1ObjectIdentifier attributeType)
+ {
+ int count = values.size();
+ for (int i = 0; i < count; ++i)
+ {
+ AttributeTypeAndValue attr = AttributeTypeAndValue.getInstance(values.getObjectAt(i));
+ if (attr.getType().equals(attributeType))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* <pre>
* RelativeDistinguishedName ::=
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/X500Name.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/X500Name.java
index 773412b9..3f54005c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/X500Name.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/X500Name.java
@@ -40,14 +40,16 @@ public class X500Name
private X500NameStyle style;
private RDN[] rdns;
+ private DERSequence rdnSeq;
/**
* @deprecated use the getInstance() method that takes a style.
*/
public X500Name(X500NameStyle style, X500Name name)
{
- this.rdns = name.rdns;
this.style = style;
+ this.rdns = name.rdns;
+ this.rdnSeq = name.rdnSeq;
}
/**
@@ -114,11 +116,24 @@ public class X500Name
this.style = style;
this.rdns = new RDN[seq.size()];
- int index = 0;
+ boolean inPlace = true;
+ int index = 0;
for (Enumeration e = seq.getObjects(); e.hasMoreElements();)
{
- rdns[index++] = RDN.getInstance(e.nextElement());
+ Object element = e.nextElement();
+ RDN rdn = RDN.getInstance(element);
+ inPlace &= (rdn == element);
+ rdns[index++] = rdn;
+ }
+
+ if (inPlace)
+ {
+ this.rdnSeq = DERSequence.convert(seq);
+ }
+ else
+ {
+ this.rdnSeq = new DERSequence(this.rdns);
}
}
@@ -132,8 +147,9 @@ public class X500Name
X500NameStyle style,
RDN[] rDNs)
{
- this.rdns = copy(rDNs);
this.style = style;
+ this.rdns = (RDN[])rDNs.clone();
+ this.rdnSeq = new DERSequence(this.rdns);
}
public X500Name(
@@ -158,11 +174,7 @@ public class X500Name
*/
public RDN[] getRDNs()
{
- RDN[] tmp = new RDN[this.rdns.length];
-
- System.arraycopy(rdns, 0, tmp, 0, tmp.length);
-
- return tmp;
+ return (RDN[])rdns.clone();
}
/**
@@ -172,38 +184,21 @@ public class X500Name
*/
public ASN1ObjectIdentifier[] getAttributeTypes()
{
- int count = 0;
-
- for (int i = 0; i != rdns.length; i++)
+ int count = rdns.length, totalSize = 0;
+ for (int i = 0; i < count; ++i)
{
RDN rdn = rdns[i];
-
- count += rdn.size();
+ totalSize += rdn.size();
}
- ASN1ObjectIdentifier[] res = new ASN1ObjectIdentifier[count];
-
- count = 0;
-
- for (int i = 0; i != rdns.length; i++)
+ ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[totalSize];
+ int oidsOff = 0;
+ for (int i = 0; i < count; ++i)
{
RDN rdn = rdns[i];
-
- if (rdn.isMultiValued())
- {
- AttributeTypeAndValue[] attr = rdn.getTypesAndValues();
- for (int j = 0; j != attr.length; j++)
- {
- res[count++] = attr[j].getType();
- }
- }
- else if (rdn.size() != 0)
- {
- res[count++] = rdn.getFirst().getType();
- }
+ oidsOff += rdn.collectAttributeTypes(oids, oidsOff);
}
-
- return res;
+ return oids;
}
/**
@@ -215,52 +210,30 @@ public class X500Name
public RDN[] getRDNs(ASN1ObjectIdentifier attributeType)
{
RDN[] res = new RDN[rdns.length];
- int count = 0;
+ int count = 0;
for (int i = 0; i != rdns.length; i++)
{
RDN rdn = rdns[i];
-
- if (rdn.isMultiValued())
- {
- AttributeTypeAndValue[] attr = rdn.getTypesAndValues();
- for (int j = 0; j != attr.length; j++)
- {
- if (attr[j].getType().equals(attributeType))
- {
- res[count++] = rdn;
- break;
- }
- }
- }
- else
+ if (rdn.containsAttributeType(attributeType))
{
- if (rdn.getFirst().getType().equals(attributeType))
- {
- res[count++] = rdn;
- }
+ res[count++] = rdn;
}
}
- RDN[] tmp = new RDN[count];
-
- System.arraycopy(res, 0, tmp, 0, tmp.length);
-
- return tmp;
- }
-
- private RDN[] copy(RDN[] rdns)
- {
- RDN[] tmp = new RDN[rdns.length];
-
- System.arraycopy(rdns, 0, tmp, 0, tmp.length);
+ if (count < res.length)
+ {
+ RDN[] tmp = new RDN[count];
+ System.arraycopy(res, 0, tmp, 0, tmp.length);
+ res = tmp;
+ }
- return tmp;
+ return res;
}
public ASN1Primitive toASN1Primitive()
{
- return new DERSequence(rdns);
+ return rdnSeq;
}
public int hashCode()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
index ae582d17..083bff96 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
@@ -46,8 +46,7 @@ public abstract class AbstractX500NameStyle
private int calcHashCode(ASN1Encodable enc)
{
- String value = IETFUtils.valueToString(enc);
- value = IETFUtils.canonicalize(value);
+ String value = IETFUtils.canonicalString(enc);
return value.hashCode();
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/BCStyle.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/BCStyle.java
index 25aaa033..a55bc293 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/BCStyle.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/BCStyle.java
@@ -17,26 +17,22 @@ import com.android.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
/**
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class BCStyle
extends AbstractX500NameStyle
{
/**
* country code - StringType(SIZE(2))
*/
- @libcore.api.CorePlatformApi
public static final ASN1ObjectIdentifier C = new ASN1ObjectIdentifier("2.5.4.6").intern();
/**
* organization - StringType(SIZE(1..64))
*/
- @libcore.api.CorePlatformApi
public static final ASN1ObjectIdentifier O = new ASN1ObjectIdentifier("2.5.4.10").intern();
/**
* organizational unit name - StringType(SIZE(1..64))
*/
- @libcore.api.CorePlatformApi
public static final ASN1ObjectIdentifier OU = new ASN1ObjectIdentifier("2.5.4.11").intern();
/**
@@ -47,11 +43,11 @@ public class BCStyle
/**
* common name - StringType(SIZE(1..64))
*/
- @libcore.api.CorePlatformApi
public static final ASN1ObjectIdentifier CN = new ASN1ObjectIdentifier("2.5.4.3").intern();
/**
* device serial number name - StringType(SIZE(1..64))
+ * @deprecated use SERIALNUMBER or SURNAME
*/
public static final ASN1ObjectIdentifier SN = new ASN1ObjectIdentifier("2.5.4.5").intern();
@@ -63,18 +59,16 @@ public class BCStyle
/**
* device serial number name - StringType(SIZE(1..64))
*/
- public static final ASN1ObjectIdentifier SERIALNUMBER = SN;
+ public static final ASN1ObjectIdentifier SERIALNUMBER = new ASN1ObjectIdentifier("2.5.4.5").intern();
/**
* locality name - StringType(SIZE(1..64))
*/
- @libcore.api.CorePlatformApi
public static final ASN1ObjectIdentifier L = new ASN1ObjectIdentifier("2.5.4.7").intern();
/**
* state, or province name - StringType(SIZE(1..64))
*/
- @libcore.api.CorePlatformApi
public static final ASN1ObjectIdentifier ST = new ASN1ObjectIdentifier("2.5.4.8").intern();
/**
@@ -86,6 +80,8 @@ public class BCStyle
public static final ASN1ObjectIdentifier GENERATION = new ASN1ObjectIdentifier("2.5.4.44").intern();
public static final ASN1ObjectIdentifier UNIQUE_IDENTIFIER = new ASN1ObjectIdentifier("2.5.4.45").intern();
+ public static final ASN1ObjectIdentifier DESCRIPTION = new ASN1ObjectIdentifier("2.5.4.13").intern();
+
/**
* businessCategory - DirectoryString(SIZE(1..128)
*/
@@ -106,6 +102,7 @@ public class BCStyle
*/
public static final ASN1ObjectIdentifier PSEUDONYM = new ASN1ObjectIdentifier("2.5.4.65").intern();
+ public static final ASN1ObjectIdentifier ROLE = new ASN1ObjectIdentifier("2.5.4.72").intern();
/**
* RFC 3039 DateOfBirth - GeneralizedTime - YYYYMMDD000000Z
@@ -182,7 +179,6 @@ public class BCStyle
/**
* email address in Verisign certificates
*/
- @libcore.api.CorePlatformApi
public static final ASN1ObjectIdentifier E = EmailAddress;
/*
@@ -215,7 +211,7 @@ public class BCStyle
DefaultSymbols.put(CN, "CN");
DefaultSymbols.put(L, "L");
DefaultSymbols.put(ST, "ST");
- DefaultSymbols.put(SN, "SERIALNUMBER");
+ DefaultSymbols.put(SERIALNUMBER, "SERIALNUMBER");
DefaultSymbols.put(EmailAddress, "E");
DefaultSymbols.put(DC, "DC");
DefaultSymbols.put(UID, "UID");
@@ -224,6 +220,8 @@ public class BCStyle
DefaultSymbols.put(GIVENNAME, "GIVENNAME");
DefaultSymbols.put(INITIALS, "INITIALS");
DefaultSymbols.put(GENERATION, "GENERATION");
+ DefaultSymbols.put(DESCRIPTION, "DESCRIPTION");
+ DefaultSymbols.put(ROLE, "ROLE");
DefaultSymbols.put(UnstructuredAddress, "unstructuredAddress");
DefaultSymbols.put(UnstructuredName, "unstructuredName");
DefaultSymbols.put(UNIQUE_IDENTIFIER, "UniqueIdentifier");
@@ -249,8 +247,8 @@ public class BCStyle
DefaultLookUp.put("cn", CN);
DefaultLookUp.put("l", L);
DefaultLookUp.put("st", ST);
- DefaultLookUp.put("sn", SN);
- DefaultLookUp.put("serialnumber", SN);
+ DefaultLookUp.put("sn", SURNAME);
+ DefaultLookUp.put("serialnumber", SERIALNUMBER);
DefaultLookUp.put("street", STREET);
DefaultLookUp.put("emailaddress", E);
DefaultLookUp.put("dc", DC);
@@ -260,13 +258,15 @@ public class BCStyle
DefaultLookUp.put("givenname", GIVENNAME);
DefaultLookUp.put("initials", INITIALS);
DefaultLookUp.put("generation", GENERATION);
+ DefaultLookUp.put("description", DESCRIPTION);
+ DefaultLookUp.put("role", ROLE);
DefaultLookUp.put("unstructuredaddress", UnstructuredAddress);
DefaultLookUp.put("unstructuredname", UnstructuredName);
DefaultLookUp.put("uniqueidentifier", UNIQUE_IDENTIFIER);
DefaultLookUp.put("dn", DN_QUALIFIER);
DefaultLookUp.put("pseudonym", PSEUDONYM);
DefaultLookUp.put("postaladdress", POSTAL_ADDRESS);
- DefaultLookUp.put("nameofbirth", NAME_AT_BIRTH);
+ DefaultLookUp.put("nameatbirth", NAME_AT_BIRTH);
DefaultLookUp.put("countryofcitizenship", COUNTRY_OF_CITIZENSHIP);
DefaultLookUp.put("countryofresidence", COUNTRY_OF_RESIDENCE);
DefaultLookUp.put("gender", GENDER);
@@ -355,6 +355,4 @@ public class BCStyle
return buf.toString();
}
-
-
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/IETFUtils.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/IETFUtils.java
index c17e2707..38a82a83 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/IETFUtils.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x500/style/IETFUtils.java
@@ -363,18 +363,17 @@ public class IETFUtils
String v = ((ASN1String)value).getString();
if (v.length() > 0 && v.charAt(0) == '#')
{
- vBuf.append("\\" + v);
- }
- else
- {
- vBuf.append(v);
+ vBuf.append('\\');
}
+
+ vBuf.append(v);
}
else
{
try
{
- vBuf.append("#" + bytesToString(Hex.encode(value.toASN1Primitive().getEncoded(ASN1Encoding.DER))));
+ vBuf.append('#');
+ vBuf.append(Hex.toHexString(value.toASN1Primitive().getEncoded(ASN1Encoding.DER)));
}
catch (IOException e)
{
@@ -382,8 +381,8 @@ public class IETFUtils
}
}
- int end = vBuf.length();
- int index = 0;
+ int end = vBuf.length();
+ int index = 0;
if (vBuf.length() >= 2 && vBuf.charAt(0) == '\\' && vBuf.charAt(1) == '#')
{
@@ -392,21 +391,28 @@ public class IETFUtils
while (index != end)
{
- if ((vBuf.charAt(index) == ',')
- || (vBuf.charAt(index) == '"')
- || (vBuf.charAt(index) == '\\')
- || (vBuf.charAt(index) == '+')
- || (vBuf.charAt(index) == '=')
- || (vBuf.charAt(index) == '<')
- || (vBuf.charAt(index) == '>')
- || (vBuf.charAt(index) == ';'))
+ switch (vBuf.charAt(index))
{
- vBuf.insert(index, "\\");
- index++;
- end++;
+ case ',':
+ case '"':
+ case '\\':
+ case '+':
+ case '=':
+ case '<':
+ case '>':
+ case ';':
+ {
+ vBuf.insert(index, "\\");
+ index += 2;
+ ++end;
+ break;
+ }
+ default:
+ {
+ ++index;
+ break;
+ }
}
-
- index++;
}
int start = 0;
@@ -430,63 +436,55 @@ public class IETFUtils
return vBuf.toString();
}
- private static String bytesToString(
- byte[] data)
- {
- char[] cs = new char[data.length];
-
- for (int i = 0; i != cs.length; i++)
- {
- cs[i] = (char)(data[i] & 0xff);
- }
-
- return new String(cs);
- }
-
public static String canonicalize(String s)
{
- String value = Strings.toLowerCase(s);
-
- if (value.length() > 0 && value.charAt(0) == '#')
+ if (s.length() > 0 && s.charAt(0) == '#')
{
- ASN1Primitive obj = decodeObject(value);
-
+ ASN1Primitive obj = decodeObject(s);
if (obj instanceof ASN1String)
{
- value = Strings.toLowerCase(((ASN1String)obj).getString());
+ s = ((ASN1String)obj).getString();
}
}
- if (value.length() > 1)
+ s = Strings.toLowerCase(s);
+
+ int length = s.length();
+ if (length < 2)
{
- int start = 0;
- while (start + 1 < value.length() && value.charAt(start) == '\\' && value.charAt(start + 1) == ' ')
- {
- start += 2;
- }
+ return s;
+ }
- int end = value.length() - 1;
- while (end - 1 > 0 && value.charAt(end - 1) == '\\' && value.charAt(end) == ' ')
- {
- end -= 2;
- }
+ int start = 0, last = length - 1;
+ while (start < last && s.charAt(start) == '\\' && s.charAt(start + 1) == ' ')
+ {
+ start += 2;
+ }
- if (start > 0 || end < value.length() - 1)
- {
- value = value.substring(start, end + 1);
- }
+ int end = last, first = start + 1;
+ while (end > first && s.charAt(end - 1) == '\\' && s.charAt(end) == ' ')
+ {
+ end -= 2;
}
- value = stripInternalSpaces(value);
+ if (start > 0 || end < last)
+ {
+ s = s.substring(start, end + 1);
+ }
+
+ return stripInternalSpaces(s);
+ }
- return value;
+ public static String canonicalString(ASN1Encodable value)
+ {
+ return canonicalize(valueToString(value));
}
private static ASN1Primitive decodeObject(String oValue)
{
try
{
- return ASN1Primitive.fromByteArray(Hex.decode(oValue.substring(1)));
+ return ASN1Primitive.fromByteArray(Hex.decodeStrict(oValue, 1, oValue.length() - 1));
}
catch (IOException e)
{
@@ -497,21 +495,22 @@ public class IETFUtils
public static String stripInternalSpaces(
String str)
{
- StringBuffer res = new StringBuffer();
-
- if (str.length() != 0)
+ if (str.indexOf(" ") < 0)
{
- char c1 = str.charAt(0);
+ return str;
+ }
- res.append(c1);
+ StringBuffer res = new StringBuffer();
- for (int k = 1; k < str.length(); k++)
+ char c1 = str.charAt(0);
+ res.append(c1);
+
+ for (int k = 1; k < str.length(); k++)
+ {
+ char c2 = str.charAt(k);
+ if (!(c1 == ' ' && c2 == ' '))
{
- char c2 = str.charAt(k);
- if (!(c1 == ' ' && c2 == ' '))
- {
- res.append(c2);
- }
+ res.append(c2);
c1 = c2;
}
}
@@ -521,38 +520,22 @@ public class IETFUtils
public static boolean rDNAreEqual(RDN rdn1, RDN rdn2)
{
- if (rdn1.isMultiValued())
+ if (rdn1.size() != rdn2.size())
{
- if (rdn2.isMultiValued())
- {
- AttributeTypeAndValue[] atvs1 = rdn1.getTypesAndValues();
- AttributeTypeAndValue[] atvs2 = rdn2.getTypesAndValues();
+ return false;
+ }
- if (atvs1.length != atvs2.length)
- {
- return false;
- }
+ AttributeTypeAndValue[] atvs1 = rdn1.getTypesAndValues();
+ AttributeTypeAndValue[] atvs2 = rdn2.getTypesAndValues();
- for (int i = 0; i != atvs1.length; i++)
- {
- if (!atvAreEqual(atvs1[i], atvs2[i]))
- {
- return false;
- }
- }
- }
- else
- {
- return false;
- }
+ if (atvs1.length != atvs2.length)
+ {
+ return false;
}
- else
+
+ for (int i = 0; i != atvs1.length; i++)
{
- if (!rdn2.isMultiValued())
- {
- return atvAreEqual(rdn1.getFirst(), rdn2.getFirst());
- }
- else
+ if (!atvAreEqual(atvs1[i], atvs2[i]))
{
return false;
}
@@ -568,12 +551,7 @@ public class IETFUtils
return true;
}
- if (atv1 == null)
- {
- return false;
- }
-
- if (atv2 == null)
+ if (null == atv1 || null == atv2)
{
return false;
}
@@ -586,8 +564,8 @@ public class IETFUtils
return false;
}
- String v1 = IETFUtils.canonicalize(IETFUtils.valueToString(atv1.getValue()));
- String v2 = IETFUtils.canonicalize(IETFUtils.valueToString(atv2.getValue()));
+ String v1 = canonicalString(atv1.getValue());
+ String v2 = canonicalString(atv2.getValue());
if (!v1.equals(v2))
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java
index 311b71ce..cd372690 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java
@@ -13,7 +13,6 @@ import com.android.org.bouncycastle.asn1.DERSequence;
/**
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class AlgorithmIdentifier
extends ASN1Object
{
@@ -43,7 +42,6 @@ public class AlgorithmIdentifier
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public AlgorithmIdentifier(
ASN1ObjectIdentifier algorithm)
{
@@ -51,7 +49,6 @@ public class AlgorithmIdentifier
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public AlgorithmIdentifier(
ASN1ObjectIdentifier algorithm,
ASN1Encodable parameters)
@@ -81,7 +78,6 @@ public class AlgorithmIdentifier
}
}
- @libcore.api.CorePlatformApi
public ASN1ObjectIdentifier getAlgorithm()
{
return algorithm;
@@ -102,7 +98,7 @@ public class AlgorithmIdentifier
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(algorithm);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java
index 1e7b5fa6..c2915ff8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java
@@ -78,7 +78,7 @@ public class AttCertValidityPeriod
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(notBeforeTime);
v.add(notAfterTime);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Attribute.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Attribute.java
index 43281738..dd47b188 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Attribute.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Attribute.java
@@ -87,7 +87,7 @@ public class Attribute
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(attrType);
v.add(attrValues);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificate.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificate.java
index af82c676..b5658e66 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificate.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificate.java
@@ -90,7 +90,7 @@ public class AttributeCertificate
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(acinfo);
v.add(signatureAlgorithm);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
index bc9e751c..f8ee2602 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
@@ -156,9 +156,9 @@ public class AttributeCertificateInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(9);
- if (version.getValue().intValue() != 0)
+ if (version.intValueExact() != 0)
{
v.add(version);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
index 5c10ce47..c4e2cf30 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
@@ -38,9 +38,9 @@ import com.android.org.bouncycastle.util.encoders.Hex;
public class AuthorityKeyIdentifier
extends ASN1Object
{
- ASN1OctetString keyidentifier=null;
- GeneralNames certissuer=null;
- ASN1Integer certserno=null;
+ ASN1OctetString keyidentifier = null;
+ GeneralNames certissuer = null;
+ ASN1Integer certserno = null;
public static AuthorityKeyIdentifier getInstance(
ASN1TaggedObject obj,
@@ -66,7 +66,7 @@ public class AuthorityKeyIdentifier
public static AuthorityKeyIdentifier fromExtensions(Extensions extensions)
{
- return AuthorityKeyIdentifier.getInstance(extensions.getExtensionParsedValue(Extension.authorityKeyIdentifier));
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.authorityKeyIdentifier));
}
protected AuthorityKeyIdentifier(
@@ -76,7 +76,7 @@ public class AuthorityKeyIdentifier
while (e.hasMoreElements())
{
- ASN1TaggedObject o = DERTaggedObject.getInstance(e.nextElement());
+ ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement());
switch (o.getTagNo())
{
@@ -142,8 +142,8 @@ public class AuthorityKeyIdentifier
digest.doFinal(resBuf, 0);
this.keyidentifier = new DEROctetString(resBuf);
- this.certissuer = GeneralNames.getInstance(name.toASN1Primitive());
- this.certserno = new ASN1Integer(serialNumber);
+ this.certissuer = name;
+ this.certserno = (serialNumber != null) ? new ASN1Integer(serialNumber) : null;
}
/**
@@ -210,7 +210,7 @@ public class AuthorityKeyIdentifier
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
if (keyidentifier != null)
{
@@ -227,12 +227,13 @@ public class AuthorityKeyIdentifier
v.add(new DERTaggedObject(false, 2, certserno));
}
-
return new DERSequence(v);
}
public String toString()
{
- return ("AuthorityKeyIdentifier: KeyID(" + ((keyidentifier != null) ? Hex.toHexString(this.keyidentifier.getOctets()) : "null") + ")");
+ String keyID = (keyidentifier != null) ? Hex.toHexString(keyidentifier.getOctets()) : "null";
+
+ return "AuthorityKeyIdentifier: KeyID(" + keyID + ")";
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/BasicConstraints.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/BasicConstraints.java
index e61cf0fd..c0b8ef81 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/BasicConstraints.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/BasicConstraints.java
@@ -15,7 +15,6 @@ import com.android.org.bouncycastle.asn1.DERSequence;
/**
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class BasicConstraints
extends ASN1Object
{
@@ -29,7 +28,6 @@ public class BasicConstraints
return getInstance(ASN1Sequence.getInstance(obj, explicit));
}
- @libcore.api.CorePlatformApi
public static BasicConstraints getInstance(
Object obj)
{
@@ -51,7 +49,7 @@ public class BasicConstraints
public static BasicConstraints fromExtensions(Extensions extensions)
{
- return BasicConstraints.getInstance(extensions.getExtensionParsedValue(Extension.basicConstraints));
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.basicConstraints));
}
private BasicConstraints(
@@ -113,7 +111,6 @@ public class BasicConstraints
this.pathLenConstraint = new ASN1Integer(pathLenConstraint);
}
- @libcore.api.CorePlatformApi
public boolean isCA()
{
return (cA != null) && cA.isTrue();
@@ -140,7 +137,7 @@ public class BasicConstraints
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
if (cA != null)
{
@@ -159,10 +156,6 @@ public class BasicConstraints
{
if (pathLenConstraint == null)
{
- if (cA == null)
- {
- return "BasicConstraints: isCa(false)";
- }
return "BasicConstraints: isCa(" + this.isCA() + ")";
}
return "BasicConstraints: isCa(" + this.isCA() + "), pathLenConstraint = " + pathLenConstraint.getValue();
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLDistPoint.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLDistPoint.java
index ded7d30f..13f95c1d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLDistPoint.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLDistPoint.java
@@ -1,7 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x509;
-import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
@@ -24,11 +23,6 @@ public class CRLDistPoint
return getInstance(ASN1Sequence.getInstance(obj, explicit));
}
- public static CRLDistPoint fromExtensions(Extensions extensions)
- {
- return CRLDistPoint.getInstance(extensions.getExtensionParsedValue(Extension.cRLDistributionPoints));
- }
-
public static CRLDistPoint getInstance(
Object obj)
{
@@ -44,6 +38,11 @@ public class CRLDistPoint
return null;
}
+ public static CRLDistPoint fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.cRLDistributionPoints));
+ }
+
private CRLDistPoint(
ASN1Sequence seq)
{
@@ -53,14 +52,7 @@ public class CRLDistPoint
public CRLDistPoint(
DistributionPoint[] points)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
-
- for (int i = 0; i != points.length; i++)
- {
- v.add(points[i]);
- }
-
- seq = new DERSequence(v);
+ seq = new DERSequence(points);
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLReason.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLReason.java
index ddd01dc9..545c5351 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLReason.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CRLReason.java
@@ -102,7 +102,7 @@ public class CRLReason
}
else if (o != null)
{
- return lookup(ASN1Enumerated.getInstance(o).getValue().intValue());
+ return lookup(ASN1Enumerated.getInstance(o).intValueExact());
}
return null;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Certificate.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Certificate.java
index 0f4e761c..c5ce691d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Certificate.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Certificate.java
@@ -20,7 +20,6 @@ import com.android.org.bouncycastle.asn1.x500.X500Name;
* </pre>
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class Certificate
extends ASN1Object
{
@@ -37,7 +36,6 @@ public class Certificate
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public static Certificate getInstance(
Object obj)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CertificateList.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CertificateList.java
index 749e2682..cc8a9db0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CertificateList.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/CertificateList.java
@@ -124,7 +124,7 @@ public class CertificateList
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(tbsCertList);
v.add(sigAlgId);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DSAParameter.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DSAParameter.java
index f8ba60b4..f10c1091 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DSAParameter.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DSAParameter.java
@@ -85,7 +85,7 @@ public class DSAParameter
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(p);
v.add(q);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DigestInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DigestInfo.java
index 01a51156..b194d3e8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DigestInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DigestInfo.java
@@ -50,7 +50,7 @@ public class DigestInfo
return null;
}
- @android.compat.annotation.UnsupportedAppUsage
+ @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
public DigestInfo(
AlgorithmIdentifier algId,
byte[] digest)
@@ -80,7 +80,7 @@ public class DigestInfo
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(algId);
v.add(new DEROctetString(digest));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DistributionPoint.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DistributionPoint.java
index c6becea5..f37199e8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DistributionPoint.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/DistributionPoint.java
@@ -102,7 +102,7 @@ public class DistributionPoint
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
if (distributionPoint != null)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java
index 2916fe5f..e44d8127 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java
@@ -70,7 +70,7 @@ public class ExtendedKeyUsage
*/
public static ExtendedKeyUsage fromExtensions(Extensions extensions)
{
- return ExtendedKeyUsage.getInstance(extensions.getExtensionParsedValue(Extension.extendedKeyUsage));
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.extendedKeyUsage));
}
/**
@@ -112,7 +112,7 @@ public class ExtendedKeyUsage
public ExtendedKeyUsage(
KeyPurposeId[] usages)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(usages.length);
for (int i = 0; i != usages.length; i++)
{
@@ -129,12 +129,12 @@ public class ExtendedKeyUsage
public ExtendedKeyUsage(
Vector usages)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
- Enumeration e = usages.elements();
+ ASN1EncodableVector v = new ASN1EncodableVector(usages.size());
+ Enumeration e = usages.elements();
while (e.hasMoreElements())
{
- KeyPurposeId o = KeyPurposeId.getInstance(e.nextElement());
+ KeyPurposeId o = KeyPurposeId.getInstance(e.nextElement());
v.add(o);
this.usageTable.put(o, o);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extension.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extension.java
index 027a96b5..3ae3404e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extension.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extension.java
@@ -185,6 +185,13 @@ public class Extension
private boolean critical;
private ASN1OctetString value;
+ /**
+ * Constructor using an ASN1Boolean and an OCTET STRING for the value.
+ *
+ * @param extnId the OID associated with this extension.
+ * @param critical will evaluate to true if the extension is critical, false otherwise.
+ * @param value the extension's value wrapped in an OCTET STRING.
+ */
public Extension(
ASN1ObjectIdentifier extnId,
ASN1Boolean critical,
@@ -193,6 +200,13 @@ public class Extension
this(extnId, critical.isTrue(), value);
}
+ /**
+ * Constructor using a byte[] for the value.
+ *
+ * @param extnId the OID associated with this extension.
+ * @param critical true if the extension is critical, false otherwise.
+ * @param value the extension's value as a byte[] to be wrapped in an OCTET STRING.
+ */
public Extension(
ASN1ObjectIdentifier extnId,
boolean critical,
@@ -201,6 +215,13 @@ public class Extension
this(extnId, critical, new DEROctetString(value));
}
+ /**
+ * Constructor using an OCTET STRING for the value.
+ *
+ * @param extnId the OID associated with this extension.
+ * @param critical true if the extension is critical, false otherwise.
+ * @param value the extension's value wrapped in an OCTET STRING.
+ */
public Extension(
ASN1ObjectIdentifier extnId,
boolean critical,
@@ -211,6 +232,24 @@ public class Extension
this.value = value;
}
+ /**
+ * Helper method to create an extension from any ASN.1 encodable object.
+ *
+ * @param extnId the OID associated with this extension.
+ * @param critical true if the extension is critical, false otherwise.
+ * @param value the value to be encoded into the extension's OCTET STRING.
+ * @return a new Extension with the encoding of value in the bytes of the extension's OCTET STRING.
+ * @throws IOException if the value cannot be encoded into bytes.
+ */
+ public static Extension create(
+ ASN1ObjectIdentifier extnId,
+ boolean critical,
+ ASN1Encodable value)
+ throws IOException
+ {
+ return new Extension(extnId, critical, value.toASN1Primitive().getEncoded());
+ }
+
private Extension(ASN1Sequence seq)
{
if (seq.size() == 2)
@@ -292,7 +331,7 @@ public class Extension
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(extnId);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extensions.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extensions.java
index 54dbcb22..c721c9c5 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extensions.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Extensions.java
@@ -15,6 +15,14 @@ import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.org.bouncycastle.asn1.DERSequence;
/**
+ * <pre>
+ * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ *
+ * Extension ::= SEQUENCE {
+ * extnId EXTENSION.&amp;id ({ExtensionSet}),
+ * critical BOOLEAN DEFAULT FALSE,
+ * extnValue OCTET STRING }
+ * </pre>
* @hide This class is not part of the Android public SDK API
*/
public class Extensions
@@ -23,6 +31,16 @@ public class Extensions
private Hashtable extensions = new Hashtable();
private Vector ordering = new Vector();
+ public static Extension getExtension(Extensions extensions, ASN1ObjectIdentifier oid)
+ {
+ return null == extensions ? null : extensions.getExtension(oid);
+ }
+
+ public static ASN1Encodable getExtensionParsedValue(Extensions extensions, ASN1ObjectIdentifier oid)
+ {
+ return null == extensions ? null : extensions.getExtensionParsedValue(oid);
+ }
+
public static Extensions getInstance(
ASN1TaggedObject obj,
boolean explicit)
@@ -149,9 +167,9 @@ public class Extensions
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector vec = new ASN1EncodableVector();
- Enumeration e = ordering.elements();
+ ASN1EncodableVector vec = new ASN1EncodableVector(ordering.size());
+ Enumeration e = ordering.elements();
while (e.hasMoreElements())
{
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ExtensionsGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
index 2aaba540..2720ba22 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
@@ -85,6 +85,94 @@ public class ExtensionsGenerator
}
/**
+ * Replace an extension with the given oid and the passed in value to be included
+ * in the OCTET STRING associated with the extension.
+ *
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the ASN.1 object to be included in the extension.
+ */
+ public void replaceExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ ASN1Encodable value)
+ throws IOException
+ {
+ this.replaceExtension(oid, critical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER));
+ }
+
+ /**
+ * Replace an extension with the given oid and the passed in byte array to be wrapped in the
+ * OCTET STRING associated with the extension.
+ *
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the byte array to be wrapped.
+ */
+ public void replaceExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ byte[] value)
+ {
+ this.replaceExtension(new Extension(oid, critical, value));
+ }
+
+ /**
+ * Replace a given extension.
+ *
+ * @param extension the full extension value.
+ */
+ public void replaceExtension(
+ Extension extension)
+ {
+ if (!extensions.containsKey(extension.getExtnId()))
+ {
+ throw new IllegalArgumentException("extension " + extension.getExtnId() + " not present");
+ }
+
+ extensions.put(extension.getExtnId(), extension);
+ }
+
+ /**
+ * Remove a given extension.
+ *
+ * @param oid OID for the extension to remove.
+ */
+ public void removeExtension(
+ ASN1ObjectIdentifier oid)
+ {
+ if (!extensions.containsKey(oid))
+ {
+ throw new IllegalArgumentException("extension " + oid + " not present");
+ }
+
+ extOrdering.removeElement(oid);
+ extensions.remove(oid);
+ }
+
+ /**
+ * 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 extensions.containsKey(oid);
+ }
+
+ /**
+ * 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 (Extension)extensions.get(oid);
+ }
+
+ /**
* Return true if there are no extension present in this generator.
*
* @return true if empty, false otherwise
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralName.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralName.java
index 0d344d98..982782b9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralName.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralName.java
@@ -44,21 +44,17 @@ import com.android.org.bouncycastle.util.IPAddress;
* </pre>
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class GeneralName
extends ASN1Object
implements ASN1Choice
{
- @libcore.api.CorePlatformApi
public static final int otherName = 0;
public static final int rfc822Name = 1;
- @libcore.api.CorePlatformApi
public static final int dNSName = 2;
public static final int x400Address = 3;
public static final int directoryName = 4;
public static final int ediPartyName = 5;
public static final int uniformResourceIdentifier = 6;
- @libcore.api.CorePlatformApi
public static final int iPAddress = 7;
public static final int registeredID = 8;
@@ -110,7 +106,6 @@ public class GeneralName
* RFC 1883, the octet string MUST contain exactly sixteen octets [RFC
* 1883].
*/
- @libcore.api.CorePlatformApi
public GeneralName(
int tag,
ASN1Encodable name)
@@ -142,7 +137,6 @@ public class GeneralName
* @param name string representation of name
* @throws IllegalArgumentException if the string encoding is not correct or * not supported.
*/
- @libcore.api.CorePlatformApi
public GeneralName(
int tag,
String name)
@@ -194,24 +188,25 @@ public class GeneralName
switch (tag)
{
+ case ediPartyName:
case otherName:
+ case x400Address:
return new GeneralName(tag, ASN1Sequence.getInstance(tagObj, false));
- case rfc822Name:
- return new GeneralName(tag, DERIA5String.getInstance(tagObj, false));
+
case dNSName:
+ case rfc822Name:
+ case uniformResourceIdentifier:
return new GeneralName(tag, DERIA5String.getInstance(tagObj, false));
- case x400Address:
- throw new IllegalArgumentException("unknown tag: " + tag);
+
case directoryName:
return new GeneralName(tag, X500Name.getInstance(tagObj, true));
- case ediPartyName:
- return new GeneralName(tag, ASN1Sequence.getInstance(tagObj, false));
- case uniformResourceIdentifier:
- return new GeneralName(tag, DERIA5String.getInstance(tagObj, false));
case iPAddress:
return new GeneralName(tag, ASN1OctetString.getInstance(tagObj, false));
case registeredID:
return new GeneralName(tag, ASN1ObjectIdentifier.getInstance(tagObj, false));
+
+ default:
+ throw new IllegalArgumentException("unknown tag: " + tag);
}
}
@@ -237,7 +232,6 @@ public class GeneralName
return GeneralName.getInstance(ASN1TaggedObject.getInstance(tagObj, true));
}
- @libcore.api.CorePlatformApi
public int getTagNo()
{
return tag;
@@ -436,13 +430,9 @@ public class GeneralName
public ASN1Primitive toASN1Primitive()
{
- if (tag == directoryName) // directoryName is explicitly tagged as it is a CHOICE
- {
- return new DERTaggedObject(true, tag, obj);
- }
- else
- {
- return new DERTaggedObject(false, tag, obj);
- }
+ // directoryName is explicitly tagged as it is a CHOICE
+ boolean explicit = (tag == directoryName);
+
+ return new DERTaggedObject(explicit, tag, obj);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralNames.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralNames.java
index 5d4ae50e..7c9df0d2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralNames.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralNames.java
@@ -17,6 +17,13 @@ public class GeneralNames
{
private final GeneralName[] names;
+ private static GeneralName[] copy(GeneralName[] names)
+ {
+ GeneralName[] result = new GeneralName[names.length];
+ System.arraycopy(names, 0, result, 0, names.length);
+ return result;
+ }
+
public static GeneralNames getInstance(
Object obj)
{
@@ -37,12 +44,12 @@ public class GeneralNames
ASN1TaggedObject obj,
boolean explicit)
{
- return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ return new GeneralNames(ASN1Sequence.getInstance(obj, explicit));
}
public static GeneralNames fromExtensions(Extensions extensions, ASN1ObjectIdentifier extOID)
{
- return GeneralNames.getInstance(extensions.getExtensionParsedValue(extOID));
+ return getInstance(Extensions.getExtensionParsedValue(extensions, extOID));
}
/**
@@ -79,15 +86,6 @@ public class GeneralNames
return copy(names);
}
- private GeneralName[] copy(GeneralName[] nms)
- {
- GeneralName[] tmp = new GeneralName[nms.length];
-
- System.arraycopy(nms, 0, tmp, 0, tmp.length);
-
- return tmp;
- }
-
/**
* Produce an object suitable for an ASN1OutputStream.
* <pre>
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralSubtree.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralSubtree.java
index 4e24d59e..6830ad50 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralSubtree.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/GeneralSubtree.java
@@ -201,11 +201,11 @@ public class GeneralSubtree
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(base);
- if (minimum != null && !minimum.getValue().equals(ZERO))
+ if (minimum != null && !minimum.hasValue(ZERO))
{
v.add(new DERTaggedObject(false, 0, minimum));
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Holder.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Holder.java
index c22b33f7..16b280ac 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Holder.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Holder.java
@@ -213,7 +213,7 @@ public class Holder
{
if (version == 1)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
if (baseCertificateID != null)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuerSerial.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuerSerial.java
index 9990388b..b92639db 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuerSerial.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuerSerial.java
@@ -112,7 +112,7 @@ public class IssuerSerial
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(issuer);
v.add(serial);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
index 95d7a29f..62fafaf8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
@@ -92,7 +92,7 @@ public class IssuingDistributionPoint
this.onlyContainsUserCerts = onlyContainsUserCerts;
this.onlySomeReasons = onlySomeReasons;
- ASN1EncodableVector vec = new ASN1EncodableVector();
+ ASN1EncodableVector vec = new ASN1EncodableVector(6);
if (distributionPoint != null)
{ // CHOICE item so explicitly tagged
vec.add(new DERTaggedObject(true, 0, distributionPoint));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyPurposeId.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyPurposeId.java
index fbc588af..8f464a15 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyPurposeId.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyPurposeId.java
@@ -125,12 +125,12 @@ public class KeyPurposeId
/**
- * Microsoft Server Gated Crypto (msSGC) see http://www.alvestrand.no/objectid/1.3.6.1.4.1.311.10.3.3.html
+ * Microsoft Server Gated Crypto (msSGC) see https://www.alvestrand.no/objectid/1.3.6.1.4.1.311.10.3.3.html
*/
public static final KeyPurposeId id_kp_msSGC = new KeyPurposeId(new ASN1ObjectIdentifier("1.3.6.1.4.1.311.10.3.3"));
/**
- * Netscape Server Gated Crypto (nsSGC) see http://www.alvestrand.no/objectid/2.16.840.1.113730.4.1.html
+ * Netscape Server Gated Crypto (nsSGC) see https://www.alvestrand.no/objectid/2.16.840.1.113730.4.1.html
*/
public static final KeyPurposeId id_kp_nsSGC = new KeyPurposeId(new ASN1ObjectIdentifier("2.16.840.1.113730.4.1"));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyUsage.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyUsage.java
index b14334bf..12d2d079 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyUsage.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/KeyUsage.java
@@ -54,7 +54,7 @@ public class KeyUsage
public static KeyUsage fromExtensions(Extensions extensions)
{
- return KeyUsage.getInstance(extensions.getExtensionParsedValue(Extension.keyUsage));
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.keyUsage));
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/NameConstraints.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/NameConstraints.java
index 94e34011..7f884981 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/NameConstraints.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/NameConstraints.java
@@ -100,7 +100,7 @@ public class NameConstraints
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
if (permitted != null)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ObjectDigestInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
index ced50f47..a5478ca8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
@@ -175,7 +175,7 @@ public class ObjectDigestInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(digestedObjectType);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/OtherName.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/OtherName.java
index cd48c0d6..0a91d493 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/OtherName.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/OtherName.java
@@ -84,7 +84,7 @@ public class OtherName
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(typeID);
v.add(new DERTaggedObject(true, 0, value));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
index b434d600..ed2ded2f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
@@ -13,7 +13,10 @@ import java.util.Set;
import com.android.org.bouncycastle.asn1.ASN1OctetString;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.DERIA5String;
+import com.android.org.bouncycastle.asn1.x500.RDN;
import com.android.org.bouncycastle.asn1.x500.X500Name;
+import com.android.org.bouncycastle.asn1.x500.style.IETFUtils;
+import com.android.org.bouncycastle.asn1.x500.style.RFC4519Style;
import com.android.org.bouncycastle.util.Arrays;
import com.android.org.bouncycastle.util.Integers;
import com.android.org.bouncycastle.util.Strings;
@@ -68,27 +71,22 @@ public class PKIXNameConstraintValidator
checkPermittedOtherName(permittedSubtreesOtherName, OtherName.getInstance(name.getName()));
break;
case GeneralName.rfc822Name:
- checkPermittedEmail(permittedSubtreesEmail,
- extractNameAsString(name));
+ checkPermittedEmail(permittedSubtreesEmail, extractNameAsString(name));
break;
case GeneralName.dNSName:
- checkPermittedDNS(permittedSubtreesDNS, DERIA5String.getInstance(
- name.getName()).getString());
+ checkPermittedDNS(permittedSubtreesDNS, extractNameAsString(name));
break;
case GeneralName.directoryName:
checkPermittedDN(X500Name.getInstance(name.getName()));
break;
case GeneralName.uniformResourceIdentifier:
- checkPermittedURI(permittedSubtreesURI, DERIA5String.getInstance(
- name.getName()).getString());
+ checkPermittedURI(permittedSubtreesURI, extractNameAsString(name));
break;
case GeneralName.iPAddress:
- byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets();
-
- checkPermittedIP(permittedSubtreesIP, ip);
+ checkPermittedIP(permittedSubtreesIP, ASN1OctetString.getInstance(name.getName()).getOctets());
break;
default:
- throw new IllegalStateException("Unknown tag encountered: " + name.getTagNo());
+ // other tags to be ignored.
}
}
@@ -111,23 +109,19 @@ public class PKIXNameConstraintValidator
checkExcludedEmail(excludedSubtreesEmail, extractNameAsString(name));
break;
case GeneralName.dNSName:
- checkExcludedDNS(excludedSubtreesDNS, DERIA5String.getInstance(
- name.getName()).getString());
+ checkExcludedDNS(excludedSubtreesDNS, extractNameAsString(name));
break;
case GeneralName.directoryName:
checkExcludedDN(X500Name.getInstance(name.getName()));
break;
case GeneralName.uniformResourceIdentifier:
- checkExcludedURI(excludedSubtreesURI, DERIA5String.getInstance(
- name.getName()).getString());
+ checkExcludedURI(excludedSubtreesURI, extractNameAsString(name));
break;
case GeneralName.iPAddress:
- byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets();
-
- checkExcludedIP(excludedSubtreesIP, ip);
+ checkExcludedIP(excludedSubtreesIP, ASN1OctetString.getInstance(name.getName()).getOctets());
break;
default:
- throw new IllegalStateException("Unknown tag encountered: " + name.getTagNo());
+ // other tags to be ignored.
}
}
@@ -158,7 +152,7 @@ public class PKIXNameConstraintValidator
((Set)subtreesMap.get(tagNo)).add(subtree);
}
- for (Iterator it = subtreesMap.entrySet().iterator(); it.hasNext(); )
+ for (Iterator it = subtreesMap.entrySet().iterator(); it.hasNext();)
{
Map.Entry entry = (Map.Entry)it.next();
@@ -255,8 +249,8 @@ public class PKIXNameConstraintValidator
extractNameAsString(base));
break;
case GeneralName.iPAddress:
- excludedSubtreesIP = unionIP(excludedSubtreesIP, ASN1OctetString
- .getInstance(base.getName()).getOctets());
+ excludedSubtreesIP = unionIP(excludedSubtreesIP,
+ ASN1OctetString.getInstance(base.getName()).getOctets());
break;
default:
throw new IllegalStateException("Unknown tag encountered: " + base.getTagNo());
@@ -300,81 +294,13 @@ public class PKIXNameConstraintValidator
&& collectionsAreEqual(constraintValidator.permittedSubtreesOtherName, permittedSubtreesOtherName);
}
- public String toString()
- {
- String temp = "";
- temp += "permitted:\n";
- if (permittedSubtreesDN != null)
- {
- temp += "DN:\n";
- temp += permittedSubtreesDN.toString() + "\n";
- }
- if (permittedSubtreesDNS != null)
- {
- temp += "DNS:\n";
- temp += permittedSubtreesDNS.toString() + "\n";
- }
- if (permittedSubtreesEmail != null)
- {
- temp += "Email:\n";
- temp += permittedSubtreesEmail.toString() + "\n";
- }
- if (permittedSubtreesURI != null)
- {
- temp += "URI:\n";
- temp += permittedSubtreesURI.toString() + "\n";
- }
- if (permittedSubtreesIP != null)
- {
- temp += "IP:\n";
- temp += stringifyIPCollection(permittedSubtreesIP) + "\n";
- }
- if (permittedSubtreesOtherName != null)
- {
- temp += "OtherName:\n";
- temp += stringifyOtherNameCollection(permittedSubtreesOtherName) + "\n";
- }
- temp += "excluded:\n";
- if (!excludedSubtreesDN.isEmpty())
- {
- temp += "DN:\n";
- temp += excludedSubtreesDN.toString() + "\n";
- }
- if (!excludedSubtreesDNS.isEmpty())
- {
- temp += "DNS:\n";
- temp += excludedSubtreesDNS.toString() + "\n";
- }
- if (!excludedSubtreesEmail.isEmpty())
- {
- temp += "Email:\n";
- temp += excludedSubtreesEmail.toString() + "\n";
- }
- if (!excludedSubtreesURI.isEmpty())
- {
- temp += "URI:\n";
- temp += excludedSubtreesURI.toString() + "\n";
- }
- if (!excludedSubtreesIP.isEmpty())
- {
- temp += "IP:\n";
- temp += stringifyIPCollection(excludedSubtreesIP) + "\n";
- }
- if (!excludedSubtreesOtherName.isEmpty())
- {
- temp += "OtherName:\n";
- temp += stringifyOtherNameCollection(excludedSubtreesOtherName) + "\n";
- }
- return temp;
- }
-
- private void checkPermittedDN(X500Name dns)
+ public void checkPermittedDN(X500Name dns)
throws NameConstraintValidatorException
{
checkPermittedDN(permittedSubtreesDN, ASN1Sequence.getInstance(dns.toASN1Primitive()));
}
- private void checkExcludedDN(X500Name dns)
+ public void checkExcludedDN(X500Name dns)
throws NameConstraintValidatorException
{
checkExcludedDN(excludedSubtreesDN, ASN1Sequence.getInstance(dns));
@@ -394,9 +320,56 @@ public class PKIXNameConstraintValidator
return false;
}
- for (int j = subtree.size() - 1; j >= 0; j--)
+ int start = 0;
+ RDN subtreeRdnStart = RDN.getInstance(subtree.getObjectAt(0));
+ for (int j = 0; j < dns.size(); j++)
+ {
+ start = j;
+ RDN dnsRdn = RDN.getInstance(dns.getObjectAt(j));
+ if (IETFUtils.rDNAreEqual(subtreeRdnStart, dnsRdn))
+ {
+ break;
+ }
+ }
+
+ if (subtree.size() > dns.size() - start)
+ {
+ return false;
+ }
+
+ for (int j = 0; j < subtree.size(); j++)
{
- if (!subtree.getObjectAt(j).equals(dns.getObjectAt(j)))
+ // both subtree and dns are a ASN.1 Name and the elements are a RDN
+ RDN subtreeRdn = RDN.getInstance(subtree.getObjectAt(j));
+ RDN dnsRdn = RDN.getInstance(dns.getObjectAt(start + j));
+
+ // check if types and values of all naming attributes are matching, other types which are not restricted are allowed, see https://tools.ietf.org/html/rfc5280#section-7.1
+ if (subtreeRdn.size() == dnsRdn.size())
+ {
+ // Two relative distinguished names
+ // RDN1 and RDN2 match if they have the same number of naming attributes
+ // and for each naming attribute in RDN1 there is a matching naming attribute in RDN2.
+ // NOTE: this is checking the attributes in the same order, which might be not necessary, if this is a problem also IETFUtils.rDNAreEqual mus tbe changed.
+ // use new RFC 5280 comparison, NOTE: this is now different from with RFC 3280, where only binary comparison is used
+ // obey RFC 5280 7.1
+ // special treatment of serialNumber for GSMA SGP.22 RSP specification
+ if (!subtreeRdn.getFirst().getType().equals(dnsRdn.getFirst().getType()))
+ {
+ return false;
+ }
+ if (subtreeRdn.size() == 1 && subtreeRdn.getFirst().getType().equals(RFC4519Style.serialNumber))
+ {
+ if (!dnsRdn.getFirst().getValue().toString().startsWith(subtreeRdn.getFirst().getValue().toString()))
+ {
+ return false;
+ }
+ }
+ else if (!IETFUtils.rDNAreEqual(subtreeRdn, dnsRdn))
+ {
+ return false;
+ }
+ }
+ else
{
return false;
}
@@ -458,7 +431,7 @@ public class PKIXNameConstraintValidator
private Set intersectDN(Set permitted, Set dns)
{
Set intersect = new HashSet();
- for (Iterator it = dns.iterator(); it.hasNext(); )
+ for (Iterator it = dns.iterator(); it.hasNext();)
{
ASN1Sequence dn = ASN1Sequence.getInstance(((GeneralSubtree)it
.next()).getBase().getName().toASN1Primitive());
@@ -509,7 +482,7 @@ public class PKIXNameConstraintValidator
Iterator it = excluded.iterator();
while (it.hasNext())
{
- ASN1Sequence subtree = (ASN1Sequence)it.next();
+ ASN1Sequence subtree = ASN1Sequence.getInstance(it.next());
if (withinDNSubtree(dn, subtree))
{
@@ -532,17 +505,43 @@ public class PKIXNameConstraintValidator
private Set intersectOtherName(Set permitted, Set otherNames)
{
- Set intersect = new HashSet(permitted);
+ Set intersect = new HashSet();
+ for (Iterator it = otherNames.iterator(); it.hasNext();)
+ {
+ OtherName otName1 = OtherName.getInstance(((GeneralSubtree)it.next()).getBase().getName());
- intersect.retainAll(otherNames);
+ if (permitted == null)
+ {
+ if (otName1 != null)
+ {
+ intersect.add(otName1);
+ }
+ }
+ else
+ {
+ Iterator it2 = permitted.iterator();
+ while (it2.hasNext())
+ {
+ OtherName otName2 = OtherName.getInstance(it2.next());
+ intersectOtherName(otName1, otName2, intersect);
+ }
+ }
+ }
return intersect;
}
+ private void intersectOtherName(OtherName otName1, OtherName otName2, Set intersect)
+ {
+ if (otName1.equals(otName2))
+ {
+ intersect.add(otName1);
+ }
+ }
private Set unionOtherName(Set permitted, OtherName otherName)
{
- Set union = new HashSet(permitted);
+ Set union = permitted != null ? new HashSet(permitted) : new HashSet();
union.add(otherName);
@@ -552,7 +551,7 @@ public class PKIXNameConstraintValidator
private Set intersectEmail(Set permitted, Set emails)
{
Set intersect = new HashSet();
- for (Iterator it = emails.iterator(); it.hasNext(); )
+ for (Iterator it = emails.iterator(); it.hasNext();)
{
String email = extractNameAsString(((GeneralSubtree)it.next())
.getBase());
@@ -618,7 +617,7 @@ public class PKIXNameConstraintValidator
private Set intersectIP(Set permitted, Set ips)
{
Set intersect = new HashSet();
- for (Iterator it = ips.iterator(); it.hasNext(); )
+ for (Iterator it = ips.iterator(); it.hasNext();)
{
byte[] ip = ASN1OctetString.getInstance(
((GeneralSubtree)it.next()).getBase().getName()).getOctets();
@@ -704,7 +703,7 @@ public class PKIXNameConstraintValidator
}
/**
- * Calculates the interesction if two IP ranges.
+ * Calculates the intersection if two IP ranges.
*
* @param ipWithSubmask1 The first IP address with its subnet mask.
* @param ipWithSubmask2 The second IP address with its subnet mask.
@@ -861,7 +860,7 @@ public class PKIXNameConstraintValidator
while (it.hasNext())
{
- OtherName str = ((OtherName)it.next());
+ OtherName str = OtherName.getInstance(it.next());
if (otherNameIsConstrained(name, str))
{
@@ -1040,6 +1039,10 @@ public class PKIXNameConstraintValidator
{
return true;
}
+ if (sub.equalsIgnoreCase(constraint.substring(1)))
+ {
+ return true;
+ }
}
// on particular host
else if (!(constraint.charAt(0) == '.'))
@@ -1428,7 +1431,7 @@ public class PKIXNameConstraintValidator
private Set intersectDNS(Set permitted, Set dnss)
{
Set intersect = new HashSet();
- for (Iterator it = dnss.iterator(); it.hasNext(); )
+ for (Iterator it = dnss.iterator(); it.hasNext();)
{
String dns = extractNameAsString(((GeneralSubtree)it.next())
.getBase());
@@ -1627,7 +1630,7 @@ public class PKIXNameConstraintValidator
private Set intersectURI(Set permitted, Set uris)
{
Set intersect = new HashSet();
- for (Iterator it = uris.iterator(); it.hasNext(); )
+ for (Iterator it = uris.iterator(); it.hasNext();)
{
String uri = extractNameAsString(((GeneralSubtree)it.next())
.getBase());
@@ -2050,7 +2053,7 @@ public class PKIXNameConstraintValidator
{
StringBuilder temp = new StringBuilder();
temp.append("[");
- for (Iterator it = ips.iterator(); it.hasNext(); )
+ for (Iterator it = ips.iterator(); it.hasNext();)
{
if (temp.length() > 1)
{
@@ -2066,7 +2069,7 @@ public class PKIXNameConstraintValidator
{
StringBuilder temp = new StringBuilder();
temp.append("[");
- for (Iterator it = otherNames.iterator(); it.hasNext(); )
+ for (Iterator it = otherNames.iterator(); it.hasNext();)
{
if (temp.length() > 1)
{
@@ -2087,4 +2090,78 @@ public class PKIXNameConstraintValidator
temp.append("]");
return temp.toString();
}
+
+ private final void addLine(StringBuilder sb, String str)
+ {
+ sb.append(str).append(Strings.lineSeparator());
+ }
+
+ public String toString()
+ {
+ StringBuilder temp = new StringBuilder();
+
+ addLine(temp, "permitted:");
+ if (permittedSubtreesDN != null)
+ {
+ addLine(temp, "DN:");
+ addLine(temp, permittedSubtreesDN.toString());
+ }
+ if (permittedSubtreesDNS != null)
+ {
+ addLine(temp, "DNS:");
+ addLine(temp, permittedSubtreesDNS.toString());
+ }
+ if (permittedSubtreesEmail != null)
+ {
+ addLine(temp, "Email:");
+ addLine(temp, permittedSubtreesEmail.toString());
+ }
+ if (permittedSubtreesURI != null)
+ {
+ addLine(temp, "URI:");
+ addLine(temp, permittedSubtreesURI.toString());
+ }
+ if (permittedSubtreesIP != null)
+ {
+ addLine(temp, "IP:");
+ addLine(temp, stringifyIPCollection(permittedSubtreesIP));
+ }
+ if (permittedSubtreesOtherName != null)
+ {
+ addLine(temp, "OtherName:");
+ addLine(temp, stringifyOtherNameCollection(permittedSubtreesOtherName));
+ }
+ addLine(temp, "excluded:");
+ if (!excludedSubtreesDN.isEmpty())
+ {
+ addLine(temp, "DN:");
+ addLine(temp, excludedSubtreesDN.toString());
+ }
+ if (!excludedSubtreesDNS.isEmpty())
+ {
+ addLine(temp, "DNS:");
+ addLine(temp, excludedSubtreesDNS.toString());
+ }
+ if (!excludedSubtreesEmail.isEmpty())
+ {
+ addLine(temp, "Email:");
+ addLine(temp, excludedSubtreesEmail.toString());
+ }
+ if (!excludedSubtreesURI.isEmpty())
+ {
+ addLine(temp, "URI:");
+ addLine(temp, excludedSubtreesURI.toString());
+ }
+ if (!excludedSubtreesIP.isEmpty())
+ {
+ addLine(temp, "IP:");
+ addLine(temp, stringifyIPCollection(excludedSubtreesIP));
+ }
+ if (!excludedSubtreesOtherName.isEmpty())
+ {
+ addLine(temp, "OtherName:");
+ addLine(temp, stringifyOtherNameCollection(excludedSubtreesOtherName));
+ }
+ return temp.toString();
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyConstraints.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyConstraints.java
index 7c4518b2..072ed34a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyConstraints.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyConstraints.java
@@ -76,7 +76,7 @@ public class PolicyConstraints
public static PolicyConstraints fromExtensions(Extensions extensions)
{
- return PolicyConstraints.getInstance(extensions.getExtensionParsedValue(Extension.policyConstraints));
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.policyConstraints));
}
public BigInteger getRequireExplicitPolicyMapping()
@@ -91,7 +91,7 @@ public class PolicyConstraints
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
if (requireExplicitPolicyMapping != null)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyInformation.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyInformation.java
index 55f02bbd..532957e0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyInformation.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyInformation.java
@@ -79,7 +79,7 @@ public class PolicyInformation
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(policyIdentifier);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
index fefa880c..933cc5f7 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
@@ -110,7 +110,7 @@ public class PolicyQualifierInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector dev = new ASN1EncodableVector();
+ ASN1EncodableVector dev = new ASN1EncodableVector(2);
dev.add(policyQualifierId);
dev.add(qualifier);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java
index 13ebc349..e4eb7c00 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java
@@ -90,7 +90,7 @@ public class RSAPublicKeyStructure
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(new ASN1Integer(getModulus()));
v.add(new ASN1Integer(getPublicExponent()));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java
index 4a7dbcb9..1d0a6563 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java
@@ -44,7 +44,7 @@ public class SubjectKeyIdentifier
public static SubjectKeyIdentifier fromExtensions(Extensions extensions)
{
- return SubjectKeyIdentifier.getInstance(extensions.getExtensionParsedValue(Extension.subjectKeyIdentifier));
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.subjectKeyIdentifier));
}
public SubjectKeyIdentifier(
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
index d1a67093..66f03690 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
@@ -20,7 +20,6 @@ import com.android.org.bouncycastle.asn1.DERSequence;
* encoded one of these.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class SubjectPublicKeyInfo
extends ASN1Object
{
@@ -35,7 +34,6 @@ public class SubjectPublicKeyInfo
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public static SubjectPublicKeyInfo getInstance(
Object obj)
{
@@ -149,7 +147,7 @@ public class SubjectPublicKeyInfo
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(algId);
v.add(keyData);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertList.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertList.java
index 616bc1c5..c25f87a3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertList.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertList.java
@@ -222,7 +222,7 @@ public class TBSCertList
{
return 1;
}
- return version.getValue().intValue() + 1;
+ return version.intValueExact() + 1;
}
public ASN1Integer getVersion()
@@ -284,7 +284,7 @@ public class TBSCertList
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(7);
if (version != null)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificate.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificate.java
index 74ae7f06..efce6aab 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificate.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificate.java
@@ -3,13 +3,18 @@ package com.android.org.bouncycastle.asn1.x509;
import java.math.BigInteger;
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1Object;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.org.bouncycastle.asn1.DERBitString;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.DERTaggedObject;
import com.android.org.bouncycastle.asn1.x500.X500Name;
+import com.android.org.bouncycastle.util.BigIntegers;
+import com.android.org.bouncycastle.util.Properties;
/**
* The TBSCertificate object.
@@ -32,7 +37,6 @@ import com.android.org.bouncycastle.asn1.x500.X500Name;
* will parse them, but you really shouldn't be creating new ones.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class TBSCertificate
extends ASN1Object
{
@@ -94,15 +98,15 @@ public class TBSCertificate
boolean isV1 = false;
boolean isV2 = false;
- if (version.getValue().equals(BigInteger.valueOf(0)))
+ if (version.hasValue(BigInteger.valueOf(0)))
{
isV1 = true;
}
- else if (version.getValue().equals(BigInteger.valueOf(1)))
+ else if (version.hasValue(BigInteger.valueOf(1)))
{
isV2 = true;
}
- else if (!version.getValue().equals(BigInteger.valueOf(2)))
+ else if (!version.hasValue(BigInteger.valueOf(2)))
{
throw new IllegalArgumentException("version number not recognised");
}
@@ -161,7 +165,7 @@ public class TBSCertificate
public int getVersionNumber()
{
- return version.getValue().intValue() + 1;
+ return version.intValueExact() + 1;
}
public ASN1Integer getVersion()
@@ -221,6 +225,69 @@ public class TBSCertificate
public ASN1Primitive toASN1Primitive()
{
- return seq;
+ if (Properties.getPropertyValue("com.android.org.bouncycastle.x509.allow_non-der_tbscert") != null)
+ {
+ if (Properties.isOverrideSet("com.android.org.bouncycastle.x509.allow_non-der_tbscert"))
+ {
+ return seq;
+ }
+ }
+ else
+ {
+ return seq;
+ }
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ // DEFAULT Zero
+ if (!version.hasValue(BigIntegers.ZERO))
+ {
+ v.add(new DERTaggedObject(true, 0, version));
+ }
+
+ v.add(serialNumber);
+ v.add(signature);
+ v.add(issuer);
+
+ //
+ // before and after dates
+ //
+ {
+ ASN1EncodableVector validity = new ASN1EncodableVector(2);
+ validity.add(startDate);
+ validity.add(endDate);
+
+ v.add(new DERSequence(validity));
+ }
+
+ if (subject != null)
+ {
+ v.add(subject);
+ }
+ else
+ {
+ v.add(new DERSequence());
+ }
+
+ v.add(subjectPublicKeyInfo);
+
+ // Note: implicit tag
+ if (issuerUniqueId != null)
+ {
+ v.add(new DERTaggedObject(false, 1, issuerUniqueId));
+ }
+
+ // Note: implicit tag
+ if (subjectUniqueId != null)
+ {
+ v.add(new DERTaggedObject(false, 2, subjectUniqueId));
+ }
+
+ if (extensions != null)
+ {
+ v.add(new DERTaggedObject(true, 3, extensions));
+ }
+
+ return new DERSequence(v);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificateStructure.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
index 107cd1c1..fc5aa921 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
@@ -7,7 +7,6 @@ import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.org.bouncycastle.asn1.DERBitString;
-import com.android.org.bouncycastle.asn1.DERTaggedObject;
import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.asn1.x500.X500Name;
@@ -82,7 +81,7 @@ public class TBSCertificateStructure
//
// some certficates don't include a version number - we assume v1
//
- if (seq.getObjectAt(0) instanceof DERTaggedObject)
+ if (seq.getObjectAt(0) instanceof ASN1TaggedObject)
{
version = ASN1Integer.getInstance((ASN1TaggedObject)seq.getObjectAt(0), true);
}
@@ -114,7 +113,7 @@ public class TBSCertificateStructure
for (int extras = seq.size() - (seqStart + 6) - 1; extras > 0; extras--)
{
- DERTaggedObject extra = (DERTaggedObject)seq.getObjectAt(seqStart + 6 + extras);
+ ASN1TaggedObject extra = ASN1TaggedObject.getInstance(seq.getObjectAt(seqStart + 6 + extras));
switch (extra.getTagNo())
{
@@ -132,7 +131,7 @@ public class TBSCertificateStructure
public int getVersion()
{
- return version.getValue().intValue() + 1;
+ return version.intValueExact() + 1;
}
public ASN1Integer getVersionNumber()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Time.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Time.java
index 21eb04a5..2b3a1228 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Time.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/Time.java
@@ -21,7 +21,6 @@ import com.android.org.bouncycastle.asn1.DERUTCTime;
/**
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class Time
extends ASN1Object
implements ASN1Choice
@@ -55,7 +54,6 @@ public class Time
* @param time a date object representing the time of interest.
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public Time(
Date time)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java
index fa780e15..4ded90a0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java
@@ -120,7 +120,7 @@ public class V1TBSCertificateGenerator
throw new IllegalStateException("not all mandatory fields set in V1 TBScertificate generator");
}
- ASN1EncodableVector seq = new ASN1EncodableVector();
+ ASN1EncodableVector seq = new ASN1EncodableVector(6);
// seq.add(version); - not required as default value.
seq.add(serialNumber);
@@ -130,12 +130,13 @@ public class V1TBSCertificateGenerator
//
// before and after dates
//
- ASN1EncodableVector validity = new ASN1EncodableVector();
-
- validity.add(startDate);
- validity.add(endDate);
+ {
+ ASN1EncodableVector validity = new ASN1EncodableVector(2);
+ validity.add(startDate);
+ validity.add(endDate);
- seq.add(new DERSequence(validity));
+ seq.add(new DERSequence(validity));
+ }
seq.add(subject);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V2Form.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V2Form.java
index a526395e..cab4fb47 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V2Form.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V2Form.java
@@ -139,7 +139,7 @@ public class V2Form
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
if (issuerName != null)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
index a48763b3..1c7d69a1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
@@ -28,7 +28,6 @@ import com.android.org.bouncycastle.asn1.x500.X500Name;
* @hide This class is not part of the Android public SDK API
*
*/
-@libcore.api.CorePlatformApi
public class V3TBSCertificateGenerator
{
DERTaggedObject version = new DERTaggedObject(true, 0, new ASN1Integer(2));
@@ -46,13 +45,11 @@ public class V3TBSCertificateGenerator
private DERBitString subjectUniqueID;
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public V3TBSCertificateGenerator()
{
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public void setSerialNumber(
ASN1Integer serialNumber)
{
@@ -60,7 +57,6 @@ public class V3TBSCertificateGenerator
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public void setSignature(
AlgorithmIdentifier signature)
{
@@ -71,7 +67,6 @@ public class V3TBSCertificateGenerator
* @deprecated use X500Name method
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public void setIssuer(
X509Name issuer)
{
@@ -91,7 +86,6 @@ public class V3TBSCertificateGenerator
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public void setStartDate(
Time startDate)
{
@@ -105,7 +99,6 @@ public class V3TBSCertificateGenerator
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public void setEndDate(
Time endDate)
{
@@ -116,7 +109,6 @@ public class V3TBSCertificateGenerator
* @deprecated use X500Name method
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public void setSubject(
X509Name subject)
{
@@ -142,7 +134,6 @@ public class V3TBSCertificateGenerator
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public void setSubjectPublicKeyInfo(
SubjectPublicKeyInfo pubKeyInfo)
{
@@ -175,7 +166,6 @@ public class V3TBSCertificateGenerator
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public TBSCertificate generateTBSCertificate()
{
if ((serialNumber == null) || (signature == null)
@@ -185,7 +175,7 @@ public class V3TBSCertificateGenerator
throw new IllegalStateException("not all mandatory fields set in V3 TBScertificate generator");
}
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(10);
v.add(version);
v.add(serialNumber);
@@ -195,12 +185,13 @@ public class V3TBSCertificateGenerator
//
// before and after dates
//
- ASN1EncodableVector validity = new ASN1EncodableVector();
-
- validity.add(startDate);
- validity.add(endDate);
+ {
+ ASN1EncodableVector validity = new ASN1EncodableVector(2);
+ validity.add(startDate);
+ validity.add(endDate);
- v.add(new DERSequence(validity));
+ v.add(new DERSequence(validity));
+ }
if (subject != null)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Extensions.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Extensions.java
index 4051b374..f93dc335 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Extensions.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Extensions.java
@@ -16,7 +16,7 @@ import com.android.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.org.bouncycastle.asn1.DERSequence;
/**
- * @deprecated use Extensions
+ * @deprecated use {@link Extensions}
* @hide This class is not part of the Android public SDK API
*/
public class X509Extensions
@@ -387,14 +387,15 @@ public class X509Extensions
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector vec = new ASN1EncodableVector();
- Enumeration e = ordering.elements();
+ ASN1EncodableVector vec = new ASN1EncodableVector(ordering.size());
+ Enumeration e = ordering.elements();
while (e.hasMoreElements())
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
- X509Extension ext = (X509Extension)extensions.get(oid);
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ X509Extension ext = (X509Extension)extensions.get(oid);
v.add(oid);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Name.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Name.java
index 1ba4481c..58fd9b7c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Name.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509Name.java
@@ -37,7 +37,6 @@ import com.android.org.bouncycastle.util.encoders.Hex;
* @deprecated use org.bouncycastle.asn1.x500.X500Name.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class X509Name
extends ASN1Object
{
@@ -51,14 +50,12 @@ public class X509Name
* organization - StringType(SIZE(1..64))
* @deprecated use a X500NameStyle
*/
- @libcore.api.CorePlatformApi
public static final ASN1ObjectIdentifier O = new ASN1ObjectIdentifier("2.5.4.10");
/**
* organizational unit name - StringType(SIZE(1..64))
* @deprecated use a X500NameStyle
*/
- @libcore.api.CorePlatformApi
public static final ASN1ObjectIdentifier OU = new ASN1ObjectIdentifier("2.5.4.11");
/**
@@ -71,8 +68,7 @@ public class X509Name
* common name - StringType(SIZE(1..64))
* @deprecated use a X500NameStyle
*/
- @android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
+ @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
public static final ASN1ObjectIdentifier CN = new ASN1ObjectIdentifier("2.5.4.3");
/**
@@ -231,7 +227,6 @@ public class X509Name
* default look up table translating OID values into their common symbols following
* the convention in RFC 2253 with a few extras
*/
- @libcore.api.CorePlatformApi
public static final Hashtable DefaultSymbols = new Hashtable();
/**
@@ -381,11 +376,10 @@ public class X509Name
return getInstance(ASN1Sequence.getInstance(obj, explicit));
}
- @libcore.api.CorePlatformApi
public static X509Name getInstance(
Object obj)
{
- if (obj == null || obj instanceof X509Name)
+ if (obj instanceof X509Name)
{
return (X509Name)obj;
}
@@ -411,7 +405,7 @@ public class X509Name
* the principal will be a list of constructed sets, each containing an (OID, String) pair.
* @deprecated use X500Name.getInstance()
*/
- @android.compat.annotation.UnsupportedAppUsage
+ @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
public X509Name(
ASN1Sequence seq)
{
@@ -601,7 +595,6 @@ public class X509Name
* @deprecated use X500Name, X500NameBuilder
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public X509Name(
String dirName)
{
@@ -873,8 +866,7 @@ public class X509Name
/**
* return a vector of the oids in the name, in the order they were found.
*/
- @android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
+ @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
public Vector getOIDs()
{
Vector v = new Vector();
@@ -891,8 +883,7 @@ public class X509Name
* return a vector of the values found in the name, in the order they
* were found.
*/
- @android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
+ @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
public Vector getValues()
{
Vector v = new Vector();
@@ -944,7 +935,7 @@ public class X509Name
for (int i = 0; i != ordering.size(); i++)
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)ordering.elementAt(i);
v.add(oid);
@@ -961,8 +952,8 @@ public class X509Name
else
{
vec.add(new DERSet(sVec));
+
sVec = new ASN1EncodableVector();
-
sVec.add(new DERSequence(v));
}
@@ -1204,7 +1195,7 @@ public class X509Name
{
try
{
- return ASN1Primitive.fromByteArray(Hex.decode(oValue.substring(1)));
+ return ASN1Primitive.fromByteArray(Hex.decodeStrict(oValue, 1, oValue.length() - 1));
}
catch (IOException e)
{
@@ -1312,7 +1303,6 @@ public class X509Name
* @param reverse if true start at the end of the sequence and work back.
* @param oidSymbols look up table strings for oids.
*/
- @libcore.api.CorePlatformApi
public String toString(
boolean reverse,
Hashtable oidSymbols)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509NameEntryConverter.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
index 913f49fb..2d48ac0a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
@@ -3,11 +3,10 @@ package com.android.org.bouncycastle.asn1.x509;
import java.io.IOException;
-import com.android.org.bouncycastle.asn1.ASN1InputStream;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.DERPrintableString;
-import com.android.org.bouncycastle.util.Strings;
+import com.android.org.bouncycastle.util.encoders.Hex;
/**
* It turns out that the number of standard ways the fields in a DN should be
@@ -64,36 +63,9 @@ public abstract class X509NameEntryConverter
int off)
throws IOException
{
- str = Strings.toLowerCase(str);
- byte[] data = new byte[(str.length() - off) / 2];
- for (int index = 0; index != data.length; index++)
- {
- char left = str.charAt((index * 2) + off);
- char right = str.charAt((index * 2) + off + 1);
-
- if (left < 'a')
- {
- data[index] = (byte)((left - '0') << 4);
- }
- else
- {
- data[index] = (byte)((left - 'a' + 10) << 4);
- }
- if (right < 'a')
- {
- data[index] |= (byte)(right - '0');
- }
- else
- {
- data[index] |= (byte)(right - 'a' + 10);
- }
- }
-
- ASN1InputStream aIn = new ASN1InputStream(data);
-
- return aIn.readObject();
+ return ASN1Primitive.fromByteArray(Hex.decodeStrict(str, off, str.length() - off));
}
-
+
/**
* return true if the passed in String can be represented without
* loss as a PrintableString, false otherwise.
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
index 1054acef..45c4582d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
@@ -8,7 +8,6 @@ import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
*/
public interface X509ObjectIdentifiers
{
-
/** Subject RDN components: commonName = 2.5.4.3 */
static final ASN1ObjectIdentifier commonName = new ASN1ObjectIdentifier("2.5.4.3").intern();
/** Subject RDN components: countryName = 2.5.4.6 */
@@ -62,6 +61,34 @@ public interface X509ObjectIdentifiers
static final ASN1ObjectIdentifier id_pkix = new ASN1ObjectIdentifier("1.3.6.1.5.5.7");
/**
+ * id-RSASSA-PSS-SHAKE128 OBJECT IDENTIFIER ::= { iso(1)
+ * identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) algorithms(6) 30 }
+ */
+ static final ASN1ObjectIdentifier id_rsassa_pss_shake128 = id_pkix.branch("6.30");
+
+ /**
+ * id-RSASSA-PSS-SHAKE256 OBJECT IDENTIFIER ::= { iso(1)
+ * identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) algorithms(6) 31 }
+ */
+ static final ASN1ObjectIdentifier id_rsassa_pss_shake256 = id_pkix.branch("6.31");
+
+ /**
+ * id-ecdsa-with-shake128 OBJECT IDENTIFIER ::= { iso(1)
+ * identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) algorithms(6) 32 }
+ */
+ static final ASN1ObjectIdentifier id_ecdsa_with_shake128 = id_pkix.branch("6.32");
+
+ /**
+ * id-ecdsa-with-shake256 OBJECT IDENTIFIER ::= { iso(1)
+ * identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) algorithms(6) 33 }
+ */
+ static final ASN1ObjectIdentifier id_ecdsa_with_shake256 = id_pkix.branch("6.33");
+
+ /**
* private internet extensions; OID = 1.3.6.1.5.5.7.1
*/
static final ASN1ObjectIdentifier id_pe = id_pkix.branch("1");
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DHDomainParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DHDomainParameters.java
index df7689a8..e05ab4d6 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DHDomainParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DHDomainParameters.java
@@ -148,7 +148,7 @@ public class DHDomainParameters
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
v.add(this.p);
v.add(this.g);
v.add(this.q);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DHValidationParms.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DHValidationParms.java
index 6ee0aaa6..01bdf6e7 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DHValidationParms.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DHValidationParms.java
@@ -76,7 +76,7 @@ public class DHValidationParms extends ASN1Object
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(this.seed);
v.add(this.pgenCounter);
return new DERSequence(v);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DomainParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DomainParameters.java
index 9fcc1932..f84dc5cc 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DomainParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/DomainParameters.java
@@ -205,7 +205,7 @@ public class DomainParameters
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
v.add(this.p);
v.add(this.g);
v.add(this.q);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ECNamedCurveTable.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
index 6e394d6b..19018b1c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
@@ -9,12 +9,12 @@ import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
// import org.bouncycastle.asn1.anssi.ANSSINamedCurves;
// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
// import org.bouncycastle.asn1.gm.GMNamedCurves;
+// import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers;
import com.android.org.bouncycastle.asn1.nist.NISTNamedCurves;
import com.android.org.bouncycastle.asn1.sec.SECNamedCurves;
// Android-removed: Unsupported curves
// import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
import com.android.org.bouncycastle.crypto.ec.CustomNamedCurves;
-import com.android.org.bouncycastle.crypto.params.ECDomainParameters;
/**
* A general class that reads all X9.62 style EC curve tables.
@@ -58,7 +58,7 @@ public class ECNamedCurveTable
if (ecP == null)
{
- ecP = fromDomainParameters(ECGOST3410NamedCurves.getByName(name));
+ ecP = ECGOST3410NamedCurves.getByNameX9(name);
}
if (ecP == null)
@@ -113,6 +113,11 @@ public class ECNamedCurveTable
{
oid = GMNamedCurves.getOID(name);
}
+
+ if (oid == null && name.equals("curve25519"))
+ {
+ oid = CryptlibObjectIdentifiers.curvey25519;
+ }
*/
// END Android-removed: Unsupported curves
@@ -206,7 +211,7 @@ public class ECNamedCurveTable
if (ecP == null)
{
- ecP = fromDomainParameters(ECGOST3410NamedCurves.getByOID(oid));
+ ecP = ECGOST3410NamedCurves.getByOIDX9(oid);
}
if (ecP == null)
@@ -250,9 +255,4 @@ public class ECNamedCurveTable
v.addElement(e.nextElement());
}
}
-
- private static X9ECParameters fromDomainParameters(ECDomainParameters dp)
- {
- return dp == null ? null : new X9ECParameters(dp.getCurve(), dp.getG(), dp.getN(), dp.getH(), dp.getSeed());
- }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ValidationParams.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ValidationParams.java
index 5f47e5a9..deac4bc5 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ValidationParams.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/ValidationParams.java
@@ -96,7 +96,7 @@ public class ValidationParams
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(this.seed);
v.add(this.pgenCounter);
return new DERSequence(v);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962NamedCurves.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962NamedCurves.java
index d7669ccf..70e96e2d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962NamedCurves.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962NamedCurves.java
@@ -7,6 +7,7 @@ import java.util.Hashtable;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.math.ec.ECCurve;
+import com.android.org.bouncycastle.math.ec.WNafUtil;
import com.android.org.bouncycastle.util.Strings;
import com.android.org.bouncycastle.util.encoders.Hex;
@@ -17,25 +18,40 @@ import com.android.org.bouncycastle.util.encoders.Hex;
*/
public class X962NamedCurves
{
+ private static X9ECPoint configureBasepoint(ECCurve curve, String encoding)
+ {
+ X9ECPoint G = new X9ECPoint(curve, Hex.decodeStrict(encoding));
+ WNafUtil.configureBasepoint(G.getPoint());
+ return G;
+ }
+
+ private static ECCurve configureCurve(ECCurve curve)
+ {
+ return curve;
+ }
+
+ private static BigInteger fromHex(String hex)
+ {
+ return new BigInteger(1, Hex.decodeStrict(hex));
+ }
+
static X9ECParametersHolder prime192v1 = new X9ECParametersHolder()
{
protected X9ECParameters createParameters()
{
- BigInteger n = new BigInteger("ffffffffffffffffffffffff99def836146bc9b1b4d22831", 16);
+ BigInteger n = fromHex("ffffffffffffffffffffffff99def836146bc9b1b4d22831");
BigInteger h = BigInteger.valueOf(1);
- ECCurve cFp192v1 = new ECCurve.Fp(
- new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 16),
- new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16),
- new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16),
- n, h);
-
- return new X9ECParameters(
- cFp192v1,
- new X9ECPoint(cFp192v1,
- Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")),
- n, h,
- Hex.decode("3045AE6FC8422f64ED579528D38120EAE12196D5"));
+ ECCurve curve = configureCurve(new ECCurve.Fp(
+ fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
+ fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
+ fromHex("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("3045AE6FC8422f64ED579528D38120EAE12196D5"));
}
};
@@ -43,21 +59,19 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger n = new BigInteger("fffffffffffffffffffffffe5fb1a724dc80418648d8dd31", 16);
+ BigInteger n = fromHex("fffffffffffffffffffffffe5fb1a724dc80418648d8dd31");
BigInteger h = BigInteger.valueOf(1);
- ECCurve cFp192v2 = new ECCurve.Fp(
- new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 16),
- new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16),
- new BigInteger("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953", 16),
- n, h);
-
- return new X9ECParameters(
- cFp192v2,
- new X9ECPoint(cFp192v2,
- Hex.decode("03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a")),
- n, h,
- Hex.decode("31a92ee2029fd10d901b113e990710f0d21ac6b6"));
+ ECCurve curve = configureCurve(new ECCurve.Fp(
+ fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
+ fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
+ fromHex("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("31a92ee2029fd10d901b113e990710f0d21ac6b6"));
}
};
@@ -65,21 +79,19 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger n = new BigInteger("ffffffffffffffffffffffff7a62d031c83f4294f640ec13", 16);
+ BigInteger n = fromHex("ffffffffffffffffffffffff7a62d031c83f4294f640ec13");
BigInteger h = BigInteger.valueOf(1);
- ECCurve cFp192v3 = new ECCurve.Fp(
- new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 16),
- new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16),
- new BigInteger("22123dc2395a05caa7423daeccc94760a7d462256bd56916", 16),
- n, h);
-
- return new X9ECParameters(
- cFp192v3,
- new X9ECPoint(cFp192v3,
- Hex.decode("027d29778100c65a1da1783716588dce2b8b4aee8e228f1896")),
- n, h,
- Hex.decode("c469684435deb378c4b65ca9591e2a5763059a2e"));
+ ECCurve curve = configureCurve(new ECCurve.Fp(
+ fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
+ fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
+ fromHex("22123dc2395a05caa7423daeccc94760a7d462256bd56916"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "027d29778100c65a1da1783716588dce2b8b4aee8e228f1896");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("c469684435deb378c4b65ca9591e2a5763059a2e"));
}
};
@@ -87,21 +99,19 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger n = new BigInteger("7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b", 16);
+ BigInteger n = fromHex("7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b");
BigInteger h = BigInteger.valueOf(1);
- ECCurve cFp239v1 = new ECCurve.Fp(
+ ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
- new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16),
- new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16),
- n, h);
-
- return new X9ECParameters(
- cFp239v1,
- new X9ECPoint(cFp239v1,
- Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")),
- n, h,
- Hex.decode("e43bb460f0b80cc0c0b075798e948060f8321b7d"));
+ fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
+ fromHex("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("e43bb460f0b80cc0c0b075798e948060f8321b7d"));
}
};
@@ -109,21 +119,19 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger n = new BigInteger("7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063", 16);
+ BigInteger n = fromHex("7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063");
BigInteger h = BigInteger.valueOf(1);
- ECCurve cFp239v2 = new ECCurve.Fp(
+ ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
- new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16),
- new BigInteger("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c", 16),
- n, h);
-
- return new X9ECParameters(
- cFp239v2,
- new X9ECPoint(cFp239v2,
- Hex.decode("0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7")),
- n, h,
- Hex.decode("e8b4011604095303ca3b8099982be09fcb9ae616"));
+ fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
+ fromHex("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("e8b4011604095303ca3b8099982be09fcb9ae616"));
}
};
@@ -131,21 +139,19 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger n = new BigInteger("7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551", 16);
+ BigInteger n = fromHex("7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551");
BigInteger h = BigInteger.valueOf(1);
- ECCurve cFp239v3 = new ECCurve.Fp(
+ ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
- new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16),
- new BigInteger("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e", 16),
- n, h);
-
- return new X9ECParameters(
- cFp239v3,
- new X9ECPoint(cFp239v3,
- Hex.decode("036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a")),
- n, h,
- Hex.decode("7d7374168ffe3471b60a857686a19475d3bfa2ff"));
+ fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
+ fromHex("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("7d7374168ffe3471b60a857686a19475d3bfa2ff"));
}
};
@@ -153,21 +159,19 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger n = new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16);
+ BigInteger n = fromHex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551");
BigInteger h = BigInteger.valueOf(1);
- ECCurve cFp256v1 = new ECCurve.Fp(
+ ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951"),
- new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
- new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
- n, h);
-
- return new X9ECParameters(
- cFp256v1,
- new X9ECPoint(cFp256v1,
- Hex.decode("036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296")),
- n, h,
- Hex.decode("c49d360886e704936a6678e1139d26b7819f7e90"));
+ fromHex("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc"),
+ fromHex("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("c49d360886e704936a6678e1139d26b7819f7e90"));
}
};
@@ -178,22 +182,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m163v1n = new BigInteger("0400000000000000000001E60FC8821CC74DAEAFC1", 16);
- BigInteger c2m163v1h = BigInteger.valueOf(2);
+ BigInteger n = fromHex("0400000000000000000001E60FC8821CC74DAEAFC1");
+ BigInteger h = BigInteger.valueOf(2);
- ECCurve c2m163v1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
- new BigInteger("072546B5435234A422E0789675F432C89435DE5242", 16),
- new BigInteger("00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", 16),
- c2m163v1n, c2m163v1h);
-
- return new X9ECParameters(
- c2m163v1,
- new X9ECPoint(c2m163v1,
- Hex.decode("0307AF69989546103D79329FCC3D74880F33BBE803CB")),
- c2m163v1n, c2m163v1h,
- Hex.decode("D2C0FB15760860DEF1EEF4D696E6768756151754"));
+ fromHex("072546B5435234A422E0789675F432C89435DE5242"),
+ fromHex("00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0307AF69989546103D79329FCC3D74880F33BBE803CB");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("D2C0FB15760860DEF1EEF4D696E6768756151754"));
}
};
@@ -201,22 +203,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m163v2n = new BigInteger("03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 16);
- BigInteger c2m163v2h = BigInteger.valueOf(2);
+ BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7");
+ BigInteger h = BigInteger.valueOf(2);
- ECCurve c2m163v2 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
- new BigInteger("0108B39E77C4B108BED981ED0E890E117C511CF072", 16),
- new BigInteger("0667ACEB38AF4E488C407433FFAE4F1C811638DF20", 16),
- c2m163v2n, c2m163v2h);
-
- return new X9ECParameters(
- c2m163v2,
- new X9ECPoint(c2m163v2,
- Hex.decode("030024266E4EB5106D0A964D92C4860E2671DB9B6CC5")),
- c2m163v2n, c2m163v2h,
- null);
+ fromHex("0108B39E77C4B108BED981ED0E890E117C511CF072"),
+ fromHex("0667ACEB38AF4E488C407433FFAE4F1C811638DF20"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "030024266E4EB5106D0A964D92C4860E2671DB9B6CC5");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -224,22 +224,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m163v3n = new BigInteger("03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 16);
- BigInteger c2m163v3h = BigInteger.valueOf(2);
+ BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309");
+ BigInteger h = BigInteger.valueOf(2);
- ECCurve c2m163v3 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
163,
1, 2, 8,
- new BigInteger("07A526C63D3E25A256A007699F5447E32AE456B50E", 16),
- new BigInteger("03F7061798EB99E238FD6F1BF95B48FEEB4854252B", 16),
- c2m163v3n, c2m163v3h);
-
- return new X9ECParameters(
- c2m163v3,
- new X9ECPoint(c2m163v3,
- Hex.decode("0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB")),
- c2m163v3n, c2m163v3h,
- null);
+ fromHex("07A526C63D3E25A256A007699F5447E32AE456B50E"),
+ fromHex("03F7061798EB99E238FD6F1BF95B48FEEB4854252B"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -247,22 +245,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m176w1n = new BigInteger("010092537397ECA4F6145799D62B0A19CE06FE26AD", 16);
- BigInteger c2m176w1h = BigInteger.valueOf(0xFF6E);
+ BigInteger n = fromHex("010092537397ECA4F6145799D62B0A19CE06FE26AD");
+ BigInteger h = BigInteger.valueOf(0xFF6E);
- ECCurve c2m176w1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
176,
1, 2, 43,
- new BigInteger("00E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", 16),
- new BigInteger("005DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", 16),
- c2m176w1n, c2m176w1h);
-
- return new X9ECParameters(
- c2m176w1,
- new X9ECPoint(c2m176w1,
- Hex.decode("038D16C2866798B600F9F08BB4A8E860F3298CE04A5798")),
- c2m176w1n, c2m176w1h,
- null);
+ fromHex("E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B"),
+ fromHex("5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "038D16C2866798B600F9F08BB4A8E860F3298CE04A5798");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -270,22 +266,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m191v1n = new BigInteger("40000000000000000000000004A20E90C39067C893BBB9A5", 16);
- BigInteger c2m191v1h = BigInteger.valueOf(2);
+ BigInteger n = fromHex("40000000000000000000000004A20E90C39067C893BBB9A5");
+ BigInteger h = BigInteger.valueOf(2);
- ECCurve c2m191v1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
191,
9,
- new BigInteger("2866537B676752636A68F56554E12640276B649EF7526267", 16),
- new BigInteger("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", 16),
- c2m191v1n, c2m191v1h);
-
- return new X9ECParameters(
- c2m191v1,
- new X9ECPoint(c2m191v1,
- Hex.decode("0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D")),
- c2m191v1n, c2m191v1h,
- Hex.decode("4E13CA542744D696E67687561517552F279A8C84"));
+ fromHex("2866537B676752636A68F56554E12640276B649EF7526267"),
+ fromHex("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("4E13CA542744D696E67687561517552F279A8C84"));
}
};
@@ -293,22 +287,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m191v2n = new BigInteger("20000000000000000000000050508CB89F652824E06B8173", 16);
- BigInteger c2m191v2h = BigInteger.valueOf(4);
+ BigInteger n = fromHex("20000000000000000000000050508CB89F652824E06B8173");
+ BigInteger h = BigInteger.valueOf(4);
- ECCurve c2m191v2 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
191,
9,
- new BigInteger("401028774D7777C7B7666D1366EA432071274F89FF01E718", 16),
- new BigInteger("0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", 16),
- c2m191v2n, c2m191v2h);
-
- return new X9ECParameters(
- c2m191v2,
- new X9ECPoint(c2m191v2,
- Hex.decode("023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10")),
- c2m191v2n, c2m191v2h,
- null);
+ fromHex("401028774D7777C7B7666D1366EA432071274F89FF01E718"),
+ fromHex("0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -316,22 +308,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m191v3n = new BigInteger("155555555555555555555555610C0B196812BFB6288A3EA3", 16);
- BigInteger c2m191v3h = BigInteger.valueOf(6);
+ BigInteger n = fromHex("155555555555555555555555610C0B196812BFB6288A3EA3");
+ BigInteger h = BigInteger.valueOf(6);
- ECCurve c2m191v3 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
191,
9,
- new BigInteger("6C01074756099122221056911C77D77E77A777E7E7E77FCB", 16),
- new BigInteger("71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", 16),
- c2m191v3n, c2m191v3h);
-
- return new X9ECParameters(
- c2m191v3,
- new X9ECPoint(c2m191v3,
- Hex.decode("03375D4CE24FDE434489DE8746E71786015009E66E38A926DD")),
- c2m191v3n, c2m191v3h,
- null);
+ fromHex("6C01074756099122221056911C77D77E77A777E7E7E77FCB"),
+ fromHex("71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "03375D4CE24FDE434489DE8746E71786015009E66E38A926DD");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -339,22 +329,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m208w1n = new BigInteger("0101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 16);
- BigInteger c2m208w1h = BigInteger.valueOf(0xFE48);
+ BigInteger n = fromHex("0101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D");
+ BigInteger h = BigInteger.valueOf(0xFE48);
- ECCurve c2m208w1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
208,
1, 2, 83,
- new BigInteger("0", 16),
- new BigInteger("00C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", 16),
- c2m208w1n, c2m208w1h);
-
- return new X9ECParameters(
- c2m208w1,
- new X9ECPoint(c2m208w1,
- Hex.decode("0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A")),
- c2m208w1n, c2m208w1h,
- null);
+ BigInteger.valueOf(0),
+ fromHex("C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -362,22 +350,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m239v1n = new BigInteger("2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 16);
- BigInteger c2m239v1h = BigInteger.valueOf(4);
+ BigInteger n = fromHex("2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447");
+ BigInteger h = BigInteger.valueOf(4);
- ECCurve c2m239v1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
239,
36,
- new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16),
- new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16),
- c2m239v1n, c2m239v1h);
-
- return new X9ECParameters(
- c2m239v1,
- new X9ECPoint(c2m239v1,
- Hex.decode("0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D")),
- c2m239v1n, c2m239v1h,
- null);
+ fromHex("32010857077C5431123A46B808906756F543423E8D27877578125778AC76"),
+ fromHex("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -385,22 +371,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m239v2n = new BigInteger("1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 16);
- BigInteger c2m239v2h = BigInteger.valueOf(6);
+ BigInteger n = fromHex("1555555555555555555555555555553C6F2885259C31E3FCDF154624522D");
+ BigInteger h = BigInteger.valueOf(6);
- ECCurve c2m239v2 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
239,
36,
- new BigInteger("4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", 16),
- new BigInteger("5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", 16),
- c2m239v2n, c2m239v2h);
-
- return new X9ECParameters(
- c2m239v2,
- new X9ECPoint(c2m239v2,
- Hex.decode("0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205")),
- c2m239v2n, c2m239v2h,
- null);
+ fromHex("4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F"),
+ fromHex("5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -408,22 +392,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m239v3n = new BigInteger("0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 16);
- BigInteger c2m239v3h = BigInteger.valueOf(10);
+ BigInteger n = fromHex("0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF");
+ BigInteger h = BigInteger.valueOf(10);
- ECCurve c2m239v3 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
239,
36,
- new BigInteger("01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", 16),
- new BigInteger("6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", 16),
- c2m239v3n, c2m239v3h);
-
- return new X9ECParameters(
- c2m239v3,
- new X9ECPoint(c2m239v3,
- Hex.decode("0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92")),
- c2m239v3n, c2m239v3h,
- null);
+ fromHex("01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F"),
+ fromHex("6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -431,22 +413,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m272w1n = new BigInteger("0100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", 16);
- BigInteger c2m272w1h = BigInteger.valueOf(0xFF06);
+ BigInteger n = fromHex("0100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521");
+ BigInteger h = BigInteger.valueOf(0xFF06);
- ECCurve c2m272w1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
272,
1, 3, 56,
- new BigInteger("0091A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", 16),
- new BigInteger("7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", 16),
- c2m272w1n, c2m272w1h);
-
- return new X9ECParameters(
- c2m272w1,
- new X9ECPoint(c2m272w1,
- Hex.decode("026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D")),
- c2m272w1n, c2m272w1h,
- null);
+ fromHex("91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20"),
+ fromHex("7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -454,22 +434,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m304w1n = new BigInteger("0101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D", 16);
- BigInteger c2m304w1h = BigInteger.valueOf(0xFE2E);
+ BigInteger n = fromHex("0101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D");
+ BigInteger h = BigInteger.valueOf(0xFE2E);
- ECCurve c2m304w1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
304,
1, 2, 11,
- new BigInteger("00FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681", 16),
- new BigInteger("00BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE", 16),
- c2m304w1n, c2m304w1h);
-
- return new X9ECParameters(
- c2m304w1,
- new X9ECPoint(c2m304w1,
- Hex.decode("02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614")),
- c2m304w1n, c2m304w1h,
- null);
+ fromHex("FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681"),
+ fromHex("BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -477,22 +455,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m359v1n = new BigInteger("01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B", 16);
- BigInteger c2m359v1h = BigInteger.valueOf(0x4C);
+ BigInteger n = fromHex("01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B");
+ BigInteger h = BigInteger.valueOf(0x4C);
- ECCurve c2m359v1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
359,
68,
- new BigInteger("5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557", 16),
- new BigInteger("2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988", 16),
- c2m359v1n, c2m359v1h);
-
- return new X9ECParameters(
- c2m359v1,
- new X9ECPoint(c2m359v1,
- Hex.decode("033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097")),
- c2m359v1n, c2m359v1h,
- null);
+ fromHex("5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557"),
+ fromHex("2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -500,22 +476,20 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m368w1n = new BigInteger("010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967", 16);
- BigInteger c2m368w1h = BigInteger.valueOf(0xFF70);
+ BigInteger n = fromHex("010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967");
+ BigInteger h = BigInteger.valueOf(0xFF70);
- ECCurve c2m368w1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
368,
1, 2, 85,
- new BigInteger("00E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D", 16),
- new BigInteger("00FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A", 16),
- c2m368w1n, c2m368w1h);
-
- return new X9ECParameters(
- c2m368w1,
- new X9ECPoint(c2m368w1,
- Hex.decode("021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F")),
- c2m368w1n, c2m368w1h,
- null);
+ fromHex("E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D"),
+ fromHex("FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
@@ -523,25 +497,24 @@ public class X962NamedCurves
{
protected X9ECParameters createParameters()
{
- BigInteger c2m431r1n = new BigInteger("0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91", 16);
- BigInteger c2m431r1h = BigInteger.valueOf(0x2760);
+ BigInteger n = fromHex("0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91");
+ BigInteger h = BigInteger.valueOf(0x2760);
- ECCurve c2m431r1 = new ECCurve.F2m(
+ ECCurve curve = configureCurve(new ECCurve.F2m(
431,
120,
- new BigInteger("1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F", 16),
- new BigInteger("10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618", 16),
- c2m431r1n, c2m431r1h);
-
- return new X9ECParameters(
- c2m431r1,
- new X9ECPoint(c2m431r1,
- Hex.decode("02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7")),
- c2m431r1n, c2m431r1h,
- null);
+ fromHex("1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F"),
+ fromHex("10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7");
+
+ return new X9ECParameters(curve, G, n, h);
}
};
+
static final Hashtable objIds = new Hashtable();
static final Hashtable curves = new Hashtable();
static final Hashtable names = new Hashtable();
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962Parameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962Parameters.java
index 96ae655e..fac3bdd1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962Parameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X962Parameters.java
@@ -1,8 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.asn1.x9;
-import java.io.IOException;
-
import com.android.org.bouncycastle.asn1.ASN1Choice;
import com.android.org.bouncycastle.asn1.ASN1Null;
import com.android.org.bouncycastle.asn1.ASN1Object;
@@ -73,11 +71,7 @@ public class X962Parameters
this.params = obj;
}
- /**
- * @deprecated use getInstance()
- */
- public X962Parameters(
- ASN1Primitive obj)
+ private X962Parameters(ASN1Primitive obj)
{
this.params = obj;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9Curve.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9Curve.java
index 3b15664d..85a3eb46 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9Curve.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9Curve.java
@@ -62,10 +62,8 @@ public class X9Curve
{
// Characteristic two field
ASN1Sequence parameters = ASN1Sequence.getInstance(fieldID.getParameters());
- int m = ((ASN1Integer)parameters.getObjectAt(0)).getValue().
- intValue();
- ASN1ObjectIdentifier representation
- = (ASN1ObjectIdentifier)parameters.getObjectAt(1);
+ int m = ((ASN1Integer)parameters.getObjectAt(0)).intValueExact();
+ ASN1ObjectIdentifier representation = (ASN1ObjectIdentifier)parameters.getObjectAt(1);
int k1 = 0;
int k2 = 0;
@@ -74,15 +72,15 @@ public class X9Curve
if (representation.equals(tpBasis))
{
// Trinomial basis representation
- k1 = ASN1Integer.getInstance(parameters.getObjectAt(2)).getValue().intValue();
+ k1 = ASN1Integer.getInstance(parameters.getObjectAt(2)).intValueExact();
}
else if (representation.equals(ppBasis))
{
// Pentanomial basis representation
ASN1Sequence pentanomial = ASN1Sequence.getInstance(parameters.getObjectAt(2));
- k1 = ASN1Integer.getInstance(pentanomial.getObjectAt(0)).getValue().intValue();
- k2 = ASN1Integer.getInstance(pentanomial.getObjectAt(1)).getValue().intValue();
- k3 = ASN1Integer.getInstance(pentanomial.getObjectAt(2)).getValue().intValue();
+ k1 = ASN1Integer.getInstance(pentanomial.getObjectAt(0)).intValueExact();
+ k2 = ASN1Integer.getInstance(pentanomial.getObjectAt(1)).intValueExact();
+ k3 = ASN1Integer.getInstance(pentanomial.getObjectAt(2)).intValueExact();
}
else
{
@@ -99,7 +97,7 @@ public class X9Curve
if (seq.size() == 3)
{
- seed = Arrays.clone(((DERBitString)seq.getObjectAt(2)).getBytes());
+ seed = ((DERBitString)seq.getObjectAt(2)).getBytes();
}
}
@@ -141,7 +139,7 @@ public class X9Curve
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
if (fieldIdentifier.equals(prime_field))
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECParameters.java
index 691ac49e..d2a48d14 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECParameters.java
@@ -38,7 +38,7 @@ public class X9ECParameters
ASN1Sequence seq)
{
if (!(seq.getObjectAt(0) instanceof ASN1Integer)
- || !((ASN1Integer)seq.getObjectAt(0)).getValue().equals(ONE))
+ || !((ASN1Integer)seq.getObjectAt(0)).hasValue(ONE))
{
throw new IllegalArgumentException("bad version in X9ECParameters");
}
@@ -86,7 +86,7 @@ public class X9ECParameters
public X9ECParameters(
ECCurve curve,
- ECPoint g,
+ X9ECPoint g,
BigInteger n)
{
this(curve, g, n, null, null);
@@ -94,16 +94,7 @@ public class X9ECParameters
public X9ECParameters(
ECCurve curve,
- X9ECPoint g,
- BigInteger n,
- BigInteger h)
- {
- this(curve, g, n, h, null);
- }
-
- public X9ECParameters(
- ECCurve curve,
- ECPoint g,
+ X9ECPoint g,
BigInteger n,
BigInteger h)
{
@@ -112,16 +103,6 @@ public class X9ECParameters
public X9ECParameters(
ECCurve curve,
- ECPoint g,
- BigInteger n,
- BigInteger h,
- byte[] seed)
- {
- this(curve, new X9ECPoint(g), n, h, seed);
- }
-
- public X9ECParameters(
- ECCurve curve,
X9ECPoint g,
BigInteger n,
BigInteger h,
@@ -185,6 +166,11 @@ public class X9ECParameters
return Arrays.clone(seed);
}
+ public boolean hasSeed()
+ {
+ return null != seed;
+ }
+
/**
* Return the ASN.1 entry representing the Curve.
*
@@ -230,7 +216,7 @@ public class X9ECParameters
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(6);
v.add(new ASN1Integer(ONE));
v.add(fieldID);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECPoint.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECPoint.java
index 6776400d..b812ec99 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECPoint.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ECPoint.java
@@ -22,12 +22,6 @@ public class X9ECPoint
private ECPoint p;
public X9ECPoint(
- ECPoint p)
- {
- this(p, false);
- }
-
- public X9ECPoint(
ECPoint p,
boolean compressed)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9FieldID.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9FieldID.java
index 9695a9a2..7f58b7a4 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9FieldID.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9FieldID.java
@@ -66,7 +66,7 @@ public class X9FieldID
public X9FieldID(int m, int k1, int k2, int k3)
{
this.id = characteristic_two_field;
- ASN1EncodableVector fieldIdParams = new ASN1EncodableVector();
+ ASN1EncodableVector fieldIdParams = new ASN1EncodableVector(3);
fieldIdParams.add(new ASN1Integer(m));
if (k2 == 0)
@@ -87,7 +87,7 @@ public class X9FieldID
}
fieldIdParams.add(ppBasis);
- ASN1EncodableVector pentanomialParams = new ASN1EncodableVector();
+ ASN1EncodableVector pentanomialParams = new ASN1EncodableVector(3);
pentanomialParams.add(new ASN1Integer(k1));
pentanomialParams.add(new ASN1Integer(k2));
pentanomialParams.add(new ASN1Integer(k3));
@@ -140,7 +140,7 @@ public class X9FieldID
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(this.id);
v.add(this.parameters);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java
index 1b42f245..82dba4b3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java
@@ -12,7 +12,6 @@ import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
* </pre>
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public interface X9ObjectIdentifiers
{
/** Base OID: 1.2.840.10045 */
@@ -56,7 +55,6 @@ public interface X9ObjectIdentifiers
/** OID: 1.2.840.10045.4.3.2 */
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
ASN1ObjectIdentifier ecdsa_with_SHA256 = ecdsa_with_SHA2.branch("2");
/** OID: 1.2.840.10045.4.3.3 */
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CipherParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CipherParameters.java
index 11c433c3..889837f7 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CipherParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CipherParameters.java
@@ -5,7 +5,6 @@ package com.android.org.bouncycastle.crypto;
* all parameter classes implement this.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public interface CipherParameters
{
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesRegistrar.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesRegistrar.java
index 2a855dab..920e33c8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesRegistrar.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/CryptoServicesRegistrar.java
@@ -30,7 +30,8 @@ public final class CryptoServicesRegistrar
private static final ThreadLocal<Map<String, Object[]>> threadProperties = new ThreadLocal<Map<String, Object[]>>();
private static final Map<String, Object[]> globalProperties = Collections.synchronizedMap(new HashMap<String, Object[]>());
- private static volatile SecureRandom defaultSecureRandom;
+ private static final Object cacheLock = new Object();
+ private static SecureRandom defaultSecureRandom;
static
{
@@ -40,7 +41,7 @@ public final class CryptoServicesRegistrar
new BigInteger("fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e17", 16),
new BigInteger("962eddcc369cba8ebb260ee6b6a126d9346e38c5", 16),
new BigInteger("678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4", 16),
- new DSAValidationParameters(Hex.decode("b869c82b35d70e1b1ff91b28e37a62ecdc34409b"), 123));
+ new DSAValidationParameters(Hex.decodeStrict("b869c82b35d70e1b1ff91b28e37a62ecdc34409b"), 123));
DSAParameters def768Params = new DSAParameters(
new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5" +
@@ -52,7 +53,7 @@ public final class CryptoServicesRegistrar
"a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d366844577" +
"1f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a" +
"7064f316933a346d3f529252", 16),
- new DSAValidationParameters(Hex.decode("77d0f8c4dad15eb8c4f2f8d6726cefd96d5bb399"), 263));
+ new DSAValidationParameters(Hex.decodeStrict("77d0f8c4dad15eb8c4f2f8d6726cefd96d5bb399"), 263));
DSAParameters def1024Params = new DSAParameters(
new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80" +
@@ -66,7 +67,7 @@ public final class CryptoServicesRegistrar
"b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f" +
"0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06" +
"928b665e807b552564014c3bfecf492a", 16),
- new DSAValidationParameters(Hex.decode("8d5155894229d5e689ee01e6018a237e2cae64cd"), 92));
+ new DSAValidationParameters(Hex.decodeStrict("8d5155894229d5e689ee01e6018a237e2cae64cd"), 92));
DSAParameters def2048Params = new DSAParameters(
new BigInteger("95475cf5d93e596c3fcd1d902add02f427f5f3c7210313bb45fb4d5b" +
@@ -90,7 +91,7 @@ public final class CryptoServicesRegistrar
"ac819a26ca9b04cb0eb9b7b035988d15bbac65212a55239cfc7e58fa" +
"e38d7250ab9991ffbc97134025fe8ce04c4399ad96569be91a546f49" +
"78693c7a", 16),
- new DSAValidationParameters(Hex.decode("b0b4417601b59cbc9d8ac8f935cadaec4f5fbb2f23785609ae466748d9b5a536"), 497));
+ new DSAValidationParameters(Hex.decodeStrict("b0b4417601b59cbc9d8ac8f935cadaec4f5fbb2f23785609ae466748d9b5a536"), 497));
localSetGlobalProperty(Property.DSA_DEFAULT_PARAMS, def512Params, def768Params, def1024Params, def2048Params);
localSetGlobalProperty(Property.DH_DEFAULT_PARAMS, toDH(def512Params), toDH(def768Params), toDH(def1024Params), toDH(def2048Params));
@@ -105,16 +106,39 @@ public final class CryptoServicesRegistrar
* Return the default source of randomness.
*
* @return the default SecureRandom
- * @throws IllegalStateException if no source of randomness has been provided.
*/
public static SecureRandom getSecureRandom()
{
- if (defaultSecureRandom == null)
+ synchronized (cacheLock)
{
- return new SecureRandom();
+ if (null != defaultSecureRandom)
+ {
+ return defaultSecureRandom;
+ }
+ }
+
+ SecureRandom tmp = new SecureRandom();
+
+ synchronized (cacheLock)
+ {
+ if (null == defaultSecureRandom)
+ {
+ defaultSecureRandom = tmp;
+ }
+
+ return defaultSecureRandom;
}
-
- return defaultSecureRandom;
+ }
+
+ /**
+ * Return either the passed-in SecureRandom, or if it is null, then the default source of randomness.
+ *
+ * @param secureRandom the SecureRandom to use if it is not null.
+ * @return the SecureRandom parameter if it is not null, or else the default SecureRandom
+ */
+ public static SecureRandom getSecureRandom(SecureRandom secureRandom)
+ {
+ return null == secureRandom ? getSecureRandom() : secureRandom;
}
/**
@@ -126,7 +150,10 @@ public final class CryptoServicesRegistrar
{
checkPermission(CanSetDefaultRandom);
- defaultSecureRandom = secureRandom;
+ synchronized (cacheLock)
+ {
+ defaultSecureRandom = secureRandom;
+ }
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/KeyGenerationParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/KeyGenerationParameters.java
index 2a43b182..45d9fb41 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/KeyGenerationParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/KeyGenerationParameters.java
@@ -23,7 +23,7 @@ public class KeyGenerationParameters
SecureRandom random,
int strength)
{
- this.random = random;
+ this.random = CryptoServicesRegistrar.getSecureRandom(random);
this.strength = strength;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/PBEParametersGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/PBEParametersGenerator.java
index 956e9332..d6277271 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/PBEParametersGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/PBEParametersGenerator.java
@@ -7,7 +7,6 @@ import com.android.org.bouncycastle.util.Strings;
* super class for all Password Based Encryption (PBE) parameter generator classes.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public abstract class PBEParametersGenerator
{
protected byte[] password;
@@ -17,7 +16,6 @@ public abstract class PBEParametersGenerator
/**
* base constructor.
*/
- @libcore.api.CorePlatformApi
protected PBEParametersGenerator()
{
}
@@ -104,7 +102,6 @@ public abstract class PBEParametersGenerator
* @param password a character array representing the password.
* @return a byte array representing the password.
*/
- @libcore.api.CorePlatformApi
public static byte[] PKCS5PasswordToBytes(
char[] password)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/StagedAgreement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/StagedAgreement.java
new file mode 100644
index 00000000..1592736e
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/StagedAgreement.java
@@ -0,0 +1,13 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto;
+
+import com.android.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface StagedAgreement
+ extends BasicAgreement
+{
+ AsymmetricKeyParameter calculateStage(CipherParameters pubKey);
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/GeneralDigest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/GeneralDigest.java
index 690c63dd..c075dce5 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/GeneralDigest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/GeneralDigest.java
@@ -10,7 +10,6 @@ import com.android.org.bouncycastle.util.Pack;
* "Handbook of Applied Cryptography", pages 344 - 347.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public abstract class GeneralDigest
implements ExtendedDigest, Memoable
{
@@ -68,7 +67,6 @@ public abstract class GeneralDigest
byteCount++;
}
- @libcore.api.CorePlatformApi
public void update(
byte[] in,
int inOff,
@@ -114,7 +112,6 @@ public abstract class GeneralDigest
byteCount += len;
}
- @libcore.api.CorePlatformApi
public void finish()
{
long bitLength = (byteCount << 3);
@@ -161,6 +158,5 @@ public abstract class GeneralDigest
protected abstract void processLength(long bitLength);
- @libcore.api.CorePlatformApi
protected abstract void processBlock();
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/MD4Digest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/MD4Digest.java
index 3a30b95d..19d2fe7c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/MD4Digest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/MD4Digest.java
@@ -12,7 +12,6 @@ import com.android.org.bouncycastle.util.Memoable;
* with legacy applications, it's not secure, don't use it for anything new!
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class MD4Digest
extends GeneralDigest
{
@@ -26,7 +25,6 @@ public class MD4Digest
/**
* Standard constructor
*/
- @libcore.api.CorePlatformApi
public MD4Digest()
{
reset();
@@ -102,7 +100,6 @@ public class MD4Digest
out[outOff + 3] = (byte)(word >>> 24);
}
- @libcore.api.CorePlatformApi
public int doFinal(
byte[] out,
int outOff)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA1Digest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA1Digest.java
index 78750ea2..ebc5bfe4 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA1Digest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA1Digest.java
@@ -11,7 +11,6 @@ import com.android.org.bouncycastle.util.Pack;
* is the "endianness" of the word processing!
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class SHA1Digest
extends GeneralDigest
implements EncodableDigest
@@ -26,7 +25,6 @@ public class SHA1Digest
/**
* Standard constructor
*/
- @libcore.api.CorePlatformApi
public SHA1Digest()
{
reset();
@@ -117,7 +115,6 @@ public class SHA1Digest
X[15] = (int)bitLength;
}
- @libcore.api.CorePlatformApi
public int doFinal(
byte[] out,
int outOff)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA256Digest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA256Digest.java
index aeee4f9d..25eda9de 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA256Digest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/SHA256Digest.java
@@ -273,42 +273,34 @@ public class SHA256Digest
}
/* SHA-256 functions */
- private int Ch(
- int x,
- int y,
- int z)
+ private static int Ch(int x, int y, int z)
{
return (x & y) ^ ((~x) & z);
+// return z ^ (x & (y ^ z));
}
- private int Maj(
- int x,
- int y,
- int z)
+ private static int Maj(int x, int y, int z)
{
- return (x & y) ^ (x & z) ^ (y & z);
+// return (x & y) ^ (x & z) ^ (y & z);
+ return (x & y) | (z & (x ^ y));
}
- private int Sum0(
- int x)
+ private static int Sum0(int x)
{
return ((x >>> 2) | (x << 30)) ^ ((x >>> 13) | (x << 19)) ^ ((x >>> 22) | (x << 10));
}
- private int Sum1(
- int x)
+ private static int Sum1(int x)
{
return ((x >>> 6) | (x << 26)) ^ ((x >>> 11) | (x << 21)) ^ ((x >>> 25) | (x << 7));
}
- private int Theta0(
- int x)
+ private static int Theta0(int x)
{
return ((x >>> 7) | (x << 25)) ^ ((x >>> 18) | (x << 14)) ^ (x >>> 3);
}
- private int Theta1(
- int x)
+ private static int Theta1(int x)
{
return ((x >>> 17) | (x << 15)) ^ ((x >>> 19) | (x << 13)) ^ (x >>> 10);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/XofUtils.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/XofUtils.java
new file mode 100644
index 00000000..13a053d9
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/digests/XofUtils.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.digests;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class XofUtils
+{
+ public static byte[] leftEncode(long strLen)
+ {
+ byte n = 1;
+
+ long v = strLen;
+ while ((v >>= 8) != 0)
+ {
+ n++;
+ }
+
+ byte[] b = new byte[n + 1];
+
+ b[0] = n;
+
+ for (int i = 1; i <= n; i++)
+ {
+ b[i] = (byte)(strLen >> (8 * (n - i)));
+ }
+
+ return b;
+ }
+
+ public static byte[] rightEncode(long strLen)
+ {
+ byte n = 1;
+
+ long v = strLen;
+ while ((v >>= 8) != 0)
+ {
+ n++;
+ }
+
+ byte[] b = new byte[n + 1];
+
+ b[n] = n;
+
+ for (int i = 0; i < n; i++)
+ {
+ b[i] = (byte)(strLen >> (8 * (n - i - 1)));
+ }
+
+ return b;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/ec/CustomNamedCurves.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/ec/CustomNamedCurves.java
index e8f250c5..aeb85903 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/ec/CustomNamedCurves.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/ec/CustomNamedCurves.java
@@ -23,6 +23,7 @@ import com.android.org.bouncycastle.math.ec.ECCurve;
// import org.bouncycastle.math.ec.custom.sec.SecP160R1Curve;
// import org.bouncycastle.math.ec.custom.sec.SecP160R2Curve;
// END android-removed
+import com.android.org.bouncycastle.math.ec.WNafUtil;
import com.android.org.bouncycastle.math.ec.custom.sec.SecP192K1Curve;
import com.android.org.bouncycastle.math.ec.custom.sec.SecP192R1Curve;
import com.android.org.bouncycastle.math.ec.custom.sec.SecP224K1Curve;
@@ -53,6 +54,7 @@ import com.android.org.bouncycastle.math.ec.custom.sec.SecP521R1Curve;
// END android-removed
import com.android.org.bouncycastle.math.ec.endo.GLVTypeBEndomorphism;
import com.android.org.bouncycastle.math.ec.endo.GLVTypeBParameters;
+import com.android.org.bouncycastle.math.ec.endo.ScalarSplitParameters;
import com.android.org.bouncycastle.util.Strings;
import com.android.org.bouncycastle.util.encoders.Hex;
@@ -61,6 +63,13 @@ import com.android.org.bouncycastle.util.encoders.Hex;
*/
public class CustomNamedCurves
{
+ private static X9ECPoint configureBasepoint(ECCurve curve, String encoding)
+ {
+ X9ECPoint G = new X9ECPoint(curve, Hex.decodeStrict(encoding));
+ WNafUtil.configureBasepoint(G.getPoint());
+ return G;
+ }
+
private static ECCurve configureCurve(ECCurve curve)
{
return curve;
@@ -92,9 +101,8 @@ public class CustomNamedCurves
*
* (The other possible y value is 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14)
*
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A"
- + "20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9"));
+ X9ECPoint G = configureBasepoint(curve,
+ "042AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
@@ -107,11 +115,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("000E0D4D696E6768756151750CC03A4473D03679");
+ byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
ECCurve curve = configureCurve(new SecP128R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "161FF7528B899B2D0C28607CA52C5B86"
- + "CF5AC8395BAFEB13C02DA292DDED7A83"));
+ X9ECPoint G = configureBasepoint(curve,
+ "04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -127,19 +134,19 @@ public class CustomNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16),
new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16),
- new BigInteger[]{
- new BigInteger("9162fbe73984472a0a9e", 16),
- new BigInteger("-96341f1138933bc2f505", 16) },
- new BigInteger[]{
- new BigInteger("127971af8721782ecffa3", 16),
- new BigInteger("9162fbe73984472a0a9e", 16) },
- new BigInteger("9162fbe73984472a0a9d0590", 16),
- new BigInteger("96341f1138933bc2f503fd44", 16),
- 176);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("9162fbe73984472a0a9e", 16),
+ new BigInteger("-96341f1138933bc2f505", 16) },
+ new BigInteger[]{
+ new BigInteger("127971af8721782ecffa3", 16),
+ new BigInteger("9162fbe73984472a0a9e", 16) },
+ new BigInteger("9162fbe73984472a0a9d0590", 16),
+ new BigInteger("96341f1138933bc2f503fd44", 16),
+ 176));
ECCurve curve = configureCurveGLV(new SecP160K1Curve(), glv);
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"
- + "938CF935318FDCED6BC28286531733C3F03C4FEE"));
+ X9ECPoint G = configureBasepoint(curve,
+ "043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -151,11 +158,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("1053CDE42C14D696E67687561517533BF3F83345");
+ byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
ECCurve curve = configureCurve(new SecP160R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "4A96B5688EF573284664698968C38BB913CBFC82"
- + "23A628553168947D59DCC912042351377AC5FB32"));
+ X9ECPoint G = configureBasepoint(curve,
+ "044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -167,11 +173,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("B99B99B099B323E02709A4D696E6768756151751");
+ byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
ECCurve curve = configureCurve(new SecP160R2Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "52DCB034293A117E1F4FF11B30F7199D3144CE6D"
- + "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -189,19 +194,19 @@ public class CustomNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16),
new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16),
- new BigInteger[]{
- new BigInteger("71169be7330b3038edb025f1", 16),
- new BigInteger("-b3fb3400dec5c4adceb8655c", 16) },
- new BigInteger[]{
- new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
- new BigInteger("71169be7330b3038edb025f1", 16) },
- new BigInteger("71169be7330b3038edb025f1d0f9", 16),
- new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
- 208);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("71169be7330b3038edb025f1", 16),
+ new BigInteger("-b3fb3400dec5c4adceb8655c", 16) },
+ new BigInteger[]{
+ new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
+ new BigInteger("71169be7330b3038edb025f1", 16) },
+ new BigInteger("71169be7330b3038edb025f1d0f9", 16),
+ new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
+ 208));
ECCurve curve = configureCurveGLV(new SecP192K1Curve(), glv);
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"
- + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"));
+ X9ECPoint G = configureBasepoint(curve,
+ "04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -213,11 +218,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("3045AE6FC8422F64ED579528D38120EAE12196D5");
+ byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
ECCurve curve = configureCurve(new SecP192R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"
- + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"));
+ X9ECPoint G = configureBasepoint(curve,
+ "04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -233,19 +237,19 @@ public class CustomNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16),
new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16),
- new BigInteger[]{
- new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
- new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) },
- new BigInteger[]{
- new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
- new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) },
- new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
- new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
- 240);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
+ new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) },
+ new BigInteger[]{
+ new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) },
+ new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
+ new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
+ 240));
ECCurve curve = configureCurveGLV(new SecP224K1Curve(), glv);
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"
- + "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"));
+ X9ECPoint G = configureBasepoint(curve,
+ "04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -257,11 +261,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
+ byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
ECCurve curve = configureCurve(new SecP224R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"
- + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"));
+ X9ECPoint G = configureBasepoint(curve,
+ "04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -277,19 +280,19 @@ public class CustomNamedCurves
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16),
new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16),
- new BigInteger[]{
- new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
- new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) },
- new BigInteger[]{
- new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
- new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) },
- new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
- new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
- 272);
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
+ new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) },
+ new BigInteger[]{
+ new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) },
+ new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
+ new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
+ 272));
ECCurve curve = configureCurveGLV(new SecP256K1Curve(), glv);
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
- + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -301,11 +304,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("C49D360886E704936A6678E1139D26B7819F7E90");
+ byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
ECCurve curve = configureCurve(new SecP256R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
- + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"));
+ X9ECPoint G = configureBasepoint(curve,
+ "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -317,11 +319,11 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("A335926AA319A27A1D00896A6773A4827ACDAC73");
+ byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
ECCurve curve = configureCurve(new SecP384R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
- + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"));
+ + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -333,11 +335,11 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("D09E8800291CB85396CC6717393284AAA0DA64BA");
+ byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
ECCurve curve = configureCurve(new SecP521R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
- + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"));
+ + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -351,11 +353,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("10E723AB14D696E6768756151756FEBF8FCB49A9");
+ byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
ECCurve curve = configureCurve(new SecT113R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "009D73616F35F4AB1407D73562C10F"
- + "00A52830277958EE84D1315ED31886"));
+ X9ECPoint G = configureBasepoint(curve,
+ "04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -367,11 +368,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("10C0FB15760860DEF1EEF4D696E676875615175D");
+ byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
ECCurve curve = configureCurve(new SecT113R2Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "01A57A6A7B26CA5EF52FCDB8164797"
- + "00B3ADC94ED1FE674C06E695BABA1D"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -383,11 +383,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("4D696E676875615175985BD3ADBADA21B43A97E2");
+ byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
ECCurve curve = configureCurve(new SecT131R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "0081BAF91FDF9833C40F9C181343638399"
- + "078C6E7EA38C001F73C8134B1B4EF9E150"));
+ X9ECPoint G = configureBasepoint(curve,
+ "040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -399,11 +398,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("985BD3ADBAD4D696E676875615175A21B43A97E3");
+ byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
ECCurve curve = configureCurve(new SecT131R2Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "0356DCD8F2F95031AD652D23951BB366A8"
- + "0648F06D867940A5366D9E265DE9EB240F"));
+ X9ECPoint G = configureBasepoint(curve,
+ "040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -417,9 +415,8 @@ public class CustomNamedCurves
{
byte[] S = null;
ECCurve curve = configureCurve(new SecT163K1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8"
- + "0289070FB05D38FF58321F2E800536D538CCDAA3D9"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -431,11 +428,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("24B7B137C8A14D696E6768756151756FD0DA2E5C");
+ byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
ECCurve curve = configureCurve(new SecT163R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "0369979697AB43897789566789567F787A7876A654"
- + "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883"));
+ X9ECPoint G = configureBasepoint(curve,
+ "040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -447,11 +443,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("85E25BFE5C86226CDB12016F7553F9D0E693A268");
+ byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
ECCurve curve = configureCurve(new SecT163R2Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "03F0EBA16286A2D57EA0991168D4994637E8343E36"
- + "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -463,11 +458,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("103FAEC74D696E676875615175777FC5B191EF30");
+ byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
ECCurve curve = configureCurve(new SecT193R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1"
- + "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -479,11 +473,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("10B7B4D696E676875615175137C8A16FD0DA2211");
+ byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
ECCurve curve = configureCurve(new SecT193R2Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F"
- + "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -497,9 +490,8 @@ public class CustomNamedCurves
{
byte[] S = null;
ECCurve curve = configureCurve(new SecT233K1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126"
- + "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3"));
+ X9ECPoint G = configureBasepoint(curve,
+ "04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -511,11 +503,10 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
+ byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
ECCurve curve = configureCurve(new SecT233R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B"
- + "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -529,9 +520,8 @@ public class CustomNamedCurves
{
byte[] S = null;
ECCurve curve = configureCurve(new SecT239K1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC"
- + "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -545,9 +535,9 @@ public class CustomNamedCurves
{
byte[] S = null;
ECCurve curve = configureCurve(new SecT283K1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
- + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259"));
+ + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -559,11 +549,11 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
+ byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
ECCurve curve = configureCurve(new SecT283R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
- + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4"));
+ + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -577,9 +567,9 @@ public class CustomNamedCurves
{
byte[] S = null;
ECCurve curve = configureCurve(new SecT409K1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
- + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B"));
+ + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -591,11 +581,11 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("4099B5A457F9D69F79213D094C4BCD4D4262210B");
+ byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
ECCurve curve = configureCurve(new SecT409R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
- + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706"));
+ + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -609,9 +599,9 @@ public class CustomNamedCurves
{
byte[] S = null;
ECCurve curve = configureCurve(new SecT571K1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
- + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3"));
+ + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -623,11 +613,11 @@ public class CustomNamedCurves
{
protected X9ECParameters createParameters()
{
- byte[] S = Hex.decode("2AA058F73A0E33AB486B0F610410C53A7F132310");
+ byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
ECCurve curve = configureCurve(new SecT571R1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ X9ECPoint G = configureBasepoint(curve, "04"
+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
- + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B"));
+ + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
@@ -641,15 +631,15 @@ public class CustomNamedCurves
{
byte[] S = null;
ECCurve curve = configureCurve(new SM2P256V1Curve());
- X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
- + "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7"
- + "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"));
+ X9ECPoint G = configureBasepoint(curve,
+ "0432C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0");
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
*/
// END Android-removed: Unsupported curves
+
static final Hashtable nameToCurve = new Hashtable();
static final Hashtable nameToOID = new Hashtable();
static final Hashtable oidToCurve = new Hashtable();
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/OAEPEncoding.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/OAEPEncoding.java
index 7bfcf44d..c0858443 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/OAEPEncoding.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/OAEPEncoding.java
@@ -303,6 +303,7 @@ public class OAEPEncoding
byte[] output = new byte[block.length - start];
System.arraycopy(block, start, output, 0, output.length);
+ Arrays.fill(block, (byte)0);
return output;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/PKCS1Encoding.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
index 44017407..7f8b1ba1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
@@ -1,8 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.crypto.encodings;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.security.SecureRandom;
import com.android.org.bouncycastle.crypto.AsymmetricBlockCipher;
@@ -12,6 +10,7 @@ import com.android.org.bouncycastle.crypto.InvalidCipherTextException;
import com.android.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import com.android.org.bouncycastle.crypto.params.ParametersWithRandom;
import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Properties;
/**
* this does your basic PKCS 1 v1.5 padding - whether or not you should be using this
@@ -97,28 +96,12 @@ public class PKCS1Encoding
//
private boolean useStrict()
{
- // required if security manager has been installed.
- String strict = (String)AccessController.doPrivileged(new PrivilegedAction()
+ if (Properties.isOverrideSetTo(NOT_STRICT_LENGTH_ENABLED_PROPERTY, true))
{
- public Object run()
- {
- return System.getProperty(STRICT_LENGTH_ENABLED_PROPERTY);
- }
- });
- String notStrict = (String)AccessController.doPrivileged(new PrivilegedAction()
- {
- public Object run()
- {
- return System.getProperty(NOT_STRICT_LENGTH_ENABLED_PROPERTY);
- }
- });
-
- if (notStrict != null)
- {
- return !notStrict.equals("true");
+ return false;
}
- return strict == null || strict.equals("true");
+ return !Properties.isOverrideSetTo(STRICT_LENGTH_ENABLED_PROPERTY, false);
}
public AsymmetricBlockCipher getUnderlyingCipher()
@@ -271,7 +254,7 @@ public class PKCS1Encoding
* Now the padding check, check for no 0 byte in the padding
*/
int plen = encoded.length - (
- pLen /* Lenght of the PMS */
+ pLen /* Length of the PMS */
+ 1 /* Final 0-byte before PMS */
);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESEngine.java
index 77186efd..8c9e2ddf 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESEngine.java
@@ -12,7 +12,7 @@ import com.android.org.bouncycastle.util.Pack;
/**
* an implementation of the AES (Rijndael), from FIPS-197.
* <p>
- * For further details see: <a href="http://csrc.nist.gov/encryption/aes/">http://csrc.nist.gov/encryption/aes/</a>.
+ * For further details see: <a href="https://csrc.nist.gov/encryption/aes/">https://csrc.nist.gov/encryption/aes/</a>.
*
* This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at
* <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
@@ -298,98 +298,97 @@ private static final int[] Tinv0 =
{
case 4:
{
- int t0 = Pack.littleEndianToInt(key, 0); W[0][0] = t0;
- int t1 = Pack.littleEndianToInt(key, 4); W[0][1] = t1;
- int t2 = Pack.littleEndianToInt(key, 8); W[0][2] = t2;
- int t3 = Pack.littleEndianToInt(key, 12); W[0][3] = t3;
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
for (int i = 1; i <= 10; ++i)
{
- int u = subWord(shift(t3, 8)) ^ rcon[i - 1];
- t0 ^= u; W[i][0] = t0;
- t1 ^= t0; W[i][1] = t1;
- t2 ^= t1; W[i][2] = t2;
- t3 ^= t2; W[i][3] = t3;
+ int colx = subWord(shift(col3, 8)) ^ rcon[i - 1];
+ col0 ^= colx; W[i][0] = col0;
+ col1 ^= col0; W[i][1] = col1;
+ col2 ^= col1; W[i][2] = col2;
+ col3 ^= col2; W[i][3] = col3;
}
break;
}
case 6:
{
- int t0 = Pack.littleEndianToInt(key, 0); W[0][0] = t0;
- int t1 = Pack.littleEndianToInt(key, 4); W[0][1] = t1;
- int t2 = Pack.littleEndianToInt(key, 8); W[0][2] = t2;
- int t3 = Pack.littleEndianToInt(key, 12); W[0][3] = t3;
- int t4 = Pack.littleEndianToInt(key, 16); W[1][0] = t4;
- int t5 = Pack.littleEndianToInt(key, 20); W[1][1] = t5;
-
- int rcon = 1;
- int u = subWord(shift(t5, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[1][2] = t0;
- t1 ^= t0; W[1][3] = t1;
- t2 ^= t1; W[2][0] = t2;
- t3 ^= t2; W[2][1] = t3;
- t4 ^= t3; W[2][2] = t4;
- t5 ^= t4; W[2][3] = t5;
-
- for (int i = 3; i < 12; i += 3)
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
+
+ int col4 = Pack.littleEndianToInt(key, 16);
+ int col5 = Pack.littleEndianToInt(key, 20);
+
+ int i = 1, rcon = 1, colx;
+ for (;;)
{
- u = subWord(shift(t5, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[i ][0] = t0;
- t1 ^= t0; W[i ][1] = t1;
- t2 ^= t1; W[i ][2] = t2;
- t3 ^= t2; W[i ][3] = t3;
- t4 ^= t3; W[i + 1][0] = t4;
- t5 ^= t4; W[i + 1][1] = t5;
- u = subWord(shift(t5, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[i + 1][2] = t0;
- t1 ^= t0; W[i + 1][3] = t1;
- t2 ^= t1; W[i + 2][0] = t2;
- t3 ^= t2; W[i + 2][1] = t3;
- t4 ^= t3; W[i + 2][2] = t4;
- t5 ^= t4; W[i + 2][3] = t5;
- }
+ W[i ][0] = col4;
+ W[i ][1] = col5;
+ colx = subWord(shift(col5, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i ][2] = col0;
+ col1 ^= col0; W[i ][3] = col1;
+
+ col2 ^= col1; W[i + 1][0] = col2;
+ col3 ^= col2; W[i + 1][1] = col3;
+ col4 ^= col3; W[i + 1][2] = col4;
+ col5 ^= col4; W[i + 1][3] = col5;
+
+ colx = subWord(shift(col5, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i + 2][0] = col0;
+ col1 ^= col0; W[i + 2][1] = col1;
+ col2 ^= col1; W[i + 2][2] = col2;
+ col3 ^= col2; W[i + 2][3] = col3;
+
+ if ((i += 3) >= 13)
+ {
+ break;
+ }
- u = subWord(shift(t5, 8)) ^ rcon;
- t0 ^= u; W[12][0] = t0;
- t1 ^= t0; W[12][1] = t1;
- t2 ^= t1; W[12][2] = t2;
- t3 ^= t2; W[12][3] = t3;
+ col4 ^= col3;
+ col5 ^= col4;
+ }
break;
}
case 8:
{
- int t0 = Pack.littleEndianToInt(key, 0); W[0][0] = t0;
- int t1 = Pack.littleEndianToInt(key, 4); W[0][1] = t1;
- int t2 = Pack.littleEndianToInt(key, 8); W[0][2] = t2;
- int t3 = Pack.littleEndianToInt(key, 12); W[0][3] = t3;
- int t4 = Pack.littleEndianToInt(key, 16); W[1][0] = t4;
- int t5 = Pack.littleEndianToInt(key, 20); W[1][1] = t5;
- int t6 = Pack.littleEndianToInt(key, 24); W[1][2] = t6;
- int t7 = Pack.littleEndianToInt(key, 28); W[1][3] = t7;
-
- int u, rcon = 1;
-
- for (int i = 2; i < 14; i += 2)
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
+
+ int col4 = Pack.littleEndianToInt(key, 16); W[1][0] = col4;
+ int col5 = Pack.littleEndianToInt(key, 20); W[1][1] = col5;
+ int col6 = Pack.littleEndianToInt(key, 24); W[1][2] = col6;
+ int col7 = Pack.littleEndianToInt(key, 28); W[1][3] = col7;
+
+ int i = 2, rcon = 1, colx;
+ for (;;)
{
- u = subWord(shift(t7, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[i ][0] = t0;
- t1 ^= t0; W[i ][1] = t1;
- t2 ^= t1; W[i ][2] = t2;
- t3 ^= t2; W[i ][3] = t3;
- u = subWord(t3);
- t4 ^= u; W[i + 1][0] = t4;
- t5 ^= t4; W[i + 1][1] = t5;
- t6 ^= t5; W[i + 1][2] = t6;
- t7 ^= t6; W[i + 1][3] = t7;
- }
+ colx = subWord(shift(col7, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i][0] = col0;
+ col1 ^= col0; W[i][1] = col1;
+ col2 ^= col1; W[i][2] = col2;
+ col3 ^= col2; W[i][3] = col3;
+ ++i;
+
+ if (i >= 15)
+ {
+ break;
+ }
- u = subWord(shift(t7, 8)) ^ rcon;
- t0 ^= u; W[14][0] = t0;
- t1 ^= t0; W[14][1] = t1;
- t2 ^= t1; W[14][2] = t2;
- t3 ^= t2; W[14][3] = t3;
+ colx = subWord(col3);
+ col4 ^= colx; W[i][0] = col4;
+ col5 ^= col4; W[i][1] = col5;
+ col6 ^= col5; W[i][2] = col6;
+ col7 ^= col6; W[i][3] = col7;
+ ++i;
+ }
break;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESFastEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESFastEngine.java
index 4d657104..95ccb38c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESFastEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESFastEngine.java
@@ -11,7 +11,7 @@ import com.android.org.bouncycastle.util.Pack;
/**
* an implementation of the AES (Rijndael), from FIPS-197.
* <p>
- * For further details see: <a href="http://csrc.nist.gov/encryption/aes/">http://csrc.nist.gov/encryption/aes/</a>.
+ * For further details see: <a href="https://csrc.nist.gov/encryption/aes/">https://csrc.nist.gov/encryption/aes/</a>.
*
* This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at
* <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
@@ -627,98 +627,97 @@ public class AESFastEngine
{
case 4:
{
- int t0 = Pack.littleEndianToInt(key, 0); W[0][0] = t0;
- int t1 = Pack.littleEndianToInt(key, 4); W[0][1] = t1;
- int t2 = Pack.littleEndianToInt(key, 8); W[0][2] = t2;
- int t3 = Pack.littleEndianToInt(key, 12); W[0][3] = t3;
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
for (int i = 1; i <= 10; ++i)
{
- int u = subWord(shift(t3, 8)) ^ rcon[i - 1];
- t0 ^= u; W[i][0] = t0;
- t1 ^= t0; W[i][1] = t1;
- t2 ^= t1; W[i][2] = t2;
- t3 ^= t2; W[i][3] = t3;
+ int colx = subWord(shift(col3, 8)) ^ rcon[i - 1];
+ col0 ^= colx; W[i][0] = col0;
+ col1 ^= col0; W[i][1] = col1;
+ col2 ^= col1; W[i][2] = col2;
+ col3 ^= col2; W[i][3] = col3;
}
break;
}
case 6:
{
- int t0 = Pack.littleEndianToInt(key, 0); W[0][0] = t0;
- int t1 = Pack.littleEndianToInt(key, 4); W[0][1] = t1;
- int t2 = Pack.littleEndianToInt(key, 8); W[0][2] = t2;
- int t3 = Pack.littleEndianToInt(key, 12); W[0][3] = t3;
- int t4 = Pack.littleEndianToInt(key, 16); W[1][0] = t4;
- int t5 = Pack.littleEndianToInt(key, 20); W[1][1] = t5;
-
- int rcon = 1;
- int u = subWord(shift(t5, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[1][2] = t0;
- t1 ^= t0; W[1][3] = t1;
- t2 ^= t1; W[2][0] = t2;
- t3 ^= t2; W[2][1] = t3;
- t4 ^= t3; W[2][2] = t4;
- t5 ^= t4; W[2][3] = t5;
-
- for (int i = 3; i < 12; i += 3)
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
+
+ int col4 = Pack.littleEndianToInt(key, 16);
+ int col5 = Pack.littleEndianToInt(key, 20);
+
+ int i = 1, rcon = 1, colx;
+ for (;;)
{
- u = subWord(shift(t5, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[i ][0] = t0;
- t1 ^= t0; W[i ][1] = t1;
- t2 ^= t1; W[i ][2] = t2;
- t3 ^= t2; W[i ][3] = t3;
- t4 ^= t3; W[i + 1][0] = t4;
- t5 ^= t4; W[i + 1][1] = t5;
- u = subWord(shift(t5, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[i + 1][2] = t0;
- t1 ^= t0; W[i + 1][3] = t1;
- t2 ^= t1; W[i + 2][0] = t2;
- t3 ^= t2; W[i + 2][1] = t3;
- t4 ^= t3; W[i + 2][2] = t4;
- t5 ^= t4; W[i + 2][3] = t5;
- }
+ W[i ][0] = col4;
+ W[i ][1] = col5;
+ colx = subWord(shift(col5, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i ][2] = col0;
+ col1 ^= col0; W[i ][3] = col1;
+
+ col2 ^= col1; W[i + 1][0] = col2;
+ col3 ^= col2; W[i + 1][1] = col3;
+ col4 ^= col3; W[i + 1][2] = col4;
+ col5 ^= col4; W[i + 1][3] = col5;
+
+ colx = subWord(shift(col5, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i + 2][0] = col0;
+ col1 ^= col0; W[i + 2][1] = col1;
+ col2 ^= col1; W[i + 2][2] = col2;
+ col3 ^= col2; W[i + 2][3] = col3;
+
+ if ((i += 3) >= 13)
+ {
+ break;
+ }
- u = subWord(shift(t5, 8)) ^ rcon;
- t0 ^= u; W[12][0] = t0;
- t1 ^= t0; W[12][1] = t1;
- t2 ^= t1; W[12][2] = t2;
- t3 ^= t2; W[12][3] = t3;
+ col4 ^= col3;
+ col5 ^= col4;
+ }
break;
}
case 8:
{
- int t0 = Pack.littleEndianToInt(key, 0); W[0][0] = t0;
- int t1 = Pack.littleEndianToInt(key, 4); W[0][1] = t1;
- int t2 = Pack.littleEndianToInt(key, 8); W[0][2] = t2;
- int t3 = Pack.littleEndianToInt(key, 12); W[0][3] = t3;
- int t4 = Pack.littleEndianToInt(key, 16); W[1][0] = t4;
- int t5 = Pack.littleEndianToInt(key, 20); W[1][1] = t5;
- int t6 = Pack.littleEndianToInt(key, 24); W[1][2] = t6;
- int t7 = Pack.littleEndianToInt(key, 28); W[1][3] = t7;
-
- int u, rcon = 1;
-
- for (int i = 2; i < 14; i += 2)
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
+
+ int col4 = Pack.littleEndianToInt(key, 16); W[1][0] = col4;
+ int col5 = Pack.littleEndianToInt(key, 20); W[1][1] = col5;
+ int col6 = Pack.littleEndianToInt(key, 24); W[1][2] = col6;
+ int col7 = Pack.littleEndianToInt(key, 28); W[1][3] = col7;
+
+ int i = 2, rcon = 1, colx;
+ for (;;)
{
- u = subWord(shift(t7, 8)) ^ rcon; rcon <<= 1;
- t0 ^= u; W[i ][0] = t0;
- t1 ^= t0; W[i ][1] = t1;
- t2 ^= t1; W[i ][2] = t2;
- t3 ^= t2; W[i ][3] = t3;
- u = subWord(t3);
- t4 ^= u; W[i + 1][0] = t4;
- t5 ^= t4; W[i + 1][1] = t5;
- t6 ^= t5; W[i + 1][2] = t6;
- t7 ^= t6; W[i + 1][3] = t7;
- }
+ colx = subWord(shift(col7, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i][0] = col0;
+ col1 ^= col0; W[i][1] = col1;
+ col2 ^= col1; W[i][2] = col2;
+ col3 ^= col2; W[i][3] = col3;
+ ++i;
+
+ if (i >= 15)
+ {
+ break;
+ }
- u = subWord(shift(t7, 8)) ^ rcon;
- t0 ^= u; W[14][0] = t0;
- t1 ^= t0; W[14][1] = t1;
- t2 ^= t1; W[14][2] = t2;
- t3 ^= t2; W[14][3] = t3;
+ colx = subWord(col3);
+ col4 ^= colx; W[i][0] = col4;
+ col5 ^= col4; W[i][1] = col5;
+ col6 ^= col5; W[i][2] = col6;
+ col7 ^= col6; W[i][3] = col7;
+ ++i;
+ }
break;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESWrapEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESWrapEngine.java
index 18c85b68..00690c1d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESWrapEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/AESWrapEngine.java
@@ -5,7 +5,7 @@ package com.android.org.bouncycastle.crypto.engines;
* an implementation of the AES Key Wrapper from the NIST Key Wrap
* Specification.
* <p>
- * For further details see: <a href="http://csrc.nist.gov/encryption/kms/key-wrap.pdf">http://csrc.nist.gov/encryption/kms/key-wrap.pdf</a>.
+ * For further details see: <a href="https://csrc.nist.gov/encryption/kms/key-wrap.pdf">https://csrc.nist.gov/encryption/kms/key-wrap.pdf</a>.
* @hide This class is not part of the Android public SDK API
*/
public class AESWrapEngine
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/BlowfishEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/BlowfishEngine.java
index 860aa806..2979a61c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/BlowfishEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/BlowfishEngine.java
@@ -422,8 +422,9 @@ implements BlockCipher
xr ^= P[ROUNDS + 1];
+ // suppress LGTM warnings index-out-of-bounds since the loop increments s by 2
table[s] = xr;
- table[s + 1] = xl;
+ table[s + 1] = xl; // lgtm [java/index-out-of-bounds]
xr = xl; // end of cycle swap
xl = table[s];
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESedeWrapEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
index f9b3de75..d1c05ce1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
@@ -311,7 +311,7 @@ public class DESedeWrapEngine
* - Compute the 20 octet SHA-1 hash on the key being wrapped.
* - Use the first 8 octets of this hash as the checksum value.
*
- * For details see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum.
+ * For details see https://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum.
*
* @param key the key to check,
* @return the CMS checksum.
@@ -331,7 +331,7 @@ public class DESedeWrapEngine
}
/**
- * For details see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum
+ * For details see https://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum
*
* @param key key to be validated.
* @param checksum the checksum.
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
index b014a526..f1f96840 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
@@ -15,8 +15,8 @@ import com.android.org.bouncycastle.util.Arrays;
* an implementation of the AES Key Wrapper from the NIST Key Wrap
* Specification as described in RFC 3394.
* <p>
- * For further details see: <a href="http://www.ietf.org/rfc/rfc3394.txt">http://www.ietf.org/rfc/rfc3394.txt</a>
- * and <a href="http://csrc.nist.gov/encryption/kms/key-wrap.pdf">http://csrc.nist.gov/encryption/kms/key-wrap.pdf</a>.
+ * For further details see: <a href="https://www.ietf.org/rfc/rfc3394.txt">https://www.ietf.org/rfc/rfc3394.txt</a>
+ * and <a href="https://csrc.nist.gov/encryption/kms/key-wrap.pdf">https://csrc.nist.gov/encryption/kms/key-wrap.pdf</a>.
* @hide This class is not part of the Android public SDK API
*/
public class RFC3394WrapEngine
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RSABlindedEngine.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RSABlindedEngine.java
index 3e89d400..2ff1b4fe 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RSABlindedEngine.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/engines/RSABlindedEngine.java
@@ -40,15 +40,31 @@ public class RSABlindedEngine
if (param instanceof ParametersWithRandom)
{
- ParametersWithRandom rParam = (ParametersWithRandom)param;
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
- key = (RSAKeyParameters)rParam.getParameters();
- random = rParam.getRandom();
+ this.key = (RSAKeyParameters)rParam.getParameters();
+
+ if (key instanceof RSAPrivateCrtKeyParameters)
+ {
+ this.random = rParam.getRandom();
+ }
+ else
+ {
+ this.random = null;
+ }
}
else
{
- key = (RSAKeyParameters)param;
- random = CryptoServicesRegistrar.getSecureRandom();
+ this.key = (RSAKeyParameters)param;
+
+ if (key instanceof RSAPrivateCrtKeyParameters)
+ {
+ this.random = CryptoServicesRegistrar.getSecureRandom();
+ }
+ else
+ {
+ this.random = null;
+ }
}
}
@@ -111,7 +127,7 @@ public class RSABlindedEngine
BigInteger blindedInput = r.modPow(e, m).multiply(input).mod(m);
BigInteger blindedResult = core.processBlock(blindedInput);
- BigInteger rInv = r.modInverse(m);
+ BigInteger rInv = BigIntegers.modOddInverse(m, r);
result = blindedResult.multiply(rInv).mod(m);
// defence against Arjen Lenstra’s CRT attack
if (!input.equals(result.modPow(e, m)))
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DSAParametersGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
index 675d1414..f69803e5 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
@@ -359,7 +359,7 @@ public class DSAParametersGenerator
{
// A.2.3 Verifiable Canonical Generation of the Generator g
BigInteger e = p.subtract(ONE).divide(q);
- byte[] ggen = Hex.decode("6767656E");
+ byte[] ggen = Hex.decodeStrict("6767656E");
// 7. U = domain_parameter_seed || "ggen" || index || count.
byte[] U = new byte[seed.length + ggen.length + 1 + 2];
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
index bd5be97c..6779b854 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
@@ -6,7 +6,6 @@ import java.security.SecureRandom;
import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
-import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.KeyGenerationParameters;
import com.android.org.bouncycastle.crypto.params.ECDomainParameters;
import com.android.org.bouncycastle.crypto.params.ECKeyGenerationParameters;
@@ -35,11 +34,6 @@ public class ECKeyPairGenerator
this.random = ecP.getRandom();
this.params = ecP.getDomainParameters();
-
- if (this.random == null)
- {
- this.random = CryptoServicesRegistrar.getSecureRandom();
- }
}
/**
@@ -57,7 +51,7 @@ public class ECKeyPairGenerator
{
d = BigIntegers.createRandomBigInteger(nBitLength, random);
- if (d.compareTo(TWO) < 0 || (d.compareTo(n) >= 0))
+ if (d.compareTo(ONE) < 0 || (d.compareTo(n) >= 0))
{
continue;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
index 7419815a..116aa7d4 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
@@ -18,7 +18,6 @@ import com.android.org.bouncycastle.crypto.digests.AndroidDigestFactory;
* <p>
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class OpenSSLPBEParametersGenerator
extends PBEParametersGenerator
{
@@ -29,7 +28,6 @@ public class OpenSSLPBEParametersGenerator
/**
* Construct a OpenSSL Parameters generator.
*/
- @libcore.api.CorePlatformApi
public OpenSSLPBEParametersGenerator()
{
}
@@ -40,7 +38,6 @@ public class OpenSSLPBEParametersGenerator
* @param password password to use.
* @param salt salt to use.
*/
- @libcore.api.CorePlatformApi
public void init(
byte[] password,
byte[] salt)
@@ -92,7 +89,6 @@ public class OpenSSLPBEParametersGenerator
* @return a KeyParameter object.
* @exception IllegalArgumentException if the key length larger than the base hash size.
*/
- @libcore.api.CorePlatformApi
public CipherParameters generateDerivedParameters(
int keySize)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java
index 9177b217..76dc31c0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java
@@ -12,7 +12,7 @@ import com.android.org.bouncycastle.crypto.params.ParametersWithIV;
* Generator for PBE derived keys and ivs as defined by PKCS 12 V1.0.
* <p>
* The document this implementation is based on can be found at
- * <a href=http://www.rsasecurity.com/rsalabs/pkcs/pkcs-12/index.html>
+ * <a href=https://www.rsasecurity.com/rsalabs/pkcs/pkcs-12/index.html>
* RSA's PKCS12 Page</a>
* @hide This class is not part of the Android public SDK API
*/
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java
index d4250741..0076cc01 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java
@@ -13,7 +13,7 @@ import com.android.org.bouncycastle.crypto.params.ParametersWithIV;
* digest used to drive it.
* <p>
* The document this implementation is based on can be found at
- * <a href=http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html>
+ * <a href=https://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html>
* RSA's PKCS5 Page</a>
* @hide This class is not part of the Android public SDK API
*/
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
index 62712be8..6eeb75a8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
@@ -18,7 +18,7 @@ import com.android.org.bouncycastle.util.Arrays;
* This generator uses a SHA-1 HMac as the calculation function.
* <p>
* The document this implementation is based on can be found at
- * <a href=http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html>
+ * <a href=https://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html>
* RSA's PKCS5 Page</a>
* @hide This class is not part of the Android public SDK API
*/
@@ -119,7 +119,7 @@ public class PKCS5S2ParametersGenerator
{
keySize = keySize / 8;
- byte[] dKey = Arrays.copyOfRange(generateDerivedKey(keySize), 0, keySize);
+ byte[] dKey = generateDerivedKey(keySize);
return new KeyParameter(dKey, 0, keySize);
}
@@ -140,7 +140,7 @@ public class PKCS5S2ParametersGenerator
keySize = keySize / 8;
ivSize = ivSize / 8;
- byte[] dKey = generateDerivedKey(keySize + ivSize);
+ byte[] dKey = generateDerivedKey(keySize + ivSize);
return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
index ebe11162..fa7aea22 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
@@ -141,7 +141,7 @@ public class RSAKeyPairGenerator
dP = d.remainder(pSub1);
dQ = d.remainder(qSub1);
- qInv = q.modInverse(p);
+ qInv = BigIntegers.modOddInverse(p, q);
result = new AsymmetricCipherKeyPair(
new RSAKeyParameters(false, n, e),
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/AEADBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/AEADBlockCipher.java
index f5a61793..da310c24 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/AEADBlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/AEADBlockCipher.java
@@ -2,147 +2,18 @@
package com.android.org.bouncycastle.crypto.modes;
import com.android.org.bouncycastle.crypto.BlockCipher;
-import com.android.org.bouncycastle.crypto.CipherParameters;
-import com.android.org.bouncycastle.crypto.DataLengthException;
-import com.android.org.bouncycastle.crypto.InvalidCipherTextException;
/**
- * A block cipher mode that includes authenticated encryption with a streaming mode and optional associated data.
- * <p>
- * Implementations of this interface may operate in a packet mode (where all input data is buffered and
- * processed dugin the call to {@link #doFinal(byte[], int)}), or in a streaming mode (where output data is
- * incrementally produced with each call to {@link #processByte(byte, byte[], int)} or
- * {@link #processBytes(byte[], int, int, byte[], int)}.
- * </p>
- * This is important to consider during decryption: in a streaming mode, unauthenticated plaintext data
- * may be output prior to the call to {@link #doFinal(byte[], int)} that results in an authentication
- * failure. The higher level protocol utilising this cipher must ensure the plaintext data is handled
- * appropriately until the end of data is reached and the entire ciphertext is authenticated.
- * @see com.android.org.bouncycastle.crypto.params.AEADParameters
+ * An {@link AEADCipher} based on a {@link BlockCipher}.
* @hide This class is not part of the Android public SDK API
*/
public interface AEADBlockCipher
+ extends AEADCipher
{
/**
- * initialise the underlying cipher. Parameter can either be an AEADParameters or a ParametersWithIV object.
+ * return the {@link BlockCipher} this object wraps.
*
- * @param forEncryption true if we are setting up for encryption, false otherwise.
- * @param params the necessary parameters for the underlying cipher to be initialised.
- * @exception IllegalArgumentException if the params argument is inappropriate.
- */
- public void init(boolean forEncryption, CipherParameters params)
- throws IllegalArgumentException;
-
- /**
- * Return the name of the algorithm.
- *
- * @return the algorithm name.
- */
- public String getAlgorithmName();
-
- /**
- * return the cipher this object wraps.
- *
- * @return the cipher this object wraps.
+ * @return the {@link BlockCipher} this object wraps.
*/
public BlockCipher getUnderlyingCipher();
-
- /**
- * Add a single byte to the associated data check.
- * <br>If the implementation supports it, this will be an online operation and will not retain the associated data.
- *
- * @param in the byte to be processed.
- */
- public void processAADByte(byte in);
-
- /**
- * Add a sequence of bytes to the associated data check.
- * <br>If the implementation supports it, this will be an online operation and will not retain the associated data.
- *
- * @param in the input byte array.
- * @param inOff the offset into the in array where the data to be processed starts.
- * @param len the number of bytes to be processed.
- */
- public void processAADBytes(byte[] in, int inOff, int len);
-
- /**
- * encrypt/decrypt a single byte.
- *
- * @param in the byte to be processed.
- * @param out the output buffer the processed byte goes into.
- * @param outOff the offset into the output byte array the processed data starts at.
- * @return the number of bytes written to out.
- * @exception DataLengthException if the output buffer is too small.
- */
- public int processByte(byte in, byte[] out, int outOff)
- throws DataLengthException;
-
- /**
- * process a block of bytes from in putting the result into out.
- *
- * @param in the input byte array.
- * @param inOff the offset into the in array where the data to be processed starts.
- * @param len the number of bytes to be processed.
- * @param out the output buffer the processed bytes go into.
- * @param outOff the offset into the output byte array the processed data starts at.
- * @return the number of bytes written to out.
- * @exception DataLengthException if the output buffer is too small.
- */
- public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
- throws DataLengthException;
-
- /**
- * Finish the operation either appending or verifying the MAC at the end of the data.
- *
- * @param out space for any resulting output data.
- * @param outOff offset into out to start copying the data at.
- * @return number of bytes written into out.
- * @throws IllegalStateException if the cipher is in an inappropriate state.
- * @throws com.android.org.bouncycastle.crypto.InvalidCipherTextException if the MAC fails to match.
- */
- public int doFinal(byte[] out, int outOff)
- throws IllegalStateException, InvalidCipherTextException;
-
- /**
- * Return the value of the MAC associated with the last stream processed.
- *
- * @return MAC for plaintext data.
- */
- public byte[] getMac();
-
- /**
- * return the size of the output buffer required for a processBytes
- * an input of len bytes.
- * <p>
- * The returned size may be dependent on the initialisation of this cipher
- * and may not be accurate once subsequent input data is processed - this method
- * should be invoked immediately prior to input data being processed.
- * </p>
- *
- * @param len the length of the input.
- * @return the space required to accommodate a call to processBytes
- * with len bytes of input.
- */
- public int getUpdateOutputSize(int len);
-
- /**
- * return the size of the output buffer required for a processBytes plus a
- * doFinal with an input of len bytes.
- * <p>
- * The returned size may be dependent on the initialisation of this cipher
- * and may not be accurate once subsequent input data is processed - this method
- * should be invoked immediately prior to a call to final processing of input data
- * and a call to {@link #doFinal(byte[], int)}.
- * </p>
- * @param len the length of the input.
- * @return the space required to accommodate a call to processBytes and doFinal
- * with len bytes of input.
- */
- public int getOutputSize(int len);
-
- /**
- * Reset the cipher. After resetting the cipher is in the same state
- * as it was after the last init (if there was one).
- */
- public void reset();
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/AEADCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/AEADCipher.java
new file mode 100644
index 00000000..71eeb292
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/AEADCipher.java
@@ -0,0 +1,140 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.modes;
+
+import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.DataLengthException;
+import com.android.org.bouncycastle.crypto.InvalidCipherTextException;
+
+/**
+ * A cipher mode that includes authenticated encryption with a streaming mode and optional associated data.
+ * <p>
+ * Implementations of this interface may operate in a packet mode (where all input data is buffered and
+ * processed during the call to {@link #doFinal(byte[], int)}), or in a streaming mode (where output data is
+ * incrementally produced with each call to {@link #processByte(byte, byte[], int)} or
+ * {@link #processBytes(byte[], int, int, byte[], int)}.
+ * </p>
+ * This is important to consider during decryption: in a streaming mode, unauthenticated plaintext data
+ * may be output prior to the call to {@link #doFinal(byte[], int)} that results in an authentication
+ * failure. The higher level protocol utilising this cipher must ensure the plaintext data is handled
+ * appropriately until the end of data is reached and the entire ciphertext is authenticated.
+ * @see com.android.org.bouncycastle.crypto.params.AEADParameters
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface AEADCipher
+{
+ /**
+ * initialise the underlying cipher. Parameter can either be an AEADParameters or a ParametersWithIV object.
+ *
+ * @param forEncryption true if we are setting up for encryption, false otherwise.
+ * @param params the necessary parameters for the underlying cipher to be initialised.
+ * @exception IllegalArgumentException if the params argument is inappropriate.
+ */
+ public void init(boolean forEncryption, CipherParameters params)
+ throws IllegalArgumentException;
+
+ /**
+ * Return the name of the algorithm.
+ *
+ * @return the algorithm name.
+ */
+ public String getAlgorithmName();
+
+ /**
+ * Add a single byte to the associated data check.
+ * <br>If the implementation supports it, this will be an online operation and will not retain the associated data.
+ *
+ * @param in the byte to be processed.
+ */
+ public void processAADByte(byte in);
+
+ /**
+ * Add a sequence of bytes to the associated data check.
+ * <br>If the implementation supports it, this will be an online operation and will not retain the associated data.
+ *
+ * @param in the input byte array.
+ * @param inOff the offset into the in array where the data to be processed starts.
+ * @param len the number of bytes to be processed.
+ */
+ public void processAADBytes(byte[] in, int inOff, int len);
+
+ /**
+ * encrypt/decrypt a single byte.
+ *
+ * @param in the byte to be processed.
+ * @param out the output buffer the processed byte goes into.
+ * @param outOff the offset into the output byte array the processed data starts at.
+ * @return the number of bytes written to out.
+ * @exception DataLengthException if the output buffer is too small.
+ */
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException;
+
+ /**
+ * process a block of bytes from in putting the result into out.
+ *
+ * @param in the input byte array.
+ * @param inOff the offset into the in array where the data to be processed starts.
+ * @param len the number of bytes to be processed.
+ * @param out the output buffer the processed bytes go into.
+ * @param outOff the offset into the output byte array the processed data starts at.
+ * @return the number of bytes written to out.
+ * @exception DataLengthException if the output buffer is too small.
+ */
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException;
+
+ /**
+ * Finish the operation either appending or verifying the MAC at the end of the data.
+ *
+ * @param out space for any resulting output data.
+ * @param outOff offset into out to start copying the data at.
+ * @return number of bytes written into out.
+ * @throws IllegalStateException if the cipher is in an inappropriate state.
+ * @throws com.android.org.bouncycastle.crypto.InvalidCipherTextException if the MAC fails to match.
+ */
+ public int doFinal(byte[] out, int outOff)
+ throws IllegalStateException, InvalidCipherTextException;
+
+ /**
+ * Return the value of the MAC associated with the last stream processed.
+ *
+ * @return MAC for plaintext data.
+ */
+ public byte[] getMac();
+
+ /**
+ * return the size of the output buffer required for a processBytes
+ * an input of len bytes.
+ * <p>
+ * The returned size may be dependent on the initialisation of this cipher
+ * and may not be accurate once subsequent input data is processed - this method
+ * should be invoked immediately prior to input data being processed.
+ * </p>
+ *
+ * @param len the length of the input.
+ * @return the space required to accommodate a call to processBytes
+ * with len bytes of input.
+ */
+ public int getUpdateOutputSize(int len);
+
+ /**
+ * return the size of the output buffer required for a processBytes plus a
+ * doFinal with an input of len bytes.
+ * <p>
+ * The returned size may be dependent on the initialisation of this cipher
+ * and may not be accurate once subsequent input data is processed - this method
+ * should be invoked immediately prior to a call to final processing of input data
+ * and a call to {@link #doFinal(byte[], int)}.
+ * </p>
+ * @param len the length of the input.
+ * @return the space required to accommodate a call to processBytes and doFinal
+ * with len bytes of input.
+ */
+ public int getOutputSize(int len);
+
+ /**
+ * Reset the cipher. After resetting the cipher is in the same state
+ * as it was after the last init (if there was one).
+ */
+ public void reset();
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CCMBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CCMBlockCipher.java
index 9a74fc3a..7bd69d20 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CCMBlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CCMBlockCipher.java
@@ -75,7 +75,7 @@ public class CCMBlockCipher
nonce = param.getNonce();
initialAssociatedText = param.getAssociatedText();
- macSize = param.getMacSize() / 8;
+ macSize = getMacSize(forEncryption, param.getMacSize());
cipherParameters = param.getKey();
}
else if (params instanceof ParametersWithIV)
@@ -84,7 +84,7 @@ public class CCMBlockCipher
nonce = param.getIV();
initialAssociatedText = null;
- macSize = macBlock.length / 2;
+ macSize = getMacSize(forEncryption, 64);
cipherParameters = param.getParameters();
}
else
@@ -436,6 +436,16 @@ public class CCMBlockCipher
return cMac.doFinal(macBlock, 0);
}
+ private int getMacSize(boolean forEncryption, int requestedMacBits)
+ {
+ if (forEncryption && (requestedMacBits < 32 || requestedMacBits > 128 || 0 != (requestedMacBits & 15)))
+ {
+ throw new IllegalArgumentException("tag length in octets must be one of {4,6,8,10,12,14,16}");
+ }
+
+ return requestedMacBits >>> 3;
+ }
+
private int getAssociatedTextLength()
{
return associatedText.size() + ((initialAssociatedText == null) ? 0 : initialAssociatedText.length);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CFBBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CFBBlockCipher.java
index 276b154b..341ef89d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CFBBlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/CFBBlockCipher.java
@@ -38,6 +38,11 @@ public class CFBBlockCipher
{
super(cipher);
+ if (bitBlockSize > (cipher.getBlockSize() * 8) || bitBlockSize < 8 || bitBlockSize % 8 != 0)
+ {
+ throw new IllegalArgumentException("CFB" + bitBlockSize + " not supported");
+ }
+
this.cipher = cipher;
this.blockSize = bitBlockSize / 8;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/OFBBlockCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/OFBBlockCipher.java
index 311442d8..dc5f0a00 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/OFBBlockCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/OFBBlockCipher.java
@@ -27,16 +27,21 @@ public class OFBBlockCipher
*
* @param cipher the block cipher to be used as the basis of the
* feedback mode.
- * @param blockSize the block size in bits (note: a multiple of 8)
+ * @param bitBlockSize the block size in bits (note: a multiple of 8)
*/
public OFBBlockCipher(
BlockCipher cipher,
- int blockSize)
+ int bitBlockSize)
{
super(cipher);
+ if (bitBlockSize > (cipher.getBlockSize() * 8) || bitBlockSize < 8 || bitBlockSize % 8 != 0)
+ {
+ throw new IllegalArgumentException("0FB" + bitBlockSize + " not supported");
+ }
+
this.cipher = cipher;
- this.blockSize = blockSize / 8;
+ this.blockSize = bitBlockSize / 8;
this.IV = new byte[cipher.getBlockSize()];
this.ofbV = new byte[cipher.getBlockSize()];
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/GCMUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
index 36c74dda..e56c31e9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
@@ -2,6 +2,7 @@
package com.android.org.bouncycastle.crypto.modes.gcm;
import com.android.org.bouncycastle.math.raw.Interleave;
+import com.android.org.bouncycastle.util.Longs;
import com.android.org.bouncycastle.util.Pack;
/**
@@ -144,24 +145,58 @@ public abstract class GCMUtil
public static void multiply(long[] x, long[] y)
{
+// long x0 = x[0], x1 = x[1];
+// long y0 = y[0], y1 = y[1];
+// long z0 = 0, z1 = 0, z2 = 0;
+//
+// for (int j = 0; j < 64; ++j)
+// {
+// long m0 = x0 >> 63; x0 <<= 1;
+// z0 ^= (y0 & m0);
+// z1 ^= (y1 & m0);
+//
+// long m1 = x1 >> 63; x1 <<= 1;
+// z1 ^= (y0 & m1);
+// z2 ^= (y1 & m1);
+//
+// long c = (y1 << 63) >> 8;
+// y1 = (y1 >>> 1) | (y0 << 63);
+// y0 = (y0 >>> 1) ^ (c & E1L);
+// }
+//
+// z0 ^= z2 ^ (z2 >>> 1) ^ (z2 >>> 2) ^ (z2 >>> 7);
+// z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57);
+//
+// x[0] = z0;
+// x[1] = z1;
+
+ /*
+ * "Three-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein.
+ *
+ * Without access to the high part of a 64x64 product x * y, we use a bit reversal to calculate it:
+ * rev(x) * rev(y) == rev((x * y) << 1)
+ */
+
long x0 = x[0], x1 = x[1];
long y0 = y[0], y1 = y[1];
- long z0 = 0, z1 = 0, z2 = 0;
+ long x0r = Longs.reverse(x0), x1r = Longs.reverse(x1);
+ long y0r = Longs.reverse(y0), y1r = Longs.reverse(y1);
- for (int j = 0; j < 64; ++j)
- {
- long m0 = x0 >> 63; x0 <<= 1;
- z0 ^= (y0 & m0);
- z1 ^= (y1 & m0);
+ long h0 = Longs.reverse(implMul64(x0r, y0r));
+ long h1 = implMul64(x0, y0) << 1;
+ long h2 = Longs.reverse(implMul64(x1r, y1r));
+ long h3 = implMul64(x1, y1) << 1;
+ long h4 = Longs.reverse(implMul64(x0r ^ x1r, y0r ^ y1r));
+ long h5 = implMul64(x0 ^ x1, y0 ^ y1) << 1;
- long m1 = x1 >> 63; x1 <<= 1;
- z1 ^= (y0 & m1);
- z2 ^= (y1 & m1);
+ long z0 = h0;
+ long z1 = h1 ^ h0 ^ h2 ^ h4;
+ long z2 = h2 ^ h1 ^ h3 ^ h5;
+ long z3 = h3;
- long c = (y1 << 63) >> 8;
- y1 = (y1 >>> 1) | (y0 << 63);
- y0 = (y0 >>> 1) ^ (c & E1L);
- }
+ z1 ^= z3 ^ (z3 >>> 1) ^ (z3 >>> 2) ^ (z3 >>> 7);
+// z2 ^= (z3 << 63) ^ (z3 << 62) ^ (z3 << 57);
+ z2 ^= (z3 << 62) ^ (z3 << 57);
z0 ^= z2 ^ (z2 >>> 1) ^ (z2 >>> 2) ^ (z2 >>> 7);
z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57);
@@ -386,4 +421,29 @@ public abstract class GCMUtil
z[0] = x[0] ^ y[0];
z[1] = x[1] ^ y[1];
}
+
+ private static long implMul64(long x, long y)
+ {
+ long x0 = x & 0x1111111111111111L;
+ long x1 = x & 0x2222222222222222L;
+ long x2 = x & 0x4444444444444444L;
+ long x3 = x & 0x8888888888888888L;
+
+ long y0 = y & 0x1111111111111111L;
+ long y1 = y & 0x2222222222222222L;
+ long y2 = y & 0x4444444444444444L;
+ long y3 = y & 0x8888888888888888L;
+
+ long z0 = (x0 * y0) ^ (x1 * y3) ^ (x2 * y2) ^ (x3 * y1);
+ long z1 = (x0 * y1) ^ (x1 * y0) ^ (x2 * y3) ^ (x3 * y2);
+ long z2 = (x0 * y2) ^ (x1 * y1) ^ (x2 * y0) ^ (x3 * y3);
+ long z3 = (x0 * y3) ^ (x1 * y2) ^ (x2 * y1) ^ (x3 * y0);
+
+ z0 &= 0x1111111111111111L;
+ z1 &= 0x2222222222222222L;
+ z2 &= 0x4444444444444444L;
+ z3 &= 0x8888888888888888L;
+
+ return z0 | z1 | z2 | z3;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
index 2820e57b..c7a7b630 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
@@ -23,14 +23,7 @@ public class ISO10126d2Padding
public void init(SecureRandom random)
throws IllegalArgumentException
{
- if (random != null)
- {
- this.random = random;
- }
- else
- {
- this.random = CryptoServicesRegistrar.getSecureRandom();
- }
+ this.random = CryptoServicesRegistrar.getSecureRandom(random);
}
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DESParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DESParameters.java
index 60f610c9..9ce49ae3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DESParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DESParameters.java
@@ -56,7 +56,7 @@ public class DESParameters
* if the given DES key material is weak or semi-weak.
* Key material that is too short is regarded as weak.
* <p>
- * See <a href="http://www.counterpane.com/applied.html">"Applied
+ * See <a href="https://www.counterpane.com/applied.html">"Applied
* Cryptography"</a> by Bruce Schneier for more information.
*
* @return true if the given DES key material is weak or semi-weak,
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DHParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DHParameters.java
index 749c6d83..d2c8f148 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DHParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DHParameters.java
@@ -4,6 +4,7 @@ package com.android.org.bouncycastle.crypto.params;
import java.math.BigInteger;
import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.util.Properties;
/**
* @hide This class is not part of the Android public SDK API
@@ -98,7 +99,7 @@ public class DHParameters
}
}
- if (m > p.bitLength())
+ if (m > p.bitLength() && !Properties.isOverrideSet("com.android.org.bouncycastle.dh.allow_unsafe_p_value"))
{
throw new IllegalArgumentException("unsafe p value so small specific l required");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DHPublicKeyParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DHPublicKeyParameters.java
index 88378764..d5937091 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DHPublicKeyParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/DHPublicKeyParameters.java
@@ -3,6 +3,9 @@ package com.android.org.bouncycastle.crypto.params;
import java.math.BigInteger;
+import com.android.org.bouncycastle.math.raw.Nat;
+import com.android.org.bouncycastle.util.Integers;
+
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -30,25 +33,39 @@ public class DHPublicKeyParameters
throw new NullPointerException("y value cannot be null");
}
+ BigInteger p = dhParams.getP();
+
// TLS check
- if (y.compareTo(TWO) < 0 || y.compareTo(dhParams.getP().subtract(TWO)) > 0)
+ if (y.compareTo(TWO) < 0 || y.compareTo(p.subtract(TWO)) > 0)
{
throw new IllegalArgumentException("invalid DH public key");
}
- if (dhParams.getQ() != null)
+ BigInteger q = dhParams.getQ();
+ if (q == null)
{
- if (ONE.equals(y.modPow(dhParams.getQ(), dhParams.getP())))
+ return y; // we can't validate without Q.
+ }
+
+ if (p.testBit(0)
+ && p.bitLength() - 1 == q.bitLength()
+ && p.shiftRight(1).equals(q))
+ {
+ // Safe prime case
+ if (1 == legendre(y, p))
{
return y;
}
-
- throw new IllegalArgumentException("Y value does not appear to be in correct group");
}
else
{
- return y; // we can't validate without Q.
+ if (ONE.equals(y.modPow(q, p)))
+ {
+ return y;
+ }
}
+
+ throw new IllegalArgumentException("Y value does not appear to be in correct group");
}
public BigInteger getY()
@@ -73,4 +90,79 @@ public class DHPublicKeyParameters
return other.getY().equals(y) && super.equals(obj);
}
+
+ private static int legendre(BigInteger a, BigInteger b)
+ {
+// int r = 0, bits = b.intValue();
+//
+// for (;;)
+// {
+// int lowestSetBit = a.getLowestSetBit();
+// a = a.shiftRight(lowestSetBit);
+// r ^= (bits ^ (bits >>> 1)) & (lowestSetBit << 1);
+//
+// int cmp = a.compareTo(b);
+// if (cmp == 0)
+// {
+// break;
+// }
+//
+// if (cmp < 0)
+// {
+// BigInteger t = a; a = b; b = t;
+//
+// int oldBits = bits;
+// bits = b.intValue();
+// r ^= oldBits & bits;
+// }
+//
+// a = a.subtract(b);
+// }
+//
+// return ONE.equals(b) ? (1 - (r & 2)) : 0;
+
+ int bitLength = b.bitLength();
+ int[] A = Nat.fromBigInteger(bitLength, a);
+ int[] B = Nat.fromBigInteger(bitLength, b);
+
+ int r = 0;
+
+ int len = B.length;
+ for (;;)
+ {
+ while (A[0] == 0)
+ {
+ Nat.shiftDownWord(len, A, 0);
+ }
+
+ int shift = Integers.numberOfTrailingZeros(A[0]);
+ if (shift > 0)
+ {
+ Nat.shiftDownBits(len, A, shift, 0);
+ int bits = B[0];
+ r ^= (bits ^ (bits >>> 1)) & (shift << 1);
+ }
+
+ int cmp = Nat.compare(len, A, B);
+ if (cmp == 0)
+ {
+ break;
+ }
+
+ if (cmp < 0)
+ {
+ r ^= A[0] & B[0];
+ int[] t = A; A = B; B = t;
+ }
+
+ while (A[len - 1] == 0)
+ {
+ len = len - 1;
+ }
+
+ Nat.sub(len, A, B, A);
+ }
+
+ return Nat.isOne(len, B) ? (1 - (r & 2)) : 0;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECDomainParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECDomainParameters.java
index a3c5498a..fea650f0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECDomainParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECDomainParameters.java
@@ -3,11 +3,13 @@ package com.android.org.bouncycastle.crypto.params;
import java.math.BigInteger;
+import com.android.org.bouncycastle.asn1.x9.X9ECParameters;
import com.android.org.bouncycastle.math.ec.ECAlgorithms;
import com.android.org.bouncycastle.math.ec.ECConstants;
import com.android.org.bouncycastle.math.ec.ECCurve;
import com.android.org.bouncycastle.math.ec.ECPoint;
import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.BigIntegers;
/**
* @hide This class is not part of the Android public SDK API
@@ -15,13 +17,19 @@ import com.android.org.bouncycastle.util.Arrays;
public class ECDomainParameters
implements ECConstants
{
- private ECCurve curve;
- private byte[] seed;
- private ECPoint G;
- private BigInteger n;
- private BigInteger h;
+ private final ECCurve curve;
+ private final byte[] seed;
+ private final ECPoint G;
+ private final BigInteger n;
+ private final BigInteger h;
+
private BigInteger hInv = null;
+ public ECDomainParameters(X9ECParameters x9)
+ {
+ this(x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
+ }
+
public ECDomainParameters(
ECCurve curve,
ECPoint G,
@@ -57,7 +65,7 @@ public class ECDomainParameters
// we can't check for h == null here as h is optional in X9.62 as it is not required for ECDSA
this.curve = curve;
- this.G = validate(curve, G);
+ this.G = validatePublicPoint(curve, G);
this.n = n;
this.h = h;
this.seed = Arrays.clone(seed);
@@ -87,7 +95,7 @@ public class ECDomainParameters
{
if (hInv == null)
{
- hInv = h.modInverse(n);
+ hInv = BigIntegers.modOddInverseVar(n, h);
}
return hInv;
}
@@ -105,33 +113,56 @@ public class ECDomainParameters
return true;
}
- if ((obj instanceof ECDomainParameters))
+ if (!(obj instanceof ECDomainParameters))
{
- ECDomainParameters other = (ECDomainParameters)obj;
-
- return this.curve.equals(other.curve) && this.G.equals(other.G) && this.n.equals(other.n) && this.h.equals(other.h);
+ return false;
}
- return false;
+ ECDomainParameters other = (ECDomainParameters)obj;
+
+ return this.curve.equals(other.curve)
+ && this.G.equals(other.G)
+ && this.n.equals(other.n);
}
public int hashCode()
{
- int hc = curve.hashCode();
- hc *= 37;
+// return Arrays.hashCode(new Object[]{ curve, G, n });
+ int hc = 4;
+ hc *= 257;
+ hc ^= curve.hashCode();
+ hc *= 257;
hc ^= G.hashCode();
- hc *= 37;
+ hc *= 257;
hc ^= n.hashCode();
- hc *= 37;
- hc ^= h.hashCode();
return hc;
}
- static ECPoint validate(ECCurve c, ECPoint q)
+ public BigInteger validatePrivateScalar(BigInteger d)
+ {
+ if (null == d)
+ {
+ throw new NullPointerException("Scalar cannot be null");
+ }
+
+ if (d.compareTo(ECConstants.ONE) < 0 || (d.compareTo(getN()) >= 0))
+ {
+ throw new IllegalArgumentException("Scalar is not in the interval [1, n - 1]");
+ }
+
+ return d;
+ }
+
+ public ECPoint validatePublicPoint(ECPoint q)
+ {
+ return validatePublicPoint(getCurve(), q);
+ }
+
+ static ECPoint validatePublicPoint(ECCurve c, ECPoint q)
{
- if (q == null)
+ if (null == q)
{
- throw new IllegalArgumentException("Point has null value");
+ throw new NullPointerException("Point cannot be null");
}
q = ECAlgorithms.importPoint(c, q).normalize();
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECKeyParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECKeyParameters.java
index 4bdf6faa..286b33df 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECKeyParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECKeyParameters.java
@@ -7,19 +7,24 @@ package com.android.org.bouncycastle.crypto.params;
public class ECKeyParameters
extends AsymmetricKeyParameter
{
- ECDomainParameters params;
+ private final ECDomainParameters parameters;
protected ECKeyParameters(
boolean isPrivate,
- ECDomainParameters params)
+ ECDomainParameters parameters)
{
super(isPrivate);
- this.params = params;
+ if (null == parameters)
+ {
+ throw new NullPointerException("'parameters' cannot be null");
+ }
+
+ this.parameters = parameters;
}
public ECDomainParameters getParameters()
{
- return params;
+ return parameters;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECNamedDomainParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECNamedDomainParameters.java
index c252c670..83088948 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECNamedDomainParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECNamedDomainParameters.java
@@ -4,6 +4,7 @@ package com.android.org.bouncycastle.crypto.params;
import java.math.BigInteger;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.org.bouncycastle.asn1.x9.X9ECParameters;
import com.android.org.bouncycastle.math.ec.ECConstants;
import com.android.org.bouncycastle.math.ec.ECCurve;
import com.android.org.bouncycastle.math.ec.ECPoint;
@@ -39,6 +40,12 @@ public class ECNamedDomainParameters
this.name = name;
}
+ public ECNamedDomainParameters(ASN1ObjectIdentifier name, X9ECParameters x9)
+ {
+ super(x9);
+ this.name = name;
+ }
+
public ASN1ObjectIdentifier getName()
{
return name;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java
index 7a658c52..7e3899bf 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java
@@ -9,14 +9,15 @@ import java.math.BigInteger;
public class ECPrivateKeyParameters
extends ECKeyParameters
{
- BigInteger d;
+ private final BigInteger d;
public ECPrivateKeyParameters(
BigInteger d,
- ECDomainParameters params)
+ ECDomainParameters parameters)
{
- super(true, params);
- this.d = d;
+ super(true, parameters);
+
+ this.d = parameters.validatePrivateScalar(d);
}
public BigInteger getD()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECPublicKeyParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECPublicKeyParameters.java
index 8378f6dd..d9a17614 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECPublicKeyParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ECPublicKeyParameters.java
@@ -9,19 +9,19 @@ import com.android.org.bouncycastle.math.ec.ECPoint;
public class ECPublicKeyParameters
extends ECKeyParameters
{
- private final ECPoint Q;
+ private final ECPoint q;
public ECPublicKeyParameters(
- ECPoint Q,
- ECDomainParameters params)
+ ECPoint q,
+ ECDomainParameters parameters)
{
- super(false, params);
+ super(false, parameters);
- this.Q = ECDomainParameters.validate(params.getCurve(), Q);
+ this.q = parameters.validatePublicPoint(q);
}
public ECPoint getQ()
{
- return Q;
+ return q;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/KeyParameter.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/KeyParameter.java
index bed0f702..ad8fa0ce 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/KeyParameter.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/KeyParameter.java
@@ -6,7 +6,6 @@ import com.android.org.bouncycastle.crypto.CipherParameters;
/**
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class KeyParameter
implements CipherParameters
{
@@ -28,7 +27,6 @@ public class KeyParameter
System.arraycopy(key, keyOff, this.key, 0, keyLen);
}
- @libcore.api.CorePlatformApi
public byte[] getKey()
{
return key;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ParametersWithRandom.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ParametersWithRandom.java
index 8e83e6f4..07642641 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ParametersWithRandom.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/ParametersWithRandom.java
@@ -19,14 +19,14 @@ public class ParametersWithRandom
CipherParameters parameters,
SecureRandom random)
{
- this.random = random;
+ this.random = CryptoServicesRegistrar.getSecureRandom(random);
this.parameters = parameters;
}
public ParametersWithRandom(
CipherParameters parameters)
{
- this(parameters, CryptoServicesRegistrar.getSecureRandom());
+ this(parameters, null);
}
public SecureRandom getRandom()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/RSAKeyParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/RSAKeyParameters.java
index a8832ba3..ac7c2eea 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/RSAKeyParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/params/RSAKeyParameters.java
@@ -3,12 +3,22 @@ package com.android.org.bouncycastle.crypto.params;
import java.math.BigInteger;
+import com.android.org.bouncycastle.util.Properties;
+
/**
* @hide This class is not part of the Android public SDK API
*/
public class RSAKeyParameters
extends AsymmetricKeyParameter
{
+ // Hexadecimal value of the product of the 131 smallest odd primes from 3 to 743
+ private static final BigInteger SMALL_PRIMES_PRODUCT = new BigInteger(
+ "8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
+ + "73d893fa424cd2edc8636a6c3285e022b0e3866a565ae8108eed8591cd4fe8d2"
+ + "ce86165a978d719ebf647f362d33fca29cd179fb42401cbaf3df0c614056f9c8"
+ + "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f",
+ 16);
+
private static final BigInteger ONE = BigInteger.valueOf(1);
private BigInteger modulus;
@@ -40,12 +50,14 @@ public class RSAKeyParameters
throw new IllegalArgumentException("RSA modulus is even");
}
- // the value is the product of the 132 smallest primes from 3 to 751
- if (!modulus.gcd(new BigInteger("145188775577763990151158743208307020242261438098488931355057091965" +
- "931517706595657435907891265414916764399268423699130577757433083166" +
- "651158914570105971074227669275788291575622090199821297575654322355" +
- "049043101306108213104080801056529374892690144291505781966373045481" +
- "8359472391642885328171302299245556663073719855")).equals(ONE))
+ // If you need to set this you need to have a serious word to whoever is generating
+ // your keys.
+ if (Properties.isOverrideSet("com.android.org.bouncycastle.rsa.allow_unsafe_mod"))
+ {
+ return modulus;
+ }
+
+ if (!modulus.gcd(SMALL_PRIMES_PRODUCT).equals(ONE))
{
throw new IllegalArgumentException("RSA modulus has a small prime factor");
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/DSASigner.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/DSASigner.java
index 268600b2..1d3c992d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/DSASigner.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/DSASigner.java
@@ -107,7 +107,7 @@ public class DSASigner
// the randomizer is to conceal timing information related to k and x.
BigInteger r = params.getG().modPow(k.add(getRandomizer(q, random)), params.getP()).mod(q);
- k = k.modInverse(q).multiply(m.add(x.multiply(r)));
+ k = BigIntegers.modOddInverse(q, k).multiply(m.add(x.multiply(r)));
BigInteger s = k.mod(q);
@@ -139,7 +139,7 @@ public class DSASigner
return false;
}
- BigInteger w = s.modInverse(q);
+ BigInteger w = BigIntegers.modOddInverseVar(q, s);
BigInteger u1 = m.multiply(w).mod(q);
BigInteger u2 = r.multiply(w).mod(q);
@@ -171,7 +171,7 @@ public class DSASigner
protected SecureRandom initSecureRandom(boolean needed, SecureRandom provided)
{
- return !needed ? null : (provided != null) ? provided : CryptoServicesRegistrar.getSecureRandom();
+ return needed ? CryptoServicesRegistrar.getSecureRandom(provided) : null;
}
private BigInteger getRandomizer(BigInteger q, SecureRandom provided)
@@ -179,6 +179,6 @@ public class DSASigner
// Calculate a random multiple of q to add to k. Note that g^q = 1 (mod p), so adding multiple of q to k does not change r.
int randomBits = 7;
- return BigIntegers.createRandomBigInteger(randomBits, provided != null ? provided : CryptoServicesRegistrar.getSecureRandom()).add(BigInteger.valueOf(128)).multiply(q);
+ return BigIntegers.createRandomBigInteger(randomBits, CryptoServicesRegistrar.getSecureRandom(provided)).add(BigInteger.valueOf(128)).multiply(q);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/ECDSASigner.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/ECDSASigner.java
index 41347acb..e81ab37b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/ECDSASigner.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/ECDSASigner.java
@@ -19,6 +19,7 @@ import com.android.org.bouncycastle.math.ec.ECFieldElement;
import com.android.org.bouncycastle.math.ec.ECMultiplier;
import com.android.org.bouncycastle.math.ec.ECPoint;
import com.android.org.bouncycastle.math.ec.FixedPointCombMultiplier;
+import com.android.org.bouncycastle.util.BigIntegers;
/**
* EC-DSA as described in X9.62
@@ -127,7 +128,7 @@ public class ECDSASigner
}
while (r.equals(ZERO));
- s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);
+ s = BigIntegers.modOddInverse(n, k).multiply(e.add(d.multiply(r))).mod(n);
}
while (s.equals(ZERO));
@@ -161,7 +162,7 @@ public class ECDSASigner
return false;
}
- BigInteger c = s.modInverse(n);
+ BigInteger c = BigIntegers.modOddInverseVar(n, s);
BigInteger u1 = e.multiply(c).mod(n);
BigInteger u2 = r.multiply(c).mod(n);
@@ -255,6 +256,6 @@ public class ECDSASigner
protected SecureRandom initSecureRandom(boolean needed, SecureRandom provided)
{
- return !needed ? null : (provided != null) ? provided : CryptoServicesRegistrar.getSecureRandom();
+ return needed ? CryptoServicesRegistrar.getSecureRandom(provided) : null;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/RSADigestSigner.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/RSADigestSigner.java
index 3f758791..54af2b52 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/RSADigestSigner.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/signers/RSADigestSigner.java
@@ -82,7 +82,15 @@ public class RSADigestSigner
ASN1ObjectIdentifier digestOid)
{
this.digest = digest;
- this.algId = new AlgorithmIdentifier(digestOid, DERNull.INSTANCE);
+ if (digestOid != null)
+ {
+ this.algId = new AlgorithmIdentifier(digestOid, DERNull.INSTANCE);
+ }
+ else
+ {
+ // NULL digester, match behaviour with DigestSignatureSpi
+ this.algId = null;
+ }
}
/**
@@ -94,7 +102,7 @@ public class RSADigestSigner
}
/**
- * initialise the signer for signing or verification.
+ * Initialize the signer for signing or verification.
*
* @param forSigning
* true if for signing, false otherwise
@@ -250,6 +258,20 @@ public class RSADigestSigner
byte[] hash)
throws IOException
{
+ if (algId == null)
+ {
+ try
+ {
+ // check hash is at least right format
+ DigestInfo.getInstance(hash);
+ return hash;
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new IOException("malformed DigestInfo for NONEwithRSA hash: " + e.getMessage());
+ }
+ }
+
DigestInfo dInfo = new DigestInfo(algId, hash);
return dInfo.getEncoded(ASN1Encoding.DER);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/tls/CertificateType.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/tls/CertificateType.java
index 3c3ef04c..f8c1e092 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/tls/CertificateType.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/tls/CertificateType.java
@@ -3,6 +3,8 @@ package com.android.org.bouncycastle.crypto.tls;
/**
* RFC 6091
+ *
+ * @deprecated Migrate to the (D)TLS API in org.bouncycastle.tls (bctls jar).
* @hide This class is not part of the Android public SDK API
*/
public class CertificateType
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/tls/TlsCloseable.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/tls/TlsCloseable.java
new file mode 100644
index 00000000..f7dd0f4e
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/tls/TlsCloseable.java
@@ -0,0 +1,13 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.tls;
+
+import java.io.IOException;
+
+/**
+ * @deprecated Migrate to the (D)TLS API in org.bouncycastle.tls (bctls jar).
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface TlsCloseable
+{
+ public void close() throws IOException;
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java
index 548fe212..e1d86bb7 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java
@@ -9,6 +9,8 @@ import java.io.EOFException;
* protocol cannot rule out truncation of the connection data (potentially malicious). It may be
* possible to check for truncation via some property of a higher level protocol built upon TLS,
* e.g. the Content-Length header for HTTPS.
+ *
+ * @deprecated Migrate to the (D)TLS API in org.bouncycastle.tls (bctls jar).
* @hide This class is not part of the Android public SDK API
*/
public class TlsNoCloseNotifyException
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PrivateKeyFactory.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PrivateKeyFactory.java
index 9e7a0171..4c3ea490 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PrivateKeyFactory.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PrivateKeyFactory.java
@@ -52,6 +52,7 @@ import com.android.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.params.X25519PrivateKeyParameters;
// import org.bouncycastle.crypto.params.X448PrivateKeyParameters;
+import com.android.org.bouncycastle.util.Arrays;
/**
* Factory for creating private key objects from PKCS8 PrivateKeyInfo objects.
@@ -151,7 +152,7 @@ public class PrivateKeyFactory
}
else if (algOID.equals(X9ObjectIdentifiers.id_ecPublicKey))
{
- X962Parameters params = new X962Parameters((ASN1Primitive)algId.getParameters());
+ X962Parameters params = X962Parameters.getInstance(algId.getParameters());
X9ECParameters x9;
ECDomainParameters dParams;
@@ -165,8 +166,7 @@ public class PrivateKeyFactory
{
x9 = ECNamedCurveTable.getByOID(oid);
}
- dParams = new ECNamedDomainParameters(
- oid, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
+ dParams = new ECNamedDomainParameters(oid, x9);
}
else
{
@@ -210,7 +210,7 @@ public class PrivateKeyFactory
if (p instanceof ASN1Sequence && (ASN1Sequence.getInstance(p).size() == 2 || ASN1Sequence.getInstance(p).size() == 3))
{
- ECDomainParameters ecP = ECGOST3410NamedCurves.getByOID(gostParams.getPublicKeyParamSet());
+ X9ECParameters ecP = ECGOST3410NamedCurves.getByOIDX9(gostParams.getPublicKeyParamSet());
ecSpec = new ECGOST3410Parameters(
new ECNamedDomainParameters(
@@ -218,25 +218,25 @@ public class PrivateKeyFactory
gostParams.getPublicKeyParamSet(),
gostParams.getDigestParamSet(),
gostParams.getEncryptionParamSet());
- ASN1Encodable privKey = keyInfo.parsePrivateKey();
- if (privKey instanceof ASN1Integer)
+ ASN1OctetString privEnc = keyInfo.getPrivateKey();
+
+ if (privEnc.getOctets().length == 32 || privEnc.getOctets().length == 64)
{
- d = ASN1Integer.getInstance(privKey).getPositiveValue();
+ d = new BigInteger(1, Arrays.reverse(privEnc.getOctets()));
}
else
{
- byte[] encVal = ASN1OctetString.getInstance(privKey).getOctets();
- byte[] dVal = new byte[encVal.length];
-
- for (int i = 0; i != encVal.length; i++)
+ ASN1Encodable privKey = keyInfo.parsePrivateKey();
+ if (privKey instanceof ASN1Integer)
{
- dVal[i] = encVal[encVal.length - 1 - i];
+ d = ASN1Integer.getInstance(privKey).getPositiveValue();
+ }
+ else
+ {
+ byte[] dVal = Arrays.reverse(ASN1OctetString.getInstance(privKey).getOctets());
+ d = new BigInteger(1, dVal);
}
-
- d = new BigInteger(1, dVal);
}
-
-
}
else
{
@@ -246,27 +246,10 @@ public class PrivateKeyFactory
{
ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters());
X9ECParameters ecP = ECNamedCurveTable.getByOID(oid);
- if (ecP == null)
- {
- ECDomainParameters gParam = ECGOST3410NamedCurves.getByOID(oid);
- ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(
- oid,
- gParam.getCurve(),
- gParam.getG(),
- gParam.getN(),
- gParam.getH(),
- gParam.getSeed()), gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(), gostParams.getEncryptionParamSet());
- }
- else
- {
- ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(
- oid,
- ecP.getCurve(),
- ecP.getG(),
- ecP.getN(),
- ecP.getH(),
- ecP.getSeed()), gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(), gostParams.getEncryptionParamSet());
- }
+
+ ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(oid, ecP),
+ gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(),
+ gostParams.getEncryptionParamSet());
}
else if (params.isImplicitlyCA())
{
@@ -275,13 +258,9 @@ public class PrivateKeyFactory
else
{
X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
- ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(
- algOID,
- ecP.getCurve(),
- ecP.getG(),
- ecP.getN(),
- ecP.getH(),
- ecP.getSeed()), gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(), gostParams.getEncryptionParamSet());
+ ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(algOID, ecP),
+ gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(),
+ gostParams.getEncryptionParamSet());
}
ASN1Encodable privKey = keyInfo.parsePrivateKey();
@@ -293,7 +272,7 @@ public class PrivateKeyFactory
}
else
{
- org.bouncycastle.asn1.sec.ECPrivateKey ec = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(privKey);
+ ECPrivateKey ec = ECPrivateKey.getInstance(privKey);
d = ec.getKey();
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PublicKeyFactory.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PublicKeyFactory.java
index 430e2dca..39e09679 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PublicKeyFactory.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/PublicKeyFactory.java
@@ -66,6 +66,8 @@ import com.android.org.bouncycastle.crypto.params.RSAKeyParameters;
// import org.bouncycastle.crypto.params.X25519PublicKeyParameters;
// import org.bouncycastle.crypto.params.X448PublicKeyParameters;
import com.android.org.bouncycastle.math.ec.ECCurve;
+import com.android.org.bouncycastle.math.ec.ECPoint;
+import com.android.org.bouncycastle.util.Arrays;
/**
* Factory to create asymmetric public key parameters for asymmetric ciphers from range of
@@ -153,17 +155,15 @@ public class PublicKeyFactory
public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo, Object defaultParams)
throws IOException
{
- AlgorithmIdentifier algId = keyInfo.getAlgorithm();
- SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)converters.get(algId.getAlgorithm());
+ AlgorithmIdentifier algID = keyInfo.getAlgorithm();
- if (converter != null)
+ SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)converters.get(algID.getAlgorithm());
+ if (null == converter)
{
- return converter.getPublicKeyParameters(keyInfo, defaultParams);
- }
- else
- {
- throw new IOException("algorithm identifier in public key not recognised: " + algId.getAlgorithm());
+ throw new IOException("algorithm identifier in public key not recognised: " + algID.getAlgorithm());
}
+
+ return converter.getPublicKeyParameters(keyInfo, defaultParams);
}
private static abstract class SubjectPublicKeyInfoConverter
@@ -294,8 +294,7 @@ public class PublicKeyFactory
{
x9 = ECNamedCurveTable.getByOID(oid);
}
- dParams = new ECNamedDomainParameters(
- oid, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
+ dParams = new ECNamedDomainParameters(oid, x9);
}
else if (params.isImplicitlyCA())
{
@@ -304,8 +303,7 @@ public class PublicKeyFactory
else
{
X9ECParameters x9 = X9ECParameters.getInstance(params.getParameters());
- dParams = new ECDomainParameters(
- x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
+ dParams = new ECDomainParameters(x9);
}
DERBitString bits = keyInfo.getPublicKeyData();
@@ -346,40 +344,47 @@ public class PublicKeyFactory
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- DERBitString bits = keyInfo.getPublicKeyData();
- ASN1OctetString key;
+ AlgorithmIdentifier algID = keyInfo.getAlgorithm();
+// ASN1ObjectIdentifier algOid = algID.getAlgorithm();
+ GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(algID.getParameters());
+ ASN1ObjectIdentifier publicKeyParamSet = gostParams.getPublicKeyParamSet();
+ ECGOST3410Parameters ecDomainParameters = new ECGOST3410Parameters(
+ new ECNamedDomainParameters(publicKeyParamSet, ECGOST3410NamedCurves.getByOIDX9(publicKeyParamSet)),
+ publicKeyParamSet,
+ gostParams.getDigestParamSet(),
+ gostParams.getEncryptionParamSet());
+
+ ASN1OctetString key;
try
{
- key = (ASN1OctetString)ASN1Primitive.fromByteArray(bits.getBytes());
+ key = (ASN1OctetString)keyInfo.parsePublicKey();
}
catch (IOException ex)
{
- throw new IllegalArgumentException("error recovering public key");
+ throw new IllegalArgumentException("error recovering GOST3410_2001 public key");
}
+ int fieldSize = 32;
+ int keySize = 2 * fieldSize;
+
byte[] keyEnc = key.getOctets();
+ if (keyEnc.length != keySize)
+ {
+ throw new IllegalArgumentException("invalid length for GOST3410_2001 public key");
+ }
- byte[] x9Encoding = new byte[65];
+ byte[] x9Encoding = new byte[1 + keySize];
x9Encoding[0] = 0x04;
- for (int i = 1; i <= 32; ++i)
+ for (int i = 1; i <= fieldSize; ++i)
{
- x9Encoding[i] = keyEnc[32 - i];
- x9Encoding[i + 32] = keyEnc[64 - i];
+ x9Encoding[i] = keyEnc[fieldSize - i];
+ x9Encoding[i + fieldSize] = keyEnc[keySize - i];
}
- GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(keyInfo.getAlgorithm().getParameters());
-
- ECGOST3410Parameters ecDomainParameters =
- new ECGOST3410Parameters(
- new ECNamedDomainParameters(gostParams.getPublicKeyParamSet(), ECGOST3410NamedCurves.getByOID(gostParams.getPublicKeyParamSet())),
- gostParams.getPublicKeyParamSet(),
- gostParams.getDigestParamSet(),
- gostParams.getEncryptionParamSet());
-
-
- return new ECPublicKeyParameters(ecDomainParameters.getCurve().decodePoint(x9Encoding), ecDomainParameters);
+ ECPoint q = ecDomainParameters.getCurve().decodePoint(x9Encoding);
+ return new ECPublicKeyParameters(q, ecDomainParameters);
}
}
@@ -388,29 +393,40 @@ public class PublicKeyFactory
{
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
{
- ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm();
- DERBitString bits = keyInfo.getPublicKeyData();
- ASN1OctetString key;
+ AlgorithmIdentifier algID = keyInfo.getAlgorithm();
+ ASN1ObjectIdentifier algOid = algID.getAlgorithm();
+ GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(algID.getParameters());
+ ASN1ObjectIdentifier publicKeyParamSet = gostParams.getPublicKeyParamSet();
+
+ ECGOST3410Parameters ecDomainParameters = new ECGOST3410Parameters(
+ new ECNamedDomainParameters(publicKeyParamSet, ECGOST3410NamedCurves.getByOIDX9(publicKeyParamSet)),
+ publicKeyParamSet,
+ gostParams.getDigestParamSet(),
+ gostParams.getEncryptionParamSet());
+ ASN1OctetString key;
try
{
- key = (ASN1OctetString)ASN1Primitive.fromByteArray(bits.getBytes());
+ key = (ASN1OctetString)keyInfo.parsePublicKey();
}
catch (IOException ex)
{
- throw new IllegalArgumentException("error recovering public key");
+ throw new IllegalArgumentException("error recovering GOST3410_2012 public key");
}
- byte[] keyEnc = key.getOctets();
-
int fieldSize = 32;
if (algOid.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512))
{
fieldSize = 64;
}
-
int keySize = 2 * fieldSize;
+ byte[] keyEnc = key.getOctets();
+ if (keyEnc.length != keySize)
+ {
+ throw new IllegalArgumentException("invalid length for GOST3410_2012 public key");
+ }
+
byte[] x9Encoding = new byte[1 + keySize];
x9Encoding[0] = 0x04;
for (int i = 1; i <= fieldSize; ++i)
@@ -419,17 +435,9 @@ public class PublicKeyFactory
x9Encoding[i + fieldSize] = keyEnc[keySize - i];
}
- GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(keyInfo.getAlgorithm().getParameters());
+ ECPoint q = ecDomainParameters.getCurve().decodePoint(x9Encoding);
- ECGOST3410Parameters ecDomainParameters =
- new ECGOST3410Parameters(
- new ECNamedDomainParameters(gostParams.getPublicKeyParamSet(), ECGOST3410NamedCurves.getByOID(gostParams.getPublicKeyParamSet())),
- gostParams.getPublicKeyParamSet(),
- gostParams.getDigestParamSet(),
- gostParams.getEncryptionParamSet());
-
-
- return new ECPublicKeyParameters(ecDomainParameters.getCurve().decodePoint(x9Encoding), ecDomainParameters);
+ return new ECPublicKeyParameters(q, ecDomainParameters);
}
}
@@ -439,53 +447,55 @@ public class PublicKeyFactory
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
throws IOException
{
- DERBitString bits = keyInfo.getPublicKeyData();
- ASN1OctetString key;
+ AlgorithmIdentifier algID = keyInfo.getAlgorithm();
+ ASN1ObjectIdentifier algOid = algID.getAlgorithm();
+ DSTU4145Params dstuParams = DSTU4145Params.getInstance(algID.getParameters());
+ ASN1OctetString key;
try
{
- key = (ASN1OctetString)ASN1Primitive.fromByteArray(bits.getBytes());
+ key = (ASN1OctetString)keyInfo.parsePublicKey();
}
catch (IOException ex)
{
- throw new IllegalArgumentException("error recovering public key");
+ throw new IllegalArgumentException("error recovering DSTU public key");
}
- byte[] keyEnc = key.getOctets();
+ byte[] keyEnc = Arrays.clone(key.getOctets());
- if (keyInfo.getAlgorithm().getAlgorithm().equals(UAObjectIdentifiers.dstu4145le))
+ if (algOid.equals(UAObjectIdentifiers.dstu4145le))
{
reverseBytes(keyEnc);
}
- DSTU4145Params dstuParams = DSTU4145Params.getInstance(keyInfo.getAlgorithm().getParameters());
-
ECDomainParameters ecDomain;
if (dstuParams.isNamedCurve())
{
- ASN1ObjectIdentifier curveOid = dstuParams.getNamedCurve();
-
- ecDomain = DSTU4145NamedCurves.getByOID(curveOid);
+ ecDomain = DSTU4145NamedCurves.getByOID(dstuParams.getNamedCurve());
}
else
{
DSTU4145ECBinary binary = dstuParams.getECBinary();
byte[] b_bytes = binary.getB();
- if (keyInfo.getAlgorithm().getAlgorithm().equals(UAObjectIdentifiers.dstu4145le))
+ if (algOid.equals(UAObjectIdentifiers.dstu4145le))
{
reverseBytes(b_bytes);
}
+ BigInteger b = new BigInteger(1, b_bytes);
DSTU4145BinaryField field = binary.getField();
- ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), new BigInteger(1, b_bytes));
+ ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), b);
byte[] g_bytes = binary.getG();
- if (keyInfo.getAlgorithm().getAlgorithm().equals(UAObjectIdentifiers.dstu4145le))
+ if (algOid.equals(UAObjectIdentifiers.dstu4145le))
{
reverseBytes(g_bytes);
}
- ecDomain = new ECDomainParameters(curve, DSTU4145PointEncoder.decodePoint(curve, g_bytes), binary.getN());
+ ECPoint g = DSTU4145PointEncoder.decodePoint(curve, g_bytes);
+ ecDomain = new ECDomainParameters(curve, g, binary.getN());
}
- return new ECPublicKeyParameters(DSTU4145PointEncoder.decodePoint(ecDomain.getCurve(), keyEnc), ecDomain);
+ ECPoint q = DSTU4145PointEncoder.decodePoint(ecDomain.getCurve(), keyEnc);
+
+ return new ECPublicKeyParameters(q, ecDomain);
}
private void reverseBytes(byte[] bytes)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/SSHNamedCurves.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/SSHNamedCurves.java
new file mode 100644
index 00000000..7c65234d
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/crypto/util/SSHNamedCurves.java
@@ -0,0 +1,134 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.crypto.util;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.org.bouncycastle.asn1.nist.NISTNamedCurves;
+import com.android.org.bouncycastle.asn1.sec.SECObjectIdentifiers;
+import com.android.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.org.bouncycastle.crypto.ec.CustomNamedCurves;
+import com.android.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.org.bouncycastle.crypto.params.ECNamedDomainParameters;
+import com.android.org.bouncycastle.math.ec.ECCurve;
+import com.android.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SSHNamedCurves
+{
+ private static final Map<ASN1ObjectIdentifier, String> oidToName;
+ private static final Map<String, ASN1ObjectIdentifier> oidMap =
+ Collections.unmodifiableMap(new HashMap<String, ASN1ObjectIdentifier>()
+ {
+ {
+ put("nistp256", SECObjectIdentifiers.secp256r1);
+ put("nistp384", SECObjectIdentifiers.secp384r1);
+ put("nistp521", SECObjectIdentifiers.secp521r1);
+ put("nistk163", SECObjectIdentifiers.sect163k1);
+ put("nistp192", SECObjectIdentifiers.secp192r1);
+ put("nistp224", SECObjectIdentifiers.secp224r1);
+ put("nistk233", SECObjectIdentifiers.sect233k1);
+ put("nistb233", SECObjectIdentifiers.sect233r1);
+ put("nistk283", SECObjectIdentifiers.sect283k1);
+ put("nistk409", SECObjectIdentifiers.sect409k1);
+ put("nistb409", SECObjectIdentifiers.sect409r1);
+ put("nistt571", SECObjectIdentifiers.sect571k1);
+ }
+ });
+
+ private static final Map<String, String> curveNameToSSHName = Collections.unmodifiableMap(new HashMap<String, String>()
+ {
+ {
+ String[][] curves = {
+ {"secp256r1", "nistp256"},
+ {"secp384r1", "nistp384"},
+ {"secp521r1", "nistp521"},
+ {"sect163k1", "nistk163"},
+ {"secp192r1", "nistp192"},
+ {"secp224r1", "nistp224"},
+ {"sect233k1", "nistk233"},
+ {"sect233r1", "nistb233"},
+ {"sect283k1", "nistk283"},
+ {"sect409k1", "nistk409"},
+ {"sect409r1", "nistb409"},
+ {"sect571k1", "nistt571"}
+ };
+ for (int i = 0; i != curves.length; i++)
+ {
+ String[] item = curves[i];
+ put(item[0], item[1]);
+ }
+ }
+ });
+ private static HashMap<ECCurve, String> curveMap = new HashMap<ECCurve, String>()
+ {
+ {
+ Enumeration<Object> e = CustomNamedCurves.getNames();
+ while (e.hasMoreElements())
+ {
+ String name = (String)e.nextElement();
+ X9ECParameters parameters = CustomNamedCurves.getByName(name);
+ put(parameters.getCurve(), name);
+ }
+
+ }
+ };
+
+ static
+ {
+ oidToName = Collections.unmodifiableMap(new HashMap<ASN1ObjectIdentifier, String>()
+ {
+ {
+ for (Iterator it = oidMap.keySet().iterator(); it.hasNext();)
+ {
+ String key = (String)it.next();
+ put(oidMap.get(key), key);
+ }
+ }
+ });
+
+
+ }
+
+ public static ASN1ObjectIdentifier getByName(String sshName)
+ {
+ return (ASN1ObjectIdentifier)oidMap.get(sshName);
+ }
+
+ public static X9ECParameters getParameters(String sshName)
+ {
+ return NISTNamedCurves.getByOID((ASN1ObjectIdentifier)oidMap.get(Strings.toLowerCase(sshName)));
+ }
+
+ public static X9ECParameters getParameters(ASN1ObjectIdentifier oid)
+ {
+ return NISTNamedCurves.getByOID(oid);
+ }
+
+ public static String getName(ASN1ObjectIdentifier oid)
+ {
+ return (String)oidToName.get(oid);
+ }
+
+ public static String getNameForParameters(ECDomainParameters parameters)
+ {
+ if (parameters instanceof ECNamedDomainParameters)
+ {
+ return getName(((ECNamedDomainParameters)parameters).getName());
+ }
+
+
+ return getNameForParameters(parameters.getCurve());
+ }
+
+ public static String getNameForParameters(ECCurve curve)
+ {
+ return (String)curveNameToSSHName.get(curveMap.get(curve));
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/AesCcmCiphertext.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/AesCcmCiphertext.java
new file mode 100644
index 00000000..9f1b3645
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/AesCcmCiphertext.java
@@ -0,0 +1,61 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DEROctetString;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * AesCcmCiphertext ::= SEQUENCE {
+ * nonce OCTET STRING (SIZE (12))
+ * ccmCiphertext Opaque -- 16 bytes longer than plaintext
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AesCcmCiphertext
+ extends ASN1Object
+{
+ private final byte[] nonce;
+ private final SequenceOfOctetString opaque;
+
+ private AesCcmCiphertext(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("sequence not length 2");
+ }
+
+ nonce = Utils.octetStringFixed(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets(), 12);
+ opaque = SequenceOfOctetString.getInstance(seq.getObjectAt(1));
+ }
+
+ public static AesCcmCiphertext getInstance(Object o)
+ {
+ if (o instanceof AesCcmCiphertext)
+ {
+ return (AesCcmCiphertext)o;
+ }
+ else if (o != null)
+ {
+ return new AesCcmCiphertext(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(new DEROctetString(nonce));
+ v.add(opaque);
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/BitmapSspRange.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/BitmapSspRange.java
new file mode 100644
index 00000000..0cb5be15
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/BitmapSspRange.java
@@ -0,0 +1,74 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DEROctetString;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * BitmapSspRange ::= SEQUENCE {
+ * sspValue OCTET STRING (SIZE(1..32)),
+ * sspBitmask OCTET STRING (SIZE(1..32))
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BitmapSspRange
+ extends ASN1Object
+{
+ private final byte[] sspValue;
+ private final byte[] sspBitmask;
+
+ private BitmapSspRange(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("expected sequence with sspValue and sspBitmask");
+ }
+
+ sspValue = Utils.octetStringFixed(
+ ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets());
+ sspBitmask = Utils.octetStringFixed(
+ ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets());
+ }
+
+ public static BitmapSspRange getInstance(Object o)
+ {
+ if (o instanceof BitmapSspRange)
+ {
+ return (BitmapSspRange)o;
+ }
+ else if (o != null)
+ {
+ return new BitmapSspRange(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public byte[] getSspValue()
+ {
+ return Arrays.clone(sspValue);
+ }
+
+ public byte[] getSspBitmask()
+ {
+ return Arrays.clone(sspBitmask);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector avec = new ASN1EncodableVector();
+
+ avec.add(new DEROctetString(sspValue));
+ avec.add(new DEROctetString(sspBitmask));
+
+ return new DERSequence(avec);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/CertificateBase.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/CertificateBase.java
new file mode 100644
index 00000000..c575053a
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/CertificateBase.java
@@ -0,0 +1,68 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * CertificateBase ::= SEQUENCE {
+ * version Uint8(3),
+ * type CertificateType,
+ * issuer IssuerIdentifier,
+ * toBeSigned ToBeSignedCertificate,
+ * signature Signature OPTIONAL
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertificateBase
+ extends ASN1Object
+{
+ private CertificateType type;
+ private byte[] version;
+
+ protected CertificateBase(ASN1Sequence seq)
+ {
+
+ }
+
+ public static CertificateBase getInstance(Object o)
+ {
+ if (o instanceof ImplicitCertificate)
+ {
+ return (ImplicitCertificate)o;
+ }
+ if (o instanceof ExplicitCertificate)
+ {
+ return (ExplicitCertificate)o;
+ }
+
+ if (o != null)
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(o);
+
+ if (seq.getObjectAt(1).equals(CertificateType.Implicit))
+ {
+ return ImplicitCertificate.getInstance(seq);
+ }
+ if (seq.getObjectAt(1).equals(CertificateType.Explicit))
+ {
+ return ExplicitCertificate.getInstance(seq);
+ }
+ throw new IllegalArgumentException("unknown certificate type");
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/CertificateType.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/CertificateType.java
new file mode 100644
index 00000000..ea9b733c
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/CertificateType.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * CertificateType ::= ENUMERATED {
+ * explicit,
+ * implicit,
+ * ...
+ * }
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertificateType
+{
+
+ public static final CertificateType Explicit = new CertificateType(0);
+ public static final CertificateType Implicit = new CertificateType(1);
+ private final ASN1Enumerated enumerated;
+
+ protected CertificateType(int ordinal)
+ {
+ enumerated = new ASN1Enumerated(ordinal);
+ }
+
+ private CertificateType(ASN1Enumerated enumerated)
+ {
+ this.enumerated = enumerated;
+ }
+
+ public CertificateType getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+ else if (src instanceof CertificateType)
+ {
+ return (CertificateType)src;
+ }
+ else
+ {
+ return new CertificateType(ASN1Enumerated.getInstance(src));
+ }
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return enumerated;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/CircularRegion.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/CircularRegion.java
new file mode 100644
index 00000000..d4987df2
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/CircularRegion.java
@@ -0,0 +1,43 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * CircularRegion ::= SEQUENCE {
+ * center TwoDLocation,
+ * radius Uint16
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CircularRegion
+ extends ASN1Object
+{
+ private CircularRegion(ASN1Sequence seq)
+ {
+
+ }
+
+ public static CircularRegion getInstance(Object o)
+ {
+ if (o instanceof CircularRegion)
+ {
+ return (CircularRegion)o;
+ }
+ else if (o != null)
+ {
+ return new CircularRegion(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Duration.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Duration.java
new file mode 100644
index 00000000..529e8065
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Duration.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Choice;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * Duration ::= CHOICE {
+ * microseconds Uint16,
+ * milliseconds Uint16,
+ * seconds Uint16,
+ * minutes Uint16,
+ * hours Uint16,
+ * sixtyHours Uint16,
+ * years Uint16
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Duration
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EncryptedData.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EncryptedData.java
new file mode 100644
index 00000000..60ca960a
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EncryptedData.java
@@ -0,0 +1,35 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * EncryptedData ::= SEQUENCE {
+ * recipients SequenceOfRecipientInfo,
+ * ciphertext SymmetricCiphertext
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EncryptedData
+{
+ private EncryptedData(ASN1Sequence seq)
+ {
+
+ }
+
+ public static EncryptedData getInstance(Object o)
+ {
+ if (o instanceof EncryptedData)
+ {
+ return (EncryptedData)o;
+ }
+ else if (o != null)
+ {
+ return new EncryptedData(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EndEntityType.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EndEntityType.java
new file mode 100644
index 00000000..b95294aa
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EndEntityType.java
@@ -0,0 +1,56 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1BitString;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.DERBitString;
+
+/**
+ * <pre>
+ * EndEntityType ::= BIT STRING { app(0), enrol(1) } (SIZE (8)) (ALL EXCEPT ())
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EndEntityType
+ extends ASN1Object
+{
+ public static final int app = (1 << 7);
+ public static final int enrol = (1 << 6);
+
+ private final ASN1BitString type;
+
+ public EndEntityType(int type)
+ {
+ if (type != app && type != enrol)
+ {
+ throw new IllegalArgumentException("value out of range");
+ }
+
+ this.type = new DERBitString(type);
+ }
+
+ private EndEntityType(DERBitString str)
+ {
+ this.type = str;
+ }
+
+ public static EndEntityType getInstance(Object src)
+ {
+ if (src instanceof EndEntityType)
+ {
+ return (EndEntityType)src;
+ }
+ else if (src != null)
+ {
+ return new EndEntityType(DERBitString.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return type;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EtsiTs103097Module.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EtsiTs103097Module.java
new file mode 100644
index 00000000..1173ebbe
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/EtsiTs103097Module.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EtsiTs103097Module
+{
+
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ExplicitCertificate.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ExplicitCertificate.java
new file mode 100644
index 00000000..49cbc013
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ExplicitCertificate.java
@@ -0,0 +1,16 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ExplicitCertificate
+ extends CertificateBase
+{
+ private ExplicitCertificate(ASN1Sequence seq)
+ {
+ super(seq);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/GeographicRegion.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/GeographicRegion.java
new file mode 100644
index 00000000..78e8ae87
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/GeographicRegion.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Choice;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * GeographicRegion ::= CHOICE {
+ * circularRegion CircularRegion,
+ * rectangularRegion SequenceOfRectangularRegion,
+ * polygonalRegion PolygonalRegion,
+ * identifiedRegion SequenceOfIdentifiedRegion,
+ * ...
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GeographicRegion
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/GroupLinkageValue.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/GroupLinkageValue.java
new file mode 100644
index 00000000..077a03d7
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/GroupLinkageValue.java
@@ -0,0 +1,69 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DEROctetString;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * GroupLinkageValue ::= SEQUENCE {
+ * jValue OCTET STRING (SIZE(4))
+ * value OCTET STRING (SIZE(9))
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GroupLinkageValue
+ extends ASN1Object
+{
+ private byte[] jValue;
+ private byte[] value;
+
+ private GroupLinkageValue(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("sequence not length 2");
+ }
+
+ jValue = Utils.octetStringFixed(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets(), 4);
+ value = Utils.octetStringFixed(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets(), 9);
+ }
+
+ public static GroupLinkageValue getInstance(Object src)
+ {
+ if (src instanceof GroupLinkageValue)
+ {
+ return (GroupLinkageValue)src;
+ }
+ else if (src != null)
+ {
+ return new GroupLinkageValue(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public byte[] getJValue()
+ {
+ return jValue;
+ }
+
+ public byte[] getValue()
+ {
+ return value;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector avec = new ASN1EncodableVector();
+ avec.add(new DEROctetString(jValue));
+ avec.add(new DEROctetString(value));
+ return new DERSequence(avec);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/HashAlgorithm.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/HashAlgorithm.java
new file mode 100644
index 00000000..c4c6274b
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/HashAlgorithm.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * CertificateType ::= ENUMERATED {
+ * explicit,
+ * implicit,
+ * ...
+ * }
+ * @hide This class is not part of the Android public SDK API
+ */
+public class HashAlgorithm
+{
+
+ public static final HashAlgorithm sha256 = new HashAlgorithm(0);
+ public static final HashAlgorithm sha384 = new HashAlgorithm(1);
+ private final ASN1Enumerated enumerated;
+
+ protected HashAlgorithm(int ordinal)
+ {
+ enumerated = new ASN1Enumerated(ordinal);
+ }
+
+ private HashAlgorithm(ASN1Enumerated enumerated)
+ {
+ this.enumerated = enumerated;
+ }
+
+ public HashAlgorithm getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+ else if (src instanceof HashAlgorithm)
+ {
+ return (HashAlgorithm)src;
+ }
+ else
+ {
+ return new HashAlgorithm(ASN1Enumerated.getInstance(src));
+ }
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return enumerated;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/HashedData.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/HashedData.java
new file mode 100644
index 00000000..2dfebbee
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/HashedData.java
@@ -0,0 +1,48 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Choice;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.DEROctetString;
+
+/**
+ * <pre>
+ * HashedData ::= CHOICE {
+ * sha256HashedData OCTET STRING (SIZE(32))
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class HashedData
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private ASN1OctetString hashData;
+
+ public HashedData(byte[] digest)
+ {
+ this.hashData = new DEROctetString(digest);
+ }
+
+ private HashedData(ASN1OctetString hashData)
+ {
+ this.hashData = hashData;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return hashData;
+ }
+
+ public ASN1OctetString getHashData()
+ {
+ return hashData;
+ }
+
+ public void setHashData(ASN1OctetString hashData)
+ {
+ this.hashData = hashData;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/HeaderInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/HeaderInfo.java
new file mode 100644
index 00000000..846d7fd1
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/HeaderInfo.java
@@ -0,0 +1,54 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * HeaderInfo ::= SEQUENCE {
+ * psid Psid,
+ * generationTime Time64 OPTIONAL,
+ * expiryTime Time64 OPTIONAL,
+ * generationLocation ThreeDLocation OPTIONAL,
+ * p2pcdLearningRequest HashedId3 OPTIONAL,
+ * missingCrlIdentifier MissingCrlIdentifier OPTIONAL,
+ * ...,
+ * inlineP2pcdRequest SequenceOfHashedId3 OPTIONAL,
+ * requestedCertificate Certificate OPTIONAL
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class HeaderInfo
+ extends ASN1Object
+{
+ private HeaderInfo(ASN1Sequence seq)
+ {
+
+ }
+
+ public static HeaderInfo getInstance(Object o)
+ {
+ if (o instanceof HeaderInfo)
+ {
+ return (HeaderInfo)o;
+ }
+ else if (o != null)
+ {
+ return new HeaderInfo(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/IValue.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/IValue.java
new file mode 100644
index 00000000..c9d38ca7
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/IValue.java
@@ -0,0 +1,54 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import java.math.BigInteger;
+
+import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.util.BigIntegers;
+
+/**
+ * <pre>
+ * Uint16 ::= INTEGER (0..65535)
+ *
+ * IValue ::= Uint16
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class IValue
+ extends ASN1Object
+{
+ private final BigInteger value;
+
+ private IValue(ASN1Integer value)
+ {
+ int i = BigIntegers.intValueExact(value.getValue());
+
+ if (i < 0 || i > 65535)
+ {
+ throw new IllegalArgumentException("value out of range");
+ }
+
+ this.value = value.getValue();
+ }
+
+ public static IValue getInstance(Object src)
+ {
+ if (src instanceof IValue)
+ {
+ return (IValue)src;
+ }
+ else if (src != null)
+ {
+ return new IValue(ASN1Integer.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new ASN1Integer(value);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Ieee1609Dot2Content.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Ieee1609Dot2Content.java
new file mode 100644
index 00000000..b3004a68
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Ieee1609Dot2Content.java
@@ -0,0 +1,48 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Choice;
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * Ieee1609Dot2Content ::= CHOICE {
+ * unsecuredData Opaque,
+ * signedData SignedData,
+ * encryptedData EncryptedData,
+ * signedCertificateRequest Opaque,
+ * ...
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Ieee1609Dot2Content
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public static Ieee1609Dot2Content getInstance(Object src)
+ {
+ if (src instanceof Ieee1609Dot2Content)
+ {
+ return (Ieee1609Dot2Content)src;
+ }
+ else if (src != null)
+ {
+ // TODO: need choice processing here
+ return getInstance(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Ieee1609Dot2Data.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Ieee1609Dot2Data.java
new file mode 100644
index 00000000..de2fee7a
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Ieee1609Dot2Data.java
@@ -0,0 +1,59 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import java.math.BigInteger;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * Ieee1609Dot2Data ::= SEQUENCE {
+ * protocolVersion Uint8(3),
+ * content Ieee1609Dot2Content
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Ieee1609Dot2Data
+ extends ASN1Object
+{
+ private final BigInteger protcolVersion;
+ private final Ieee1609Dot2Content content;
+
+ private Ieee1609Dot2Data(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("sequence not length 2");
+ }
+
+ protcolVersion = ASN1Integer.getInstance(seq.getObjectAt(0)).getValue();
+ content = Ieee1609Dot2Content.getInstance(seq.getObjectAt(1));
+ }
+
+ public static Ieee1609Dot2Data getInstance(Object src)
+ {
+ if (src instanceof Ieee1609Dot2Data)
+ {
+ return (Ieee1609Dot2Data)src;
+ }
+ else if (src != null)
+ {
+ return new Ieee1609Dot2Data(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ImplicitCertificate.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ImplicitCertificate.java
new file mode 100644
index 00000000..c45de63c
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ImplicitCertificate.java
@@ -0,0 +1,16 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ImplicitCertificate
+ extends CertificateBase
+{
+ private ImplicitCertificate(ASN1Sequence seq)
+ {
+ super(seq);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/IssuerIdentifier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/IssuerIdentifier.java
new file mode 100644
index 00000000..654f606a
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/IssuerIdentifier.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Choice;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * IssuerIdentifier ::= CHOICE {
+ * sha256AndDigest HashedId8,
+ * self HashAlgorithm,
+ * ...,
+ * sha384AndDigest HashedId8
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class IssuerIdentifier
+ extends ASN1Object
+ implements ASN1Choice
+{
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Latitude.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Latitude.java
new file mode 100644
index 00000000..95bebdb9
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Latitude.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * Latitude ::= NinetyDegreeInt
+ *
+ * NinetyDegreeInt ::= INTEGER {
+ * min (-900000000),
+ * max (900000000),
+ * unknown (900000001)
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Latitude
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/LinkageData.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/LinkageData.java
new file mode 100644
index 00000000..156aa956
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/LinkageData.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * LinkageData ::= SEQUENCE {
+ * iCert IValue,
+ * linkage-value LinkageValue,
+ * group-linkage-value GroupLinkageValue OPTIONAL
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class LinkageData
+ extends ASN1Object
+{
+ private final IValue iCert;
+ private final LinkageValue linkageValue;
+ private final GroupLinkageValue groupLinkageValue;
+
+ private LinkageData(ASN1Sequence seq)
+ {
+ if (seq.size() != 2 && seq.size() != 3)
+ {
+ throw new IllegalArgumentException("sequence must be size 2 or 3");
+ }
+
+ this.iCert = IValue.getInstance(seq.getObjectAt(2));
+ this.linkageValue = LinkageValue.getInstance(seq.getObjectAt(2));
+ this.groupLinkageValue = GroupLinkageValue.getInstance(seq.getObjectAt(2));
+ }
+
+ public static LinkageData getInstance(Object src)
+ {
+ if (src instanceof LinkageData)
+ {
+ return (LinkageData)src;
+ }
+ else if (src != null)
+ {
+ // TODO: need choice processing here
+ return new LinkageData(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/LinkageValue.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/LinkageValue.java
new file mode 100644
index 00000000..fde2a76f
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/LinkageValue.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.DEROctetString;
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * LinkageValue ::= OCTET STRING (SIZE(9))
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class LinkageValue
+ extends ASN1Object
+{
+ private final byte[] value;
+
+ private LinkageValue(ASN1OctetString octs)
+ {
+ this.value = Arrays.clone(Utils.octetStringFixed(octs.getOctets(), 9));
+ }
+
+ public static LinkageValue getInstance(Object src)
+ {
+ if (src instanceof LinkageValue)
+ {
+ return (LinkageValue)src;
+ }
+ else if (src != null)
+ {
+ return new LinkageValue(ASN1OctetString.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new DEROctetString(Arrays.clone(value));
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Longitude.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Longitude.java
new file mode 100644
index 00000000..68fa22e5
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Longitude.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * Latitude ::= OneEightyDegreeInt
+ *
+ * NinetyDegreeInt ::= INTEGER {
+ * min (-17999999999),
+ * max (1800000000),
+ * unknown (1800000001)
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Longitude
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PKRecipientInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PKRecipientInfo.java
new file mode 100644
index 00000000..dd53d94f
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PKRecipientInfo.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * PKRecipientInfo ::= SEQUENCE {
+ * recipientId HashedId8,
+ * encKey EncryptedDataEncryptionKey
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKRecipientInfo
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PolygonalRegion.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PolygonalRegion.java
new file mode 100644
index 00000000..97a7cfb0
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PolygonalRegion.java
@@ -0,0 +1,20 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * SEQUENCE SIZE(3..MAX) OF TwoDLocation
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PolygonalRegion
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PsidGroupPermissions.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PsidGroupPermissions.java
new file mode 100644
index 00000000..1ad2194a
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PsidGroupPermissions.java
@@ -0,0 +1,61 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import java.math.BigInteger;
+
+import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * PsidGroupPermissions ::= SEQUENCE {
+ * subjectPermissions SubjectPermissions,
+ * minChainLength INTEGER DEFAULT 1,
+ * chainLengthRange INTEGER DEFAULT 0,
+ * eeType EndEntityType DEFAULT (app)
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PsidGroupPermissions
+ extends ASN1Object
+{
+ private final SubjectPermissions subjectPermissions;
+ private final BigInteger minChainLength;
+ private final BigInteger chainLengthRange;
+ private final Object eeType;
+
+ private PsidGroupPermissions(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("sequence not length 2");
+ }
+
+ this.subjectPermissions = SubjectPermissions.getInstance(seq.getObjectAt(0));
+ this.minChainLength = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue();
+ this.chainLengthRange = ASN1Integer.getInstance(seq.getObjectAt(2)).getValue();
+ this.eeType = EndEntityType.getInstance(seq.getObjectAt(3));
+ }
+
+ public static PsidGroupPermissions getInstance(Object src)
+ {
+ if (src instanceof PsidGroupPermissions)
+ {
+ return (PsidGroupPermissions)src;
+ }
+ else if (src != null)
+ {
+ return new PsidGroupPermissions(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PsidSspRange.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PsidSspRange.java
new file mode 100644
index 00000000..79469400
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/PsidSspRange.java
@@ -0,0 +1,91 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * PsidSspRange ::= SEQUENCE {
+ * psid Psid,
+ * sspRange SspRange OPTIONAL
+ * }
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PsidSspRange
+ extends ASN1Object
+{
+ private ASN1Integer psid;
+ private SspRange sspRange;
+
+ public PsidSspRange()
+ {
+
+ }
+
+ public static PsidSspRange getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+ else if (src instanceof PsidSspRange)
+ {
+ return (PsidSspRange)src;
+ }
+ else
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(src);
+ PsidSspRange psidSspRange = new PsidSspRange();
+ if (seq.size() < 1 || seq.size() > 2)
+ {
+ throw new IllegalStateException("expected sequences with one or optionally two items");
+ }
+
+ if (seq.size() == 1)
+ {
+ psidSspRange.psid = (ASN1Integer)seq.getObjectAt(0);
+ }
+ if (seq.size() == 2)
+ {
+ psidSspRange.sspRange = SspRange.getInstance(seq.getObjectAt(1));
+ }
+ return psidSspRange;
+ }
+ }
+
+
+ public ASN1Integer getPsid()
+ {
+ return psid;
+ }
+
+ public void setPsid(ASN1Integer psid)
+ {
+ this.psid = psid;
+ }
+
+ public SspRange getSspRange()
+ {
+ return sspRange;
+ }
+
+ public void setSspRange(SspRange sspRange)
+ {
+ this.sspRange = sspRange;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector avec = new ASN1EncodableVector();
+ avec.add(psid);
+ if (sspRange != null)
+ {
+ avec.add(sspRange);
+ }
+ return new DERSequence(avec);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/RecipientInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/RecipientInfo.java
new file mode 100644
index 00000000..cc6b17ac
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/RecipientInfo.java
@@ -0,0 +1,18 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+/**
+ * <pre>
+ * RecipientInfo ::= CHOICE {
+ * pskRecipInfo PreSharedKeyReicpientInfo,
+ * symmRecipInfo SymmRecipientInfo,
+ * certRecipInfo PKRecipientInfo,
+ * signedDataRecipInfo PKRecipientInfo,
+ * rekRecipInfo PKRecipientInfo
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RecipientInfo
+{
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/RectangularRegion.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/RectangularRegion.java
new file mode 100644
index 00000000..3d668889
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/RectangularRegion.java
@@ -0,0 +1,43 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * RectangularRegion ::= SEQUENCE {
+ * northWest TwoDLocation,
+ * southEast TwoDLocation
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RectangularRegion
+ extends ASN1Object
+{
+ private RectangularRegion(ASN1Sequence seq)
+ {
+
+ }
+
+ public static RectangularRegion getInstance(Object o)
+ {
+ if (o instanceof RectangularRegion)
+ {
+ return (RectangularRegion)o;
+ }
+ else if (o != null)
+ {
+ return new RectangularRegion(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfCertificate.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfCertificate.java
new file mode 100644
index 00000000..8bebd2ca
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfCertificate.java
@@ -0,0 +1,24 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SequenceOfCertificate ::= SEQUENCE OF Certificate
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SequenceOfCertificate
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfOctetString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfOctetString.java
new file mode 100644
index 00000000..885f846a
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfOctetString.java
@@ -0,0 +1,70 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DEROctetString;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * SequenceOfOctetString ::= SEQUENCE (SIZE(0..MAX)) OF OCTET STRING (SIZE(0..MAX))
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SequenceOfOctetString
+ extends ASN1Object
+{
+ private byte[][] octetStrings;
+
+ private SequenceOfOctetString(ASN1Sequence seq)
+ {
+ this.octetStrings = toByteArrays(seq);
+ }
+
+ public static SequenceOfOctetString getInstance(Object o)
+ {
+ if (o instanceof SequenceOfOctetString)
+ {
+ return (SequenceOfOctetString)o;
+ }
+ else if (o != null)
+ {
+ return new SequenceOfOctetString(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public int size()
+ {
+ return octetStrings.length;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (int i = 0; i != octetStrings.length; i++)
+ {
+ v.add(new DEROctetString(Arrays.clone(octetStrings[i])));
+ }
+
+ return new DERSequence(v);
+ }
+
+ static byte[][] toByteArrays(ASN1Sequence seq)
+ {
+ byte[][] octetStrings = new byte[seq.size()][];
+ for (int i = 0; i != seq.size(); i++)
+ {
+ octetStrings[i] = ASN1OctetString.getInstance(seq.getObjectAt(i)).getOctets();
+ }
+
+ return octetStrings;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfPsidGroupPermissions.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfPsidGroupPermissions.java
new file mode 100644
index 00000000..0024ae13
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfPsidGroupPermissions.java
@@ -0,0 +1,24 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SEQUENCE OF PsidGroupPermissions
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SequenceOfPsidGroupPermissions
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfRecipientInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfRecipientInfo.java
new file mode 100644
index 00000000..2f23aade
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfRecipientInfo.java
@@ -0,0 +1,24 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SequenceOfRecipientInfo ::= SEQUENCE OF RecipientInfo
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SequenceOfRecipientInfo
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfRectangularRegion.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfRectangularRegion.java
new file mode 100644
index 00000000..d1f4865f
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SequenceOfRectangularRegion.java
@@ -0,0 +1,34 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SequenceOfRectangularRegion ::= SEQUENCE OF RectangularRegion
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SequenceOfRectangularRegion
+ extends ASN1Object
+{
+ private final RectangularRegion[] sequence;
+
+ private SequenceOfRectangularRegion(ASN1Sequence seq)
+ {
+ this.sequence = new RectangularRegion[seq.size()];
+
+ for (int i = 0; i != seq.size(); i++)
+ {
+ sequence[i] = RectangularRegion.getInstance(seq.getObjectAt(i));
+ }
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new DERSequence(sequence);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ServiceSpecificPermissions.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ServiceSpecificPermissions.java
new file mode 100644
index 00000000..527ec47d
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ServiceSpecificPermissions.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ServiceSpecificPermissions
+{
+
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Signature.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Signature.java
new file mode 100644
index 00000000..b8ffc657
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Signature.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Choice;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * Signature ::= CHOICE {
+ * ecdsaNistP256Signature EcdsaP256Signature,
+ * ecdsaBrainpoolP256r1Signature EcdsaP256Signature,
+ * ...
+ * ecdsaBrainpoolP384r1Signature EcdsaP384Signature
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Signature
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SignedData.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SignedData.java
new file mode 100644
index 00000000..fb50ce10
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SignedData.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SignedData ::= SEQUENCE {
+ * hashId HashAlgorithm,
+ * tbsData ToBeSignedData,
+ * signer SignerIdentifier,
+ * signature Signature
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignedData
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SignedDataPayload.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SignedDataPayload.java
new file mode 100644
index 00000000..218e15f0
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SignedDataPayload.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SignedDataPayload ::= SEQUENCE {
+ * data Ieee1609Dot2Data OPTIONAL,
+ * extDataHash HashedData OPTIONAL,
+ * ...
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignedDataPayload
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SignerIdentifier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SignerIdentifier.java
new file mode 100644
index 00000000..925cbec6
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SignerIdentifier.java
@@ -0,0 +1,31 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Choice;
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SignerIdentifier ::= CHOICE {
+ * digest HashedId8,
+ * certificate SequenceOfCertificate,
+ * self NULL,
+ * ...
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignerIdentifier
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SspRange.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SspRange.java
new file mode 100644
index 00000000..7c5903d2
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SspRange.java
@@ -0,0 +1,142 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import java.io.IOException;
+
+import com.android.org.bouncycastle.asn1.ASN1Null;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DERNull;
+
+/**
+ * <pre>
+ * SspRange ::= CHOICE {
+ * opaque SequenceOfOctetString,
+ * all NULL,
+ * ...
+ * bitmapSspRange BitmapSspRange
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SspRange
+ extends ASN1Object
+{
+ private final boolean isAll;
+ private final SequenceOfOctetString opaque;
+ private final BitmapSspRange bitmapSspRange;
+
+ private SspRange()
+ {
+ isAll = true;
+ opaque = null;
+ bitmapSspRange = null;
+ }
+
+ private SspRange(SequenceOfOctetString seq)
+ {
+ this.isAll = false;
+ if (seq.size() != 2)
+ {
+ opaque = seq;
+ bitmapSspRange = null;
+ }
+ else
+ {
+ // ambiguous
+ opaque = SequenceOfOctetString.getInstance(seq);
+
+ BitmapSspRange bitMapRange;
+ try
+ {
+ bitMapRange = BitmapSspRange.getInstance(seq);
+ }
+ catch (IllegalArgumentException e)
+ {
+ bitMapRange = null;
+ }
+
+ bitmapSspRange = bitMapRange;
+ }
+ }
+
+ public SspRange(BitmapSspRange range)
+ {
+ this.isAll = false;
+ this.bitmapSspRange = range;
+ this.opaque = null;
+ }
+
+ public static SspRange getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+
+ if (src instanceof SspRange)
+ {
+ return (SspRange)src;
+ }
+
+ if (src instanceof ASN1Null)
+ {
+ return new SspRange();
+ }
+
+ if (src instanceof ASN1Sequence)
+ {
+ return new SspRange(SequenceOfOctetString.getInstance(src));
+ }
+
+ if (src instanceof byte[])
+ {
+ try
+ {
+ return getInstance(ASN1Primitive.fromByteArray((byte[])src));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to parse encoded general name");
+ }
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance: " + src.getClass().getName());
+ }
+
+ public boolean isAll()
+ {
+ return isAll;
+ }
+
+ public boolean maybeOpaque()
+ {
+ return opaque != null;
+ }
+
+ public BitmapSspRange getBitmapSspRange()
+ {
+ return bitmapSspRange;
+ }
+
+ public SequenceOfOctetString getOpaque()
+ {
+ return opaque;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ if (isAll)
+ {
+ return DERNull.INSTANCE;
+ }
+
+ if (bitmapSspRange != null)
+ {
+ return bitmapSspRange.toASN1Primitive();
+ }
+
+ return opaque.toASN1Primitive();
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SubjectPermissions.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SubjectPermissions.java
new file mode 100644
index 00000000..ce53e77f
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SubjectPermissions.java
@@ -0,0 +1,41 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Choice;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * SubjectPermissions ::= CHOICE {
+ * explicit SequenceOfPsidSspRange,
+ * all NULL,
+ * ...
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SubjectPermissions
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public static SubjectPermissions getInstance(Object src)
+ {
+ if (src instanceof SubjectPermissions)
+ {
+ return (SubjectPermissions)src;
+ }
+ else if (src != null)
+ {
+ // TODO: ....
+ return null;
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SymmAlgorithm.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SymmAlgorithm.java
new file mode 100644
index 00000000..28468a3d
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SymmAlgorithm.java
@@ -0,0 +1,57 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SymmAlgorithm
+ extends ASN1Object
+{
+ public static SymmAlgorithm aes128Ccm = new SymmAlgorithm(new ASN1Enumerated(0));
+ private ASN1Enumerated symmAlgorithm;
+
+ private SymmAlgorithm(ASN1Enumerated symmAlgorithm)
+ {
+ this.symmAlgorithm = symmAlgorithm;
+ }
+
+ public SymmAlgorithm(int ordinal)
+ {
+ this.symmAlgorithm = new ASN1Enumerated(ordinal);
+ }
+
+ public SymmAlgorithm getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+ else if (src instanceof SymmAlgorithm)
+ {
+ return (SymmAlgorithm)src;
+ }
+ else
+ {
+ return new SymmAlgorithm(ASN1Enumerated.getInstance(src));
+ }
+ }
+
+ public ASN1Enumerated getSymmAlgorithm()
+ {
+ return symmAlgorithm;
+ }
+
+ public void setSymmAlgorithm(ASN1Enumerated symmAlgorithm)
+ {
+ this.symmAlgorithm = symmAlgorithm;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return symmAlgorithm.toASN1Primitive();
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SymmRecipientInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SymmRecipientInfo.java
new file mode 100644
index 00000000..1ea2a4a2
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/SymmRecipientInfo.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SymmRecipientInfo ::= SEQUENCE {
+ * recipientId HashedId8,
+ * encKey SymmetricCiphertext
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SymmRecipientInfo
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ToBeSignedCertificate.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ToBeSignedCertificate.java
new file mode 100644
index 00000000..babeee69
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ToBeSignedCertificate.java
@@ -0,0 +1,56 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * ToBeSignedCertificate ::= SEQUENCE {
+ * id CertificateId,
+ * cracaId HashedId3,
+ * crlSeries CrlSeries,
+ * validityPeriod ValidityPeriod,
+ * region GeographicRegion OPTIONAL,
+ * assuranceLevel SubjectAssurance OPTIONAL,
+ * appPermissions SequenceOfPsidSep OPTIONAL,
+ * certIssuePermissions SequenceOfPsidGroupPermissions OPTIONAL,
+ * certRequestPermissions NULL OPTIONAL,
+ * encryptionKey PublicEncryptionKey OPTIONAL,
+ * verifyKeyIndicator VerificationKeyIndicator,
+ * ...
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ToBeSignedCertificate
+ extends ASN1Object
+{
+// private final CertificateId certificateId;
+
+ private ToBeSignedCertificate(ASN1Sequence seq)
+ {
+ //TODO: this.certificateId = CertificateId.
+ }
+
+ public static ToBeSignedCertificate getInstance(Object src)
+ {
+ if (src instanceof ToBeSignedCertificate)
+ {
+ return (ToBeSignedCertificate)src;
+ }
+ else if (src != null)
+ {
+ // TODO: need choice processing here
+ return new ToBeSignedCertificate(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ToBeSignedData.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ToBeSignedData.java
new file mode 100644
index 00000000..8bd2419a
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ToBeSignedData.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * ToBeSignedData ::= SEQUENCE {
+ * payload SignedDataPayload,
+ * headerInfo HeaderInfo
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ToBeSignedData
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/TwoDLocation.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/TwoDLocation.java
new file mode 100644
index 00000000..c6d3ff9b
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/TwoDLocation.java
@@ -0,0 +1,23 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * TwoDLocation ::= SEQUENCE {
+ * latitude Latitude,
+ * longitude Longitude
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TwoDLocation
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Utils.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Utils.java
new file mode 100644
index 00000000..52a91b7b
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/Utils.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.util.Arrays;
+
+class Utils
+{
+ /**
+ * <pre>
+ * OCTET STRING (SIZE(n))
+ * </pre>
+ */
+ static byte[] octetStringFixed(byte[] octets, int n)
+ {
+ if (octets.length != n)
+ {
+ throw new IllegalArgumentException("octet string out of range");
+ }
+
+ return octets;
+ }
+
+ /**
+ * <pre>
+ * OCTET STRING (SIZE(1..32))
+ * </pre>
+ */
+ static byte[] octetStringFixed(byte[] octets)
+ {
+ if (octets.length < 1 || octets.length > 32)
+ {
+ throw new IllegalArgumentException("octet string out of range");
+ }
+
+ return Arrays.clone(octets);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ValidityPeriod.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ValidityPeriod.java
new file mode 100644
index 00000000..ab81f25b
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/ValidityPeriod.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * ValidityPeriod ::= SEQUENCE {
+ * start Time32,
+ * duration Duration
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ValidityPeriod
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/VerificationKeyIndicator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/VerificationKeyIndicator.java
new file mode 100644
index 00000000..f0de0429
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/its/asn1/VerificationKeyIndicator.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.its.asn1;
+
+import com.android.org.bouncycastle.asn1.ASN1Choice;
+import com.android.org.bouncycastle.asn1.ASN1Object;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * VerificationKeyIndicator ::= CHOICE {
+ * verificationKey PublicVerificationKey,
+ * reconstructionValue EccP256CurvePoint,
+ * ...
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class VerificationKeyIndicator
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePrivateKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePrivateKey.java
new file mode 100644
index 00000000..f5edf6d9
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePrivateKey.java
@@ -0,0 +1,105 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce;
+
+import java.io.IOException;
+import java.security.PrivateKey;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * A composite private key class.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CompositePrivateKey
+ implements PrivateKey
+{
+ private final List<PrivateKey> keys;
+
+ /**
+ * Create a composite key containing a single private key.
+ *
+ * @param keys the private keys the composite private key wraps.
+ */
+ public CompositePrivateKey(PrivateKey... keys)
+ {
+ if (keys == null || keys.length == 0)
+ {
+ throw new IllegalArgumentException("at least one public key must be provided");
+ }
+
+ List<PrivateKey> keyList = new ArrayList<PrivateKey>(keys.length);
+ for (int i = 0; i != keys.length; i++)
+ {
+ keyList.add(keys[i]);
+ }
+ this.keys = Collections.unmodifiableList(keyList);
+ }
+
+ /**
+ * Return a list of the component private keys making up this composite.
+ *
+ * @return an immutable list of private keys.
+ */
+ public List<PrivateKey> getPrivateKeys()
+ {
+ return keys;
+ }
+
+ public String getAlgorithm()
+ {
+ return "Composite";
+ }
+
+ public String getFormat()
+ {
+ return "PKCS#8";
+ }
+
+ public byte[] getEncoded()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (int i = 0; i != keys.size(); i++)
+ {
+ v.add(PrivateKeyInfo.getInstance(keys.get(i).getEncoded()));
+ }
+
+ try
+ {
+ return new PrivateKeyInfo(
+ new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to encode composite key: " + e.getMessage());
+ }
+ }
+
+ public int hashCode()
+ {
+ return keys.hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (o instanceof CompositePrivateKey)
+ {
+ return keys.equals(((CompositePrivateKey)o).keys);
+ }
+
+ return false;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePublicKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePublicKey.java
new file mode 100644
index 00000000..d7161e8b
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/CompositePublicKey.java
@@ -0,0 +1,105 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce;
+
+import java.io.IOException;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.org.bouncycastle.asn1.DERSequence;
+import com.android.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+
+/**
+ * A composite key class.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CompositePublicKey
+ implements PublicKey
+{
+ private final List<PublicKey> keys;
+
+ /**
+ * Create a composite key containing a single public key.
+ *
+ * @param keys the public keys the composite key wraps.
+ */
+ public CompositePublicKey(PublicKey... keys)
+ {
+ if (keys == null || keys.length == 0)
+ {
+ throw new IllegalArgumentException("at least one public key must be provided");
+ }
+
+ List<PublicKey> keyList = new ArrayList<PublicKey>(keys.length);
+ for (int i = 0; i != keys.length; i++)
+ {
+ keyList.add(keys[i]);
+ }
+ this.keys = Collections.unmodifiableList(keyList);
+ }
+
+ /**
+ * Return a list of the component private keys making up this composite.
+ *
+ * @return an immutable list of private keys.
+ */
+ public List<PublicKey> getPublicKeys()
+ {
+ return keys;
+ }
+
+ public String getAlgorithm()
+ {
+ return "Composite";
+ }
+
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ public byte[] getEncoded()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (int i = 0; i != keys.size(); i++)
+ {
+ v.add(SubjectPublicKeyInfo.getInstance(keys.get(i).getEncoded()));
+ }
+
+ try
+ {
+ return new SubjectPublicKeyInfo(
+ new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to encode composite key: " + e.getMessage());
+ }
+ }
+
+ public int hashCode()
+ {
+ return keys.hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (o instanceof CompositePublicKey)
+ {
+ return keys.equals(((CompositePublicKey)o).keys);
+ }
+
+ return false;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXCertRevocationChecker.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXCertRevocationChecker.java
new file mode 100644
index 00000000..8be6e2ad
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXCertRevocationChecker.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce;
+
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.Certificate;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PKIXCertRevocationChecker
+{
+ void setParameter(String name, Object value);
+
+ void initialize(PKIXCertRevocationCheckerParameters params)
+ throws CertPathValidatorException;
+
+ void check(Certificate cert)
+ throws CertPathValidatorException;
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXCertRevocationCheckerParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXCertRevocationCheckerParameters.java
new file mode 100644
index 00000000..22780272
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXCertRevocationCheckerParameters.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce;
+
+import java.security.PublicKey;
+import java.security.cert.CertPath;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKIXCertRevocationCheckerParameters
+{
+ private final PKIXExtendedParameters paramsPKIX;
+ private final Date validDate;
+ private final CertPath certPath;
+ private final int index;
+ private final X509Certificate signingCert;
+ private final PublicKey workingPublicKey;
+
+ public PKIXCertRevocationCheckerParameters(PKIXExtendedParameters paramsPKIX, Date validDate, CertPath certPath, int index, X509Certificate signingCert, PublicKey workingPublicKey)
+ {
+ this.paramsPKIX = paramsPKIX;
+ this.validDate = validDate;
+ this.certPath = certPath;
+ this.index = index;
+ this.signingCert = signingCert;
+ this.workingPublicKey = workingPublicKey;
+ }
+
+ public PKIXExtendedParameters getParamsPKIX()
+ {
+ return paramsPKIX;
+ }
+
+ public Date getValidDate()
+ {
+ return new Date(validDate.getTime());
+ }
+
+ public CertPath getCertPath()
+ {
+ return certPath;
+ }
+
+ public int getIndex()
+ {
+ return index;
+ }
+
+ public X509Certificate getSigningCert()
+ {
+ return signingCert;
+ }
+
+ public PublicKey getWorkingPublicKey()
+ {
+ return workingPublicKey;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXCertStoreSelector.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXCertStoreSelector.java
index a2cdb8c7..a893293f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXCertStoreSelector.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXCertStoreSelector.java
@@ -56,6 +56,21 @@ public class PKIXCertStoreSelector<T extends Certificate>
this.baseSelector = baseSelector;
}
+ /**
+ * Return the specific certificate this selector is designed to match.
+ *
+ * @return a specific certificate where the selector has been configured explicitly.
+ */
+ public Certificate getCertificate()
+ {
+ if (baseSelector instanceof X509CertSelector)
+ {
+ return ((X509CertSelector)baseSelector).getCertificate();
+ }
+
+ return null;
+ }
+
public boolean match(Certificate cert)
{
return baseSelector.match(cert);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXExtendedParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXExtendedParameters.java
index e07d5430..25c5f925 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXExtendedParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/PKIXExtendedParameters.java
@@ -24,26 +24,22 @@ public class PKIXExtendedParameters
implements CertPathParameters
{
/**
- * This is the default PKIX validity model. Actually there are two variants
- * of this: The PKIX model and the modified PKIX model. The PKIX model
- * verifies that all involved certificates must have been valid at the
- * current time. The modified PKIX model verifies that all involved
- * certificates were valid at the signing time. Both are indirectly choosen
- * with the {@link PKIXParameters#setDate(Date)} method, so this
- * methods sets the Date when <em>all</em> certificates must have been
- * valid.
+ * This is the default PKIX validity model. Actually there are two variants of this: The PKIX
+ * model and the modified PKIX model. The PKIX model verifies that all involved certificates
+ * must have been valid at the current time. The modified PKIX model verifies that all involved
+ * certificates were valid at the signing time. Both are indirectly chosen with the
+ * {@link PKIXParameters#setDate(Date)} method, so this methods sets the Date when <em>all</em>
+ * certificates must have been valid.
*/
public static final int PKIX_VALIDITY_MODEL = 0;
/**
- * This model uses the following validity model. Each certificate must have
- * been valid at the moment where is was used. That means the end
- * certificate must have been valid at the time the signature was done. The
- * CA certificate which signed the end certificate must have been valid,
- * when the end certificate was signed. The CA (or Root CA) certificate must
- * have been valid, when the CA certificate was signed and so on. So the
- * {@link PKIXParameters#setDate(Date)} method sets the time, when
- * the <em>end certificate</em> must have been valid. It is used e.g.
+ * This model uses the following validity model. Each certificate must have been valid at the
+ * moment when it was used. That means the end certificate must have been valid at the time the
+ * signature was done. The CA certificate which signed the end certificate must have been valid,
+ * when the end certificate was signed. The CA (or Root CA) certificate must have been valid
+ * when the CA certificate was signed, and so on. So the {@link PKIXParameters#setDate(Date)}
+ * method sets the time, when the <em>end certificate</em> must have been valid. It is used e.g.
* in the German signature law.
*/
public static final int CHAIN_VALIDITY_MODEL = 1;
@@ -55,6 +51,7 @@ public class PKIXExtendedParameters
public static class Builder
{
private final PKIXParameters baseParameters;
+ private final Date validityDate;
private final Date date;
private PKIXCertStoreSelector targetConstraints;
@@ -75,8 +72,8 @@ public class PKIXExtendedParameters
{
this.targetConstraints = new PKIXCertStoreSelector.Builder(constraints).build();
}
- Date checkDate = baseParameters.getDate();
- this.date = (checkDate == null) ? new Date() : checkDate;
+ this.validityDate = baseParameters.getDate();
+ this.date = (validityDate == null) ? new Date() : validityDate;
this.revocationEnabled = baseParameters.isRevocationEnabled();
this.trustAnchors = baseParameters.getTrustAnchors();
}
@@ -84,6 +81,7 @@ public class PKIXExtendedParameters
public Builder(PKIXExtendedParameters baseParameters)
{
this.baseParameters = baseParameters.baseParameters;
+ this.validityDate = baseParameters.validityDate;
this.date = baseParameters.date;
this.targetConstraints = baseParameters.targetConstraints;
this.extraCertStores = new ArrayList<PKIXCertStore>(baseParameters.extraCertStores);
@@ -199,6 +197,7 @@ public class PKIXExtendedParameters
private final PKIXParameters baseParameters;
private final PKIXCertStoreSelector targetConstraints;
+ private final Date validityDate;
private final Date date;
private final List<PKIXCertStore> extraCertStores;
private final Map<GeneralName, PKIXCertStore> namedCertificateStoreMap;
@@ -212,6 +211,7 @@ public class PKIXExtendedParameters
private PKIXExtendedParameters(Builder builder)
{
this.baseParameters = builder.baseParameters;
+ this.validityDate = builder.validityDate;
this.date = builder.date;
this.extraCertStores = Collections.unmodifiableList(builder.extraCertStores);
this.namedCertificateStoreMap = Collections.unmodifiableMap(new HashMap<GeneralName, PKIXCertStore>(builder.namedCertificateStoreMap));
@@ -245,14 +245,25 @@ public class PKIXExtendedParameters
return namedCRLStoreMap;
}
+ /**
+ * Returns the time at which to check the validity of the certification path. If {@code null},
+ * the current time is used.
+ *
+ * @return the {@code Date}, or {@code null} if not set
+ */
+ public Date getValidityDate()
+ {
+ return null == validityDate ? null : new Date(validityDate.getTime());
+ }
+
+ /**
+ * @deprecated Use 'getValidityDate' instead (which can return null).
+ */
public Date getDate()
{
return new Date(date.getTime());
}
-
-
-
/**
* Defaults to <code>false</code>.
*
@@ -263,8 +274,6 @@ public class PKIXExtendedParameters
return useDeltas;
}
-
-
/**
* @return Returns the validity model.
* @see #CHAIN_VALIDITY_MODEL
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/interfaces/BCX509Certificate.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/interfaces/BCX509Certificate.java
new file mode 100644
index 00000000..31ac7e05
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/interfaces/BCX509Certificate.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.interfaces;
+
+import com.android.org.bouncycastle.asn1.x500.X500Name;
+import com.android.org.bouncycastle.asn1.x509.TBSCertificate;
+
+/**
+ * Interface exposing some additional methods on a BC native certificate object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface BCX509Certificate
+{
+ /**
+ * Return the certificate issuer as an X500Name.
+ *
+ * @return the issuer.
+ */
+ X500Name getIssuerX500Name();
+
+ /**
+ * Return the ASN.1 class representing the TBSCertificate for this certificate.
+ *
+ * @return the issuer.
+ */
+ TBSCertificate getTBSCertificateNative();
+
+ /**
+ * Return the certificate subject as an X500Name.
+ *
+ * @return the issuer.
+ */
+ X500Name getSubjectX500Name();
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/EC.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/EC.java
index ffaecbf8..2dfdd58d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/EC.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/EC.java
@@ -46,12 +46,12 @@ public class EC
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("AlgorithmParameters.EC", PREFIX + "AlgorithmParametersSpi");
provider.addAttributes("KeyAgreement.ECDH", generalEcAttributes);
provider.addAlgorithm("KeyAgreement.ECDH", PREFIX + "KeyAgreementSpi$DH");
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAttributes("KeyAgreement.ECDHC", generalEcAttributes);
provider.addAlgorithm("KeyAgreement.ECDHC", PREFIX + "KeyAgreementSpi$DHC");
provider.addAttributes("KeyAgreement.ECCDH", generalEcAttributes);
@@ -121,13 +121,9 @@ public class EC
provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_RIPEMD160, PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF");
provider.addAlgorithm("KeyAgreement.ECKAEGWITHRIPEMD160KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF");
- */
- // END Android-removed: Unsupported algorithms
registerOid(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC", new KeyFactorySpi.EC());
- // BEGIN Android-removed: Unsupported algorithms
- /*
registerOid(provider, X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC());
registerOid(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV());
@@ -182,11 +178,8 @@ public class EC
provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA384KDFAndSharedInfo");
provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA512KDFAndSharedInfo");
- */
- // END Android-removed: Unsupported algorithms
registerOid(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC());
- // BEGIN Android-removed: Unsupported algorithms
- /*
+
registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "EC");
registerOid(provider, SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV());
@@ -204,21 +197,13 @@ public class EC
provider.addAlgorithm("KeyFactory.ECMQV", PREFIX + "KeyFactorySpi$ECMQV");
provider.addAlgorithm("KeyPairGenerator.ECMQV", PREFIX + "KeyPairGeneratorSpi$ECMQV");
}
- */
- // END Android-removed: Unsupported algorithms
-
+
provider.addAlgorithm("KeyFactory.EC", PREFIX + "KeyFactorySpi$EC");
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAlgorithm("KeyFactory.ECDSA", PREFIX + "KeyFactorySpi$ECDSA");
provider.addAlgorithm("KeyFactory.ECDH", PREFIX + "KeyFactorySpi$ECDH");
provider.addAlgorithm("KeyFactory.ECDHC", PREFIX + "KeyFactorySpi$ECDHC");
- */
- // END Android-removed: Unsupported algorithms
-
+
provider.addAlgorithm("KeyPairGenerator.EC", PREFIX + "KeyPairGeneratorSpi$EC");
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAlgorithm("KeyPairGenerator.ECDSA", PREFIX + "KeyPairGeneratorSpi$ECDSA");
provider.addAlgorithm("KeyPairGenerator.ECDH", PREFIX + "KeyPairGeneratorSpi$ECDH");
provider.addAlgorithm("KeyPairGenerator.ECDHWITHSHA1KDF", PREFIX + "KeyPairGeneratorSpi$ECDH");
@@ -233,10 +218,7 @@ public class EC
provider.addAlgorithm("Cipher.ECIESWITHDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC");
provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA");
- */
- // END Android-removed: Unsupported algorithms
- // BEGIN Android-changed: Change primary ID from ECDSA to SHA1withECDSA
provider.addAlgorithm("Signature.SHA1withECDSA", PREFIX + "SignatureSpi$ecDSA");
provider.addAlgorithm("Signature.NONEwithECDSA", PREFIX + "SignatureSpi$ecDSAnone");
@@ -247,9 +229,6 @@ public class EC
provider.addAlgorithm("Alg.Alias.Signature.SHA1WithECDSA", "SHA1withECDSA");
provider.addAlgorithm("Alg.Alias.Signature.ECDSAWithSHA1", "SHA1withECDSA");
provider.addAlgorithm("Alg.Alias.Signature.1.2.840.10045.4.1", "SHA1withECDSA");
- // END Android-changed: Change primary ID from ECDSA to SHA1withECDSA
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAlgorithm("Alg.Alias.Signature." + TeleTrusTObjectIdentifiers.ecSignWithSha1, "ECDSA");
provider.addAlgorithm("Signature.ECDDSA", PREFIX + "SignatureSpi$ecDetDSA");
@@ -269,15 +248,11 @@ public class EC
provider.addAlgorithm("Alg.Alias.Signature.SHA256WITHDETECDSA", "SHA256WITHECDDSA");
provider.addAlgorithm("Alg.Alias.Signature.SHA384WITHDETECDSA", "SHA384WITHECDDSA");
provider.addAlgorithm("Alg.Alias.Signature.SHA512WITHDETECDSA", "SHA512WITHECDDSA");
- */
- // END Android-removed: Unsupported algorithms
addSignatureAlgorithm(provider, "SHA224", "ECDSA", PREFIX + "SignatureSpi$ecDSA224", X9ObjectIdentifiers.ecdsa_with_SHA224);
addSignatureAlgorithm(provider, "SHA256", "ECDSA", PREFIX + "SignatureSpi$ecDSA256", X9ObjectIdentifiers.ecdsa_with_SHA256);
addSignatureAlgorithm(provider, "SHA384", "ECDSA", PREFIX + "SignatureSpi$ecDSA384", X9ObjectIdentifiers.ecdsa_with_SHA384);
addSignatureAlgorithm(provider, "SHA512", "ECDSA", PREFIX + "SignatureSpi$ecDSA512", X9ObjectIdentifiers.ecdsa_with_SHA512);
- // BEGIN Android-removed: Unsupported algorithms
- /*
addSignatureAlgorithm(provider, "SHA3-224", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_224", NISTObjectIdentifiers.id_ecdsa_with_sha3_224);
addSignatureAlgorithm(provider, "SHA3-256", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_256", NISTObjectIdentifiers.id_ecdsa_with_sha3_256);
addSignatureAlgorithm(provider, "SHA3-384", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_384", NISTObjectIdentifiers.id_ecdsa_with_sha3_384);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/RSA.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
index cce3129e..c4a04009 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
@@ -43,7 +43,8 @@ public class RSA
public void configure(ConfigurableProvider provider)
{
- provider.addAlgorithm("AlgorithmParameters.OAEP", PREFIX + "AlgorithmParametersSpi$OAEP");
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("AlgorithmParameters.OAEP", PREFIX + "AlgorithmParametersSpi$OAEP");
provider.addAlgorithm("AlgorithmParameters.PSS", PREFIX + "AlgorithmParametersSpi$PSS");
// BEGIN Android-removed: Unsupported algorithms
@@ -102,6 +103,11 @@ public class RSA
provider.addAlgorithm("KeyFactory.RSA", PREFIX + "KeyFactorySpi");
provider.addAlgorithm("KeyPairGenerator.RSA", PREFIX + "KeyPairGeneratorSpi");
+ // BEGIN Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("KeyFactory.RSASSA-PSS", PREFIX + "KeyFactorySpi");
+ // provider.addAlgorithm("KeyPairGenerator.RSASSA-PSS", PREFIX + "KeyPairGeneratorSpi$PSS");
+ // END Android-removed: Unsupported algorithms
+
AsymmetricKeyInfoConverter keyFact = new KeyFactorySpi();
registerOid(provider, PKCSObjectIdentifiers.rsaEncryption, "RSA", keyFact);
@@ -152,43 +158,32 @@ public class RSA
{
addDigestSignature(provider, "MD4", PREFIX + "DigestSignatureSpi$MD4", PKCSObjectIdentifiers.md4WithRSAEncryption);
}
- */
- // END Android-removed: Unsupported algorithms
if (provider.hasAlgorithm("MessageDigest", "MD5"))
{
addDigestSignature(provider, "MD5", PREFIX + "DigestSignatureSpi$MD5", PKCSObjectIdentifiers.md5WithRSAEncryption);
- // Android-removed: Unsupported algorithms
- // addISO9796Signature(provider, "MD5", PREFIX + "ISOSignatureSpi$MD5WithRSAEncryption");
+ addISO9796Signature(provider, "MD5", PREFIX + "ISOSignatureSpi$MD5WithRSAEncryption");
}
if (provider.hasAlgorithm("MessageDigest", "SHA1"))
{
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1withRSA/PSS", "PSS");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1WITHRSAANDMGF1", "PSS");
addPSSSignature(provider, "SHA1", PREFIX + "PSSSignatureSpi$SHA1withRSA");
- */
- // END Android-removed: Unsupported algorithms
addDigestSignature(provider, "SHA1", PREFIX + "DigestSignatureSpi$SHA1", PKCSObjectIdentifiers.sha1WithRSAEncryption);
- // Android-removed: Unsupported algorithms
- // addISO9796Signature(provider, "SHA1", PREFIX + "ISOSignatureSpi$SHA1WithRSAEncryption");
+ addISO9796Signature(provider, "SHA1", PREFIX + "ISOSignatureSpi$SHA1WithRSAEncryption");
provider.addAlgorithm("Alg.Alias.Signature." + OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
provider.addAlgorithm("Alg.Alias.Signature.OID." + OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
- // BEGIN Android-removed: Unsupported algorithms
- // addX931Signature(provider, "SHA1", PREFIX + "X931SignatureSpi$SHA1WithRSAEncryption");
+ addX931Signature(provider, "SHA1", PREFIX + "X931SignatureSpi$SHA1WithRSAEncryption");
}
addDigestSignature(provider, "SHA224", PREFIX + "DigestSignatureSpi$SHA224", PKCSObjectIdentifiers.sha224WithRSAEncryption);
addDigestSignature(provider, "SHA256", PREFIX + "DigestSignatureSpi$SHA256", PKCSObjectIdentifiers.sha256WithRSAEncryption);
addDigestSignature(provider, "SHA384", PREFIX + "DigestSignatureSpi$SHA384", PKCSObjectIdentifiers.sha384WithRSAEncryption);
addDigestSignature(provider, "SHA512", PREFIX + "DigestSignatureSpi$SHA512", PKCSObjectIdentifiers.sha512WithRSAEncryption);
- // BEGIN Android-removed: Unsupported algorithms
- /*
addDigestSignature(provider, "SHA512(224)", PREFIX + "DigestSignatureSpi$SHA512_224", PKCSObjectIdentifiers.sha512_224WithRSAEncryption);
addDigestSignature(provider, "SHA512(256)", PREFIX + "DigestSignatureSpi$SHA512_256", PKCSObjectIdentifiers.sha512_256WithRSAEncryption);
@@ -296,6 +291,10 @@ public class RSA
provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/PSS", digest + "WITHRSAANDMGF1");
provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSAandMGF1", digest + "WITHRSAANDMGF1");
provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSAAndMGF1", digest + "WITHRSAANDMGF1");
+ // BEGIN Android-removed: unsupported algorithms
+ // provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSASSA-PSS", digest + "WITHRSAANDMGF1");
+ // provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSASSA-PSS", digest + "WITHRSAANDMGF1");
+ // provider.addAlgorithm("Alg.Alias.Signature." + digest + "WITHRSASSA-PSS", digest + "WITHRSAANDMGF1");
provider.addAlgorithm("Signature." + digest + "WITHRSAANDMGF1", className);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/X509.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/X509.java
index 4aae9405..5931535d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/X509.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/X509.java
@@ -24,15 +24,17 @@ public class X509
public void configure(ConfigurableProvider provider)
{
// BEGIN Android-removed: Unsupported algorithms
- // provider.addAlgorithm("KeyFactory.X.509", "org.bouncycastle.jcajce.provider.asymmetric.x509.KeyFactory");
- // provider.addAlgorithm("Alg.Alias.KeyFactory.X509", "X.509");
- // END Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("KeyFactory.X.509", "org.bouncycastle.jcajce.provider.asymmetric.x509.KeyFactory");
+ provider.addAlgorithm("Alg.Alias.KeyFactory.X509", "X.509");
//
// certificate factories.
//
- provider.addAlgorithm("CertificateFactory.X.509", "com.android.org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory");
+ provider.addAlgorithm("CertificateFactory.X.509", "org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory");
provider.addAlgorithm("Alg.Alias.CertificateFactory.X509", "X.509");
+ */
+ // END Android-removed: Unsupported algorithms
}
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java
index 39b08a26..4a652215 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java
@@ -56,14 +56,7 @@ public class AlgorithmParameterGeneratorSpi
int certainty = PrimeCertaintyCalculator.getDefaultCertainty(strength);
- if (random != null)
- {
- pGen.init(strength, certainty, random);
- }
- else
- {
- pGen.init(strength, certainty, CryptoServicesRegistrar.getSecureRandom());
- }
+ pGen.init(strength, certainty, CryptoServicesRegistrar.getSecureRandom(random));
DHParameters p = pGen.generateParameters();
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java
index 68bca28d..4dcdf3f6 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java
@@ -28,6 +28,7 @@ import com.android.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
import com.android.org.bouncycastle.crypto.params.DHValidationParameters;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
import com.android.org.bouncycastle.jcajce.spec.DHDomainParameterSpec;
+import com.android.org.bouncycastle.jcajce.spec.DHExtendedPrivateKeySpec;
import com.android.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
@@ -62,7 +63,14 @@ public class BCDHPrivateKey
DHPrivateKeySpec spec)
{
this.x = spec.getX();
- this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
+ if (spec instanceof DHExtendedPrivateKeySpec)
+ {
+ this.dhSpec = ((DHExtendedPrivateKeySpec)spec).getParams();
+ }
+ else
+ {
+ this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
+ }
}
public BCDHPrivateKey(
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java
index d7880142..84c8cd71 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java
@@ -25,6 +25,7 @@ import com.android.org.bouncycastle.crypto.params.DHPublicKeyParameters;
import com.android.org.bouncycastle.crypto.params.DHValidationParameters;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
import com.android.org.bouncycastle.jcajce.spec.DHDomainParameterSpec;
+import com.android.org.bouncycastle.jcajce.spec.DHExtendedPublicKeySpec;
/**
* @hide This class is not part of the Android public SDK API
@@ -44,8 +45,25 @@ public class BCDHPublicKey
DHPublicKeySpec spec)
{
this.y = spec.getY();
- this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
- this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(spec.getP(), spec.getG()));
+ if (spec instanceof DHExtendedPublicKeySpec)
+ {
+ this.dhSpec = ((DHExtendedPublicKeySpec)spec).getParams();
+ }
+ else
+ {
+ this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
+
+ }
+
+ if (dhSpec instanceof DHDomainParameterSpec)
+ {
+ DHDomainParameterSpec dhSp = (DHDomainParameterSpec)dhSpec;
+ this.dhPublicKey = new DHPublicKeyParameters(y, dhSp.getDomainParameters());
+ }
+ else
+ {
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(spec.getP(), spec.getG()));
+ }
}
BCDHPublicKey(
@@ -53,7 +71,15 @@ public class BCDHPublicKey
{
this.y = key.getY();
this.dhSpec = key.getParams();
- this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
+ if (dhSpec instanceof DHDomainParameterSpec)
+ {
+ DHDomainParameterSpec dhSp = (DHDomainParameterSpec)dhSpec;
+ this.dhPublicKey = new DHPublicKeyParameters(y, dhSp.getDomainParameters());
+ }
+ else
+ {
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
+ }
}
BCDHPublicKey(
@@ -109,12 +135,14 @@ public class BCDHPublicKey
if (params.getL() != null)
{
this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue());
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG(), null, dhSpec.getL()));
}
else
{
this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
}
- this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
+
}
else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java
index 42335fb7..b3761663 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java
@@ -55,7 +55,7 @@ public class BCDSAPublicKey
DSAPublicKeyParameters params)
{
this.y = params.getY();
- if (params != null)
+ if (params.getParameters() != null)
{
this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG());
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
index 0ad26090..c7e20d2b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
@@ -2,6 +2,7 @@
package com.android.org.bouncycastle.jcajce.provider.asymmetric.dsa;
import java.math.BigInteger;
+import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.PublicKey;
@@ -144,6 +145,11 @@ public class DSASigner
return signer.verifySignature(hash, sig[0], sig[1]);
}
+ protected AlgorithmParameters engineGetParameters()
+ {
+ return null;
+ }
+
protected void engineSetParameter(
AlgorithmParameterSpec params)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java
index 4b178bd5..69fe872d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java
@@ -81,6 +81,30 @@ public class KeyFactorySpi
throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
}
}
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPublicKeySpec.class) && key instanceof java.security.interfaces.DSAPublicKey)
+ {
+ DSAPublicKey k = (DSAPublicKey)key;
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPublicKeySpec(OpenSSHPublicKeyUtil.encodePublicKey(new DSAPublicKeyParameters(k.getY(), new DSAParameters(k.getParams().getP(), k.getParams().getQ(), k.getParams().getG()))));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec.class) && key instanceof java.security.interfaces.DSAPrivateKey)
+ {
+ DSAPrivateKey k = (DSAPrivateKey)key;
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec(OpenSSHPrivateKeyUtil.encodePrivateKey(new DSAPrivateKeyParameters(k.getX(), new DSAParameters(k.getParams().getP(), k.getParams().getQ(), k.getParams().getG()))));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
*/
// END Android-removed: Unsupported algorithms
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
index 1a5daa94..a1f852f2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
@@ -13,6 +13,7 @@ import com.android.org.bouncycastle.asn1.DERNull;
import com.android.org.bouncycastle.asn1.x9.ECNamedCurveTable;
import com.android.org.bouncycastle.asn1.x9.X962Parameters;
import com.android.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.org.bouncycastle.asn1.x9.X9ECPoint;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
@@ -127,7 +128,7 @@ public class AlgorithmParametersSpi
}
else
{
- ASN1ObjectIdentifier namedCurveOid = ECUtil.getNamedCurveOid(EC5Util.convertSpec(ecParameterSpec, false));
+ ASN1ObjectIdentifier namedCurveOid = ECUtil.getNamedCurveOid(EC5Util.convertSpec(ecParameterSpec));
if (namedCurveOid != null)
{
@@ -163,10 +164,10 @@ public class AlgorithmParametersSpi
}
else
{
- com.android.org.bouncycastle.jce.spec.ECParameterSpec ecSpec = EC5Util.convertSpec(ecParameterSpec, false);
+ com.android.org.bouncycastle.jce.spec.ECParameterSpec ecSpec = EC5Util.convertSpec(ecParameterSpec);
X9ECParameters ecP = new X9ECParameters(
ecSpec.getCurve(),
- ecSpec.getG(),
+ new X9ECPoint(ecSpec.getG(), false),
ecSpec.getN(),
ecSpec.getH(),
ecSpec.getSeed());
@@ -183,6 +184,6 @@ public class AlgorithmParametersSpi
@Override
protected String engineToString()
{
- return "EC AlgorithmParameters ";
+ return "EC Parameters";
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
index c385035a..ced733f3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
@@ -7,7 +7,6 @@ import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.interfaces.ECPrivateKey;
import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.EllipticCurve;
import java.util.Enumeration;
@@ -302,14 +301,14 @@ public class BCECPrivateKey
return null;
}
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
com.android.org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec()
{
if (ecSpec != null)
{
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
return configuration.getEcImplicitlyCa();
@@ -370,11 +369,6 @@ public class BCECPrivateKey
return ECUtil.privateKeyToString("EC", d, engineGetSpec());
}
- private com.android.org.bouncycastle.math.ec.ECPoint calculateQ(com.android.org.bouncycastle.jce.spec.ECParameterSpec spec)
- {
- return spec.getG().multiply(d).normalize();
- }
-
private DERBitString getPublicKeyDetails(BCECPublicKey pub)
{
try
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
index 56c19465..94e74154 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
@@ -10,7 +10,6 @@ import java.security.spec.ECPoint;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.EllipticCurve;
-import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1OctetString;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.DERBitString;
@@ -30,6 +29,7 @@ import com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration
import com.android.org.bouncycastle.jce.interfaces.ECPointEncoder;
import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.android.org.bouncycastle.math.ec.ECCurve;
+import com.android.org.bouncycastle.util.Properties;
/**
* @hide This class is not part of the Android public SDK API
@@ -64,7 +64,7 @@ public class BCECPublicKey
{
this.algorithm = algorithm;
this.ecSpec = spec.getParams();
- this.ecPublicKey = new ECPublicKeyParameters(EC5Util.convertPoint(ecSpec, spec.getW(), false), EC5Util.getDomainParameters(configuration, spec.getParams()));
+ this.ecPublicKey = new ECPublicKeyParameters(EC5Util.convertPoint(ecSpec, spec.getW()), EC5Util.getDomainParameters(configuration, spec.getParams()));
this.configuration = configuration;
}
@@ -168,7 +168,8 @@ public class BCECPublicKey
{
this.algorithm = key.getAlgorithm();
this.ecSpec = key.getParams();
- this.ecPublicKey = new ECPublicKeyParameters(EC5Util.convertPoint(this.ecSpec, key.getW(), false), EC5Util.getDomainParameters(configuration, key.getParams()));
+ this.ecPublicKey = new ECPublicKeyParameters(EC5Util.convertPoint(this.ecSpec, key.getW()), EC5Util.getDomainParameters(configuration, key.getParams()));
+ this.configuration = configuration;
}
BCECPublicKey(
@@ -238,13 +239,16 @@ public class BCECPublicKey
public byte[] getEncoded()
{
- ASN1Encodable params = ECUtils.getDomainParametersFromName(ecSpec, withCompression);
- ASN1OctetString p = ASN1OctetString.getInstance(new X9ECPoint(ecPublicKey.getQ(), withCompression).toASN1Primitive());
+ boolean compress = withCompression || Properties.isOverrideSet("com.android.org.bouncycastle.ec.enable_pc");
- // stored curve is null if ImplicitlyCa
- SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets());
+ AlgorithmIdentifier algId = new AlgorithmIdentifier(
+ X9ObjectIdentifiers.id_ecPublicKey,
+ ECUtils.getDomainParametersFromName(ecSpec, compress));
- return KeyUtil.getEncodedSubjectPublicKeyInfo(info);
+ byte[] pubKeyOctets = ecPublicKey.getQ().getEncoded(compress);
+
+ // stored curve is null if ImplicitlyCa
+ return KeyUtil.getEncodedSubjectPublicKeyInfo(algId, pubKeyOctets);
}
public ECParameterSpec getParams()
@@ -259,7 +263,7 @@ public class BCECPublicKey
return null;
}
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
public ECPoint getW()
@@ -288,7 +292,7 @@ public class BCECPublicKey
{
if (ecSpec != null)
{
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
return configuration.getEcImplicitlyCa();
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
index 020cfc8e..99bdedbb 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
@@ -11,6 +11,7 @@ import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.DERNull;
import com.android.org.bouncycastle.asn1.x9.X962Parameters;
import com.android.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.org.bouncycastle.asn1.x9.X9ECPoint;
import com.android.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
@@ -84,7 +85,7 @@ class ECUtils
X9ECParameters ecP = new X9ECParameters(
curve,
- EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression),
+ new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), withCompression),
ecSpec.getOrder(),
BigInteger.valueOf(ecSpec.getCofactor()),
ecSpec.getCurve().getSeed());
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
index 8877a9d7..72c58805 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
@@ -25,6 +25,8 @@ import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFacto
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+import com.android.org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec;
+import com.android.org.bouncycastle.jcajce.spec.OpenSSHPublicKeySpec;
import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.android.org.bouncycastle.jce.spec.ECParameterSpec;
import com.android.org.bouncycastle.jce.spec.ECPrivateKeySpec;
@@ -72,7 +74,7 @@ public class KeyFactorySpi
Class spec)
throws InvalidKeySpecException
{
- if (spec.isAssignableFrom(java.security.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey)
+ if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(java.security.spec.ECPublicKeySpec.class)) && key instanceof ECPublicKey)
{
ECPublicKey k = (ECPublicKey)key;
if (k.getParams() != null)
@@ -86,7 +88,7 @@ public class KeyFactorySpi
return new java.security.spec.ECPublicKeySpec(k.getW(), EC5Util.convertSpec(EC5Util.convertCurve(implicitSpec.getCurve(), implicitSpec.getSeed()), implicitSpec));
}
}
- else if (spec.isAssignableFrom(java.security.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey)
+ else if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(java.security.spec.ECPrivateKeySpec.class)) && key instanceof ECPrivateKey)
{
ECPrivateKey k = (ECPrivateKey)key;
@@ -106,13 +108,13 @@ public class KeyFactorySpi
ECPublicKey k = (ECPublicKey)key;
if (k.getParams() != null)
{
- return new com.android.org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), EC5Util.convertSpec(k.getParams(), false));
+ return new com.android.org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW()), EC5Util.convertSpec(k.getParams()));
}
else
{
ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
- return new com.android.org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), implicitSpec);
+ return new com.android.org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW()), implicitSpec);
}
}
else if (spec.isAssignableFrom(com.android.org.bouncycastle.jce.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey)
@@ -121,7 +123,7 @@ public class KeyFactorySpi
if (k.getParams() != null)
{
- return new com.android.org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(k.getParams(), false));
+ return new com.android.org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(k.getParams()));
}
else
{
@@ -173,6 +175,46 @@ public class KeyFactorySpi
}
}
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPublicKeySpec.class) && key instanceof ECPublicKey)
+ {
+ if (key instanceof BCECPublicKey)
+ {
+ BCECPublicKey bcPk = (BCECPublicKey)key;
+ ECParameterSpec sc = bcPk.getParameters();
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPublicKeySpec(
+ OpenSSHPublicKeyUtil.encodePublicKey(
+ new ECPublicKeyParameters(bcPk.getQ(), new ECDomainParameters(sc.getCurve(), sc.getG(), sc.getN(), sc.getH(), sc.getSeed()))));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid key type: " + key.getClass().getName());
+ }
+ }
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec.class) && key instanceof ECPrivateKey)
+ {
+ if (key instanceof BCECPrivateKey)
+ {
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec(PrivateKeyInfo.getInstance(key.getEncoded()).parsePrivateKey().toASN1Primitive().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("cannot encoded key: " + e.getMessage());
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid key type: " + key.getClass().getName());
+ }
+ }
*/
// END Android-removed: Unsupported algorithms
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
index ab973039..b2dd4cf2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
@@ -22,6 +22,7 @@ import com.android.org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import com.android.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import com.android.org.bouncycastle.crypto.params.ECPublicKeyParameters;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
import com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.android.org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec;
@@ -160,7 +161,16 @@ public abstract class KeyPairGeneratorSpi
}
else
{
- throw new InvalidAlgorithmParameterException("parameter object not a ECParameterSpec");
+ String name = ECUtil.getNameFrom(params);
+
+ if (name != null)
+ {
+ initializeNamedCurve(name, random);
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("invalid parameterSpec: " + params);
+ }
}
engine.init(param);
@@ -208,8 +218,20 @@ public abstract class KeyPairGeneratorSpi
protected ECKeyGenerationParameters createKeyGenParamsJCE(java.security.spec.ECParameterSpec p, SecureRandom r)
{
+ if (p instanceof ECNamedCurveSpec)
+ {
+ X9ECParameters x9P = ECUtils.getDomainParametersFromName(((ECNamedCurveSpec)p).getName());
+
+ if (x9P != null)
+ {
+ ECDomainParameters dp = new ECDomainParameters(x9P.getCurve(), x9P.getG(), x9P.getN(), x9P.getH());
+
+ return new ECKeyGenerationParameters(dp, r);
+ }
+ }
+
ECCurve curve = EC5Util.convertCurve(p.getCurve());
- ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false);
+ ECPoint g = EC5Util.convertPoint(curve, p.getGenerator());
BigInteger n = p.getOrder();
BigInteger h = BigInteger.valueOf(p.getCofactor());
ECDomainParameters dp = new ECDomainParameters(curve, g, n, h);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
index 9d3f46fd..45431765 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
@@ -1,6 +1,7 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.jcajce.provider.asymmetric.ec;
+import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.PublicKey;
@@ -65,6 +66,11 @@ public class SignatureSpi
}
}
+ protected AlgorithmParameters engineGetParameters()
+ {
+ return null;
+ }
+
/**
* @hide This class is not part of the Android public SDK API
*/
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java
index 01043bde..3e148a27 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java
@@ -2,17 +2,18 @@
package com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa;
import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.spec.RSAPrivateCrtKeySpec;
-import com.android.org.bouncycastle.asn1.DERNull;
-import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import com.android.org.bouncycastle.asn1.pkcs.RSAPrivateKey;
import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
+import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
import com.android.org.bouncycastle.util.Strings;
/**
@@ -50,6 +51,20 @@ public class BCRSAPrivateCrtKey
this.crtCoefficient = key.getQInv();
}
+ BCRSAPrivateCrtKey(
+ AlgorithmIdentifier algorithmIdentifier,
+ RSAPrivateCrtKeyParameters key)
+ {
+ super(algorithmIdentifier, key);
+
+ this.publicExponent = key.getPublicExponent();
+ this.primeP = key.getP();
+ this.primeQ = key.getQ();
+ this.primeExponentP = key.getDP();
+ this.primeExponentQ = key.getDQ();
+ this.crtCoefficient = key.getQInv();
+ }
+
/**
* construct a private key from an RSAPrivateCrtKeySpec
*
@@ -58,6 +73,10 @@ public class BCRSAPrivateCrtKey
BCRSAPrivateCrtKey(
RSAPrivateCrtKeySpec spec)
{
+ super(new RSAPrivateCrtKeyParameters(spec.getModulus(),
+ spec.getPublicExponent(), spec.getPrivateExponent(),
+ spec.getPrimeP(), spec.getPrimeQ(), spec.getPrimeExponentP(), spec.getPrimeExponentQ(), spec.getCrtCoefficient()));
+
this.modulus = spec.getModulus();
this.publicExponent = spec.getPublicExponent();
this.privateExponent = spec.getPrivateExponent();
@@ -76,6 +95,10 @@ public class BCRSAPrivateCrtKey
BCRSAPrivateCrtKey(
RSAPrivateCrtKey key)
{
+ super(new RSAPrivateCrtKeyParameters(key.getModulus(),
+ key.getPublicExponent(), key.getPrivateExponent(),
+ key.getPrimeP(), key.getPrimeQ(), key.getPrimeExponentP(), key.getPrimeExponentQ(), key.getCrtCoefficient()));
+
this.modulus = key.getModulus();
this.publicExponent = key.getPublicExponent();
this.privateExponent = key.getPrivateExponent();
@@ -93,7 +116,7 @@ public class BCRSAPrivateCrtKey
PrivateKeyInfo info)
throws IOException
{
- this(RSAPrivateKey.getInstance(info.parsePrivateKey()));
+ this(info.getPrivateKeyAlgorithm(), RSAPrivateKey.getInstance(info.parsePrivateKey()));
}
/**
@@ -102,6 +125,17 @@ public class BCRSAPrivateCrtKey
BCRSAPrivateCrtKey(
RSAPrivateKey key)
{
+ this(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER, key);
+ }
+
+ BCRSAPrivateCrtKey(
+ AlgorithmIdentifier algorithmIdentifier,
+ RSAPrivateKey key)
+ {
+ super(algorithmIdentifier, new RSAPrivateCrtKeyParameters(key.getModulus(),
+ key.getPublicExponent(), key.getPrivateExponent(),
+ key.getPrime1(), key.getPrime2(), key.getExponent1(), key.getExponent2(), key.getCoefficient()));
+
this.modulus = key.getModulus();
this.publicExponent = key.getPublicExponent();
this.privateExponent = key.getPrivateExponent();
@@ -130,7 +164,7 @@ public class BCRSAPrivateCrtKey
*/
public byte[] getEncoded()
{
- return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPrivateKey(getModulus(), getPublicExponent(), getPrivateExponent(), getPrimeP(), getPrimeQ(), getPrimeExponentP(), getPrimeExponentQ(), getCrtCoefficient()));
+ return KeyUtil.getEncodedPrivateKeyInfo(algorithmIdentifier, new RSAPrivateKey(getModulus(), getPublicExponent(), getPrivateExponent(), getPrimeP(), getPrimeQ(), getPrimeExponentP(), getPrimeExponentQ(), getCrtCoefficient()));
}
/**
@@ -224,6 +258,26 @@ public class BCRSAPrivateCrtKey
&& this.getCrtCoefficient().equals(key.getCrtCoefficient());
}
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
+ this.rsaPrivateKey = new RSAPrivateCrtKeyParameters(this.getModulus(),
+ this.getPublicExponent(), this.getPrivateExponent(),
+ this.getPrimeP(), this.getPrimeQ(),
+ this.getPrimeExponentP(), this.getPrimeExponentQ(), this.getCrtCoefficient());
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+ }
+
public String toString()
{
StringBuffer buf = new StringBuffer();
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java
index 79cc2fb1..3c70d527 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java
@@ -11,7 +11,6 @@ import java.util.Enumeration;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import com.android.org.bouncycastle.asn1.DERNull;
import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.org.bouncycastle.crypto.params.RSAKeyParameters;
@@ -32,18 +31,30 @@ public class BCRSAPrivateKey
protected BigInteger modulus;
protected BigInteger privateExponent;
+ private byte[] algorithmIdentifierEnc = getEncoding(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER);
- private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
+ protected transient AlgorithmIdentifier algorithmIdentifier = BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER;
+ protected transient RSAKeyParameters rsaPrivateKey;
+ protected transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
- protected BCRSAPrivateKey()
+ BCRSAPrivateKey(
+ RSAKeyParameters key)
{
+ this.modulus = key.getModulus();
+ this.privateExponent = key.getExponent();
+ this.rsaPrivateKey = key;
}
BCRSAPrivateKey(
+ AlgorithmIdentifier algID,
RSAKeyParameters key)
{
+ this.algorithmIdentifier = algID;
+ this.algorithmIdentifierEnc = getEncoding(algID);
+
this.modulus = key.getModulus();
this.privateExponent = key.getExponent();
+ this.rsaPrivateKey = key;
}
BCRSAPrivateKey(
@@ -51,6 +62,7 @@ public class BCRSAPrivateKey
{
this.modulus = spec.getModulus();
this.privateExponent = spec.getPrivateExponent();
+ this.rsaPrivateKey = new RSAKeyParameters(true, modulus, privateExponent);
}
BCRSAPrivateKey(
@@ -58,12 +70,17 @@ public class BCRSAPrivateKey
{
this.modulus = key.getModulus();
this.privateExponent = key.getPrivateExponent();
+ this.rsaPrivateKey = new RSAKeyParameters(true, modulus, privateExponent);
}
- BCRSAPrivateKey(com.android.org.bouncycastle.asn1.pkcs.RSAPrivateKey key)
+ BCRSAPrivateKey(AlgorithmIdentifier algID, com.android.org.bouncycastle.asn1.pkcs.RSAPrivateKey key)
{
+ this.algorithmIdentifier = algID;
+ this.algorithmIdentifierEnc = getEncoding(algID);
+
this.modulus = key.getModulus();
this.privateExponent = key.getPrivateExponent();
+ this.rsaPrivateKey = new RSAKeyParameters(true, modulus, privateExponent);
}
public BigInteger getModulus()
@@ -78,6 +95,10 @@ public class BCRSAPrivateKey
public String getAlgorithm()
{
+ if (algorithmIdentifier.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ return "RSASSA-PSS";
+ }
return "RSA";
}
@@ -86,9 +107,14 @@ public class BCRSAPrivateKey
return "PKCS#8";
}
+ RSAKeyParameters engineGetKeyParameters()
+ {
+ return rsaPrivateKey;
+ }
+
public byte[] getEncoded()
{
- return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new com.android.org.bouncycastle.asn1.pkcs.RSAPrivateKey(getModulus(), ZERO, getPrivateExponent(), ZERO, ZERO, ZERO, ZERO, ZERO));
+ return KeyUtil.getEncodedPrivateKeyInfo(algorithmIdentifier, new com.android.org.bouncycastle.asn1.pkcs.RSAPrivateKey(getModulus(), ZERO, getPrivateExponent(), ZERO, ZERO, ZERO, ZERO, ZERO));
}
public boolean equals(Object o)
@@ -138,7 +164,15 @@ public class BCRSAPrivateKey
{
in.defaultReadObject();
+ if (algorithmIdentifierEnc == null)
+ {
+ algorithmIdentifierEnc = getEncoding(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER);
+ }
+
+ this.algorithmIdentifier = AlgorithmIdentifier.getInstance(algorithmIdentifierEnc);
+
this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
+ this.rsaPrivateKey = new RSAKeyParameters(true, modulus, privateExponent);
}
private void writeObject(
@@ -159,4 +193,16 @@ public class BCRSAPrivateKey
return buf.toString();
}
+
+ private static byte[] getEncoding(AlgorithmIdentifier algorithmIdentifier)
+ {
+ try
+ {
+ return algorithmIdentifier.getEncoded();
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java
index 2d502a14..625bd694 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java
@@ -22,20 +22,30 @@ import com.android.org.bouncycastle.util.Strings;
public class BCRSAPublicKey
implements RSAPublicKey
{
- private static final AlgorithmIdentifier DEFAULT_ALGORITHM_IDENTIFIER = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
+ static final AlgorithmIdentifier DEFAULT_ALGORITHM_IDENTIFIER = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
static final long serialVersionUID = 2675817738516720772L;
private BigInteger modulus;
private BigInteger publicExponent;
+
private transient AlgorithmIdentifier algorithmIdentifier;
+ private transient RSAKeyParameters rsaPublicKey;
BCRSAPublicKey(
RSAKeyParameters key)
{
- this.algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER;
+ this(DEFAULT_ALGORITHM_IDENTIFIER, key);
+ }
+
+ BCRSAPublicKey(
+ AlgorithmIdentifier algId,
+ RSAKeyParameters key)
+ {
+ this.algorithmIdentifier = algId;
this.modulus = key.getModulus();
this.publicExponent = key.getExponent();
+ this.rsaPublicKey = key;
}
BCRSAPublicKey(
@@ -44,6 +54,7 @@ public class BCRSAPublicKey
this.algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER;
this.modulus = spec.getModulus();
this.publicExponent = spec.getPublicExponent();
+ this.rsaPublicKey = new RSAKeyParameters(false, modulus, publicExponent);
}
BCRSAPublicKey(
@@ -52,6 +63,7 @@ public class BCRSAPublicKey
this.algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER;
this.modulus = key.getModulus();
this.publicExponent = key.getPublicExponent();
+ this.rsaPublicKey = new RSAKeyParameters(false, modulus, publicExponent);
}
BCRSAPublicKey(
@@ -69,6 +81,7 @@ public class BCRSAPublicKey
this.algorithmIdentifier = info.getAlgorithm();
this.modulus = pubKey.getModulus();
this.publicExponent = pubKey.getPublicExponent();
+ this.rsaPublicKey = new RSAKeyParameters(false, modulus, publicExponent);
}
catch (IOException e)
{
@@ -98,6 +111,10 @@ public class BCRSAPublicKey
public String getAlgorithm()
{
+ if (algorithmIdentifier.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ return "RSASSA-PSS";
+ }
return "RSA";
}
@@ -111,6 +128,11 @@ public class BCRSAPublicKey
return KeyUtil.getEncodedSubjectPublicKeyInfo(algorithmIdentifier, new com.android.org.bouncycastle.asn1.pkcs.RSAPublicKey(getModulus(), getPublicExponent()));
}
+ RSAKeyParameters engineGetKeyParameters()
+ {
+ return rsaPublicKey;
+ }
+
public int hashCode()
{
return this.getModulus().hashCode() ^ this.getPublicExponent().hashCode();
@@ -164,6 +186,7 @@ public class BCRSAPublicKey
{
algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER;
}
+ this.rsaPublicKey = new RSAKeyParameters(false, modulus, publicExponent);
}
private void writeObject(
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java
index 5e39097b..7eb6c7da 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java
@@ -46,19 +46,13 @@ public class KeyFactorySpi
Class spec)
throws InvalidKeySpecException
{
- if (spec.isAssignableFrom(RSAPublicKeySpec.class) && key instanceof RSAPublicKey)
+ if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(RSAPublicKeySpec.class)) && key instanceof RSAPublicKey)
{
RSAPublicKey k = (RSAPublicKey)key;
return new RSAPublicKeySpec(k.getModulus(), k.getPublicExponent());
}
- else if (spec.isAssignableFrom(RSAPrivateKeySpec.class) && key instanceof java.security.interfaces.RSAPrivateKey)
- {
- java.security.interfaces.RSAPrivateKey k = (java.security.interfaces.RSAPrivateKey)key;
-
- return new RSAPrivateKeySpec(k.getModulus(), k.getPrivateExponent());
- }
- else if (spec.isAssignableFrom(RSAPrivateCrtKeySpec.class) && key instanceof RSAPrivateCrtKey)
+ else if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(RSAPrivateCrtKeySpec.class)) && key instanceof RSAPrivateCrtKey)
{
RSAPrivateCrtKey k = (RSAPrivateCrtKey)key;
@@ -69,6 +63,12 @@ public class KeyFactorySpi
k.getPrimeExponentP(), k.getPrimeExponentQ(),
k.getCrtCoefficient());
}
+ else if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(RSAPrivateKeySpec.class)) && key instanceof java.security.interfaces.RSAPrivateKey)
+ {
+ java.security.interfaces.RSAPrivateKey k = (java.security.interfaces.RSAPrivateKey)key;
+
+ return new RSAPrivateKeySpec(k.getModulus(), k.getPrivateExponent());
+ }
// BEGIN Android-removed: Unsupported algorithms
/*
else if (spec.isAssignableFrom(OpenSSHPublicKeySpec.class) && key instanceof RSAPublicKey)
@@ -109,6 +109,44 @@ public class KeyFactorySpi
throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
}
}
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPublicKeySpec.class) && key instanceof RSAPublicKey)
+ {
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPublicKeySpec(
+ OpenSSHPublicKeyUtil.encodePublicKey(
+ new RSAKeyParameters(
+ false,
+ ((RSAPublicKey)key).getModulus(),
+ ((RSAPublicKey)key).getPublicExponent())
+ )
+ );
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec.class) && key instanceof RSAPrivateCrtKey)
+ {
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec(OpenSSHPrivateKeyUtil.encodePrivateKey(new RSAPrivateCrtKeyParameters(
+ ((RSAPrivateCrtKey)key).getModulus(),
+ ((RSAPrivateCrtKey)key).getPublicExponent(),
+ ((RSAPrivateCrtKey)key).getPrivateExponent(),
+ ((RSAPrivateCrtKey)key).getPrimeP(),
+ ((RSAPrivateCrtKey)key).getPrimeQ(),
+ ((RSAPrivateCrtKey)key).getPrimeExponentP(),
+ ((RSAPrivateCrtKey)key).getPrimeExponentQ(),
+ ((RSAPrivateCrtKey)key).getCrtCoefficient()
+ )));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
*/
// END Android-removed: Unsupported algorithms
@@ -227,7 +265,7 @@ public class KeyFactorySpi
if (rsaPrivKey.getCoefficient().intValue() == 0)
{
- return new BCRSAPrivateKey(rsaPrivKey);
+ return new BCRSAPrivateKey(keyInfo.getPrivateKeyAlgorithm(), rsaPrivKey);
}
else
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java
index 9b773119..a4985fdd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java
@@ -8,6 +8,9 @@ import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
+import com.android.org.bouncycastle.asn1.DERNull;
+import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.generators.RSAKeyPairGenerator;
@@ -22,27 +25,33 @@ import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.PrimeCertain
public class KeyPairGeneratorSpi
extends java.security.KeyPairGenerator
{
- public KeyPairGeneratorSpi(
- String algorithmName)
- {
- super(algorithmName);
- }
+ private static final AlgorithmIdentifier PKCS_ALGID = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
+ private static final AlgorithmIdentifier PSS_ALGID = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS);
final static BigInteger defaultPublicExponent = BigInteger.valueOf(0x10001);
RSAKeyGenerationParameters param;
RSAKeyPairGenerator engine;
+ AlgorithmIdentifier algId;
- public KeyPairGeneratorSpi()
+ public KeyPairGeneratorSpi(
+ String algorithmName,
+ AlgorithmIdentifier algId)
{
- super("RSA");
+ super(algorithmName);
+ this.algId = algId;
engine = new RSAKeyPairGenerator();
param = new RSAKeyGenerationParameters(defaultPublicExponent,
CryptoServicesRegistrar.getSecureRandom(), 2048, PrimeCertaintyCalculator.getDefaultCertainty(2048));
engine.init(param);
}
+ public KeyPairGeneratorSpi()
+ {
+ this("RSA", PKCS_ALGID);
+ }
+
public void initialize(
int strength,
SecureRandom random)
@@ -81,7 +90,19 @@ public class KeyPairGeneratorSpi
RSAKeyParameters pub = (RSAKeyParameters)pair.getPublic();
RSAPrivateCrtKeyParameters priv = (RSAPrivateCrtKeyParameters)pair.getPrivate();
- return new KeyPair(new BCRSAPublicKey(pub),
- new BCRSAPrivateCrtKey(priv));
+ return new KeyPair(new BCRSAPublicKey(algId, pub),
+ new BCRSAPrivateCrtKey(algId, priv));
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PSS
+ extends KeyPairGeneratorSpi
+ {
+ public PSS()
+ {
+ super("RSASSA-PSS", PSS_ALGID);
+ }
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java
index 49b1c33a..7e8d58ef 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java
@@ -45,13 +45,22 @@ public class RSAUtil
static RSAKeyParameters generatePublicKeyParameter(
RSAPublicKey key)
{
- return new RSAKeyParameters(false, key.getModulus(), key.getPublicExponent());
+ if (key instanceof BCRSAPublicKey)
+ {
+ return ((BCRSAPublicKey)key).engineGetKeyParameters();
+ }
+ return new RSAKeyParameters(false, key.getModulus(), key.getPublicExponent());
}
static RSAKeyParameters generatePrivateKeyParameter(
RSAPrivateKey key)
{
+ if (key instanceof BCRSAPrivateKey)
+ {
+ return ((BCRSAPrivateKey)key).engineGetKeyParameters();
+ }
+
if (key instanceof RSAPrivateCrtKey)
{
RSAPrivateCrtKey k = (RSAPrivateCrtKey)key;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
index 24e2e95f..78423c3c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
@@ -14,12 +14,16 @@ import java.util.Map;
import java.util.Set;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
+// import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters;
import com.android.org.bouncycastle.asn1.x9.ECNamedCurveTable;
import com.android.org.bouncycastle.asn1.x9.X962Parameters;
import com.android.org.bouncycastle.asn1.x9.X9ECParameters;
import com.android.org.bouncycastle.crypto.ec.CustomNamedCurves;
import com.android.org.bouncycastle.crypto.params.ECDomainParameters;
import com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
+// import org.bouncycastle.jce.ECGOST3410NamedCurveTable;
import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.android.org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import com.android.org.bouncycastle.jce.spec.ECNamedCurveSpec;
@@ -98,15 +102,33 @@ public class EC5Util
{
curve = configuration.getEcImplicitlyCa().getCurve();
}
- else if (acceptableCurves.isEmpty())
- {
- X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
-
- curve = ecP.getCurve();
- }
else
{
- throw new IllegalStateException("encoded parameters not acceptable");
+ ASN1Sequence pSeq = ASN1Sequence.getInstance(params.getParameters());
+ if (acceptableCurves.isEmpty())
+ {
+ if (pSeq.size() > 3)
+ {
+ X9ECParameters ecP = X9ECParameters.getInstance(pSeq);
+
+ curve = ecP.getCurve();
+ }
+ else // GOST parameters
+ {
+ // BEGIN Android-removed: unsupported algorithms
+ /*
+ ASN1ObjectIdentifier gostCurve = ASN1ObjectIdentifier.getInstance(pSeq.getObjectAt(0));
+
+ curve = ECGOST3410NamedCurves.getByOIDX9(gostCurve).getCurve();
+ */
+ // END Android-removed: unsupported algorithms
+ throw new IllegalStateException("GOST is not supported");
+ }
+ }
+ else
+ {
+ throw new IllegalStateException("encoded parameters not acceptable");
+ }
}
return curve;
@@ -126,7 +148,7 @@ public class EC5Util
}
else
{
- domainParameters = ECUtil.getDomainParameters(configuration, convertSpec(params, false));
+ domainParameters = ECUtil.getDomainParameters(configuration, convertSpec(params));
}
return domainParameters;
@@ -166,25 +188,51 @@ public class EC5Util
}
else
{
- X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
+ ASN1Sequence pSeq = ASN1Sequence.getInstance(params.getParameters());
+ if (pSeq.size() > 3)
+ {
+ X9ECParameters ecP = X9ECParameters.getInstance(pSeq);
- ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
+ ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
- if (ecP.getH() != null)
- {
- ecSpec = new ECParameterSpec(
- ellipticCurve,
- convertPoint(ecP.getG()),
- ecP.getN(),
- ecP.getH().intValue());
+ if (ecP.getH() != null)
+ {
+ ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ convertPoint(ecP.getG()),
+ ecP.getN(),
+ ecP.getH().intValue());
+ }
+ else
+ {
+ ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ convertPoint(ecP.getG()),
+ ecP.getN(),
+ 1); // TODO: not strictly correct... need to fix the test data...
+ }
}
- else
+ else // GOST parameters
{
- ecSpec = new ECParameterSpec(
+ // BEGIN Android-removed: unsupported algorithms
+ /*
+ GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(pSeq);
+
+ ECNamedCurveParameterSpec spec = ECGOST3410NamedCurveTable.getParameterSpec(ECGOST3410NamedCurves.getName(
+ gostParams.getPublicKeyParamSet()));
+
+ curve = spec.getCurve();
+ ellipticCurve = EC5Util.convertCurve(curve, spec.getSeed());
+
+ ecSpec = new ECNamedCurveSpec(
+ ECGOST3410NamedCurves.getName(gostParams.getPublicKeyParamSet()),
ellipticCurve,
- convertPoint(ecP.getG()),
- ecP.getN(),
- 1); // TODO: not strictly correct... need to fix the test data...
+ EC5Util.convertPoint(spec.getG()),
+ spec.getN(), spec.getH());
+
+ */
+ // END Android-removed: unsupported algorithms
+ ecSpec = null;
}
}
@@ -269,64 +317,46 @@ public class EC5Util
EllipticCurve ellipticCurve,
com.android.org.bouncycastle.jce.spec.ECParameterSpec spec)
{
+ ECPoint g = convertPoint(spec.getG());
+
if (spec instanceof ECNamedCurveParameterSpec)
{
- return new ECNamedCurveSpec(
- ((ECNamedCurveParameterSpec)spec).getName(),
- ellipticCurve,
- convertPoint(spec.getG()),
- spec.getN(),
- spec.getH());
+ String name = ((ECNamedCurveParameterSpec)spec).getName();
+
+ return new ECNamedCurveSpec(name, ellipticCurve, g, spec.getN(), spec.getH());
}
else
{
- return new ECParameterSpec(
- ellipticCurve,
- convertPoint(spec.getG()),
- spec.getN(),
- spec.getH().intValue());
+ return new ECParameterSpec(ellipticCurve, g, spec.getN(), spec.getH().intValue());
}
}
- public static com.android.org.bouncycastle.jce.spec.ECParameterSpec convertSpec(
- ECParameterSpec ecSpec,
- boolean withCompression)
+ public static com.android.org.bouncycastle.jce.spec.ECParameterSpec convertSpec(ECParameterSpec ecSpec)
{
ECCurve curve = convertCurve(ecSpec.getCurve());
+ com.android.org.bouncycastle.math.ec.ECPoint g = convertPoint(curve, ecSpec.getGenerator());
+ BigInteger n = ecSpec.getOrder();
+ BigInteger h = BigInteger.valueOf(ecSpec.getCofactor());
+ byte[] seed = ecSpec.getCurve().getSeed();
+
if (ecSpec instanceof ECNamedCurveSpec)
{
- return new com.android.org.bouncycastle.jce.spec.ECNamedCurveParameterSpec(
- ((ECNamedCurveSpec)ecSpec).getName(),
- curve,
- convertPoint(curve, ecSpec.getGenerator(), withCompression),
- ecSpec.getOrder(),
- BigInteger.valueOf(ecSpec.getCofactor()),
- ecSpec.getCurve().getSeed());
+ return new com.android.org.bouncycastle.jce.spec.ECNamedCurveParameterSpec(((ECNamedCurveSpec)ecSpec).getName(), curve,
+ g, n, h, seed);
}
else
{
- return new com.android.org.bouncycastle.jce.spec.ECParameterSpec(
- curve,
- convertPoint(curve, ecSpec.getGenerator(), withCompression),
- ecSpec.getOrder(),
- BigInteger.valueOf(ecSpec.getCofactor()),
- ecSpec.getCurve().getSeed());
+ return new com.android.org.bouncycastle.jce.spec.ECParameterSpec(curve, g, n, h, seed);
}
}
- public static com.android.org.bouncycastle.math.ec.ECPoint convertPoint(
- ECParameterSpec ecSpec,
- ECPoint point,
- boolean withCompression)
+ public static com.android.org.bouncycastle.math.ec.ECPoint convertPoint(ECParameterSpec ecSpec, ECPoint point)
{
- return convertPoint(convertCurve(ecSpec.getCurve()), point, withCompression);
+ return convertPoint(convertCurve(ecSpec.getCurve()), point);
}
- public static com.android.org.bouncycastle.math.ec.ECPoint convertPoint(
- ECCurve curve,
- ECPoint point,
- boolean withCompression)
+ public static com.android.org.bouncycastle.math.ec.ECPoint convertPoint(ECCurve curve, ECPoint point)
{
return curve.createPoint(point.getAffineX(), point.getAffineY());
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
index 86ba281e..e3ea672b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
@@ -1,10 +1,14 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.jcajce.provider.asymmetric.util;
+import java.lang.reflect.Method;
import java.math.BigInteger;
+import java.security.AccessController;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
+import java.security.PrivilegedAction;
import java.security.PublicKey;
+import java.security.spec.AlgorithmParameterSpec;
import java.util.Enumeration;
import java.util.Map;
@@ -28,6 +32,7 @@ import com.android.org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import com.android.org.bouncycastle.jce.spec.ECParameterSpec;
import com.android.org.bouncycastle.math.ec.ECCurve;
import com.android.org.bouncycastle.math.ec.ECPoint;
+import com.android.org.bouncycastle.math.ec.FixedPointCombMultiplier;
import com.android.org.bouncycastle.util.Arrays;
import com.android.org.bouncycastle.util.Fingerprint;
import com.android.org.bouncycastle.util.Strings;
@@ -152,7 +157,7 @@ public class ECUtil
ecP = (X9ECParameters)extraCurves.get(oid);
}
- domainParameters = new ECNamedDomainParameters(oid, ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed());
+ domainParameters = new ECNamedDomainParameters(oid, ecP);
}
else if (params.isImplicitlyCA())
{
@@ -186,9 +191,9 @@ public class ECUtil
else if (key instanceof java.security.interfaces.ECPublicKey)
{
java.security.interfaces.ECPublicKey pubKey = (java.security.interfaces.ECPublicKey)key;
- ECParameterSpec s = EC5Util.convertSpec(pubKey.getParams(), false);
+ ECParameterSpec s = EC5Util.convertSpec(pubKey.getParams());
return new ECPublicKeyParameters(
- EC5Util.convertPoint(pubKey.getParams(), pubKey.getW(), false),
+ EC5Util.convertPoint(pubKey.getParams(), pubKey.getW()),
new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
}
else
@@ -251,7 +256,7 @@ public class ECUtil
else if (key instanceof java.security.interfaces.ECPrivateKey)
{
java.security.interfaces.ECPrivateKey privKey = (java.security.interfaces.ECPrivateKey)key;
- ECParameterSpec s = EC5Util.convertSpec(privKey.getParams(), false);
+ ECParameterSpec s = EC5Util.convertSpec(privKey.getParams());
return new ECPrivateKeyParameters(
privKey.getS(),
new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
@@ -386,7 +391,7 @@ public class ECUtil
StringBuffer buf = new StringBuffer();
String nl = Strings.lineSeparator();
- com.android.org.bouncycastle.math.ec.ECPoint q = calculateQ(d, spec);
+ com.android.org.bouncycastle.math.ec.ECPoint q = new FixedPointCombMultiplier().multiply(spec.getG(), d).normalize();
buf.append(algorithm);
buf.append(" Private Key [").append(ECUtil.generateKeyFingerprint(q, spec)).append("]").append(nl);
@@ -396,11 +401,6 @@ public class ECUtil
return buf.toString();
}
- private static com.android.org.bouncycastle.math.ec.ECPoint calculateQ(BigInteger d, com.android.org.bouncycastle.jce.spec.ECParameterSpec spec)
- {
- return spec.getG().multiply(d).normalize();
- }
-
public static String publicKeyToString(String algorithm, com.android.org.bouncycastle.math.ec.ECPoint q, com.android.org.bouncycastle.jce.spec.ECParameterSpec spec)
{
StringBuffer buf = new StringBuffer();
@@ -426,4 +426,26 @@ public class ECUtil
return new Fingerprint(publicPoint.getEncoded(false)).toString();
}
+
+ public static String getNameFrom(final AlgorithmParameterSpec paramSpec)
+ {
+ return (String)AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ try
+ {
+ Method m = paramSpec.getClass().getMethod("getName");
+
+ return m.invoke(paramSpec);
+ }
+ catch (Exception e)
+ {
+ // ignore - maybe log?
+ }
+
+ return null;
+ }
+ });
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java
index 1fdfb6f5..9f2332f8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java
@@ -87,13 +87,12 @@ public class PKCS12BagAttributeCarrierImpl
else
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
- Enumeration e = this.getBagAttributeKeys();
+ ASN1OutputStream aOut = ASN1OutputStream.create(bOut);
+ Enumeration e = this.getBagAttributeKeys();
while (e.hasMoreElements())
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(e.nextElement());
aOut.writeObject(oid);
aOut.writeObject((ASN1Encodable)pkcs12Attributes.get(oid));
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
index b0483e48..452d3867 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
@@ -9,43 +9,64 @@ import com.android.org.bouncycastle.util.encoders.Base64;
class PEMUtil
{
- private final String _header1;
- private final String _header2;
- private final String _header3;
- private final String _footer1;
- private final String _footer2;
- private final String _footer3;
-
- PEMUtil(
- String type)
+ /**
+ * Boundary class. Keeps track of the required header/footer pair for the
+ * current PEM object.
+ *
+ */
+ private class Boundaries
{
- _header1 = "-----BEGIN " + type + "-----";
- _header2 = "-----BEGIN X509 " + type + "-----";
- _header3 = "-----BEGIN PKCS7-----";
- _footer1 = "-----END " + type + "-----";
- _footer2 = "-----END X509 " + type + "-----";
- _footer3 = "-----END PKCS7-----";
+ private final String _header;
+ private final String _footer;
+
+ private Boundaries(String type)
+ {
+ this._header = "-----BEGIN " + type + "-----";
+ this._footer = "-----END " + type + "-----";
+ }
+
+ public boolean isTheExpectedHeader(String line)
+ {
+ return line.startsWith(_header);
+ }
+
+ public boolean isTheExpectedFooter(String line)
+ {
+ return line.startsWith(_footer);
+ }
}
- private String readLine(
- InputStream in)
- throws IOException
+ private final Boundaries[] _supportedBoundaries;
+
+ PEMUtil(String type)
{
- int c;
+ _supportedBoundaries = new Boundaries[]
+ { new Boundaries(type), new Boundaries("X509 " + type),
+ new Boundaries("PKCS7") };
+ }
+
+ private String readLine(InputStream in) throws IOException
+ {
+ int c;
StringBuffer l = new StringBuffer();
do
{
while (((c = in.read()) != '\r') && c != '\n' && (c >= 0))
{
- l.append((char)c);
+ l.append((char) c);
}
}
while (c >= 0 && l.length() == 0);
-
+
if (c < 0)
{
- return null;
+ // make sure to return the read bytes if the end of file is encountered
+ if (l.length() == 0)
+ {
+ return null;
+ }
+ return l.toString();
}
// make sure we parse to end of line.
@@ -67,6 +88,30 @@ class PEMUtil
return l.toString();
}
+ /**
+ * Returns a {@link Boundaries} object representing the passed in boundary
+ * string.
+ *
+ * @param line the boundary string
+ * @return the {@link Boundaries} object corresponding to the given boundary
+ * string or <code>null</code> if the passed in string is not a valid
+ * boundary.
+ */
+ private Boundaries getBoundaries(String line)
+ {
+ for (int i = 0; i != _supportedBoundaries.length; i++)
+ {
+ Boundaries boundary = _supportedBoundaries[i];
+
+ if (boundary.isTheExpectedHeader(line) || boundary.isTheExpectedFooter(line))
+ {
+ return boundary;
+ }
+ }
+
+ return null;
+ }
+
ASN1Sequence readPEMObject(
InputStream in)
throws IOException
@@ -74,22 +119,43 @@ class PEMUtil
String line;
StringBuffer pemBuf = new StringBuffer();
- while ((line = readLine(in)) != null)
+ Boundaries header = null;
+
+ while (header == null && (line = readLine(in)) != null)
{
- if (line.startsWith(_header1) || line.startsWith(_header2) || line.startsWith(_header3))
+ header = getBoundaries(line);
+ if (header != null && !header.isTheExpectedHeader(line))
{
- break;
+ throw new IOException("malformed PEM data: found footer where header was expected");
}
}
- while ((line = readLine(in)) != null)
+ if (header == null)
+ {
+ throw new IOException("malformed PEM data: no header found");
+ }
+
+ Boundaries footer = null;
+
+ while (footer == null && (line = readLine(in)) != null)
{
- if (line.startsWith(_footer1) || line.startsWith(_footer2) || line.startsWith(_footer3))
+ footer = getBoundaries(line);
+ if (footer != null)
{
- break;
+ if (!header.isTheExpectedFooter(line))
+ {
+ throw new IOException("malformed PEM data: header/footer mismatch");
+ }
}
+ else
+ {
+ pemBuf.append(line);
+ }
+ }
- pemBuf.append(line);
+ if (footer == null)
+ {
+ throw new IOException("malformed PEM data: no footer found");
}
if (pemBuf.length() != 0)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureCreator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureCreator.java
new file mode 100644
index 00000000..404021b0
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureCreator.java
@@ -0,0 +1,12 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Signature;
+
+interface SignatureCreator
+{
+ Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java
index f9c39a8b..ad7a4aee 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java
@@ -37,8 +37,9 @@ class X509CRLEntryObject extends X509CRLEntry
private TBSCertList.CRLEntry c;
private X500Name certificateIssuer;
- private int hashValue;
- private boolean isHashValueSet;
+
+ private volatile boolean hashValueSet;
+ private volatile int hashValue;
protected X509CRLEntryObject(TBSCertList.CRLEntry c)
{
@@ -203,27 +204,35 @@ class X509CRLEntryObject extends X509CRLEntry
*/
public int hashCode()
{
- if (!isHashValueSet)
+ if (!hashValueSet)
{
hashValue = super.hashCode();
- isHashValueSet = true;
+ hashValueSet = true;
}
return hashValue;
}
- public boolean equals(Object o)
+ public boolean equals(Object other)
{
- if (o == this)
+ if (other == this)
{
return true;
}
- if (o instanceof X509CRLEntryObject)
+ if (other instanceof X509CRLEntryObject)
{
- X509CRLEntryObject other = (X509CRLEntryObject)o;
+ X509CRLEntryObject otherBC = (X509CRLEntryObject)other;
+
+ if (this.hashValueSet && otherBC.hashValueSet)
+ {
+ if (this.hashValue != otherBC.hashValue)
+ {
+ return false;
+ }
+ }
- return this.c.equals(other.c);
+ return this.c.equals(otherBC.c);
}
return super.equals(this);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
new file mode 100644
index 00000000..fcf84c8d
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
@@ -0,0 +1,737 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CRLException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.org.bouncycastle.asn1.ASN1Integer;
+import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DERBitString;
+import com.android.org.bouncycastle.asn1.util.ASN1Dump;
+import com.android.org.bouncycastle.asn1.x500.X500Name;
+import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.org.bouncycastle.asn1.x509.CRLDistPoint;
+import com.android.org.bouncycastle.asn1.x509.CRLNumber;
+import com.android.org.bouncycastle.asn1.x509.CertificateList;
+import com.android.org.bouncycastle.asn1.x509.Extension;
+import com.android.org.bouncycastle.asn1.x509.Extensions;
+import com.android.org.bouncycastle.asn1.x509.GeneralNames;
+import com.android.org.bouncycastle.asn1.x509.IssuingDistributionPoint;
+import com.android.org.bouncycastle.asn1.x509.TBSCertList;
+import com.android.org.bouncycastle.asn1.x509.Time;
+import com.android.org.bouncycastle.jcajce.CompositePublicKey;
+import com.android.org.bouncycastle.jcajce.io.OutputStreamFactory;
+import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.org.bouncycastle.jce.X509Principal;
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Strings;
+
+/**
+ * The following extensions are listed in RFC 2459 as relevant to CRLs
+ * <p>
+ * Authority Key Identifier
+ * Issuer Alternative Name
+ * CRL Number
+ * Delta CRL Indicator (critical)
+ * Issuing Distribution Point (critical)
+ */
+abstract class X509CRLImpl
+ extends X509CRL
+{
+ protected JcaJceHelper bcHelper;
+ protected CertificateList c;
+ protected String sigAlgName;
+ protected byte[] sigAlgParams;
+ protected boolean isIndirect;
+
+ X509CRLImpl(JcaJceHelper bcHelper, CertificateList c, String sigAlgName, byte[] sigAlgParams, boolean isIndirect)
+ {
+ this.bcHelper = bcHelper;
+ this.c = c;
+ this.sigAlgName = sigAlgName;
+ this.sigAlgParams = sigAlgParams;
+ this.isIndirect = isIndirect;
+ }
+
+ /**
+ * Will return true if any extensions are present and marked
+ * as critical as we currently dont handle any extensions!
+ */
+ public boolean hasUnsupportedCriticalExtension()
+ {
+ Set extns = getCriticalExtensionOIDs();
+
+ if (extns == null)
+ {
+ return false;
+ }
+
+ extns.remove(Extension.issuingDistributionPoint.getId());
+ extns.remove(Extension.deltaCRLIndicator.getId());
+
+ return !extns.isEmpty();
+ }
+
+ private Set getExtensionOIDs(boolean critical)
+ {
+ if (this.getVersion() == 2)
+ {
+ Extensions extensions = c.getTBSCertList().getExtensions();
+
+ if (extensions != null)
+ {
+ Set set = new HashSet();
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (critical == ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+ }
+
+ return null;
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(true);
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(false);
+ }
+
+ public byte[] getExtensionValue(String oid)
+ {
+ ASN1OctetString extValue = getExtensionValue(c, oid);
+ if (null != extValue)
+ {
+ try
+ {
+ return extValue.getEncoded();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException("error parsing " + e.toString());
+ }
+ }
+ return null;
+ }
+
+ public byte[] getEncoded()
+ throws CRLException
+ {
+ try
+ {
+ return c.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CRLException(e.toString());
+ }
+ }
+
+ public void verify(PublicKey key)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ try
+ {
+ return bcHelper.createSignature(sigName);
+ }
+ catch (Exception e)
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+
+ public void verify(PublicKey key, final String sigProvider)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ if (sigProvider != null)
+ {
+ return Signature.getInstance(sigName, sigProvider);
+ }
+ else
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+
+ public void verify(PublicKey key, final Provider sigProvider)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
+ try
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ if (sigProvider != null)
+ {
+ return Signature.getInstance(getSigAlgName(), sigProvider);
+ }
+ else
+ {
+ return Signature.getInstance(getSigAlgName());
+ }
+ }
+ });
+ }
+ catch (NoSuchProviderException e)
+ {
+ // can't happen, but just in case
+ throw new NoSuchAlgorithmException("provider issue: " + e.getMessage());
+ }
+ }
+
+ private void doVerify(PublicKey key, SignatureCreator sigCreator)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException, NoSuchProviderException
+ {
+ if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature()))
+ {
+ throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList.");
+ }
+
+ if (key instanceof CompositePublicKey && X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
+ {
+ List<PublicKey> pubKeys = ((CompositePublicKey)key).getPublicKeys();
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+
+ boolean success = false;
+ for (int i = 0; i != pubKeys.size(); i++)
+ {
+ if (pubKeys.get(i) == null)
+ {
+ continue;
+ }
+
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ String sigName = X509SignatureUtil.getSignatureName(sigAlg);
+
+ Signature signature = sigCreator.createSignature(sigName);
+
+ SignatureException sigExc = null;
+
+ try
+ {
+ checkSignature(
+ (PublicKey)pubKeys.get(i), signature,
+ sigAlg.getParameters(),
+ DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ success = true;
+ }
+ catch (SignatureException e)
+ {
+ sigExc = e;
+ }
+
+ if (sigExc != null)
+ {
+ throw sigExc;
+ }
+ }
+
+ if (!success)
+ {
+ throw new InvalidKeyException("no matching key found");
+ }
+ }
+ else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
+ {
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+
+ boolean success = false;
+ for (int i = 0; i != sigSeq.size(); i++)
+ {
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ String sigName = X509SignatureUtil.getSignatureName(sigAlg);
+
+ SignatureException sigExc = null;
+
+ try
+ {
+ Signature signature = sigCreator.createSignature(sigName);
+
+ checkSignature(
+ key, signature,
+ sigAlg.getParameters(),
+ DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+
+ success = true;
+ }
+ catch (InvalidKeyException e)
+ {
+ // ignore
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // ignore
+ }
+ catch (SignatureException e)
+ {
+ sigExc = e;
+ }
+
+ if (sigExc != null)
+ {
+ throw sigExc;
+ }
+ }
+
+ if (!success)
+ {
+ throw new InvalidKeyException("no matching key found");
+ }
+ }
+ else
+ {
+ Signature sig = sigCreator.createSignature(getSigAlgName());
+
+ if (sigAlgParams == null)
+ {
+ checkSignature(key, sig, null, this.getSignature());
+ }
+ else
+ {
+ try
+ {
+ checkSignature(key, sig, ASN1Primitive.fromByteArray(sigAlgParams), this.getSignature());
+ }
+ catch (IOException e)
+ {
+ throw new SignatureException("cannot decode signature parameters: " + e.getMessage());
+ }
+ }
+ }
+ }
+
+ private void checkSignature(PublicKey key, Signature sig, ASN1Encodable sigAlgParams, byte[] encSig)
+ throws NoSuchAlgorithmException, SignatureException, InvalidKeyException, CRLException
+ {
+ if (sigAlgParams != null)
+ {
+ // needs to be called before initVerify().
+ X509SignatureUtil.setSignatureParameters(sig, sigAlgParams);
+ }
+
+ sig.initVerify(key);
+
+ try
+ {
+ OutputStream sigOut = new BufferedOutputStream(OutputStreamFactory.createStream(sig), 512);
+
+ c.getTBSCertList().encodeTo(sigOut, ASN1Encoding.DER);
+
+ sigOut.close();
+ }
+ catch (IOException e)
+ {
+ throw new CRLException(e.toString());
+ }
+
+ if (!sig.verify(encSig))
+ {
+ throw new SignatureException("CRL does not verify with supplied public key.");
+ }
+ }
+
+ public int getVersion()
+ {
+ return c.getVersionNumber();
+ }
+
+ public Principal getIssuerDN()
+ {
+ return new X509Principal(X500Name.getInstance(c.getIssuer().toASN1Primitive()));
+ }
+
+ public X500Principal getIssuerX500Principal()
+ {
+ try
+ {
+ return new X500Principal(c.getIssuer().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("can't encode issuer DN");
+ }
+ }
+
+ public Date getThisUpdate()
+ {
+ return c.getThisUpdate().getDate();
+ }
+
+ public Date getNextUpdate()
+ {
+ Time nextUpdate = c.getNextUpdate();
+
+ return null == nextUpdate ? null : nextUpdate.getDate();
+ }
+
+ private Set loadCRLEntries()
+ {
+ Set entrySet = new HashSet();
+ Enumeration certs = c.getRevokedCertificateEnumeration();
+
+ X500Name previousCertificateIssuer = null; // the issuer
+ while (certs.hasMoreElements())
+ {
+ TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement();
+ X509CRLEntryObject crlEntry = new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer);
+ entrySet.add(crlEntry);
+ if (isIndirect && entry.hasExtensions())
+ {
+ Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
+
+ if (currentCaName != null)
+ {
+ previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
+ }
+ }
+ }
+
+ return entrySet;
+ }
+
+ public X509CRLEntry getRevokedCertificate(BigInteger serialNumber)
+ {
+ Enumeration certs = c.getRevokedCertificateEnumeration();
+
+ X500Name previousCertificateIssuer = null; // the issuer
+ while (certs.hasMoreElements())
+ {
+ TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement();
+
+ if (entry.getUserCertificate().hasValue(serialNumber))
+ {
+ return new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer);
+ }
+
+ if (isIndirect && entry.hasExtensions())
+ {
+ Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
+
+ if (currentCaName != null)
+ {
+ previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public Set getRevokedCertificates()
+ {
+ Set entrySet = loadCRLEntries();
+
+ if (!entrySet.isEmpty())
+ {
+ return Collections.unmodifiableSet(entrySet);
+ }
+
+ return null;
+ }
+
+ public byte[] getTBSCertList()
+ throws CRLException
+ {
+ try
+ {
+ return c.getTBSCertList().getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CRLException(e.toString());
+ }
+ }
+
+ public byte[] getSignature()
+ {
+ return c.getSignature().getOctets();
+ }
+
+ public String getSigAlgName()
+ {
+ return sigAlgName;
+ }
+
+ public String getSigAlgOID()
+ {
+ return c.getSignatureAlgorithm().getAlgorithm().getId();
+ }
+
+ public byte[] getSigAlgParams()
+ {
+ return Arrays.clone(sigAlgParams);
+ }
+
+ /**
+ * Returns a string representation of this CRL.
+ *
+ * @return a string representation of this CRL.
+ */
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append(" Version: ").append(this.getVersion()).append(
+ nl);
+ buf.append(" IssuerDN: ").append(this.getIssuerDN())
+ .append(nl);
+ buf.append(" This update: ").append(this.getThisUpdate())
+ .append(nl);
+ buf.append(" Next update: ").append(this.getNextUpdate())
+ .append(nl);
+ buf.append(" Signature Algorithm: ").append(this.getSigAlgName())
+ .append(nl);
+
+ X509SignatureUtil.prettyPrintSignature(this.getSignature(), buf, nl);
+
+ Extensions extensions = c.getTBSCertList().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ if (e.hasMoreElements())
+ {
+ buf.append(" Extensions: ").append(nl);
+ }
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.getExtnValue() != null)
+ {
+ byte[] octs = ext.getExtnValue().getOctets();
+ ASN1InputStream dIn = new ASN1InputStream(octs);
+ buf.append(" critical(").append(
+ ext.isCritical()).append(") ");
+ try
+ {
+ if (oid.equals(Extension.cRLNumber))
+ {
+ buf.append(
+ new CRLNumber(ASN1Integer.getInstance(
+ dIn.readObject()).getPositiveValue()))
+ .append(nl);
+ }
+ else if (oid.equals(Extension.deltaCRLIndicator))
+ {
+ buf.append(
+ "Base CRL: "
+ + new CRLNumber(ASN1Integer.getInstance(
+ dIn.readObject()).getPositiveValue()))
+ .append(nl);
+ }
+ else if (oid
+ .equals(Extension.issuingDistributionPoint))
+ {
+ buf.append(
+ IssuingDistributionPoint.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid
+ .equals(Extension.cRLDistributionPoints))
+ {
+ buf.append(
+ CRLDistPoint.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid.equals(Extension.freshestCRL))
+ {
+ buf.append(
+ CRLDistPoint.getInstance(dIn.readObject())).append(nl);
+ }
+ else
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append(
+ ASN1Dump.dumpAsString(dIn.readObject()))
+ .append(nl);
+ }
+ }
+ catch (Exception ex)
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append("*****").append(nl);
+ }
+ }
+ else
+ {
+ buf.append(nl);
+ }
+ }
+ }
+ Set set = getRevokedCertificates();
+ if (set != null)
+ {
+ Iterator it = set.iterator();
+ while (it.hasNext())
+ {
+ buf.append(it.next());
+ buf.append(nl);
+ }
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Checks whether the given certificate is on this CRL.
+ *
+ * @param cert the certificate to check for.
+ * @return true if the given certificate is on this CRL,
+ * false otherwise.
+ */
+ public boolean isRevoked(Certificate cert)
+ {
+ if (!cert.getType().equals("X.509"))
+ {
+ throw new IllegalArgumentException("X.509 CRL used with non X.509 Cert");
+ }
+
+ Enumeration certs = c.getRevokedCertificateEnumeration();
+
+ X500Name caName = c.getIssuer();
+
+ if (certs.hasMoreElements())
+ {
+ BigInteger serial = ((X509Certificate)cert).getSerialNumber();
+
+ while (certs.hasMoreElements())
+ {
+ TBSCertList.CRLEntry entry = TBSCertList.CRLEntry.getInstance(certs.nextElement());
+
+ if (isIndirect && entry.hasExtensions())
+ {
+ Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
+
+ if (currentCaName != null)
+ {
+ caName = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
+ }
+ }
+
+ if (entry.getUserCertificate().hasValue(serial))
+ {
+ X500Name issuer;
+
+ if (cert instanceof X509Certificate)
+ {
+ issuer = X500Name.getInstance(((X509Certificate)cert).getIssuerX500Principal().getEncoded());
+ }
+ else
+ {
+ try
+ {
+ issuer = com.android.org.bouncycastle.asn1.x509.Certificate.getInstance(cert.getEncoded()).getIssuer();
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IllegalArgumentException("Cannot process certificate: " + e.getMessage());
+ }
+ }
+
+ if (!caName.equals(issuer))
+ {
+ return false;
+ }
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ protected static byte[] getExtensionOctets(CertificateList c, String oid)
+ {
+ ASN1OctetString extValue = getExtensionValue(c, oid);
+ if (null != extValue)
+ {
+ return extValue.getOctets();
+ }
+ return null;
+ }
+
+ protected static ASN1OctetString getExtensionValue(CertificateList c, String oid)
+ {
+ Extensions exts = c.getTBSCertList().getExtensions();
+ if (null != exts)
+ {
+ Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
+ if (null != ext)
+ {
+ return ext.getExtnValue();
+ }
+ }
+ return null;
+ }
+}
+
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
new file mode 100644
index 00000000..73cf1bf9
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.security.cert.CRLException;
+
+import com.android.org.bouncycastle.asn1.x509.CertificateList;
+import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
+
+class X509CRLInternal extends X509CRLImpl
+{
+ private final byte[] encoding;
+
+ X509CRLInternal(JcaJceHelper bcHelper, CertificateList c, String sigAlgName, byte[] sigAlgParams, boolean isIndirect,
+ byte[] encoding)
+ {
+ super(bcHelper, c, sigAlgName, sigAlgParams, isIndirect);
+
+ this.encoding = encoding;
+ }
+
+ public byte[] getEncoded() throws CRLException
+ {
+ if (null == encoding)
+ {
+ throw new CRLException();
+ }
+
+ return encoding;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
index bb91b05c..c9635a46 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
@@ -1,682 +1,150 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.jcajce.provider.asymmetric.x509;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Principal;
-import java.security.Provider;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
import java.security.cert.CRLException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509CRL;
-import java.security.cert.X509CRLEntry;
-import java.security.cert.X509Certificate;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import javax.security.auth.x500.X500Principal;
+import com.android.org.bouncycastle.asn1.ASN1BitString;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1Encoding;
-import com.android.org.bouncycastle.asn1.ASN1InputStream;
-import com.android.org.bouncycastle.asn1.ASN1Integer;
-import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import com.android.org.bouncycastle.asn1.ASN1OctetString;
-import com.android.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.org.bouncycastle.asn1.util.ASN1Dump;
-import com.android.org.bouncycastle.asn1.x500.X500Name;
-import com.android.org.bouncycastle.asn1.x509.CRLDistPoint;
-import com.android.org.bouncycastle.asn1.x509.CRLNumber;
import com.android.org.bouncycastle.asn1.x509.CertificateList;
import com.android.org.bouncycastle.asn1.x509.Extension;
-import com.android.org.bouncycastle.asn1.x509.Extensions;
-import com.android.org.bouncycastle.asn1.x509.GeneralNames;
import com.android.org.bouncycastle.asn1.x509.IssuingDistributionPoint;
-import com.android.org.bouncycastle.asn1.x509.TBSCertList;
import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
-import com.android.org.bouncycastle.jce.X509Principal;
-import com.android.org.bouncycastle.util.Strings;
-import com.android.org.bouncycastle.util.encoders.Hex;
-/**
- * The following extensions are listed in RFC 2459 as relevant to CRLs
- *
- * Authority Key Identifier
- * Issuer Alternative Name
- * CRL Number
- * Delta CRL Indicator (critical)
- * Issuing Distribution Point (critical)
- */
class X509CRLObject
- extends X509CRL
+ extends X509CRLImpl
{
- private JcaJceHelper bcHelper;
- private CertificateList c;
- private String sigAlgName;
- private byte[] sigAlgParams;
- private boolean isIndirect;
- private boolean isHashCodeSet = false;
- private int hashCodeValue;
+ private final Object cacheLock = new Object();
+ private X509CRLInternal internalCRLValue;
- static boolean isIndirectCRL(X509CRL crl)
- throws CRLException
- {
- try
- {
- byte[] idp = crl.getExtensionValue(Extension.issuingDistributionPoint.getId());
- return idp != null
- && IssuingDistributionPoint.getInstance(ASN1OctetString.getInstance(idp).getOctets()).isIndirectCRL();
- }
- catch (Exception e)
- {
- throw new ExtCRLException(
- "Exception reading IssuingDistributionPoint", e);
- }
- }
+ private volatile boolean hashValueSet;
+ private volatile int hashValue;
- protected X509CRLObject(
- JcaJceHelper bcHelper,
- CertificateList c)
- throws CRLException
+ X509CRLObject(JcaJceHelper bcHelper, CertificateList c) throws CRLException
{
- this.bcHelper = bcHelper;
- this.c = c;
-
- try
- {
- this.sigAlgName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
-
- if (c.getSignatureAlgorithm().getParameters() != null)
- {
- this.sigAlgParams = ((ASN1Encodable)c.getSignatureAlgorithm().getParameters()).toASN1Primitive().getEncoded(ASN1Encoding.DER);
- }
- else
- {
- this.sigAlgParams = null;
- }
-
- this.isIndirect = isIndirectCRL(this);
- }
- catch (Exception e)
- {
- throw new CRLException("CRL contents invalid: " + e);
- }
+ super(bcHelper, c, createSigAlgName(c), createSigAlgParams(c), isIndirectCRL(c));
}
- /**
- * Will return true if any extensions are present and marked
- * as critical as we currently dont handle any extensions!
- */
- public boolean hasUnsupportedCriticalExtension()
+ public boolean equals(Object other)
{
- Set extns = getCriticalExtensionOIDs();
-
- if (extns == null)
+ if (this == other)
{
- return false;
+ return true;
}
- extns.remove(Extension.issuingDistributionPoint.getId());
- extns.remove(Extension.deltaCRLIndicator.getId());
-
- return !extns.isEmpty();
- }
-
- private Set getExtensionOIDs(boolean critical)
- {
- if (this.getVersion() == 2)
+ if (other instanceof X509CRLObject)
{
- Extensions extensions = c.getTBSCertList().getExtensions();
+ X509CRLObject otherBC = (X509CRLObject)other;
- if (extensions != null)
+ if (this.hashValueSet && otherBC.hashValueSet)
{
- Set set = new HashSet();
- Enumeration e = extensions.oids();
-
- while (e.hasMoreElements())
+ if (this.hashValue != otherBC.hashValue)
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
- Extension ext = extensions.getExtension(oid);
-
- if (critical == ext.isCritical())
- {
- set.add(oid.getId());
- }
+ return false;
}
-
- return set;
}
- }
-
- return null;
- }
-
- public Set getCriticalExtensionOIDs()
- {
- return getExtensionOIDs(true);
- }
-
- public Set getNonCriticalExtensionOIDs()
- {
- return getExtensionOIDs(false);
- }
-
- public byte[] getExtensionValue(String oid)
- {
- Extensions exts = c.getTBSCertList().getExtensions();
-
- if (exts != null)
- {
- Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
-
- if (ext != null)
+ else if (null == internalCRLValue || null == otherBC.internalCRLValue)
{
- try
- {
- return ext.getExtnValue().getEncoded();
- }
- catch (Exception e)
+ ASN1BitString signature = c.getSignature();
+ if (null != signature && !signature.equals(otherBC.c.getSignature()))
{
- throw new IllegalStateException("error parsing " + e.toString());
+ return false;
}
}
}
- return null;
- }
-
- public byte[] getEncoded()
- throws CRLException
- {
- try
- {
- return c.getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
- {
- throw new CRLException(e.toString());
- }
- }
-
- public void verify(PublicKey key)
- throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException
- {
- Signature sig;
-
- try
- {
- sig = bcHelper.createSignature(getSigAlgName());
- }
- catch (Exception e)
- {
- sig = Signature.getInstance(getSigAlgName());
- }
-
- doVerify(key, sig);
- }
-
- public void verify(PublicKey key, String sigProvider)
- throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException
- {
- Signature sig;
-
- if (sigProvider != null)
- {
- sig = Signature.getInstance(getSigAlgName(), sigProvider);
- }
- else
- {
- sig = Signature.getInstance(getSigAlgName());
- }
-
- doVerify(key, sig);
+ return getInternalCRL().equals(other);
}
- public void verify(PublicKey key, Provider sigProvider)
- throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, SignatureException
+ public int hashCode()
{
- Signature sig;
-
- if (sigProvider != null)
+ if (!hashValueSet)
{
- sig = Signature.getInstance(getSigAlgName(), sigProvider);
- }
- else
- {
- sig = Signature.getInstance(getSigAlgName());
+ hashValue = getInternalCRL().hashCode();
+ hashValueSet = true;
}
- doVerify(key, sig);
+ return hashValue;
}
- private void doVerify(PublicKey key, Signature sig)
- throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, SignatureException
+ private X509CRLInternal getInternalCRL()
{
- if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature()))
+ synchronized (cacheLock)
{
- throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList.");
- }
-
- if (sigAlgParams != null)
- {
- try
- {
- // needs to be called before initVerify().
- X509SignatureUtil.setSignatureParameters(sig, ASN1Primitive.fromByteArray(sigAlgParams));
- }
- catch (IOException e)
+ if (null != internalCRLValue)
{
- throw new SignatureException("cannot decode signature parameters: " + e.getMessage());
+ return internalCRLValue;
}
}
- sig.initVerify(key);
- sig.update(this.getTBSCertList());
-
- if (!sig.verify(this.getSignature()))
- {
- throw new SignatureException("CRL does not verify with supplied public key.");
- }
- }
-
- public int getVersion()
- {
- return c.getVersionNumber();
- }
-
- public Principal getIssuerDN()
- {
- return new X509Principal(X500Name.getInstance(c.getIssuer().toASN1Primitive()));
- }
-
- public X500Principal getIssuerX500Principal()
- {
+ byte[] encoding;
try
{
- return new X500Principal(c.getIssuer().getEncoded());
- }
- catch (IOException e)
- {
- throw new IllegalStateException("can't encode issuer DN");
+ encoding = getEncoded();
}
- }
-
- public Date getThisUpdate()
- {
- return c.getThisUpdate().getDate();
- }
-
- public Date getNextUpdate()
- {
- if (c.getNextUpdate() != null)
- {
- return c.getNextUpdate().getDate();
- }
-
- return null;
- }
-
- private Set loadCRLEntries()
- {
- Set entrySet = new HashSet();
- Enumeration certs = c.getRevokedCertificateEnumeration();
-
- X500Name previousCertificateIssuer = null; // the issuer
- while (certs.hasMoreElements())
+ catch (CRLException e)
{
- TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement();
- X509CRLEntryObject crlEntry = new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer);
- entrySet.add(crlEntry);
- if (isIndirect && entry.hasExtensions())
- {
- Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
-
- if (currentCaName != null)
- {
- previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
- }
- }
+ encoding = null;
}
- return entrySet;
- }
-
- public X509CRLEntry getRevokedCertificate(BigInteger serialNumber)
- {
- Enumeration certs = c.getRevokedCertificateEnumeration();
+ X509CRLInternal temp = new X509CRLInternal(bcHelper, c, sigAlgName,sigAlgParams, isIndirect, encoding);
- X500Name previousCertificateIssuer = null; // the issuer
- while (certs.hasMoreElements())
+ synchronized (cacheLock)
{
- TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement();
-
- if (serialNumber.equals(entry.getUserCertificate().getValue()))
- {
- return new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer);
- }
-
- if (isIndirect && entry.hasExtensions())
+ if (null == internalCRLValue)
{
- Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
-
- if (currentCaName != null)
- {
- previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
- }
+ internalCRLValue = temp;
}
- }
-
- return null;
- }
-
- public Set getRevokedCertificates()
- {
- Set entrySet = loadCRLEntries();
- if (!entrySet.isEmpty())
- {
- return Collections.unmodifiableSet(entrySet);
+ return internalCRLValue;
}
-
- return null;
}
- public byte[] getTBSCertList()
- throws CRLException
+ private static String createSigAlgName(CertificateList c) throws CRLException
{
try
{
- return c.getTBSCertList().getEncoded("DER");
+ return X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
}
- catch (IOException e)
- {
- throw new CRLException(e.toString());
- }
- }
-
- public byte[] getSignature()
- {
- return c.getSignature().getOctets();
- }
-
- public String getSigAlgName()
- {
- return sigAlgName;
- }
-
- public String getSigAlgOID()
- {
- return c.getSignatureAlgorithm().getAlgorithm().getId();
- }
-
- public byte[] getSigAlgParams()
- {
- if (sigAlgParams != null)
+ catch (Exception e)
{
- byte[] tmp = new byte[sigAlgParams.length];
-
- System.arraycopy(sigAlgParams, 0, tmp, 0, tmp.length);
-
- return tmp;
+ throw new CRLException("CRL contents invalid: " + e);
}
-
- return null;
}
- /**
- * Returns a string representation of this CRL.
- *
- * @return a string representation of this CRL.
- */
- public String toString()
+ private static byte[] createSigAlgParams(CertificateList c) throws CRLException
{
- StringBuffer buf = new StringBuffer();
- String nl = Strings.lineSeparator();
-
- buf.append(" Version: ").append(this.getVersion()).append(
- nl);
- buf.append(" IssuerDN: ").append(this.getIssuerDN())
- .append(nl);
- buf.append(" This update: ").append(this.getThisUpdate())
- .append(nl);
- buf.append(" Next update: ").append(this.getNextUpdate())
- .append(nl);
- buf.append(" Signature Algorithm: ").append(this.getSigAlgName())
- .append(nl);
-
- byte[] sig = this.getSignature();
-
- buf.append(" Signature: ").append(
- new String(Hex.encode(sig, 0, 20))).append(nl);
- for (int i = 20; i < sig.length; i += 20)
- {
- if (i < sig.length - 20)
- {
- buf.append(" ").append(
- new String(Hex.encode(sig, i, 20))).append(nl);
- }
- else
- {
- buf.append(" ").append(
- new String(Hex.encode(sig, i, sig.length - i))).append(nl);
- }
- }
-
- Extensions extensions = c.getTBSCertList().getExtensions();
-
- if (extensions != null)
- {
- Enumeration e = extensions.oids();
-
- if (e.hasMoreElements())
- {
- buf.append(" Extensions: ").append(nl);
- }
-
- while (e.hasMoreElements())
- {
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement();
- Extension ext = extensions.getExtension(oid);
-
- if (ext.getExtnValue() != null)
- {
- byte[] octs = ext.getExtnValue().getOctets();
- ASN1InputStream dIn = new ASN1InputStream(octs);
- buf.append(" critical(").append(
- ext.isCritical()).append(") ");
- try
- {
- if (oid.equals(Extension.cRLNumber))
- {
- buf.append(
- new CRLNumber(ASN1Integer.getInstance(
- dIn.readObject()).getPositiveValue()))
- .append(nl);
- }
- else if (oid.equals(Extension.deltaCRLIndicator))
- {
- buf.append(
- "Base CRL: "
- + new CRLNumber(ASN1Integer.getInstance(
- dIn.readObject()).getPositiveValue()))
- .append(nl);
- }
- else if (oid
- .equals(Extension.issuingDistributionPoint))
- {
- buf.append(
- IssuingDistributionPoint.getInstance(dIn.readObject())).append(nl);
- }
- else if (oid
- .equals(Extension.cRLDistributionPoints))
- {
- buf.append(
- CRLDistPoint.getInstance(dIn.readObject())).append(nl);
- }
- else if (oid.equals(Extension.freshestCRL))
- {
- buf.append(
- CRLDistPoint.getInstance(dIn.readObject())).append(nl);
- }
- else
- {
- buf.append(oid.getId());
- buf.append(" value = ").append(
- ASN1Dump.dumpAsString(dIn.readObject()))
- .append(nl);
- }
- }
- catch (Exception ex)
- {
- buf.append(oid.getId());
- buf.append(" value = ").append("*****").append(nl);
- }
- }
- else
- {
- buf.append(nl);
- }
- }
- }
- Set set = getRevokedCertificates();
- if (set != null)
+ try
{
- Iterator it = set.iterator();
- while (it.hasNext())
+ ASN1Encodable parameters = c.getSignatureAlgorithm().getParameters();
+ if (null == parameters)
{
- buf.append(it.next());
- buf.append(nl);
+ return null;
}
- }
- return buf.toString();
- }
- /**
- * Checks whether the given certificate is on this CRL.
- *
- * @param cert the certificate to check for.
- * @return true if the given certificate is on this CRL,
- * false otherwise.
- */
- public boolean isRevoked(Certificate cert)
- {
- if (!cert.getType().equals("X.509"))
- {
- throw new IllegalArgumentException("X.509 CRL used with non X.509 Cert");
+ return parameters.toASN1Primitive().getEncoded(ASN1Encoding.DER);
}
-
- Enumeration certs = c.getRevokedCertificateEnumeration();
-
- X500Name caName = c.getIssuer();
-
- if (certs.hasMoreElements())
+ catch (Exception e)
{
- BigInteger serial = ((X509Certificate)cert).getSerialNumber();
-
- while (certs.hasMoreElements())
- {
- TBSCertList.CRLEntry entry = TBSCertList.CRLEntry.getInstance(certs.nextElement());
-
- if (isIndirect && entry.hasExtensions())
- {
- Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
-
- if (currentCaName != null)
- {
- caName = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
- }
- }
-
- if (entry.getUserCertificate().getValue().equals(serial))
- {
- X500Name issuer;
-
- if (cert instanceof X509Certificate)
- {
- issuer = X500Name.getInstance(((X509Certificate)cert).getIssuerX500Principal().getEncoded());
- }
- else
- {
- try
- {
- issuer = com.android.org.bouncycastle.asn1.x509.Certificate.getInstance(cert.getEncoded()).getIssuer();
- }
- catch (CertificateEncodingException e)
- {
- throw new IllegalArgumentException("Cannot process certificate: " + e.getMessage());
- }
- }
-
- if (!caName.equals(issuer))
- {
- return false;
- }
-
- return true;
- }
- }
+ throw new CRLException("CRL contents invalid: " + e);
}
-
- return false;
}
- public boolean equals(Object other)
+ private static boolean isIndirectCRL(CertificateList c) throws CRLException
{
- if (this == other)
- {
- return true;
- }
-
- if (!(other instanceof X509CRL))
- {
- return false;
- }
-
- if (other instanceof X509CRLObject)
+ try
{
- X509CRLObject crlObject = (X509CRLObject)other;
-
- if (isHashCodeSet)
+ byte[] extOctets = getExtensionOctets(c, Extension.issuingDistributionPoint.getId());
+ if (null == extOctets)
{
- boolean otherIsHashCodeSet = crlObject.isHashCodeSet;
- if (otherIsHashCodeSet)
- {
- if (crlObject.hashCodeValue != hashCodeValue)
- {
- return false;
- }
- }
+ return false;
}
- return this.c.equals(crlObject.c);
+ return IssuingDistributionPoint.getInstance(extOctets).isIndirectCRL();
}
-
- return super.equals(other);
- }
-
- public int hashCode()
- {
- if (!isHashCodeSet)
+ catch (Exception e)
{
- isHashCodeSet = true;
- hashCodeValue = super.hashCode();
+ throw new ExtCRLException("Exception reading IssuingDistributionPoint", e);
}
-
- return hashCodeValue;
}
}
-
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
new file mode 100644
index 00000000..6a3aa065
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
@@ -0,0 +1,941 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1String;
+import com.android.org.bouncycastle.asn1.DERBitString;
+import com.android.org.bouncycastle.asn1.DERIA5String;
+import com.android.org.bouncycastle.asn1.DERNull;
+import com.android.org.bouncycastle.asn1.DEROctetString;
+import com.android.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import com.android.org.bouncycastle.asn1.misc.NetscapeCertType;
+import com.android.org.bouncycastle.asn1.misc.NetscapeRevocationURL;
+import com.android.org.bouncycastle.asn1.misc.VerisignCzagExtension;
+import com.android.org.bouncycastle.asn1.util.ASN1Dump;
+import com.android.org.bouncycastle.asn1.x500.X500Name;
+import com.android.org.bouncycastle.asn1.x500.style.RFC4519Style;
+import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.org.bouncycastle.asn1.x509.BasicConstraints;
+import com.android.org.bouncycastle.asn1.x509.Extension;
+import com.android.org.bouncycastle.asn1.x509.Extensions;
+import com.android.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.org.bouncycastle.asn1.x509.KeyUsage;
+import com.android.org.bouncycastle.asn1.x509.TBSCertificate;
+import com.android.org.bouncycastle.jcajce.CompositePublicKey;
+import com.android.org.bouncycastle.jcajce.interfaces.BCX509Certificate;
+import com.android.org.bouncycastle.jcajce.io.OutputStreamFactory;
+import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.org.bouncycastle.jce.X509Principal;
+import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Integers;
+import com.android.org.bouncycastle.util.Properties;
+import com.android.org.bouncycastle.util.Strings;
+
+abstract class X509CertificateImpl
+ extends X509Certificate
+ implements BCX509Certificate
+{
+ protected JcaJceHelper bcHelper;
+ protected com.android.org.bouncycastle.asn1.x509.Certificate c;
+ protected BasicConstraints basicConstraints;
+ protected boolean[] keyUsage;
+ protected String sigAlgName;
+ protected byte[] sigAlgParams;
+
+ X509CertificateImpl(JcaJceHelper bcHelper, com.android.org.bouncycastle.asn1.x509.Certificate c,
+ BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams)
+ {
+ this.bcHelper = bcHelper;
+ this.c = c;
+ this.basicConstraints = basicConstraints;
+ this.keyUsage = keyUsage;
+ this.sigAlgName = sigAlgName;
+ this.sigAlgParams = sigAlgParams;
+ }
+
+ public X500Name getIssuerX500Name()
+ {
+ return c.getIssuer();
+ }
+
+ public TBSCertificate getTBSCertificateNative()
+ {
+ return c.getTBSCertificate();
+ }
+
+ public X500Name getSubjectX500Name()
+ {
+ return c.getSubject();
+ }
+
+ public void checkValidity()
+ throws CertificateExpiredException, CertificateNotYetValidException
+ {
+ this.checkValidity(new Date());
+ }
+
+ public void checkValidity(
+ Date date)
+ throws CertificateExpiredException, CertificateNotYetValidException
+ {
+ if (date.getTime() > this.getNotAfter().getTime()) // for other VM compatibility
+ {
+ throw new CertificateExpiredException("certificate expired on " + c.getEndDate().getTime());
+ }
+
+ if (date.getTime() < this.getNotBefore().getTime())
+ {
+ throw new CertificateNotYetValidException("certificate not valid till " + c.getStartDate().getTime());
+ }
+ }
+
+ public int getVersion()
+ {
+ return c.getVersionNumber();
+ }
+
+ public BigInteger getSerialNumber()
+ {
+ return c.getSerialNumber().getValue();
+ }
+
+ public Principal getIssuerDN()
+ {
+ return new X509Principal(c.getIssuer());
+ }
+
+ public X500Principal getIssuerX500Principal()
+ {
+ try
+ {
+ byte[] encoding = c.getIssuer().getEncoded(ASN1Encoding.DER);
+
+ return new X500Principal(encoding);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("can't encode issuer DN");
+ }
+ }
+
+ public Principal getSubjectDN()
+ {
+ return new X509Principal(c.getSubject());
+ }
+
+ public X500Principal getSubjectX500Principal()
+ {
+ try
+ {
+ byte[] encoding = c.getSubject().getEncoded(ASN1Encoding.DER);
+
+ return new X500Principal(encoding);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("can't encode subject DN");
+ }
+ }
+
+ public Date getNotBefore()
+ {
+ return c.getStartDate().getDate();
+ }
+
+ public Date getNotAfter()
+ {
+ return c.getEndDate().getDate();
+ }
+
+ public byte[] getTBSCertificate()
+ throws CertificateEncodingException
+ {
+ try
+ {
+ return c.getTBSCertificate().getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException(e.toString());
+ }
+ }
+
+ public byte[] getSignature()
+ {
+ return c.getSignature().getOctets();
+ }
+
+ /**
+ * return a more "meaningful" representation for the signature algorithm used in
+ * the certificate.
+ */
+ public String getSigAlgName()
+ {
+ return sigAlgName;
+ }
+
+ /**
+ * return the object identifier for the signature.
+ */
+ public String getSigAlgOID()
+ {
+ return c.getSignatureAlgorithm().getAlgorithm().getId();
+ }
+
+ /**
+ * return the signature parameters, or null if there aren't any.
+ */
+ public byte[] getSigAlgParams()
+ {
+ return Arrays.clone(sigAlgParams);
+ }
+
+ public boolean[] getIssuerUniqueID()
+ {
+ DERBitString id = c.getTBSCertificate().getIssuerUniqueId();
+
+ if (id != null)
+ {
+ byte[] bytes = id.getBytes();
+ boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
+
+ for (int i = 0; i != boolId.length; i++)
+ {
+ boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ }
+
+ return boolId;
+ }
+
+ return null;
+ }
+
+ public boolean[] getSubjectUniqueID()
+ {
+ DERBitString id = c.getTBSCertificate().getSubjectUniqueId();
+
+ if (id != null)
+ {
+ byte[] bytes = id.getBytes();
+ boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
+
+ for (int i = 0; i != boolId.length; i++)
+ {
+ boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ }
+
+ return boolId;
+ }
+
+ return null;
+ }
+
+ public boolean[] getKeyUsage()
+ {
+ return Arrays.clone(keyUsage);
+ }
+
+ public List getExtendedKeyUsage()
+ throws CertificateParsingException
+ {
+ byte[] extOctets = getExtensionOctets(c, "2.5.29.37");
+ if (null == extOctets)
+ {
+ return null;
+ }
+
+ try
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(ASN1Primitive.fromByteArray(extOctets));
+
+ List list = new ArrayList();
+ for (int i = 0; i != seq.size(); i++)
+ {
+ list.add(((ASN1ObjectIdentifier)seq.getObjectAt(i)).getId());
+ }
+ return Collections.unmodifiableList(list);
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException("error processing extended key usage extension");
+ }
+ }
+
+ public int getBasicConstraints()
+ {
+ if (basicConstraints != null)
+ {
+ if (basicConstraints.isCA())
+ {
+ if (basicConstraints.getPathLenConstraint() == null)
+ {
+ return Integer.MAX_VALUE;
+ }
+ else
+ {
+ return basicConstraints.getPathLenConstraint().intValue();
+ }
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ return -1;
+ }
+
+ public Collection getSubjectAlternativeNames()
+ throws CertificateParsingException
+ {
+ return getAlternativeNames(c, Extension.subjectAlternativeName.getId());
+ }
+
+ public Collection getIssuerAlternativeNames()
+ throws CertificateParsingException
+ {
+ return getAlternativeNames(c, Extension.issuerAlternativeName.getId());
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ if (this.getVersion() == 3)
+ {
+ Set set = new HashSet();
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+ }
+
+ return null;
+ }
+
+ public byte[] getExtensionValue(String oid)
+ {
+ ASN1OctetString extValue = getExtensionValue(c, oid);
+ if (null != extValue)
+ {
+ try
+ {
+ return extValue.getEncoded();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException("error parsing " + e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ if (this.getVersion() == 3)
+ {
+ Set set = new HashSet();
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (!ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+ }
+
+ return null;
+ }
+
+ public boolean hasUnsupportedCriticalExtension()
+ {
+ if (this.getVersion() == 3)
+ {
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+
+ if (oid.equals(Extension.keyUsage)
+ || oid.equals(Extension.certificatePolicies)
+ || oid.equals(Extension.policyMappings)
+ || oid.equals(Extension.inhibitAnyPolicy)
+ || oid.equals(Extension.cRLDistributionPoints)
+ || oid.equals(Extension.issuingDistributionPoint)
+ || oid.equals(Extension.deltaCRLIndicator)
+ || oid.equals(Extension.policyConstraints)
+ || oid.equals(Extension.basicConstraints)
+ || oid.equals(Extension.subjectAlternativeName)
+ || oid.equals(Extension.nameConstraints))
+ {
+ continue;
+ }
+
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.isCritical())
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public PublicKey getPublicKey()
+ {
+ try
+ {
+ return BouncyCastleProvider.getPublicKey(c.getSubjectPublicKeyInfo());
+ }
+ catch (IOException e)
+ {
+ return null; // should never happen...
+ }
+ }
+
+ public byte[] getEncoded()
+ throws CertificateEncodingException
+ {
+ try
+ {
+ return c.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException(e.toString());
+ }
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append(" [0] Version: ").append(this.getVersion()).append(nl);
+ buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl);
+ buf.append(" IssuerDN: ").append(this.getIssuerDN()).append(nl);
+ buf.append(" Start Date: ").append(this.getNotBefore()).append(nl);
+ buf.append(" Final Date: ").append(this.getNotAfter()).append(nl);
+ buf.append(" SubjectDN: ").append(this.getSubjectDN()).append(nl);
+ buf.append(" Public Key: ").append(this.getPublicKey()).append(nl);
+ buf.append(" Signature Algorithm: ").append(this.getSigAlgName()).append(nl);
+
+ X509SignatureUtil.prettyPrintSignature(this.getSignature(), buf, nl);
+
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ if (e.hasMoreElements())
+ {
+ buf.append(" Extensions: \n");
+ }
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.getExtnValue() != null)
+ {
+ byte[] octs = ext.getExtnValue().getOctets();
+ ASN1InputStream dIn = new ASN1InputStream(octs);
+ buf.append(" critical(").append(ext.isCritical()).append(") ");
+ try
+ {
+ if (oid.equals(Extension.basicConstraints))
+ {
+ buf.append(BasicConstraints.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid.equals(Extension.keyUsage))
+ {
+ buf.append(KeyUsage.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid.equals(MiscObjectIdentifiers.netscapeCertType))
+ {
+ buf.append(new NetscapeCertType(DERBitString.getInstance(dIn.readObject()))).append(nl);
+ }
+ else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL))
+ {
+ buf.append(new NetscapeRevocationURL(DERIA5String.getInstance(dIn.readObject()))).append(nl);
+ }
+ else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension))
+ {
+ buf.append(new VerisignCzagExtension(DERIA5String.getInstance(dIn.readObject()))).append(nl);
+ }
+ else
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl);
+ //buf.append(" value = ").append("*****").append(nl);
+ }
+ }
+ catch (Exception ex)
+ {
+ buf.append(oid.getId());
+ // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl);
+ buf.append(" value = ").append("*****").append(nl);
+ }
+ }
+ else
+ {
+ buf.append(nl);
+ }
+ }
+ }
+
+ return buf.toString();
+ }
+
+ public final void verify(
+ PublicKey key)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException
+ {
+ try
+ {
+ return bcHelper.createSignature(sigName);
+ }
+ catch (Exception e)
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+
+ public final void verify(
+ PublicKey key,
+ final String sigProvider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ if (sigProvider != null)
+ {
+ return Signature.getInstance(sigName, sigProvider);
+ }
+ else
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+
+ public final void verify(
+ PublicKey key,
+ final Provider sigProvider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
+ try
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException
+ {
+ if (sigProvider != null)
+ {
+ return Signature.getInstance(sigName, sigProvider);
+ }
+ else
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+ catch (NoSuchProviderException e)
+ {
+ // can't happen, but just in case
+ throw new NoSuchAlgorithmException("provider issue: " + e.getMessage());
+ }
+ }
+
+ private void doVerify(
+ PublicKey key,
+ SignatureCreator signatureCreator)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException, NoSuchProviderException
+ {
+ if (key instanceof CompositePublicKey && X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
+ {
+ List<PublicKey> pubKeys = ((CompositePublicKey)key).getPublicKeys();
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+
+ boolean success = false;
+ for (int i = 0; i != pubKeys.size(); i++)
+ {
+ if (pubKeys.get(i) == null)
+ {
+ continue;
+ }
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ String sigName = X509SignatureUtil.getSignatureName(sigAlg);
+
+ Signature signature = signatureCreator.createSignature(sigName);
+
+ SignatureException sigExc = null;
+
+ try
+ {
+ checkSignature(
+ (PublicKey)pubKeys.get(i), signature,
+ sigAlg.getParameters(),
+ DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ success = true;
+ }
+ catch (SignatureException e)
+ {
+ sigExc = e;
+ }
+
+ if (sigExc != null)
+ {
+ throw sigExc;
+ }
+ }
+
+ if (!success)
+ {
+ throw new InvalidKeyException("no matching key found");
+ }
+ }
+ else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
+ {
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+
+ boolean success = false;
+ for (int i = 0; i != sigSeq.size(); i++)
+ {
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ String sigName = X509SignatureUtil.getSignatureName(sigAlg);
+
+ SignatureException sigExc = null;
+
+ try
+ {
+ Signature signature = signatureCreator.createSignature(sigName);
+
+ checkSignature(
+ key, signature,
+ sigAlg.getParameters(),
+ DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+
+ success = true;
+ }
+ catch (InvalidKeyException e)
+ {
+ // ignore
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // ignore
+ }
+ catch (SignatureException e)
+ {
+ sigExc = e;
+ }
+
+ if (sigExc != null)
+ {
+ throw sigExc;
+ }
+ }
+
+ if (!success)
+ {
+ throw new InvalidKeyException("no matching key found");
+ }
+ }
+ else
+ {
+ String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
+
+ Signature signature = signatureCreator.createSignature(sigName);
+
+ if (key instanceof CompositePublicKey)
+ {
+ List<PublicKey> keys = ((CompositePublicKey)key).getPublicKeys();
+
+ for (int i = 0; i != keys.size(); i++)
+ {
+ try
+ {
+ checkSignature((PublicKey)keys.get(i), signature,
+ c.getSignatureAlgorithm().getParameters(), this.getSignature());
+ return; // found the match!
+ }
+ catch (InvalidKeyException e)
+ {
+ // continue;
+ }
+ }
+
+ throw new InvalidKeyException("no matching signature found");
+ }
+ else
+ {
+ checkSignature(key, signature,
+ c.getSignatureAlgorithm().getParameters(), this.getSignature());
+ }
+ }
+ }
+
+ private void checkSignature(
+ PublicKey key,
+ Signature signature,
+ ASN1Encodable params,
+ byte[] sigBytes)
+ throws CertificateException, NoSuchAlgorithmException,
+ SignatureException, InvalidKeyException
+ {
+ if (!isAlgIdEqual(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature()))
+ {
+ throw new CertificateException("signature algorithm in TBS cert not same as outer cert");
+ }
+
+ // TODO This should go after the initVerify?
+ X509SignatureUtil.setSignatureParameters(signature, params);
+
+ signature.initVerify(key);
+
+ try
+ {
+ OutputStream sigOut = new BufferedOutputStream(OutputStreamFactory.createStream(signature), 512);
+
+ c.getTBSCertificate().encodeTo(sigOut, ASN1Encoding.DER);
+
+ sigOut.close();
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException(e.toString());
+ }
+
+ if (!signature.verify(sigBytes))
+ {
+ throw new SignatureException("certificate does not verify with supplied key");
+ }
+ }
+
+ private boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2)
+ {
+ if (!id1.getAlgorithm().equals(id2.getAlgorithm()))
+ {
+ return false;
+ }
+
+ if (Properties.isOverrideSet("com.android.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;
+ }
+
+ private static Collection getAlternativeNames(com.android.org.bouncycastle.asn1.x509.Certificate c, String oid)
+ throws CertificateParsingException
+ {
+ byte[] extOctets = getExtensionOctets(c, oid);
+ if (extOctets == null)
+ {
+ return null;
+ }
+ try
+ {
+ Collection temp = new ArrayList();
+ Enumeration it = ASN1Sequence.getInstance(extOctets).getObjects();
+ while (it.hasMoreElements())
+ {
+ GeneralName genName = GeneralName.getInstance(it.nextElement());
+ List list = new ArrayList();
+ list.add(Integers.valueOf(genName.getTagNo()));
+ switch (genName.getTagNo())
+ {
+ case GeneralName.ediPartyName:
+ case GeneralName.x400Address:
+ case GeneralName.otherName:
+ list.add(genName.getEncoded());
+ break;
+ case GeneralName.directoryName:
+ list.add(X500Name.getInstance(RFC4519Style.INSTANCE, genName.getName()).toString());
+ break;
+ case GeneralName.dNSName:
+ case GeneralName.rfc822Name:
+ case GeneralName.uniformResourceIdentifier:
+ list.add(((ASN1String)genName.getName()).getString());
+ break;
+ case GeneralName.registeredID:
+ list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId());
+ break;
+ case GeneralName.iPAddress:
+ byte[] addrBytes = DEROctetString.getInstance(genName.getName()).getOctets();
+ final String addr;
+ try
+ {
+ addr = InetAddress.getByAddress(addrBytes).getHostAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ continue;
+ }
+ list.add(addr);
+ break;
+ default:
+ throw new IOException("Bad tag number: " + genName.getTagNo());
+ }
+
+ temp.add(Collections.unmodifiableList(list));
+ }
+ if (temp.size() == 0)
+ {
+ return null;
+ }
+ return Collections.unmodifiableCollection(temp);
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException(e.getMessage());
+ }
+ }
+
+ protected static byte[] getExtensionOctets(com.android.org.bouncycastle.asn1.x509.Certificate c, String oid)
+ {
+ ASN1OctetString extValue = getExtensionValue(c, oid);
+ if (null != extValue)
+ {
+ return extValue.getOctets();
+ }
+ return null;
+ }
+
+ protected static ASN1OctetString getExtensionValue(com.android.org.bouncycastle.asn1.x509.Certificate c, String oid)
+ {
+ Extensions exts = c.getTBSCertificate().getExtensions();
+ if (null != exts)
+ {
+ Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
+ if (null != ext)
+ {
+ return ext.getExtnValue();
+ }
+ }
+ return null;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
new file mode 100644
index 00000000..e74b8bed
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.security.cert.CertificateEncodingException;
+
+import com.android.org.bouncycastle.asn1.x509.BasicConstraints;
+import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
+
+class X509CertificateInternal extends X509CertificateImpl
+{
+ private final byte[] encoding;
+
+ X509CertificateInternal(JcaJceHelper bcHelper, com.android.org.bouncycastle.asn1.x509.Certificate c,
+ BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams, byte[] encoding)
+ {
+ super(bcHelper, c, basicConstraints, keyUsage, sigAlgName, sigAlgParams);
+
+ this.encoding = encoding;
+ }
+
+ public byte[] getEncoded() throws CertificateEncodingException
+ {
+ if (null == encoding)
+ {
+ throw new CertificateEncodingException();
+ }
+
+ return encoding;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
index 68dedd5a..bfaf29fd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
@@ -70,476 +70,140 @@ import com.android.org.bouncycastle.util.Strings;
import com.android.org.bouncycastle.util.encoders.Hex;
class X509CertificateObject
- extends X509Certificate
+ extends X509CertificateImpl
implements PKCS12BagAttributeCarrier
{
- private JcaJceHelper bcHelper;
- private com.android.org.bouncycastle.asn1.x509.Certificate c;
- private BasicConstraints basicConstraints;
- private boolean[] keyUsage;
- private boolean hashValueSet;
- private int hashValue;
+ private final Object cacheLock = new Object();
+ private X509CertificateInternal internalCertificateValue;
+ private X500Principal issuerValue;
+ private PublicKey publicKeyValue;
+ private X500Principal subjectValue;
+ private long[] validityValues;
+
+ private volatile boolean hashValueSet;
+ private volatile int hashValue;
private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl();
- public X509CertificateObject(
- JcaJceHelper bcHelper,
- com.android.org.bouncycastle.asn1.x509.Certificate c)
+ X509CertificateObject(JcaJceHelper bcHelper, com.android.org.bouncycastle.asn1.x509.Certificate c)
throws CertificateParsingException
{
- this.bcHelper = bcHelper;
- this.c = c;
-
- try
- {
- byte[] bytes = this.getExtensionBytes("2.5.29.19");
-
- if (bytes != null)
- {
- basicConstraints = BasicConstraints.getInstance(ASN1Primitive.fromByteArray(bytes));
- }
- }
- catch (Exception e)
- {
- throw new CertificateParsingException("cannot construct BasicConstraints: " + e);
- }
-
- try
- {
- byte[] bytes = this.getExtensionBytes("2.5.29.15");
- if (bytes != null)
- {
- ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes));
-
- bytes = bits.getBytes();
- int length = (bytes.length * 8) - bits.getPadBits();
-
- keyUsage = new boolean[(length < 9) ? 9 : length];
-
- for (int i = 0; i != length; i++)
- {
- keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
- }
- }
- else
- {
- keyUsage = null;
- }
- }
- catch (Exception e)
- {
- throw new CertificateParsingException("cannot construct KeyUsage: " + e);
- }
+ super(bcHelper, c, createBasicConstraints(c), createKeyUsage(c), createSigAlgName(c), createSigAlgParams(c));
}
- public void checkValidity()
- throws CertificateExpiredException, CertificateNotYetValidException
+ public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException
{
- this.checkValidity(new Date());
- }
+ long checkTime = date.getTime();
+ long[] validityValues = getValidityValues();
- public void checkValidity(
- Date date)
- throws CertificateExpiredException, CertificateNotYetValidException
- {
- if (date.getTime() > this.getNotAfter().getTime()) // for other VM compatibility
+ if (checkTime > validityValues[1]) // for other VM compatibility
{
throw new CertificateExpiredException("certificate expired on " + c.getEndDate().getTime());
}
-
- if (date.getTime() < this.getNotBefore().getTime())
+ if (checkTime < validityValues[0])
{
throw new CertificateNotYetValidException("certificate not valid till " + c.getStartDate().getTime());
}
}
- public int getVersion()
- {
- return c.getVersionNumber();
- }
-
- public BigInteger getSerialNumber()
- {
- return c.getSerialNumber().getValue();
- }
-
- public Principal getIssuerDN()
- {
- try
- {
- return new X509Principal(X500Name.getInstance(c.getIssuer().getEncoded()));
- }
- catch (IOException e)
- {
- return null;
- }
- }
-
public X500Principal getIssuerX500Principal()
{
- try
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
- aOut.writeObject(c.getIssuer());
-
- return new X500Principal(bOut.toByteArray());
- }
- catch (IOException e)
- {
- throw new IllegalStateException("can't encode issuer DN");
- }
- }
-
- public Principal getSubjectDN()
- {
- return new X509Principal(X500Name.getInstance(c.getSubject().toASN1Primitive()));
- }
-
- public X500Principal getSubjectX500Principal()
- {
- try
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
- aOut.writeObject(c.getSubject());
-
- return new X500Principal(bOut.toByteArray());
- }
- catch (IOException e)
- {
- throw new IllegalStateException("can't encode issuer DN");
- }
- }
-
- public Date getNotBefore()
- {
- return c.getStartDate().getDate();
- }
-
- public Date getNotAfter()
- {
- return c.getEndDate().getDate();
- }
-
- public byte[] getTBSCertificate()
- throws CertificateEncodingException
- {
- try
- {
- return c.getTBSCertificate().getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
- {
- throw new CertificateEncodingException(e.toString());
- }
- }
-
- public byte[] getSignature()
- {
- return c.getSignature().getOctets();
- }
-
- /**
- * return a more "meaningful" representation for the signature algorithm used in
- * the certificate.
- */
- public String getSigAlgName()
- {
- return X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
- }
-
- /**
- * return the object identifier for the signature.
- */
- public String getSigAlgOID()
- {
- return c.getSignatureAlgorithm().getAlgorithm().getId();
- }
-
- /**
- * return the signature parameters, or null if there aren't any.
- */
- public byte[] getSigAlgParams()
- {
- if (c.getSignatureAlgorithm().getParameters() != null)
+ synchronized (cacheLock)
{
- try
+ if (null != issuerValue)
{
- return c.getSignatureAlgorithm().getParameters().toASN1Primitive().getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
- {
- return null;
+ return issuerValue;
}
}
- else
- {
- return null;
- }
- }
- public boolean[] getIssuerUniqueID()
- {
- DERBitString id = c.getTBSCertificate().getIssuerUniqueId();
+ X500Principal temp = super.getIssuerX500Principal();
- if (id != null)
+ synchronized (cacheLock)
{
- byte[] bytes = id.getBytes();
- boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
-
- for (int i = 0; i != boolId.length; i++)
+ if (null == issuerValue)
{
- boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ issuerValue = temp;
}
- return boolId;
+ return issuerValue;
}
-
- return null;
}
- public boolean[] getSubjectUniqueID()
+ public PublicKey getPublicKey()
{
- DERBitString id = c.getTBSCertificate().getSubjectUniqueId();
-
- if (id != null)
+ // Cache the public key to support repeated-use optimizations
+ synchronized (cacheLock)
{
- byte[] bytes = id.getBytes();
- boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
-
- for (int i = 0; i != boolId.length; i++)
+ if (null != publicKeyValue)
{
- boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ return publicKeyValue;
}
-
- return boolId;
}
-
- return null;
- }
-
- public boolean[] getKeyUsage()
- {
- return keyUsage;
- }
- public List getExtendedKeyUsage()
- throws CertificateParsingException
- {
- byte[] bytes = this.getExtensionBytes("2.5.29.37");
-
- if (bytes != null)
+ PublicKey temp = super.getPublicKey();
+ if (null == temp)
{
- try
- {
- ASN1InputStream dIn = new ASN1InputStream(bytes);
- ASN1Sequence seq = (ASN1Sequence)dIn.readObject();
- List list = new ArrayList();
-
- for (int i = 0; i != seq.size(); i++)
- {
- list.add(((ASN1ObjectIdentifier)seq.getObjectAt(i)).getId());
- }
-
- return Collections.unmodifiableList(list);
- }
- catch (Exception e)
- {
- throw new CertificateParsingException("error processing extended key usage extension");
- }
+ return null;
}
- return null;
- }
-
- public int getBasicConstraints()
- {
- if (basicConstraints != null)
+ synchronized (cacheLock)
{
- if (basicConstraints.isCA())
+ if (null == publicKeyValue)
{
- if (basicConstraints.getPathLenConstraint() == null)
- {
- return Integer.MAX_VALUE;
- }
- else
- {
- return basicConstraints.getPathLenConstraint().intValue();
- }
+ publicKeyValue = temp;
}
- else
- {
- return -1;
- }
- }
-
- return -1;
- }
-
- public Collection getSubjectAlternativeNames()
- throws CertificateParsingException
- {
- return getAlternativeNames(getExtensionBytes(Extension.subjectAlternativeName.getId()));
- }
-
- public Collection getIssuerAlternativeNames()
- throws CertificateParsingException
- {
- return getAlternativeNames(getExtensionBytes(Extension.issuerAlternativeName.getId()));
- }
-
- public Set getCriticalExtensionOIDs()
- {
- if (this.getVersion() == 3)
- {
- Set set = new HashSet();
- Extensions extensions = c.getTBSCertificate().getExtensions();
-
- if (extensions != null)
- {
- Enumeration e = extensions.oids();
- while (e.hasMoreElements())
- {
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
- Extension ext = extensions.getExtension(oid);
-
- if (ext.isCritical())
- {
- set.add(oid.getId());
- }
- }
-
- return set;
- }
+ return publicKeyValue;
}
-
- return null;
}
- private byte[] getExtensionBytes(String oid)
+ public X500Principal getSubjectX500Principal()
{
- Extensions exts = c.getTBSCertificate().getExtensions();
-
- if (exts != null)
+ synchronized (cacheLock)
{
- Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
- if (ext != null)
+ if (null != subjectValue)
{
- return ext.getExtnValue().getOctets();
+ return subjectValue;
}
}
- return null;
- }
+ X500Principal temp = super.getSubjectX500Principal();
- public byte[] getExtensionValue(String oid)
- {
- Extensions exts = c.getTBSCertificate().getExtensions();
-
- if (exts != null)
+ synchronized (cacheLock)
{
- Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
-
- if (ext != null)
+ if (null == subjectValue)
{
- try
- {
- return ext.getExtnValue().getEncoded();
- }
- catch (Exception e)
- {
- throw new IllegalStateException("error parsing " + e.toString());
- }
+ subjectValue = temp;
}
- }
- return null;
+ return subjectValue;
+ }
}
- public Set getNonCriticalExtensionOIDs()
+ public long[] getValidityValues()
{
- if (this.getVersion() == 3)
+ synchronized (cacheLock)
{
- Set set = new HashSet();
- Extensions extensions = c.getTBSCertificate().getExtensions();
-
- if (extensions != null)
+ if (null != validityValues)
{
- Enumeration e = extensions.oids();
-
- while (e.hasMoreElements())
- {
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
- Extension ext = extensions.getExtension(oid);
-
- if (!ext.isCritical())
- {
- set.add(oid.getId());
- }
- }
-
- return set;
+ return validityValues;
}
}
- return null;
- }
-
- public boolean hasUnsupportedCriticalExtension()
- {
- if (this.getVersion() == 3)
+ long[] temp = new long[]
{
- Extensions extensions = c.getTBSCertificate().getExtensions();
+ super.getNotBefore().getTime(),
+ super.getNotAfter().getTime()
+ };
- if (extensions != null)
+ synchronized (cacheLock)
+ {
+ if (null == validityValues)
{
- Enumeration e = extensions.oids();
-
- while (e.hasMoreElements())
- {
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
-
- if (oid.equals(Extension.keyUsage)
- || oid.equals(Extension.certificatePolicies)
- || oid.equals(Extension.policyMappings)
- || oid.equals(Extension.inhibitAnyPolicy)
- || oid.equals(Extension.cRLDistributionPoints)
- || oid.equals(Extension.issuingDistributionPoint)
- || oid.equals(Extension.deltaCRLIndicator)
- || oid.equals(Extension.policyConstraints)
- || oid.equals(Extension.basicConstraints)
- || oid.equals(Extension.subjectAlternativeName)
- || oid.equals(Extension.nameConstraints))
- {
- continue;
- }
-
- Extension ext = extensions.getExtension(oid);
-
- if (ext.isCritical())
- {
- return true;
- }
- }
+ validityValues = temp;
}
- }
-
- return false;
- }
- public PublicKey getPublicKey()
- {
- try
- {
- return BouncyCastleProvider.getPublicKey(c.getSubjectPublicKeyInfo());
- }
- catch (IOException e)
- {
- return null; // should never happen...
+ return validityValues;
}
}
@@ -564,36 +228,42 @@ class X509CertificateObject
}
public boolean equals(
- Object o)
+ Object other)
{
- if (o == this)
+ if (other == this)
{
return true;
}
- if (o instanceof X509CertificateObject)
+ if (other instanceof X509CertificateObject)
{
- X509CertificateObject other = (X509CertificateObject)o;
+ X509CertificateObject otherBC = (X509CertificateObject)other;
- if (this.hashValueSet && other.hashValueSet)
+ if (this.hashValueSet && otherBC.hashValueSet)
{
- if (this.hashValue != other.hashValue)
+ if (this.hashValue != otherBC.hashValue)
+ {
+ return false;
+ }
+ }
+ else if (null == internalCertificateValue || null == otherBC.internalCertificateValue)
+ {
+ ASN1BitString signature = c.getSignature();
+ if (null != signature && !signature.equals(otherBC.c.getSignature()))
{
return false;
}
}
-
- return this.c.equals(other.c);
}
- return super.equals(o);
+ return getInternalCertificate().equals(other);
}
- public synchronized int hashCode()
+ public int hashCode()
{
if (!hashValueSet)
{
- hashValue = super.hashCode();
+ hashValue = getInternalCertificate().hashCode();
hashValueSet = true;
}
@@ -610,7 +280,7 @@ class X509CertificateObject
try
{
int hashCode = 0;
- byte[] certData = this.getEncoded();
+ byte[] certData = getInternalCertificate().getEncoded();
for (int i = 1; i < certData.length; i++)
{
hashCode += certData[i] * i;
@@ -623,15 +293,12 @@ class X509CertificateObject
}
}
- public void setBagAttribute(
- ASN1ObjectIdentifier oid,
- ASN1Encodable attribute)
+ public void setBagAttribute(ASN1ObjectIdentifier oid, ASN1Encodable attribute)
{
attrCarrier.setBagAttribute(oid, attribute);
}
- public ASN1Encodable getBagAttribute(
- ASN1ObjectIdentifier oid)
+ public ASN1Encodable getBagAttribute(ASN1ObjectIdentifier oid)
{
return attrCarrier.getBagAttribute(oid);
}
@@ -641,284 +308,116 @@ class X509CertificateObject
return attrCarrier.getBagAttributeKeys();
}
- public String toString()
+ private X509CertificateInternal getInternalCertificate()
{
- StringBuffer buf = new StringBuffer();
- String nl = Strings.lineSeparator();
-
- buf.append(" [0] Version: ").append(this.getVersion()).append(nl);
- buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl);
- buf.append(" IssuerDN: ").append(this.getIssuerDN()).append(nl);
- buf.append(" Start Date: ").append(this.getNotBefore()).append(nl);
- buf.append(" Final Date: ").append(this.getNotAfter()).append(nl);
- buf.append(" SubjectDN: ").append(this.getSubjectDN()).append(nl);
- buf.append(" Public Key: ").append(this.getPublicKey()).append(nl);
- buf.append(" Signature Algorithm: ").append(this.getSigAlgName()).append(nl);
-
- byte[] sig = this.getSignature();
-
- buf.append(" Signature: ").append(new String(Hex.encode(sig, 0, 20))).append(nl);
- for (int i = 20; i < sig.length; i += 20)
+ synchronized (cacheLock)
{
- if (i < sig.length - 20)
- {
- buf.append(" ").append(new String(Hex.encode(sig, i, 20))).append(nl);
- }
- else
+ if (null != internalCertificateValue)
{
- buf.append(" ").append(new String(Hex.encode(sig, i, sig.length - i))).append(nl);
+ return internalCertificateValue;
}
}
- Extensions extensions = c.getTBSCertificate().getExtensions();
-
- if (extensions != null)
- {
- Enumeration e = extensions.oids();
-
- if (e.hasMoreElements())
- {
- buf.append(" Extensions: \n");
- }
-
- while (e.hasMoreElements())
- {
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
- Extension ext = extensions.getExtension(oid);
-
- if (ext.getExtnValue() != null)
- {
- byte[] octs = ext.getExtnValue().getOctets();
- ASN1InputStream dIn = new ASN1InputStream(octs);
- buf.append(" critical(").append(ext.isCritical()).append(") ");
- try
- {
- if (oid.equals(Extension.basicConstraints))
- {
- buf.append(BasicConstraints.getInstance(dIn.readObject())).append(nl);
- }
- else if (oid.equals(Extension.keyUsage))
- {
- buf.append(KeyUsage.getInstance(dIn.readObject())).append(nl);
- }
- else if (oid.equals(MiscObjectIdentifiers.netscapeCertType))
- {
- buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl);
- }
- else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL))
- {
- buf.append(new NetscapeRevocationURL((DERIA5String)dIn.readObject())).append(nl);
- }
- else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension))
- {
- buf.append(new VerisignCzagExtension((DERIA5String)dIn.readObject())).append(nl);
- }
- else
- {
- buf.append(oid.getId());
- buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl);
- //buf.append(" value = ").append("*****").append(nl);
- }
- }
- catch (Exception ex)
- {
- buf.append(oid.getId());
- // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl);
- buf.append(" value = ").append("*****").append(nl);
- }
- }
- else
- {
- buf.append(nl);
- }
- }
- }
-
- return buf.toString();
- }
-
- public final void verify(
- PublicKey key)
- throws CertificateException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException
- {
- Signature signature;
- String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
-
+ byte[] encoding;
try
{
- signature = bcHelper.createSignature(sigName);
+ encoding = getEncoded();
}
- catch (Exception e)
+ catch (CertificateEncodingException e)
{
- signature = Signature.getInstance(sigName);
+ encoding = null;
}
-
- checkSignature(key, signature);
- }
-
- public final void verify(
- PublicKey key,
- String sigProvider)
- throws CertificateException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException
- {
- String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
- Signature signature;
- if (sigProvider != null)
- {
- signature = Signature.getInstance(sigName, sigProvider);
- }
- else
+ X509CertificateInternal temp = new X509CertificateInternal(bcHelper, c, basicConstraints, keyUsage, sigAlgName,
+ sigAlgParams, encoding);
+
+ synchronized (cacheLock)
{
- signature = Signature.getInstance(sigName);
+ if (null == internalCertificateValue)
+ {
+ internalCertificateValue = temp;
+ }
+
+ return internalCertificateValue;
}
-
- checkSignature(key, signature);
}
- public final void verify(
- PublicKey key,
- Provider sigProvider)
- throws CertificateException, NoSuchAlgorithmException,
- InvalidKeyException, SignatureException
+ private static BasicConstraints createBasicConstraints(com.android.org.bouncycastle.asn1.x509.Certificate c)
+ throws CertificateParsingException
{
- String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
- Signature signature;
-
- if (sigProvider != null)
+ try
{
- signature = Signature.getInstance(sigName, sigProvider);
+ byte[] extOctets = getExtensionOctets(c, "2.5.29.19");
+ if (null == extOctets)
+ {
+ return null;
+ }
+
+ return BasicConstraints.getInstance(ASN1Primitive.fromByteArray(extOctets));
}
- else
+ catch (Exception e)
{
- signature = Signature.getInstance(sigName);
+ throw new CertificateParsingException("cannot construct BasicConstraints: " + e);
}
-
- checkSignature(key, signature);
}
- private void checkSignature(
- PublicKey key,
- Signature signature)
- throws CertificateException, NoSuchAlgorithmException,
- SignatureException, InvalidKeyException
+ private static boolean[] createKeyUsage(com.android.org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException
{
- if (!isAlgIdEqual(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature()))
+ try
{
- throw new CertificateException("signature algorithm in TBS cert not same as outer cert");
- }
+ byte[] extOctets = getExtensionOctets(c, "2.5.29.15");
+ if (null == extOctets)
+ {
+ return null;
+ }
- ASN1Encodable params = c.getSignatureAlgorithm().getParameters();
+ ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(extOctets));
- // TODO This should go after the initVerify?
- X509SignatureUtil.setSignatureParameters(signature, params);
+ byte[] bytes = bits.getBytes();
+ int length = (bytes.length * 8) - bits.getPadBits();
- signature.initVerify(key);
+ boolean[] keyUsage = new boolean[(length < 9) ? 9 : length];
- signature.update(this.getTBSCertificate());
+ for (int i = 0; i != length; i++)
+ {
+ keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ }
- if (!signature.verify(this.getSignature()))
+ return keyUsage;
+ }
+ catch (Exception e)
{
- throw new SignatureException("certificate does not verify with supplied key");
+ throw new CertificateParsingException("cannot construct KeyUsage: " + e);
}
}
- private boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2)
+ private static String createSigAlgName(com.android.org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException
{
- if (!id1.getAlgorithm().equals(id2.getAlgorithm()))
- {
- return false;
- }
-
- if (id1.getParameters() == null)
+ try
{
- if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE))
- {
- return false;
- }
-
- return true;
+ return X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
}
-
- if (id2.getParameters() == null)
+ catch (Exception e)
{
- if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE))
- {
- return false;
- }
-
- return true;
+ throw new CertificateParsingException("cannot construct SigAlgName: " + e);
}
-
- return id1.getParameters().equals(id2.getParameters());
}
- private static Collection getAlternativeNames(byte[] extVal)
- throws CertificateParsingException
+ private static byte[] createSigAlgParams(com.android.org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException
{
- if (extVal == null)
- {
- return null;
- }
try
{
- Collection temp = new ArrayList();
- Enumeration it = ASN1Sequence.getInstance(extVal).getObjects();
- while (it.hasMoreElements())
- {
- GeneralName genName = GeneralName.getInstance(it.nextElement());
- List list = new ArrayList();
- list.add(Integers.valueOf(genName.getTagNo()));
- switch (genName.getTagNo())
- {
- case GeneralName.ediPartyName:
- case GeneralName.x400Address:
- case GeneralName.otherName:
- list.add(genName.getEncoded());
- break;
- case GeneralName.directoryName:
- // Android-changed: Unknown reason
- // list.add(X500Name.getInstance(RFC4519Style.INSTANCE, genName.getName()).toString());
- list.add(X509Name.getInstance(genName.getName()).toString(true, X509Name.DefaultSymbols));
- break;
- case GeneralName.dNSName:
- case GeneralName.rfc822Name:
- case GeneralName.uniformResourceIdentifier:
- list.add(((ASN1String)genName.getName()).getString());
- break;
- case GeneralName.registeredID:
- list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId());
- break;
- case GeneralName.iPAddress:
- byte[] addrBytes = DEROctetString.getInstance(genName.getName()).getOctets();
- final String addr;
- try
- {
- addr = InetAddress.getByAddress(addrBytes).getHostAddress();
- }
- catch (UnknownHostException e)
- {
- continue;
- }
- list.add(addr);
- break;
- default:
- throw new IOException("Bad tag number: " + genName.getTagNo());
- }
-
- temp.add(Collections.unmodifiableList(list));
- }
- if (temp.size() == 0)
+ ASN1Encodable parameters = c.getSignatureAlgorithm().getParameters();
+ if (null == parameters)
{
return null;
}
- return Collections.unmodifiableCollection(temp);
+
+ return parameters.toASN1Primitive().getEncoded(ASN1Encoding.DER);
}
catch (Exception e)
{
- throw new CertificateParsingException(e.getMessage());
+ throw new CertificateParsingException("cannot construct SigAlgParams: " + e);
}
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
index ccb2eb9b..9903c5fd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
@@ -11,22 +11,43 @@ import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.PSSParameterSpec;
+import java.util.HashMap;
+import java.util.Map;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1Null;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.DERNull;
+// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
+import com.android.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import com.android.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import com.android.org.bouncycastle.jcajce.util.MessageDigestUtils;
import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.org.bouncycastle.util.encoders.Hex;
class X509SignatureUtil
{
- private static final ASN1Null derNull = DERNull.INSTANCE;
+ private static final Map<ASN1ObjectIdentifier, String> algNames = new HashMap<ASN1ObjectIdentifier, String>();
+
+ static
+ {
+ // algNames.put(EdECObjectIdentifiers.id_Ed25519, "Ed25519");
+ // algNames.put(EdECObjectIdentifiers.id_Ed448, "Ed448");
+ algNames.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1withDSA");
+ algNames.put(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1withDSA");
+ }
+
+ private static final ASN1Null derNull = DERNull.INSTANCE;
+
+ static boolean isCompositeAlgorithm(AlgorithmIdentifier algorithmIdentifier)
+ {
+ return MiscObjectIdentifiers.id_alg_composite.equals(algorithmIdentifier.getAlgorithm());
+ }
static void setSignatureParameters(
Signature signature,
@@ -35,8 +56,8 @@ class X509SignatureUtil
{
if (params != null && !derNull.equals(params))
{
- AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider());
-
+ AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider());
+
try
{
sigParams.init(params.toASN1Primitive().getEncoded());
@@ -45,7 +66,7 @@ class X509SignatureUtil
{
throw new SignatureException("IOException decoding parameters: " + e.getMessage());
}
-
+
if (signature.getAlgorithm().endsWith("MGF1"))
{
try
@@ -59,34 +80,63 @@ class X509SignatureUtil
}
}
}
-
+
static String getSignatureName(
- AlgorithmIdentifier sigAlgId)
+ AlgorithmIdentifier sigAlgId)
{
ASN1Encodable params = sigAlgId.getParameters();
-
+
if (params != null && !derNull.equals(params))
{
if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
{
RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params);
-
+
return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "withRSAandMGF1";
}
if (sigAlgId.getAlgorithm().equals(X9ObjectIdentifiers.ecdsa_with_SHA2))
{
ASN1Sequence ecDsaParams = ASN1Sequence.getInstance(params);
-
+
return getDigestAlgName((ASN1ObjectIdentifier)ecDsaParams.getObjectAt(0)) + "withECDSA";
}
}
+ // deal with the "weird" ones.
+ String algName = (String)algNames.get(sigAlgId.getAlgorithm());
+ if (algName != null)
+ {
+ return algName;
+ }
+
+ return findAlgName(sigAlgId.getAlgorithm());
+ }
+
+ /**
+ * Return the digest algorithm using one of the standard JCA string
+ * representations rather the the algorithm identifier (if possible).
+ */
+ private static String getDigestAlgName(
+ ASN1ObjectIdentifier digestAlgOID)
+ {
+ String name = MessageDigestUtils.getDigestName(digestAlgOID);
+
+ int dIndex = name.indexOf('-');
+ if (dIndex > 0 && !name.startsWith("SHA3"))
+ {
+ return name.substring(0, dIndex) + name.substring(dIndex + 1);
+ }
+
+ return name;
+ }
+
+ private static String findAlgName(ASN1ObjectIdentifier algOid)
+ {
Provider prov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);
if (prov != null)
{
- String algName = prov.getProperty("Alg.Alias.Signature." + sigAlgId.getAlgorithm().getId());
-
+ String algName = lookupAlg(prov, algOid);
if (algName != null)
{
return algName;
@@ -95,36 +145,61 @@ class X509SignatureUtil
Provider[] provs = Security.getProviders();
- //
- // search every provider looking for a real algorithm
- //
for (int i = 0; i != provs.length; i++)
{
- String algName = provs[i].getProperty("Alg.Alias.Signature." + sigAlgId.getAlgorithm().getId());
- if (algName != null)
+ if (prov != provs[i])
{
- return algName;
+ String algName = lookupAlg(provs[i], algOid);
+ if (algName != null)
+ {
+ return algName;
+ }
}
}
- return sigAlgId.getAlgorithm().getId();
+ return algOid.getId();
}
-
- /**
- * Return the digest algorithm using one of the standard JCA string
- * representations rather the the algorithm identifier (if possible).
- */
- private static String getDigestAlgName(
- ASN1ObjectIdentifier digestAlgOID)
+
+ private static String lookupAlg(Provider prov, ASN1ObjectIdentifier algOid)
{
- String name = MessageDigestUtils.getDigestName(digestAlgOID);
+ String algName = prov.getProperty("Alg.Alias.Signature." + algOid);
- int dIndex = name.indexOf('-');
- if (dIndex > 0 && !name.startsWith("SHA3"))
+ if (algName != null)
{
- return name.substring(0, dIndex) + name.substring(dIndex + 1);
+ return algName;
}
- return MessageDigestUtils.getDigestName(digestAlgOID);
+ algName = prov.getProperty("Alg.Alias.Signature.OID." + algOid);
+
+ if (algName != null)
+ {
+ return algName;
+ }
+
+ return null;
}
+
+ static void prettyPrintSignature(byte[] sig, StringBuffer buf, String nl)
+ {
+ if (sig.length > 20)
+ {
+ buf.append(" Signature: ").append(Hex.toHexString(sig, 0, 20)).append(nl);
+ for (int i = 20; i < sig.length; i += 20)
+ {
+ if (i < sig.length - 20)
+ {
+ buf.append(" ").append(Hex.toHexString(sig, i, 20)).append(nl);
+ }
+ else
+ {
+ buf.append(" ").append(Hex.toHexString(sig, i, sig.length - i)).append(nl);
+ }
+ }
+ }
+ else
+ {
+ buf.append(" Signature: ").append(Hex.toHexString(sig)).append(nl);
+ }
+ }
+
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java
index 569fd242..da69af72 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
@@ -53,5 +53,7 @@ public interface ConfigurableProvider
void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter);
+ AsymmetricKeyInfoConverter getKeyInfoConverter(ASN1ObjectIdentifier oid);
+
void addAttributes(String key, Map<String, String> attributeMap);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
index 3e652240..2bb20070 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
@@ -4,6 +4,8 @@ package com.android.org.bouncycastle.jcajce.provider.digest;
import java.security.MessageDigest;
import com.android.org.bouncycastle.crypto.Digest;
+// BEGIN Android-removed:
+// import org.bouncycastle.crypto.Xof;
/**
* @hide This class is not part of the Android public SDK API
@@ -12,6 +14,7 @@ public class BCMessageDigest
extends MessageDigest
{
protected Digest digest;
+ protected int digestSize;
protected BCMessageDigest(
Digest digest)
@@ -19,8 +22,21 @@ public class BCMessageDigest
super(digest.getAlgorithmName());
this.digest = digest;
+ this.digestSize = digest.getDigestSize();
}
+ // BEGIN Android-removed:
+ /*
+ protected BCMessageDigest(
+ Xof digest, int outputSize)
+ {
+ super(digest.getAlgorithmName());
+
+ this.digest = digest;
+ this.digestSize = outputSize / 8;
+ }
+ */
+ // END Android-removed:
public void engineReset()
{
digest.reset();
@@ -40,9 +56,14 @@ public class BCMessageDigest
digest.update(input, offset, len);
}
+ public int engineGetDigestLength()
+ {
+ return digestSize;
+ }
+
public byte[] engineDigest()
{
- byte[] digestBytes = new byte[digest.getDigestSize()];
+ byte[] digestBytes = new byte[digestSize];
digest.doFinal(digestBytes, 0);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/MD5.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/MD5.java
index 9f076734..dd89e6e9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/MD5.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/MD5.java
@@ -81,11 +81,15 @@ public class MD5
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
provider.addAlgorithm("MessageDigest.MD5", PREFIX + "$Digest");
provider.addAlgorithm("Alg.Alias.MessageDigest." + PKCSObjectIdentifiers.md5, "MD5");
addHMACAlgorithm(provider, "MD5", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "MD5", IANAObjectIdentifiers.hmacMD5);
+ */
+ // END Android-removed: Unsupported algorithm
}
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA1.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA1.java
index c4a7b24b..f0976145 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA1.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/digest/SHA1.java
@@ -109,6 +109,8 @@ public class SHA1
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
provider.addAlgorithm("MessageDigest.SHA-1", PREFIX + "$Digest");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA1", "SHA-1");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA", "SHA-1");
@@ -117,6 +119,8 @@ public class SHA1
addHMACAlgorithm(provider, "SHA1", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "SHA1", PKCSObjectIdentifiers.id_hmacWithSHA1);
addHMACAlias(provider, "SHA1", IANAObjectIdentifiers.hmacSHA1);
+ */
+ // END Android-removed: Unsupported algorithm
provider.addAlgorithm("Mac.PBEWITHHMACSHA", PREFIX + "$SHA1Mac");
provider.addAlgorithm("Mac.PBEWITHHMACSHA1", PREFIX + "$SHA1Mac");
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 9c0eda9a..e9f436a8 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
@@ -80,15 +80,18 @@ public class SHA224
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("MessageDigest.SHA-224", PREFIX + "$Digest");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA224", "SHA-224");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha224, "SHA-224");
provider.addAlgorithm("Mac.PBEWITHHMACSHA224", PREFIX + "$HashMac");
-
+
addHMACAlgorithm(provider, "SHA224", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "SHA224", PKCSObjectIdentifiers.id_hmacWithSHA224);
-
+ */
+ // END Android-removed: Unsupported algorithms
}
}
}
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 a5df2b67..706d4ab3 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
@@ -98,21 +98,23 @@ public class SHA256
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("MessageDigest.SHA-256", PREFIX + "$Digest");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA256", "SHA-256");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha256, "SHA-256");
- // BEGIN Android-removed: Unsupported algorithms
- // provider.addAlgorithm("SecretKeyFactory.PBEWITHHMACSHA256", PREFIX + "$PBEWithMacKeyFactory");
- // provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHHMACSHA-256", "PBEWITHHMACSHA256");
- // provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + NISTObjectIdentifiers.id_sha256, "PBEWITHHMACSHA256");
- // END Android-removed: Unsupported algorithms
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHHMACSHA256", PREFIX + "$PBEWithMacKeyFactory");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHHMACSHA-256", "PBEWITHHMACSHA256");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + NISTObjectIdentifiers.id_sha256, "PBEWITHHMACSHA256");
provider.addAlgorithm("Mac.PBEWITHHMACSHA256", PREFIX + "$HashMac");
addHMACAlgorithm(provider, "SHA256", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "SHA256", PKCSObjectIdentifiers.id_hmacWithSHA256);
addHMACAlias(provider, "SHA256", NISTObjectIdentifiers.id_sha256);
+ */
+ // END Android-removed: Unsupported algorithms
}
}
}
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 57d32b0d..b7d97164 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
@@ -96,16 +96,19 @@ public class SHA384
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("MessageDigest.SHA-384", PREFIX + "$Digest");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA384", "SHA-384");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha384, "SHA-384");
- // Android-removed: Unsupported algorithms
- // provider.addAlgorithm("Mac.OLDHMACSHA384", PREFIX + "$OldSHA384");
+ provider.addAlgorithm("Mac.OLDHMACSHA384", PREFIX + "$OldSHA384");
provider.addAlgorithm("Mac.PBEWITHHMACSHA384", PREFIX + "$HashMac");
addHMACAlgorithm(provider, "SHA384", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "SHA384", PKCSObjectIdentifiers.id_hmacWithSHA384);
+ */
+ // END Android-removed: Unsupported algorithms
}
}
}
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 5f3267ff..dbd513c7 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
@@ -182,12 +182,12 @@ public class SHA512
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("MessageDigest.SHA-512", PREFIX + "$Digest");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512", "SHA-512");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512, "SHA-512");
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAlgorithm("MessageDigest.SHA-512/224", PREFIX + "$DigestT224");
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512/224", "SHA-512/224");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512_224, "SHA-512/224");
@@ -197,17 +197,15 @@ public class SHA512
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512_256, "SHA-512/256");
provider.addAlgorithm("Mac.OLDHMACSHA512", PREFIX + "$OldSHA512");
- */
- // END Android-removed: Unsupported algorithms
provider.addAlgorithm("Mac.PBEWITHHMACSHA512", PREFIX + "$HashMac");
addHMACAlgorithm(provider, "SHA512", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "SHA512", PKCSObjectIdentifiers.id_hmacWithSHA512);
- // BEGIN Android-removed: Unsupported algorithms
- // addHMACAlgorithm(provider, "SHA512/224", PREFIX + "$HashMacT224", PREFIX + "$KeyGeneratorT224");
- // addHMACAlgorithm(provider, "SHA512/256", PREFIX + "$HashMacT256", PREFIX + "$KeyGeneratorT256");
+ addHMACAlgorithm(provider, "SHA512/224", PREFIX + "$HashMacT224", PREFIX + "$KeyGeneratorT224");
+ addHMACAlgorithm(provider, "SHA512/256", PREFIX + "$HashMacT256", PREFIX + "$KeyGeneratorT256");
+ */
// END Android-removed: Unsupported algorithms
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
index 37a1c082..44faf7db 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
@@ -52,6 +52,8 @@ import com.android.org.bouncycastle.crypto.macs.HMac;
// Android-changed: Use default provider for JCA algorithms instead of BC
// Was: import org.bouncycastle.jcajce.util.BCJcaJceHelper;
import com.android.org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+// import org.bouncycastle.jcajce.io.CipherInputStream;
+// import org.bouncycastle.jcajce.io.CipherOutputStream;
import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
import com.android.org.bouncycastle.jce.interfaces.BCKeyStore;
import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
@@ -149,7 +151,6 @@ public class BcKeyStoreSpi
byte[] salt = new byte[KEY_SALT_SIZE];
- random.setSeed(System.currentTimeMillis());
random.nextBytes(salt);
int iterationCount = MIN_ITERATIONS + (random.nextInt() & 0x3ff);
@@ -686,7 +687,7 @@ public class BcKeyStoreSpi
}
catch (Exception e)
{
- throw new KeyStoreException(e.toString());
+ throw new BCKeyStoreException(e.toString(), e);
}
}
@@ -1079,4 +1080,21 @@ public class BcKeyStoreSpi
super(1);
}
}
+
+ private static class BCKeyStoreException
+ extends KeyStoreException
+ {
+ private final Exception cause;
+
+ public BCKeyStoreException(String msg, Exception cause)
+ {
+ super(msg);
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
}
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 2354e19d..fb5f2fdd 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
@@ -3,7 +3,6 @@ package com.android.org.bouncycastle.jcajce.provider.keystore.pkcs12;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -58,11 +57,10 @@ import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1Set;
import com.android.org.bouncycastle.asn1.BEROctetString;
-import com.android.org.bouncycastle.asn1.BEROutputStream;
+import com.android.org.bouncycastle.asn1.BERSequence;
import com.android.org.bouncycastle.asn1.DERBMPString;
import com.android.org.bouncycastle.asn1.DERNull;
import com.android.org.bouncycastle.asn1.DEROctetString;
-import com.android.org.bouncycastle.asn1.DEROutputStream;
import com.android.org.bouncycastle.asn1.DERSequence;
import com.android.org.bouncycastle.asn1.DERSet;
// Android-removed: Unsupported algorithms
@@ -407,26 +405,16 @@ public class PKCS12KeyStoreSpi
X509Certificate x509c = (X509Certificate)c;
Certificate nextC = null;
- byte[] bytes = x509c.getExtensionValue(Extension.authorityKeyIdentifier.getId());
- if (bytes != null)
+ byte[] akiBytes = x509c.getExtensionValue(Extension.authorityKeyIdentifier.getId());
+ if (akiBytes != null)
{
- try
- {
- ASN1InputStream aIn = new ASN1InputStream(bytes);
-
- byte[] authBytes = ((ASN1OctetString)aIn.readObject()).getOctets();
- aIn = new ASN1InputStream(authBytes);
+ ASN1OctetString akiValue = ASN1OctetString.getInstance(akiBytes);
+ AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance(akiValue.getOctets());
- AuthorityKeyIdentifier id = AuthorityKeyIdentifier.getInstance(aIn.readObject());
- if (id.getKeyIdentifier() != null)
- {
- nextC = (Certificate)chainCerts.get(new CertId(id.getKeyIdentifier()));
- }
-
- }
- catch (IOException e)
+ byte[] keyID = aki.getKeyIdentifier();
+ if (null != keyID)
{
- throw new RuntimeException(e.toString());
+ nextC = (Certificate)chainCerts.get(new CertId(keyID));
}
}
@@ -786,11 +774,6 @@ public class PKCS12KeyStoreSpi
return;
}
- if (password == null)
- {
- throw new NullPointerException("No password supplied for PKCS#12 KeyStore.");
- }
-
BufferedInputStream bufIn = new BufferedInputStream(stream);
bufIn.mark(10);
@@ -823,6 +806,11 @@ public class PKCS12KeyStoreSpi
if (bag.getMacData() != null) // check the mac code
{
+ if (password == null)
+ {
+ throw new NullPointerException("no password supplied when one expected");
+ }
+
MacData mData = bag.getMacData();
DigestInfo dInfo = mData.getMac();
macAlgorithm = dInfo.getAlgorithmId();
@@ -864,23 +852,33 @@ public class PKCS12KeyStoreSpi
throw new IOException("error constructing MAC: " + e.toString());
}
}
+ // BEGIN Android-removed: keep v1.61 behaviour to keep backwards-compatibility
+ /*
+ else if (password != null)
+ {
+ if (!Properties.isOverrideSet("org.bouncycastle.pkcs12.ignore_useless_passwd"))
+ {
+ throw new IOException("password supplied for keystore that does not require one");
+ }
+ }
+ */
+ // END Android-removed: keep v1.61 behaviour to keep backwards-compatibility
keys = new IgnoresCaseHashtable();
localIds = new Hashtable();
if (info.getContentType().equals(data))
{
- bIn = new ASN1InputStream(((ASN1OctetString)info.getContent()).getOctets());
-
- AuthenticatedSafe authSafe = AuthenticatedSafe.getInstance(bIn.readObject());
+ ASN1OctetString content = ASN1OctetString.getInstance(info.getContent());
+ AuthenticatedSafe authSafe = AuthenticatedSafe.getInstance(content.getOctets());
ContentInfo[] c = authSafe.getContentInfo();
for (int i = 0; i != c.length; i++)
{
if (c[i].getContentType().equals(data))
{
- ASN1InputStream dIn = new ASN1InputStream(((ASN1OctetString)c[i].getContent()).getOctets());
- ASN1Sequence seq = (ASN1Sequence)dIn.readObject();
+ ASN1OctetString authSafeContent = ASN1OctetString.getInstance(c[i].getContent());
+ ASN1Sequence seq = ASN1Sequence.getInstance(authSafeContent.getOctets());
for (int j = 0; j != seq.size(); j++)
{
@@ -977,7 +975,7 @@ public class PKCS12KeyStoreSpi
EncryptedData d = EncryptedData.getInstance(c[i].getContent());
byte[] octets = cryptData(false, d.getEncryptionAlgorithm(),
password, wrongPKCS12Zero, d.getContent().getOctets());
- ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(octets);
+ ASN1Sequence seq = ASN1Sequence.getInstance(octets);
for (int j = 0; j != seq.size(); j++)
{
@@ -1312,10 +1310,69 @@ public class PKCS12KeyStoreSpi
private void doStore(OutputStream stream, char[] password, boolean useDEREncoding)
throws IOException
{
+ // BEGIN Android-changed: Upstream allows null passwords, but we maintain historical Android
+ // behaviour.
+ // See CtsKeystoreTestCases:android.keystore.cts.KeyStoreTest
if (password == null)
{
throw new NullPointerException("No password supplied for PKCS#12 KeyStore.");
}
+ /*
+ if (keys.size() == 0)
+ {
+ if (password == null)
+ {
+ Enumeration cs = certs.keys();
+
+ ASN1EncodableVector certSeq = new ASN1EncodableVector();
+
+ while (cs.hasMoreElements())
+ {
+ try
+ {
+ String certId = (String)cs.nextElement();
+ Certificate cert = (Certificate)certs.get(certId);
+
+ SafeBag sBag = createSafeBag(certId, cert);
+
+ certSeq.add(sBag);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IOException("Error encoding certificate: " + e.toString());
+ }
+ }
+
+ if (useDEREncoding)
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.DER);
+ }
+ else
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.BER);
+ }
+
+ return;
+ }
+ }
+ else
+ {
+ if (password == null)
+ {
+ throw new NullPointerException("no password supplied for PKCS#12 KeyStore");
+ }
+ }
+ */
+ // END Android-changed: Upstream allows null passwords, but we maintain historical Android
+ // behaviour.
//
// handle the key
@@ -1500,66 +1557,13 @@ public class PKCS12KeyStoreSpi
{
String certId = (String)cs.nextElement();
Certificate cert = (Certificate)certs.get(certId);
- boolean cAttrSet = false;
if (keys.get(certId) != null)
{
continue;
}
- CertBag cBag = new CertBag(
- x509Certificate,
- new DEROctetString(cert.getEncoded()));
- ASN1EncodableVector fName = new ASN1EncodableVector();
-
- if (cert instanceof PKCS12BagAttributeCarrier)
- {
- PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert;
- //
- // make sure we are using the local alias on store
- //
- DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
- if (nm == null || !nm.getString().equals(certId))
- {
- bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(certId));
- }
-
- Enumeration e = bagAttrs.getBagAttributeKeys();
-
- while (e.hasMoreElements())
- {
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
-
- // a certificate not immediately linked to a key doesn't require
- // a localKeyID and will confuse some PKCS12 implementations.
- //
- // If we find one, we'll prune it out.
- if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId))
- {
- continue;
- }
-
- ASN1EncodableVector fSeq = new ASN1EncodableVector();
-
- fSeq.add(oid);
- fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid)));
- fName.add(new DERSequence(fSeq));
-
- cAttrSet = true;
- }
- }
-
- if (!cAttrSet)
- {
- ASN1EncodableVector fSeq = new ASN1EncodableVector();
-
- fSeq.add(pkcs_9_at_friendlyName);
- fSeq.add(new DERSet(new DERBMPString(certId)));
-
- fName.add(new DERSequence(fSeq));
- }
-
- SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName));
+ SafeBag sBag = createSafeBag(certId, cert);
certSeq.add(sBag);
@@ -1644,20 +1648,7 @@ public class PKCS12KeyStoreSpi
AuthenticatedSafe auth = new AuthenticatedSafe(info);
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- DEROutputStream asn1Out;
- if (useDEREncoding)
- {
- asn1Out = new DEROutputStream(bOut);
- }
- else
- {
- asn1Out = new BEROutputStream(bOut);
- }
-
- asn1Out.writeObject(auth);
-
- byte[] pkg = bOut.toByteArray();
+ byte[] pkg = auth.getEncoded(useDEREncoding ? ASN1Encoding.DER : ASN1Encoding.BER);
ContentInfo mainInfo = new ContentInfo(data, new BEROctetString(pkg));
@@ -1690,16 +1681,69 @@ public class PKCS12KeyStoreSpi
//
Pfx pfx = new Pfx(mainInfo, mData);
- if (useDEREncoding)
+ pfx.encodeTo(stream, useDEREncoding ? ASN1Encoding.DER : ASN1Encoding.BER);
+ }
+
+ private SafeBag createSafeBag(String certId, Certificate cert)
+ throws CertificateEncodingException
+ {
+ CertBag cBag = new CertBag(
+ x509Certificate,
+ new DEROctetString(cert.getEncoded()));
+ ASN1EncodableVector fName = new ASN1EncodableVector();
+
+ boolean cAttrSet = false;
+ if (cert instanceof PKCS12BagAttributeCarrier)
{
- asn1Out = new DEROutputStream(stream);
+ PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert;
+ //
+ // make sure we are using the local alias on store
+ //
+ DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
+ if (nm == null || !nm.getString().equals(certId))
+ {
+ if (certId != null)
+ {
+ bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(certId));
+ }
+ }
+
+ Enumeration e = bagAttrs.getBagAttributeKeys();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+
+ // a certificate not immediately linked to a key doesn't require
+ // a localKeyID and will confuse some PKCS12 implementations.
+ //
+ // If we find one, we'll prune it out.
+ if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId))
+ {
+ continue;
+ }
+
+ ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ fSeq.add(oid);
+ fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid)));
+ fName.add(new DERSequence(fSeq));
+
+ cAttrSet = true;
+ }
}
- else
+
+ if (!cAttrSet)
{
- asn1Out = new BEROutputStream(stream);
+ ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ fSeq.add(pkcs_9_at_friendlyName);
+ fSeq.add(new DERSet(new DERBMPString(certId)));
+
+ fName.add(new DERSequence(fSeq));
}
- asn1Out.writeObject(pfx);
+ return new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName));
}
private Set getUsedCertificateSet()
@@ -1842,6 +1886,11 @@ public class PKCS12KeyStoreSpi
{
return orig.elements();
}
+
+ public int size()
+ {
+ return orig.size();
+ }
}
private static class DefaultSecretKeyProvider
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 604cd08c..9e2a493d 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
@@ -27,6 +27,7 @@ import com.android.org.bouncycastle.crypto.BlockCipher;
import com.android.org.bouncycastle.crypto.BufferedBlockCipher;
import com.android.org.bouncycastle.crypto.CipherKeyGenerator;
import com.android.org.bouncycastle.crypto.CipherParameters;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
import com.android.org.bouncycastle.crypto.DataLengthException;
import com.android.org.bouncycastle.crypto.InvalidCipherTextException;
import com.android.org.bouncycastle.crypto.Mac;
@@ -56,6 +57,7 @@ import com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenera
// import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory;
import com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher;
import com.android.org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider;
+import com.android.org.bouncycastle.jcajce.provider.symmetric.util.GcmSpecUtil;
import com.android.org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters;
import com.android.org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory;
import com.android.org.bouncycastle.jcajce.spec.AEADParameterSpec;
@@ -159,7 +161,7 @@ public final class AES
{
public CCM()
{
- super(new CCMBlockCipher(new AESEngine()), false, 16);
+ super(new CCMBlockCipher(new AESEngine()), false, 12);
}
}
@@ -594,7 +596,7 @@ public final class AES
if (random == null)
{
- random = new SecureRandom();
+ random = CryptoServicesRegistrar.getSecureRandom();
}
random.nextBytes(iv);
@@ -907,6 +909,8 @@ public final class AES
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("AlgorithmParameters.AES", PREFIX + "$AlgParams");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + wrongAES128, "AES");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + wrongAES192, "AES");
@@ -919,9 +923,7 @@ public final class AES
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes128_GCM, "GCM");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes192_GCM, "GCM");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes256_GCM, "GCM");
-
- // BEGIN Android-removed: Unsupported algorithms
- /*
+
provider.addAlgorithm("AlgorithmParameters.CCM", PREFIX + "$AlgParamsCCM");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes128_CCM, "CCM");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes192_CCM, "CCM");
@@ -993,20 +995,14 @@ public final class AES
provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes128_GCM, "GCM");
provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes192_GCM, "GCM");
provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes256_GCM, "GCM");
- */
- // END Android-removed: Unsupported algorithms
-
- // BEGIN Android-changed: Use standard name for AES/GCM/NOPADDING instead of "GCM"
+
provider.addAttributes("Cipher.AES/GCM/NOPADDING", generalAesAttributes);
provider.addAlgorithm("Cipher.AES/GCM/NOPADDING", PREFIX + "$GCM");
provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes128_GCM, "AES/GCM/NOPADDING");
provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes192_GCM, "AES/GCM/NOPADDING");
provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes256_GCM, "AES/GCM/NOPADDING");
- // END Android-changed: Use standard name for AES/GCM/NOPADDING instead of "GCM"
-
+
provider.addAlgorithm("KeyGenerator.AES", PREFIX + "$KeyGen");
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAlgorithm("KeyGenerator." + wrongAES128, PREFIX + "$KeyGen128");
provider.addAlgorithm("KeyGenerator." + wrongAES192, PREFIX + "$KeyGen192");
provider.addAlgorithm("KeyGenerator." + wrongAES256, PREFIX + "$KeyGen256");
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/ARC4.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/ARC4.java
index 2df70a54..a0b7c538 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/ARC4.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/ARC4.java
@@ -112,10 +112,14 @@ public final class ARC4
public void configure(ConfigurableProvider provider)
{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("Cipher.ARC4", PREFIX + "$Base");
provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.rc4, "ARC4");
provider.addAlgorithm("Alg.Alias.Cipher.ARCFOUR", "ARC4");
provider.addAlgorithm("Alg.Alias.Cipher.RC4", "ARC4");
+ */
+ // END Android-removed: Unsupported algorithms
provider.addAlgorithm("KeyGenerator.ARC4", PREFIX + "$KeyGen");
provider.addAlgorithm("Alg.Alias.KeyGenerator.RC4", "ARC4");
provider.addAlgorithm("Alg.Alias.KeyGenerator.1.2.840.113549.3.4", "ARC4");
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/DESede.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/DESede.java
index df1b354e..f93b3e43 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/DESede.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/DESede.java
@@ -427,22 +427,21 @@ public final class DESede
provider.addAlgorithm("Alg.Alias.Cipher.TDEA", "DESEDE");
provider.addAlgorithm("Alg.Alias.Cipher.TDEAWRAP", "DESEDEWRAP");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
provider.addAlgorithm("Alg.Alias.KeyGenerator.TDEA", "DESEDE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.TDEA", "DESEDE");
- // Android-removed: Unsupported algorithms
- // provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator.TDEA", "DESEDE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator.TDEA", "DESEDE");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory.TDEA", "DESEDE");
+ */
+ // END Android-removed: Unsupported algorithms
- if (provider.hasAlgorithm("MessageDigest", "SHA-1"))
+ // Android-removed Bouncy Castle's SHA-1 implementation is removed but we still need PBEWithSHAAnd3-KeyTripleDES-CBC
+ // if (provider.hasAlgorithm("MessageDigest", "SHA-1"))
{
provider.addAlgorithm("Cipher.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES3Key");
- // BEGIN Android-removed: Unsupported algorithms
- // provider.addAlgorithm("Cipher.BROKENPBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$BrokePBEWithSHAAndDES3Key");
- // provider.addAlgorithm("Cipher.OLDPBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$OldPBEWithSHAAndDES3Key");
- // END Android-removed: Unsupported algorithms
provider.addAlgorithm("Cipher.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES2Key");
- // Android-removed: Unsupported algorithms
- // provider.addAlgorithm("Cipher.BROKENPBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$BrokePBEWithSHAAndDES2Key");
+
provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDDESEDE", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
@@ -455,16 +454,14 @@ public final class DESede
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDDESEDE-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
}
- provider.addAlgorithm("KeyGenerator.DESEDE", PREFIX + "$KeyGenerator");
// BEGIN Android-removed: Unsupported algorithms
- // provider.addAlgorithm("KeyGenerator." + PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$KeyGenerator3");
- // provider.addAlgorithm("KeyGenerator.DESEDEWRAP", PREFIX + "$KeyGenerator");
- // END Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("KeyGenerator.DESEDE", PREFIX + "$KeyGenerator");
+ provider.addAlgorithm("KeyGenerator." + PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$KeyGenerator3");
+ provider.addAlgorithm("KeyGenerator.DESEDEWRAP", PREFIX + "$KeyGenerator");
provider.addAlgorithm("SecretKeyFactory.DESEDE", PREFIX + "$KeyFactory");
- // BEGIN Android-removed: Unsupported algorithms
- /*
provider.addAlgorithm("SecretKeyFactory", OIWObjectIdentifiers.desEDE, PREFIX + "$KeyFactory");
provider.addAlgorithm("Mac.DESEDECMAC", PREFIX + "$CMAC");
@@ -481,11 +478,11 @@ public final class DESede
provider.addAlgorithm("Alg.Alias.Mac.DESEDE64WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1MACWITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
- */
- // END Android-removed: Unsupported algorithms
provider.addAlgorithm("AlgorithmParameters.DESEDE", PACKAGE + ".util.IvAlgorithmParameters");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE");
+ */
+ // END Android-removed: Unsupported algorithms
// BEGIN Android-removed: Unsupported algorithms
// provider.addAlgorithm("AlgorithmParameterGenerator.DESEDE", PREFIX + "$AlgParamGen");
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 766646e6..2109104c 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
@@ -18,6 +18,7 @@ import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
// import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import com.android.org.bouncycastle.asn1.pkcs.PBKDF2Params;
import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -43,18 +44,21 @@ public class PBEPBKDF2
static
{
- // Android-removed: Unsupported algorithm
- // prfCodes.put(CryptoProObjectIdentifiers.gostR3411Hmac, Integers.valueOf(PBE.GOST3411));
+ // 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));
- // Android-remove: Unsupported algorithms
- // 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));
- // prfCodes.put(NISTObjectIdentifiers.id_hmacWithSHA3_512, Integers.valueOf(PBE.SHA3_512));
+ 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));
+ prfCodes.put(NISTObjectIdentifiers.id_hmacWithSHA3_512, Integers.valueOf(PBE.SHA3_512));
+ prfCodes.put(GMObjectIdentifiers.hmac_sm3, Integers.valueOf(PBE.SM3));
+ */
+ // END Android-removed: Unsupported algorithm
}
private PBEPBKDF2()
@@ -96,7 +100,7 @@ public class PBEPBKDF2
Class paramSpec)
throws InvalidParameterSpecException
{
- if (paramSpec == PBEParameterSpec.class)
+ if (paramSpec == PBEParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
{
return new PBEParameterSpec(params.getSalt(),
params.getIterationCount().intValue());
@@ -606,6 +610,18 @@ public class PBEPBKDF2
}
// END Android-added: Android implementations of PBKDF2 algorithms.
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class PBKDF2withSM3
+ extends BasePBKDF2
+ {
+ public PBKDF2withSM3() {
+ super("PBKDF2", PKCS5S2_UTF8, SM3);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
/**
* @hide This class is not part of the Android public SDK API
*/
@@ -647,6 +663,7 @@ public class PBEPBKDF2
provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA3-384", PREFIX + "$PBKDF2withSHA3_384");
provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA3-512", PREFIX + "$PBKDF2withSHA3_512");
provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACGOST3411", PREFIX + "$PBKDF2withGOST3411");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSM3", PREFIX + "$PBKDF2withSM3");
*/
// END Android-removed: Bouncy Castle versions of algorithms.
// BEGIN Android-added: Android versions of algorithms.
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java
index 1cc9510c..d340b55c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java
@@ -59,7 +59,7 @@ public class PBEPKCS12
Class paramSpec)
throws InvalidParameterSpecException
{
- if (paramSpec == PBEParameterSpec.class)
+ if (paramSpec == PBEParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
{
return new PBEParameterSpec(params.getIV(),
params.getIterations().intValue());
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/RC2.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/RC2.java
index 761766ff..827d3818 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/RC2.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/RC2.java
@@ -387,7 +387,7 @@ public final class RC2
}
}
- if (paramSpec == IvParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
+ if (paramSpec == IvParameterSpec.class)
{
return new IvParameterSpec(iv);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
index 980aad12..8013761a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
@@ -1,31 +1,40 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.jcajce.provider.symmetric.util;
-import java.security.spec.KeySpec;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.crypto.interfaces.PBEKey;
import javax.crypto.spec.PBEKeySpec;
+import javax.security.auth.Destroyable;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.crypto.CipherParameters;
import com.android.org.bouncycastle.crypto.PBEParametersGenerator;
import com.android.org.bouncycastle.crypto.params.KeyParameter;
import com.android.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.org.bouncycastle.util.Arrays;
/**
* @hide This class is not part of the Android public SDK API
*/
public class BCPBEKey
- implements PBEKey
+ implements PBEKey, Destroyable
{
+ private final AtomicBoolean hasBeenDestroyed = new AtomicBoolean(false);
+
String algorithm;
ASN1ObjectIdentifier oid;
int type;
int digest;
int keySize;
int ivSize;
- CipherParameters param;
- PBEKeySpec pbeKeySpec;
+
+ private final char[] password;
+ private final byte[] salt;
+ private final int iterationCount;
+
+ private final CipherParameters param;
+
boolean tryWrong = false;
/**
@@ -47,19 +56,25 @@ public class BCPBEKey
this.digest = digest;
this.keySize = keySize;
this.ivSize = ivSize;
- this.pbeKeySpec = pbeKeySpec;
+ this.password = pbeKeySpec.getPassword();
+ this.iterationCount = pbeKeySpec.getIterationCount();
+ this.salt = pbeKeySpec.getSalt();
this.param = param;
}
- public BCPBEKey(String algName,
- KeySpec pbeSpec, CipherParameters param)
+ public BCPBEKey(String algName, CipherParameters param)
{
this.algorithm = algName;
this.param = param;
+ this.password = null;
+ this.iterationCount = -1;
+ this.salt = null;
}
public String getAlgorithm()
{
+ checkDestroyed(this);
+
return algorithm;
}
@@ -70,6 +85,8 @@ public class BCPBEKey
public byte[] getEncoded()
{
+ checkDestroyed(this);
+
if (param != null)
{
KeyParameter kParam;
@@ -89,41 +106,51 @@ public class BCPBEKey
{
if (type == PBE.PKCS12)
{
- return PBEParametersGenerator.PKCS12PasswordToBytes(pbeKeySpec.getPassword());
+ return PBEParametersGenerator.PKCS12PasswordToBytes(password);
}
else if (type == PBE.PKCS5S2_UTF8)
{
- return PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(pbeKeySpec.getPassword());
+ return PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password);
}
else
{
- return PBEParametersGenerator.PKCS5PasswordToBytes(pbeKeySpec.getPassword());
+ return PBEParametersGenerator.PKCS5PasswordToBytes(password);
}
}
}
int getType()
{
+ checkDestroyed(this);
+
return type;
}
int getDigest()
{
+ checkDestroyed(this);
+
return digest;
}
int getKeySize()
{
+ checkDestroyed(this);
+
return keySize;
}
public int getIvSize()
{
+ checkDestroyed(this);
+
return ivSize;
}
public CipherParameters getParam()
{
+ checkDestroyed(this);
+
return param;
}
@@ -132,7 +159,14 @@ public class BCPBEKey
*/
public char[] getPassword()
{
- return pbeKeySpec.getPassword();
+ checkDestroyed(this);
+
+ if (password == null)
+ {
+ throw new IllegalStateException("no password available");
+ }
+
+ return Arrays.clone(password);
}
/* (non-Javadoc)
@@ -140,7 +174,9 @@ public class BCPBEKey
*/
public byte[] getSalt()
{
- return pbeKeySpec.getSalt();
+ checkDestroyed(this);
+
+ return Arrays.clone(salt);
}
/* (non-Javadoc)
@@ -148,11 +184,15 @@ public class BCPBEKey
*/
public int getIterationCount()
{
- return pbeKeySpec.getIterationCount();
+ checkDestroyed(this);
+
+ return iterationCount;
}
public ASN1ObjectIdentifier getOID()
{
+ checkDestroyed(this);
+
return oid;
}
@@ -165,4 +205,32 @@ public class BCPBEKey
{
return tryWrong;
}
+
+ public void destroy()
+ {
+ if (!hasBeenDestroyed.getAndSet(true))
+ {
+ if (password != null)
+ {
+ Arrays.fill(password, (char)0);
+ }
+ if (salt != null)
+ {
+ Arrays.fill(salt, (byte)0);
+ }
+ }
+ }
+
+ public boolean isDestroyed()
+ {
+ return hasBeenDestroyed.get();
+ }
+
+ static void checkDestroyed(Destroyable destroyable)
+ {
+ if (destroyable.isDestroyed())
+ {
+ throw new IllegalStateException("key has been destroyed");
+ }
+ }
}
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 13514775..1eeb6e96 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
@@ -2,7 +2,6 @@
package com.android.org.bouncycastle.jcajce.provider.symmetric.util;
import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
@@ -29,7 +28,9 @@ import javax.crypto.spec.PBEParameterSpec;
// import javax.crypto.spec.RC2ParameterSpec;
// import javax.crypto.spec.RC5ParameterSpec;
+import com.android.org.bouncycastle.asn1.DEROctetString;
import com.android.org.bouncycastle.asn1.cms.GCMParameters;
+import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.crypto.BlockCipher;
import com.android.org.bouncycastle.crypto.BufferedBlockCipher;
import com.android.org.bouncycastle.crypto.CipherParameters;
@@ -40,6 +41,7 @@ import com.android.org.bouncycastle.crypto.OutputLengthException;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.engines.DSTU7624Engine;
import com.android.org.bouncycastle.crypto.modes.AEADBlockCipher;
+import com.android.org.bouncycastle.crypto.modes.AEADCipher;
import com.android.org.bouncycastle.crypto.modes.CBCBlockCipher;
import com.android.org.bouncycastle.crypto.modes.CCMBlockCipher;
import com.android.org.bouncycastle.crypto.modes.CFBBlockCipher;
@@ -83,6 +85,7 @@ import com.android.org.bouncycastle.jcajce.spec.AEADParameterSpec;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
// import org.bouncycastle.jcajce.spec.RepeatedSecretKeySpec;
+import com.android.org.bouncycastle.util.Arrays;
import com.android.org.bouncycastle.util.Strings;
/**
@@ -92,41 +95,42 @@ public class BaseBlockCipher
extends BaseWrapCipher
implements PBE
{
+ private static final int BUF_SIZE = 512;
private static final Class gcmSpecClass = ClassUtil.loadClass(BaseBlockCipher.class, "javax.crypto.spec.GCMParameterSpec");
//
// specs we can handle.
//
- private Class[] availableSpecs =
- {
- // Android-removed: Unsupported algorithms
- // RC2ParameterSpec.class,
- // RC5ParameterSpec.class,
- gcmSpecClass,
- // Android-removed: Unsupported algorithms
- // GOST28147ParameterSpec.class
- IvParameterSpec.class,
- PBEParameterSpec.class
- };
-
- private BlockCipher baseEngine;
- private BlockCipherProvider engineProvider;
- private GenericBlockCipher cipher;
- private ParametersWithIV ivParam;
- private AEADParameters aeadParams;
+ private Class[] availableSpecs =
+ {
+ // Android-removed: Unsupported alhorithms
+ // RC2ParameterSpec.class,
+ // RC5ParameterSpec.class,
+ gcmSpecClass,
+ // Android-removed: unsupported algorithms
+ // GOST28147ParameterSpec.class,
+ IvParameterSpec.class,
+ PBEParameterSpec.class
+ };
+
+ private BlockCipher baseEngine;
+ private BlockCipherProvider engineProvider;
+ private GenericBlockCipher cipher;
+ private ParametersWithIV ivParam;
+ private AEADParameters aeadParams;
private int keySizeInBits;
private int scheme = -1;
private int digest;
- private int ivLength = 0;
+ private int ivLength = 0;
- private boolean padded;
- private boolean fixedIv = true;
- private PBEParameterSpec pbeSpec = null;
- private String pbeAlgorithm = null;
+ private boolean padded;
+ private boolean fixedIv = true;
+ private PBEParameterSpec pbeSpec = null;
+ private String pbeAlgorithm = null;
- private String modeName = null;
+ private String modeName = null;
protected BaseBlockCipher(
BlockCipher engine)
@@ -171,6 +175,17 @@ public class BaseBlockCipher
}
protected BaseBlockCipher(
+ AEADCipher engine,
+ boolean fixedIv,
+ int ivLength)
+ {
+ this.baseEngine = null;
+ this.fixedIv = fixedIv;
+ this.ivLength = ivLength;
+ this.cipher = new AEADGenericBlockCipher(engine);
+ }
+
+ protected BaseBlockCipher(
AEADBlockCipher engine,
boolean fixedIv,
int ivLength)
@@ -221,6 +236,10 @@ public class BaseBlockCipher
protected int engineGetBlockSize()
{
+ if (baseEngine == null)
+ {
+ return -1;
+ }
return baseEngine.getBlockSize();
}
@@ -235,13 +254,13 @@ public class BaseBlockCipher
}
protected int engineGetKeySize(
- Key key)
+ Key key)
{
return key.getEncoded().length * 8;
}
protected int engineGetOutputSize(
- int inputLen)
+ int inputLen)
{
return cipher.getOutputSize(inputLen);
}
@@ -264,19 +283,35 @@ public class BaseBlockCipher
}
else if (aeadParams != null)
{
- try
+ // CHACHA20-Poly1305
+ if (baseEngine == null)
{
- engineParams = createParametersInstance("GCM");
- engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize() / 8).getEncoded());
+ try
+ {
+ engineParams = createParametersInstance(PKCSObjectIdentifiers.id_alg_AEADChaCha20Poly1305.getId());
+ engineParams.init(new DEROctetString(aeadParams.getNonce()).getEncoded());
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.toString());
+ }
}
- catch (Exception e)
+ else
{
- throw new RuntimeException(e.toString());
+ try
+ {
+ engineParams = createParametersInstance("GCM");
+ engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize() / 8).getEncoded());
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.toString());
+ }
}
}
else if (ivParam != null)
{
- String name = cipher.getUnderlyingCipher().getAlgorithmName();
+ String name = cipher.getUnderlyingCipher().getAlgorithmName();
if (name.indexOf('/') >= 0)
{
@@ -299,9 +334,13 @@ public class BaseBlockCipher
}
protected void engineSetMode(
- String mode)
+ String mode)
throws NoSuchAlgorithmException
{
+ if (baseEngine == null)
+ {
+ throw new NoSuchAlgorithmException("no mode supported for this algorithm");
+ }
modeName = Strings.toUpperCase(mode);
if (modeName.equals("ECB"))
@@ -313,7 +352,7 @@ public class BaseBlockCipher
{
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(
- new CBCBlockCipher(baseEngine));
+ new CBCBlockCipher(baseEngine));
}
else if (modeName.startsWith("OFB"))
{
@@ -323,12 +362,12 @@ public class BaseBlockCipher
int wordSize = Integer.parseInt(modeName.substring(3));
cipher = new BufferedGenericBlockCipher(
- new OFBBlockCipher(baseEngine, wordSize));
+ new OFBBlockCipher(baseEngine, wordSize));
}
else
{
cipher = new BufferedGenericBlockCipher(
- new OFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
+ new OFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
}
}
else if (modeName.startsWith("CFB"))
@@ -339,31 +378,36 @@ public class BaseBlockCipher
int wordSize = Integer.parseInt(modeName.substring(3));
cipher = new BufferedGenericBlockCipher(
- new CFBBlockCipher(baseEngine, wordSize));
+ new CFBBlockCipher(baseEngine, wordSize));
}
else
{
cipher = new BufferedGenericBlockCipher(
- new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
+ new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
}
}
// BEGIN Android-removed: Unsupported modes
/*
- else if (modeName.startsWith("PGP"))
+ else if (modeName.startsWith("PGPCFB"))
{
- boolean inlineIV = modeName.equalsIgnoreCase("PGPCFBwithIV");
+ boolean inlineIV = modeName.equals("PGPCFBWITHIV");
+ if (!inlineIV && modeName.length() != 6)
+ {
+ throw new NoSuchAlgorithmException("no mode support for " + modeName);
+ }
+
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(
new PGPCFBBlockCipher(baseEngine, inlineIV));
}
- else if (modeName.equalsIgnoreCase("OpenPGPCFB"))
+ else if (modeName.equals("OPENPGPCFB"))
{
ivLength = 0;
cipher = new BufferedGenericBlockCipher(
new OpenPGPCFBBlockCipher(baseEngine));
}
- else if (modeName.startsWith("SIC"))
+ else if (modeName.equals("SIC"))
{
ivLength = baseEngine.getBlockSize();
if (ivLength < 16)
@@ -372,11 +416,11 @@ public class BaseBlockCipher
}
fixedIv = false;
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new SICBlockCipher(baseEngine)));
+ new SICBlockCipher(baseEngine)));
}
*/
// END Android-removed: Unsupported modes
- else if (modeName.startsWith("CTR"))
+ else if (modeName.equals("CTR"))
{
ivLength = baseEngine.getBlockSize();
fixedIv = false;
@@ -385,7 +429,7 @@ public class BaseBlockCipher
if (baseEngine instanceof DSTU7624Engine)
{
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new KCTRBlockCipher(baseEngine)));
+ new KCTRBlockCipher(baseEngine)));
}
else
{
@@ -398,26 +442,26 @@ public class BaseBlockCipher
}
// BEGIN Android-removed: Unsupported modes
/*
- else if (modeName.startsWith("GOFB"))
+ else if (modeName.equals("GOFB"))
{
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new GOFBBlockCipher(baseEngine)));
+ new GOFBBlockCipher(baseEngine)));
}
- else if (modeName.startsWith("GCFB"))
+ else if (modeName.equals("GCFB"))
{
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new GCFBBlockCipher(baseEngine)));
+ new GCFBBlockCipher(baseEngine)));
}
*/
// END Android-removed: Unsupported modes
- else if (modeName.startsWith("CTS"))
+ else if (modeName.equals("CTS"))
{
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(new CBCBlockCipher(baseEngine)));
}
- else if (modeName.startsWith("CCM"))
+ else if (modeName.equals("CCM"))
{
ivLength = 12; // CCM nonce 7..13 bytes
// BEGIN Android-removed: Unsupported algorithms
@@ -436,7 +480,7 @@ public class BaseBlockCipher
}
// BEGIN Android-removed: Unsupported modes
/*
- else if (modeName.startsWith("OCB"))
+ else if (modeName.equals("OCB"))
{
if (engineProvider != null)
{
@@ -451,15 +495,14 @@ public class BaseBlockCipher
throw new NoSuchAlgorithmException("can't support mode " + mode);
}
}
- else if (modeName.startsWith("EAX"))
+ else if (modeName.equals("EAX"))
{
ivLength = baseEngine.getBlockSize();
cipher = new AEADGenericBlockCipher(new EAXBlockCipher(baseEngine));
}
*/
// END Android-removed: Unsupported modes
- // Android-changed: Use equals instead of startsWith to not catch GCM-SIV
- else if (modeName.equalsIgnoreCase("GCM"))
+ else if (modeName.equals("GCM"))
{
ivLength = baseEngine.getBlockSize();
// BEGIN Android-removed: Unsupported algorithms
@@ -483,10 +526,15 @@ public class BaseBlockCipher
}
protected void engineSetPadding(
- String padding)
- throws NoSuchPaddingException
+ String padding)
+ throws NoSuchPaddingException
{
- String paddingName = Strings.toUpperCase(padding);
+ if (baseEngine == null)
+ {
+ throw new NoSuchPaddingException("no padding supported for this algorithm");
+ }
+
+ String paddingName = Strings.toUpperCase(padding);
if (paddingName.equals("NOPADDING"))
{
@@ -545,13 +593,13 @@ public class BaseBlockCipher
// END Android-added: Handling missing IVs
protected void engineInit(
- int opmode,
- Key key,
- AlgorithmParameterSpec params,
- SecureRandom random)
+ int opmode,
+ Key key,
+ final AlgorithmParameterSpec params,
+ SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException
{
- CipherParameters param;
+ CipherParameters param;
this.pbeSpec = null;
this.pbeAlgorithm = null;
@@ -569,7 +617,7 @@ public class BaseBlockCipher
//
// for RC5-64 we must have some default parameters
//
- if (params == null && baseEngine.getAlgorithmName().startsWith("RC5-64"))
+ if (params == null && (baseEngine != null && baseEngine.getAlgorithmName().startsWith("RC5-64")))
{
throw new InvalidAlgorithmParameterException("RC5 requires an RC5ParametersSpec to be passed in.");
}
@@ -593,7 +641,7 @@ public class BaseBlockCipher
throw new InvalidKeyException("PKCS12 requires a SecretKey/PBEKey");
}
- if (params instanceof PBEParameterSpec)
+ if (params instanceof PBEParameterSpec)
{
pbeSpec = (PBEParameterSpec)params;
}
@@ -798,10 +846,10 @@ public class BaseBlockCipher
/*
else if (params instanceof GOST28147ParameterSpec)
{
- GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
+ GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
param = new ParametersWithSBox(
- new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSbox());
+ new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSbox());
if (gost28147Param.getIV() != null && ivLength != 0)
{
@@ -818,7 +866,7 @@ public class BaseBlockCipher
}
else if (params instanceof RC2ParameterSpec)
{
- RC2ParameterSpec rc2Param = (RC2ParameterSpec)params;
+ RC2ParameterSpec rc2Param = (RC2ParameterSpec)params;
param = new RC2Parameters(key.getEncoded(), ((RC2ParameterSpec)params).getEffectiveKeyBits());
@@ -837,7 +885,7 @@ public class BaseBlockCipher
}
else if (params instanceof RC5ParameterSpec)
{
- RC5ParameterSpec rc5Param = (RC5ParameterSpec)params;
+ RC5ParameterSpec rc5Param = (RC5ParameterSpec)params;
param = new RC5Parameters(key.getEncoded(), ((RC5ParameterSpec)params).getRounds());
if (baseEngine.getAlgorithmName().startsWith("RC5"))
@@ -883,26 +931,17 @@ public class BaseBlockCipher
throw new InvalidAlgorithmParameterException("GCMParameterSpec can only be used with AEAD modes.");
}
- try
+ final KeyParameter keyParam;
+ if (param instanceof ParametersWithIV)
{
- Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]);
- Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]);
-
- KeyParameter keyParam;
- if (param instanceof ParametersWithIV)
- {
- keyParam = (KeyParameter)((ParametersWithIV)param).getParameters();
- }
- else
- {
- keyParam = (KeyParameter)param;
- }
- param = aeadParams = new AEADParameters(keyParam, ((Integer)tLen.invoke(params, new Object[0])).intValue(), (byte[])iv.invoke(params, new Object[0]));
+ keyParam = (KeyParameter)((ParametersWithIV)param).getParameters();
}
- catch (Exception e)
+ else
{
- throw new InvalidAlgorithmParameterException("Cannot process GCMParameterSpec.");
+ keyParam = (KeyParameter)param;
}
+
+ param = aeadParams = GcmSpecUtil.extractAeadParameters(keyParam, params);
}
else if (params != null && !(params instanceof PBEParameterSpec))
{
@@ -911,7 +950,7 @@ public class BaseBlockCipher
if ((ivLength != 0) && !(param instanceof ParametersWithIV) && !(param instanceof AEADParameters))
{
- SecureRandom ivRandom = random;
+ SecureRandom ivRandom = random;
if (ivRandom == null)
{
@@ -920,7 +959,7 @@ public class BaseBlockCipher
if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE))
{
- byte[] iv = new byte[ivLength];
+ byte[] iv = new byte[ivLength];
// BEGIN Android-changed: For PBE keys with no IV, log and use IV of 0
// These keys were accepted in BC 1.52 (and treated as having an IV of 0) but
@@ -976,7 +1015,6 @@ public class BaseBlockCipher
}
-
if (random != null && padded)
{
param = new ParametersWithRandom(param, random);
@@ -1000,12 +1038,20 @@ public class BaseBlockCipher
if (cipher instanceof AEADGenericBlockCipher && aeadParams == null)
{
- AEADBlockCipher aeadCipher = ((AEADGenericBlockCipher)cipher).cipher;
+ AEADCipher aeadCipher = ((AEADGenericBlockCipher)cipher).cipher;
aeadParams = new AEADParameters((KeyParameter)ivParam.getParameters(), aeadCipher.getMac().length * 8, ivParam.getIV());
}
}
- catch (final Exception e)
+ // BEGIN Android-removed: keeping pre 1.68 behaviour
+ /*
+ catch (IllegalArgumentException e)
+ {
+ throw new InvalidAlgorithmParameterException(e.getMessage(), e);
+ }
+ */
+ // END Android-removed: keeping pre 1.68 behaviour
+ catch (Exception e)
{
throw new InvalidKeyOrParametersException(e.getMessage(), e);
}
@@ -1073,33 +1119,17 @@ public class BaseBlockCipher
}
protected void engineInit(
- int opmode,
- Key key,
+ int opmode,
+ Key key,
AlgorithmParameters params,
- SecureRandom random)
- throws InvalidKeyException, InvalidAlgorithmParameterException
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
{
- AlgorithmParameterSpec paramSpec = null;
+ AlgorithmParameterSpec paramSpec = null;
if (params != null)
{
- for (int i = 0; i != availableSpecs.length; i++)
- {
- if (availableSpecs[i] == null)
- {
- continue;
- }
-
- try
- {
- paramSpec = params.getParameterSpec(availableSpecs[i]);
- break;
- }
- catch (Exception e)
- {
- // try again if possible
- }
- }
+ paramSpec = SpecUtil.extractSpec(params, availableSpecs);
if (paramSpec == null)
{
@@ -1108,14 +1138,14 @@ public class BaseBlockCipher
}
engineInit(opmode, key, paramSpec, random);
-
+
engineParams = params;
}
protected void engineInit(
- int opmode,
- Key key,
- SecureRandom random)
+ int opmode,
+ Key key,
+ SecureRandom random)
throws InvalidKeyException
{
try
@@ -1133,40 +1163,67 @@ public class BaseBlockCipher
cipher.updateAAD(input, offset, length);
}
- protected void engineUpdateAAD(ByteBuffer bytebuffer)
+ protected void engineUpdateAAD(ByteBuffer src)
{
- int offset = bytebuffer.arrayOffset() + bytebuffer.position();
- int length = bytebuffer.limit() - bytebuffer.position();
- engineUpdateAAD(bytebuffer.array(), offset, length);
+ int remaining = src.remaining();
+ if (remaining < 1)
+ {
+ // No data to update
+ }
+ else if (src.hasArray())
+ {
+ engineUpdateAAD(src.array(), src.arrayOffset() + src.position(), remaining);
+ src.position(src.limit());
+ }
+ else if (remaining <= BUF_SIZE)
+ {
+ byte[] data = new byte[remaining];
+ src.get(data);
+ engineUpdateAAD(data, 0, data.length);
+ Arrays.fill(data, (byte)0);
+ }
+ else
+ {
+ byte[] data = new byte[BUF_SIZE];
+ do
+ {
+ int length = Math.min(data.length, remaining);
+ src.get(data, 0, length);
+ engineUpdateAAD(data, 0, length);
+ remaining -= length;
+ }
+ while (remaining > 0);
+ Arrays.fill(data, (byte)0);
+ }
}
protected byte[] engineUpdate(
- byte[] input,
- int inputOffset,
- int inputLen)
+ byte[] input,
+ int inputOffset,
+ int inputLen)
{
- int length = cipher.getUpdateOutputSize(inputLen);
+ int length = cipher.getUpdateOutputSize(inputLen);
if (length > 0)
{
- byte[] out = new byte[length];
+ byte[] out = new byte[length];
- int len = cipher.processBytes(input, inputOffset, inputLen, out, 0);
+ int len = cipher.processBytes(input, inputOffset, inputLen, out, 0);
- if (len == 0)
- {
- return null;
- }
- else if (len != out.length)
- {
- byte[] tmp = new byte[len];
+ if (len == 0)
+ {
+ return null;
+ }
+ else if (len != out.length)
+ {
+ byte[] tmp = new byte[len];
- System.arraycopy(out, 0, tmp, 0, len);
+ System.arraycopy(out, 0, tmp, 0, len);
- return tmp;
- }
+ return tmp;
+ }
- return out;
+ return out;
}
cipher.processBytes(input, inputOffset, inputLen, null, 0);
@@ -1175,11 +1232,11 @@ public class BaseBlockCipher
}
protected int engineUpdate(
- byte[] input,
- int inputOffset,
- int inputLen,
- byte[] output,
- int outputOffset)
+ byte[] input,
+ int inputOffset,
+ int inputLen,
+ byte[] output,
+ int outputOffset)
throws ShortBufferException
{
if (outputOffset + cipher.getUpdateOutputSize(inputLen) > output.length)
@@ -1199,13 +1256,13 @@ public class BaseBlockCipher
}
protected byte[] engineDoFinal(
- byte[] input,
- int inputOffset,
- int inputLen)
+ byte[] input,
+ int inputOffset,
+ int inputLen)
throws IllegalBlockSizeException, BadPaddingException
{
- int len = 0;
- byte[] tmp = new byte[engineGetOutputSize(inputLen)];
+ int len = 0;
+ byte[] tmp = new byte[engineGetOutputSize(inputLen)];
if (inputLen != 0)
{
@@ -1226,7 +1283,12 @@ public class BaseBlockCipher
return tmp;
}
- byte[] out = new byte[len];
+ if (len > tmp.length)
+ {
+ throw new IllegalBlockSizeException("internal buffer overflow");
+ }
+
+ byte[] out = new byte[len];
System.arraycopy(tmp, 0, out, 0, len);
@@ -1234,14 +1296,14 @@ public class BaseBlockCipher
}
protected int engineDoFinal(
- byte[] input,
- int inputOffset,
- int inputLen,
- byte[] output,
- int outputOffset)
+ byte[] input,
+ int inputOffset,
+ int inputLen,
+ byte[] output,
+ int outputOffset)
throws IllegalBlockSizeException, BadPaddingException, ShortBufferException
{
- int len = 0;
+ int len = 0;
if (outputOffset + engineGetOutputSize(inputLen) > output.length)
{
@@ -1363,17 +1425,20 @@ public class BaseBlockCipher
throw new UnsupportedOperationException("AAD is not supported in the current mode.");
}
- public int processByte(byte in, byte[] out, int outOff) throws DataLengthException
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException
{
return cipher.processByte(in, out, outOff);
}
- public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException
{
return cipher.processBytes(in, inOff, len, out, outOff);
}
- public int doFinal(byte[] out, int outOff) throws IllegalStateException, BadPaddingException
+ public int doFinal(byte[] out, int outOff)
+ throws IllegalStateException, BadPaddingException
{
try
{
@@ -1391,7 +1456,8 @@ public class BaseBlockCipher
{
private static final Constructor aeadBadTagConstructor;
- static {
+ static
+ {
Class aeadBadTagClass = ClassUtil.loadClass(BaseBlockCipher.class, "javax.crypto.AEADBadTagException");
if (aeadBadTagClass != null)
{
@@ -1415,9 +1481,9 @@ public class BaseBlockCipher
}
}
- private AEADBlockCipher cipher;
+ private AEADCipher cipher;
- AEADGenericBlockCipher(AEADBlockCipher cipher)
+ AEADGenericBlockCipher(AEADCipher cipher)
{
this.cipher = cipher;
}
@@ -1430,7 +1496,12 @@ public class BaseBlockCipher
public String getAlgorithmName()
{
- return cipher.getUnderlyingCipher().getAlgorithmName();
+ if (cipher instanceof AEADBlockCipher)
+ {
+ return ((AEADBlockCipher)cipher).getUnderlyingCipher().getAlgorithmName();
+ }
+
+ return cipher.getAlgorithmName();
}
public boolean wrapOnNoPadding()
@@ -1440,7 +1511,12 @@ public class BaseBlockCipher
public com.android.org.bouncycastle.crypto.BlockCipher getUnderlyingCipher()
{
- return cipher.getUnderlyingCipher();
+ if (cipher instanceof AEADBlockCipher)
+ {
+ return ((AEADBlockCipher)cipher).getUnderlyingCipher();
+ }
+
+ return null;
}
public int getOutputSize(int len)
@@ -1458,17 +1534,20 @@ public class BaseBlockCipher
cipher.processAADBytes(input, offset, length);
}
- public int processByte(byte in, byte[] out, int outOff) throws DataLengthException
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException
{
return cipher.processByte(in, out, outOff);
}
- public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException
{
return cipher.processBytes(in, inOff, len, out, outOff);
}
- public int doFinal(byte[] out, int outOff) throws IllegalStateException, BadPaddingException
+ public int doFinal(byte[] out, int outOff)
+ throws IllegalStateException, BadPaddingException
{
try
{
@@ -1482,7 +1561,7 @@ public class BaseBlockCipher
try
{
aeadBadTag = (BadPaddingException)aeadBadTagConstructor
- .newInstance(new Object[]{e.getMessage()});
+ .newInstance(new Object[]{e.getMessage()});
}
catch (Exception i)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
index 00fd5285..d7b1c4ed 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
@@ -1,7 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.jcajce.provider.symmetric.util;
-import java.lang.reflect.Method;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
@@ -65,7 +64,7 @@ public class BaseMac
protected void engineInit(
Key key,
- AlgorithmParameterSpec params)
+ final AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException
{
CipherParameters param;
@@ -180,7 +179,7 @@ public class BaseMac
param = new KeyParameter(key.getEncoded());
}
- KeyParameter keyParam;
+ final KeyParameter keyParam;
if (param instanceof ParametersWithIV)
{
keyParam = (KeyParameter)((ParametersWithIV)param).getParameters();
@@ -218,17 +217,7 @@ public class BaseMac
}
else if (gcmSpecClass != null && gcmSpecClass.isAssignableFrom(params.getClass()))
{
- try
- {
- Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]);
- Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]);
-
- param = new AEADParameters(keyParam, ((Integer)tLen.invoke(params, new Object[0])).intValue(), (byte[])iv.invoke(params, new Object[0]));
- }
- catch (Exception e)
- {
- throw new InvalidAlgorithmParameterException("Cannot process GCMParameterSpec.");
- }
+ param = GcmSpecUtil.extractAeadParameters(keyParam, params);
}
else if (!(params instanceof PBEParameterSpec))
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java
index e7e98dc2..5d986aed 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java
@@ -68,6 +68,14 @@ public class BaseStreamCipher
protected BaseStreamCipher(
StreamCipher engine,
int ivLength,
+ int keySizeInBits)
+ {
+ this(engine, ivLength, keySizeInBits, -1);
+ }
+
+ protected BaseStreamCipher(
+ StreamCipher engine,
+ int ivLength,
int keySizeInBits,
int digest)
{
@@ -320,18 +328,7 @@ public class BaseStreamCipher
if (params != null)
{
- for (int i = 0; i != availableSpecs.length; i++)
- {
- try
- {
- paramSpec = params.getParameterSpec(availableSpecs[i]);
- break;
- }
- catch (Exception e)
- {
- continue;
- }
- }
+ paramSpec = SpecUtil.extractSpec(params, availableSpecs);
if (paramSpec == null)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java
index b03b2254..77ec9c2a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java
@@ -290,18 +290,7 @@ public abstract class BaseWrapCipher
if (params != null)
{
- for (int i = 0; i != availableSpecs.length; i++)
- {
- try
- {
- paramSpec = params.getParameterSpec(availableSpecs[i]);
- break;
- }
- catch (Exception e)
- {
- // try next spec
- }
- }
+ paramSpec = SpecUtil.extractSpec(params, availableSpecs);
if (paramSpec == null)
{
@@ -373,7 +362,10 @@ public abstract class BaseWrapCipher
throw new IllegalStateException("not supported in a wrapping mode");
}
- wrapStream.write(input, inputOffset, inputLen);
+ if (input != null)
+ {
+ wrapStream.write(input, inputOffset, inputLen);
+ }
try
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
new file mode 100644
index 00000000..00997557
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
@@ -0,0 +1,136 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import com.android.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.org.bouncycastle.asn1.cms.GCMParameters;
+import com.android.org.bouncycastle.crypto.params.AEADParameters;
+import com.android.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.org.bouncycastle.util.Integers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GcmSpecUtil
+{
+ static final Class gcmSpecClass = ClassUtil.loadClass(GcmSpecUtil.class, "javax.crypto.spec.GCMParameterSpec");
+
+ static final Method tLen;
+ static final Method iv;
+
+ static
+ {
+ if (gcmSpecClass != null)
+ {
+ tLen = extractMethod("getTLen");
+ iv = extractMethod("getIV");
+ }
+ else
+ {
+ tLen = null;
+ iv = null;
+ }
+ }
+
+ private static Method extractMethod(final String name)
+ {
+ try
+ {
+ return (Method)AccessController.doPrivileged(new PrivilegedExceptionAction()
+ {
+ public Object run()
+ throws Exception
+ {
+ return gcmSpecClass.getDeclaredMethod(name, new Class[0]);
+ }
+ });
+ }
+ catch (PrivilegedActionException e)
+ {
+ return null;
+ }
+ }
+
+ public static boolean gcmSpecExists()
+ {
+ return gcmSpecClass != null;
+ }
+
+ public static boolean isGcmSpec(AlgorithmParameterSpec paramSpec)
+ {
+ return gcmSpecClass != null && gcmSpecClass.isInstance(paramSpec);
+ }
+
+ public static boolean isGcmSpec(Class paramSpecClass)
+ {
+ return gcmSpecClass == paramSpecClass;
+ }
+
+ public static AlgorithmParameterSpec extractGcmSpec(ASN1Primitive spec)
+ throws InvalidParameterSpecException
+ {
+ try
+ {
+ GCMParameters gcmParams = GCMParameters.getInstance(spec);
+ Constructor constructor = gcmSpecClass.getConstructor(new Class[]{Integer.TYPE, byte[].class});
+
+ return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(gcmParams.getIcvLen() * 8), gcmParams.getNonce() });
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new InvalidParameterSpecException("No constructor found!"); // should never happen
+ }
+ catch (Exception e)
+ {
+ throw new InvalidParameterSpecException("Construction failed: " + e.getMessage()); // should never happen
+ }
+ }
+
+ static AEADParameters extractAeadParameters(final KeyParameter keyParam, final AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException
+ {
+ try
+ {
+ return (AEADParameters)AccessController.doPrivileged(new PrivilegedExceptionAction()
+ {
+ public Object run()
+ throws Exception
+ {
+ return new AEADParameters(keyParam, ((Integer)tLen.invoke(params, new Object[0])).intValue(), (byte[])iv.invoke(params, new Object[0]));
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ throw new InvalidAlgorithmParameterException("Cannot process GCMParameterSpec.");
+ }
+ }
+
+ public static GCMParameters extractGcmParameters(final AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ try
+ {
+ return (GCMParameters)AccessController.doPrivileged(new PrivilegedExceptionAction()
+ {
+ public Object run()
+ throws Exception
+ {
+ return new GCMParameters((byte[])iv.invoke(paramSpec, new Object[0]), ((Integer)tLen.invoke(paramSpec, new Object[0])).intValue() / 8);
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ throw new InvalidParameterSpecException("Cannot process GCMParameterSpec");
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
index e46a9726..f61f91e9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
@@ -21,6 +21,7 @@ import com.android.org.bouncycastle.crypto.PBEParametersGenerator;
// import org.bouncycastle.crypto.digests.MD2Digest;
// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
// import org.bouncycastle.crypto.digests.TigerDigest;
+// import org.bouncycastle.crypto.digests.SM3Digest;
import com.android.org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator;
import com.android.org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
import com.android.org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
@@ -53,10 +54,12 @@ public interface PBE
static final int SHA224 = 7;
static final int SHA384 = 8;
static final int SHA512 = 9;
- static final int SHA3_224 = 10;
- static final int SHA3_256 = 11;
- static final int SHA3_384 = 12;
- static final int SHA3_512 = 13;
+ // Android-removed: Unsupported algorithms
+ // static final int SHA3_224 = 10;
+ // static final int SHA3_256 = 11;
+ // static final int SHA3_384 = 12;
+ // static final int SHA3_512 = 13;
+ // static final int SM3 = 14;
static final int PKCS5S1 = 0;
static final int PKCS5S2 = 1;
@@ -164,6 +167,9 @@ public interface PBE
case SHA3_512:
generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_512());
break;
+ case SM3:
+ generator = new PKCS5S2ParametersGenerator(new SM3Digest());
+ break;
*/
// END Android-removed: Unsupported algorithms
default:
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/SpecUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/SpecUtil.java
new file mode 100644
index 00000000..25200dc1
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/util/SpecUtil.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.security.AlgorithmParameters;
+import java.security.spec.AlgorithmParameterSpec;
+
+class SpecUtil
+{
+ static AlgorithmParameterSpec extractSpec(AlgorithmParameters params, Class[] availableSpecs)
+ {
+ try
+ {
+ return params.getParameterSpec(AlgorithmParameterSpec.class);
+ }
+ catch (Exception e)
+ {
+ for (int i = 0; i != availableSpecs.length; i++)
+ {
+ if (availableSpecs[i] == null)
+ {
+ continue;
+ }
+
+ try
+ {
+ return params.getParameterSpec(availableSpecs[i]);
+ }
+ catch (Exception ex)
+ {
+ // try again if possible
+ }
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java
new file mode 100644
index 00000000..2073ff1b
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java
@@ -0,0 +1,72 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CompositeAlgorithmSpec
+ implements AlgorithmParameterSpec
+{
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Builder
+ {
+ private List<String> algorithmNames = new ArrayList<String>();
+ private List<AlgorithmParameterSpec> parameterSpecs = new ArrayList<AlgorithmParameterSpec>();
+
+ public Builder()
+ {
+ }
+
+ public Builder add(String algorithmName)
+ {
+ algorithmNames.add(algorithmName);
+ parameterSpecs.add(null);
+
+ return this;
+ }
+
+ public Builder add(String algorithmName, AlgorithmParameterSpec parameterSpec)
+ {
+ algorithmNames.add(algorithmName);
+ parameterSpecs.add(parameterSpec);
+
+ return this;
+ }
+
+ public CompositeAlgorithmSpec build()
+ {
+ if (algorithmNames.isEmpty())
+ {
+ throw new IllegalStateException("cannot call build with no algorithm names added");
+ }
+
+ return new CompositeAlgorithmSpec(this);
+ }
+ }
+
+ private final List<String> algorithmNames;
+ private final List<AlgorithmParameterSpec> parameterSpecs;
+
+ public CompositeAlgorithmSpec(Builder builder)
+ {
+ this.algorithmNames = Collections.unmodifiableList(new ArrayList<String>(builder.algorithmNames));
+ this.parameterSpecs = Collections.unmodifiableList(new ArrayList<AlgorithmParameterSpec>(builder.parameterSpecs));
+ }
+
+ public List<String> getAlgorithmNames()
+ {
+ return algorithmNames;
+ }
+
+ public List<AlgorithmParameterSpec> getParameterSpecs()
+ {
+ return parameterSpecs;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/DHExtendedPrivateKeySpec.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/DHExtendedPrivateKeySpec.java
new file mode 100644
index 00000000..af3fcb64
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/DHExtendedPrivateKeySpec.java
@@ -0,0 +1,39 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.spec;
+
+import java.math.BigInteger;
+
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPrivateKeySpec;
+
+/**
+ * A DHPrivateKeySpec that also carries a set of DH domain parameters.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHExtendedPrivateKeySpec
+ extends DHPrivateKeySpec
+{
+ private final DHParameterSpec params;
+
+ /**
+ * Base constructor.
+ *
+ * @param x the private value.
+ * @param params the domain parameter set.
+ */
+ public DHExtendedPrivateKeySpec(BigInteger x, DHParameterSpec params)
+ {
+ super(x, params.getP(), params.getG());
+ this.params = params;
+ }
+
+ /**
+ * Return the domain parameters associated with this key spec.
+ *
+ * @return the Diffie-Hellman domain parameters.
+ */
+ public DHParameterSpec getParams()
+ {
+ return params;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/DHExtendedPublicKeySpec.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/DHExtendedPublicKeySpec.java
new file mode 100644
index 00000000..a95501e7
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/DHExtendedPublicKeySpec.java
@@ -0,0 +1,39 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.spec;
+
+import java.math.BigInteger;
+
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPublicKeySpec;
+
+/**
+ * A DHPublicKeySpec that also carries a set of DH domain parameters.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHExtendedPublicKeySpec
+ extends DHPublicKeySpec
+{
+ private final DHParameterSpec params;
+
+ /**
+ * Base constructor.
+ *
+ * @param y the public value.
+ * @param params the domain parameter set.
+ */
+ public DHExtendedPublicKeySpec(BigInteger y, DHParameterSpec params)
+ {
+ super(y, params.getP(), params.getG());
+ this.params = params;
+ }
+
+ /**
+ * Return the domain parameters associated with this key spec.
+ *
+ * @return the Diffie-Hellman domain parameters.
+ */
+ public DHParameterSpec getParams()
+ {
+ return params;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/OpenSSHPrivateKeySpec.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/OpenSSHPrivateKeySpec.java
new file mode 100644
index 00000000..9577d93c
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/OpenSSHPrivateKeySpec.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.EncodedKeySpec;
+
+/**
+ * OpenSSHPrivateKeySpec holds and encoded OpenSSH private key.
+ * The format of the key can be either ASN.1 or OpenSSH.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OpenSSHPrivateKeySpec
+ extends EncodedKeySpec
+{
+ private final String format;
+
+ /**
+ * Accept an encoded key and determine the format.
+ * <p>
+ * The encoded key should be the Base64 decoded blob between the "---BEGIN and ---END" markers.
+ * This constructor will endeavour to find the OpenSSH format magic value. If it can not then it
+ * will default to ASN.1. It does not attempt to validate the ASN.1
+ * <p>
+ * Example:
+ * OpenSSHPrivateKeySpec privSpec = new OpenSSHPrivateKeySpec(rawPriv);
+ * <p>
+ * KeyFactory kpf = KeyFactory.getInstance("RSA", "BC");
+ * PrivateKey prk = kpf.generatePrivate(privSpec);
+ * <p>
+ * OpenSSHPrivateKeySpec rcPrivateSpec = kpf.getKeySpec(prk, OpenSSHPrivateKeySpec.class);
+ *
+ * @param encodedKey The encoded key.
+ */
+ public OpenSSHPrivateKeySpec(byte[] encodedKey)
+ {
+ super(encodedKey);
+
+ if (encodedKey[0] == 0x30) // DER SEQUENCE
+ {
+ format = "ASN.1";
+ }
+ else if (encodedKey[0] == 'o')
+ {
+ format = "OpenSSH";
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown byte encoding");
+ }
+ }
+
+ /**
+ * Return the format, either OpenSSH for the OpenSSH propriety format or ASN.1.
+ *
+ * @return the format OpenSSH or ASN.1
+ */
+ public String getFormat()
+ {
+ return format;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/OpenSSHPublicKeySpec.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/OpenSSHPublicKeySpec.java
new file mode 100644
index 00000000..3ae067c3
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/spec/OpenSSHPublicKeySpec.java
@@ -0,0 +1,79 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.EncodedKeySpec;
+
+import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.Strings;
+
+/**
+ * Holds an OpenSSH encoded public key.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OpenSSHPublicKeySpec
+ extends EncodedKeySpec
+{
+ private static final String[] allowedTypes = new String[]{"ssh-rsa", "ssh-ed25519", "ssh-dss"};
+ private final String type;
+
+
+ /**
+ * Construct and instance and determine the OpenSSH public key type.
+ * The current types are ssh-rsa, ssh-ed25519, ssh-dss and ecdsa-*
+ * <p>
+ * It does not validate the key beyond identifying the type.
+ *
+ * @param encodedKey
+ */
+ public OpenSSHPublicKeySpec(byte[] encodedKey)
+ {
+ super(encodedKey);
+
+ //
+ // The type is encoded at the start of the blob.
+ //
+ int pos = 0;
+ int i = (encodedKey[pos++] & 0xFF) << 24;
+ i |= (encodedKey[pos++] & 0xFF) << 16;
+ i |= (encodedKey[pos++] & 0xFF) << 8;
+ i |= (encodedKey[pos++] & 0xFF);
+
+ if ((pos + i) >= encodedKey.length)
+ {
+ throw new IllegalArgumentException("invalid public key blob: type field longer than blob");
+ }
+
+ this.type = Strings.fromByteArray(Arrays.copyOfRange(encodedKey, pos, pos + i));
+
+ if (type.startsWith("ecdsa"))
+ {
+ return; // These have a curve name and digest in them and can't be compared exactly.
+ }
+
+ for (int t = 0; t < allowedTypes.length; t++)
+ {
+ if (allowedTypes[t].equals(this.type))
+ {
+ return;
+ }
+ }
+
+ throw new IllegalArgumentException("unrecognised public key type " + type);
+
+ }
+
+ public String getFormat()
+ {
+ return "OpenSSH";
+ }
+
+ /**
+ * The type of OpenSSH public key.
+ *
+ * @return the type.
+ */
+ public String getType()
+ {
+ return type;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/AnnotatedPrivateKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/AnnotatedPrivateKey.java
new file mode 100644
index 00000000..1dafbcb8
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/AnnotatedPrivateKey.java
@@ -0,0 +1,118 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.util;
+
+import java.security.PrivateKey;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Wrapper for a private key that carries annotations that can be used
+ * for tracking or debugging.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AnnotatedPrivateKey
+ implements PrivateKey
+{
+ public static final String LABEL = "label";
+
+ private final PrivateKey key;
+ private final Map<String, Object> annotations;
+
+ AnnotatedPrivateKey(PrivateKey key, String label)
+ {
+ this.key = key;
+ this.annotations = Collections.singletonMap(LABEL, (Object)label);
+ }
+
+ AnnotatedPrivateKey(PrivateKey key, Map<String, Object> annotations)
+ {
+ this.key = key;
+ this.annotations = annotations;
+ }
+
+ public PrivateKey getKey()
+ {
+ return key;
+ }
+
+ public Map<String, Object> getAnnotations()
+ {
+ return annotations;
+ }
+
+ public String getAlgorithm()
+ {
+ return key.getAlgorithm();
+ }
+
+ public Object getAnnotation(String key)
+ {
+ return annotations.get(key);
+ }
+
+ /**
+ * Return a new annotated key with an additional annotation added to it.
+ *
+ * @param name the name of the annotation to add.
+ * @param annotation the object providing the annotation details.
+ * @return a new annotated key with the extra annotation.
+ */
+ public AnnotatedPrivateKey addAnnotation(String name, Object annotation)
+ {
+ Map<String, Object> newAnnotations = new HashMap<String, Object>(annotations);
+
+ newAnnotations.put(name, annotation);
+
+ return new AnnotatedPrivateKey(this.key, Collections.unmodifiableMap(newAnnotations));
+ }
+
+ /**
+ * Return a new annotated key with the named annotation removed.
+ *
+ * @param name the name of the annotation to remove.
+ * @return a new annotated key with the named annotation removed.
+ */
+ public AnnotatedPrivateKey removeAnnotation(String name)
+ {
+ Map<String, Object> newAnnotations = new HashMap<String, Object>(annotations);
+
+ newAnnotations.remove(name);
+
+ return new AnnotatedPrivateKey(this.key, Collections.unmodifiableMap(newAnnotations));
+ }
+
+ public String getFormat()
+ {
+ return key.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ return key.getEncoded();
+ }
+
+ public int hashCode()
+ {
+ return this.key.hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o instanceof AnnotatedPrivateKey)
+ {
+ return this.key.equals(((AnnotatedPrivateKey)o).key);
+ }
+ return this.key.equals(o);
+ }
+
+ public String toString()
+ {
+ if (annotations.containsKey(LABEL))
+ {
+ return annotations.get(LABEL).toString();
+ }
+
+ return key.toString();
+ }
+}
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 f102521d..65523d84 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
@@ -17,9 +17,12 @@ public class BCJcaJceHelper
private static synchronized Provider getBouncyCastleProvider()
{
- if (Security.getProvider("BC") != null)
+ final Provider system = Security.getProvider("BC");
+ // Avoid using the old, deprecated system BC provider on Android.
+ // See: https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html
+ if (system instanceof BouncyCastleProvider)
{
- return Security.getProvider("BC");
+ return system;
}
else if (bcProvider != null)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java
index 3e289996..c72ff005 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java
@@ -3,16 +3,24 @@ package com.android.org.bouncycastle.jcajce.util;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Signature;
+import java.security.cert.CertPathBuilder;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreParameters;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.crypto.Cipher;
+import javax.crypto.ExemptionMechanism;
import javax.crypto.KeyAgreement;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
@@ -24,11 +32,9 @@ import javax.crypto.SecretKeyFactory;
* without specifying a provider).
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class DefaultJcaJceHelper
implements JcaJceHelper
{
- @libcore.api.CorePlatformApi
public Cipher createCipher(
String algorithm)
throws NoSuchAlgorithmException, NoSuchPaddingException
@@ -84,12 +90,19 @@ public class DefaultJcaJceHelper
return KeyPairGenerator.getInstance(algorithm);
}
+ /** @deprecated Use createMessageDigest instead */
public MessageDigest createDigest(String algorithm)
throws NoSuchAlgorithmException
{
return MessageDigest.getInstance(algorithm);
}
+ public MessageDigest createMessageDigest(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return MessageDigest.getInstance(algorithm);
+ }
+
public Signature createSignature(String algorithm)
throws NoSuchAlgorithmException
{
@@ -107,4 +120,34 @@ public class DefaultJcaJceHelper
{
return SecureRandom.getInstance(algorithm);
}
+
+ public CertPathBuilder createCertPathBuilder(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return CertPathBuilder.getInstance(algorithm);
+ }
+
+ public CertPathValidator createCertPathValidator(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return CertPathValidator.getInstance(algorithm);
+ }
+
+ public CertStore createCertStore(String type, CertStoreParameters params)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException
+ {
+ return CertStore.getInstance(type, params);
+ }
+
+ public ExemptionMechanism createExemptionMechanism(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return ExemptionMechanism.getInstance(algorithm);
+ }
+
+ public KeyStore createKeyStore(String type)
+ throws KeyStoreException
+ {
+ return KeyStore.getInstance(type);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/ECKeyUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/ECKeyUtil.java
new file mode 100644
index 00000000..a0831b6d
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/ECKeyUtil.java
@@ -0,0 +1,108 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.util;
+
+import java.io.IOException;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+
+import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.org.bouncycastle.asn1.x9.ECNamedCurveTable;
+import com.android.org.bouncycastle.asn1.x9.X962Parameters;
+import com.android.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.org.bouncycastle.asn1.x9.X9ECPoint;
+import com.android.org.bouncycastle.crypto.ec.CustomNamedCurves;
+
+/**
+ * Utility class for EC Keys.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECKeyUtil
+{
+ /**
+ * Convert an ECPublicKey into an ECPublicKey which always encodes
+ * with point compression.
+ *
+ * @param ecPublicKey the originating public key.
+ * @return a wrapped version of ecPublicKey which uses point compression.
+ */
+ public static ECPublicKey createKeyWithCompression(ECPublicKey ecPublicKey)
+ {
+ return new ECPublicKeyWithCompression(ecPublicKey);
+ }
+
+ private static class ECPublicKeyWithCompression
+ implements ECPublicKey
+ {
+ private final ECPublicKey ecPublicKey;
+
+ public ECPublicKeyWithCompression(ECPublicKey ecPublicKey)
+ {
+ this.ecPublicKey = ecPublicKey;
+ }
+
+ public ECPoint getW()
+ {
+ return ecPublicKey.getW();
+ }
+
+ public String getAlgorithm()
+ {
+ return ecPublicKey.getAlgorithm();
+ }
+
+ public String getFormat()
+ {
+ return ecPublicKey.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(ecPublicKey.getEncoded());
+
+ X962Parameters params = X962Parameters.getInstance(publicKeyInfo.getAlgorithm().getParameters());
+
+ com.android.org.bouncycastle.math.ec.ECCurve curve;
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
+
+ X9ECParameters x9 = CustomNamedCurves.getByOID(oid);
+ if (x9 == null)
+ {
+ x9 = ECNamedCurveTable.getByOID(oid);
+ }
+ curve = x9.getCurve();
+ }
+ else if (params.isImplicitlyCA())
+ {
+ throw new IllegalStateException("unable to identify implictlyCA");
+ }
+ else
+ {
+ X9ECParameters x9 = X9ECParameters.getInstance(params.getParameters());
+ curve = x9.getCurve();
+ }
+
+ com.android.org.bouncycastle.math.ec.ECPoint p = curve.decodePoint(publicKeyInfo.getPublicKeyData().getOctets());
+ ASN1OctetString pEnc = ASN1OctetString.getInstance(new X9ECPoint(p,true).toASN1Primitive());
+
+ try
+ {
+ return new SubjectPublicKeyInfo(publicKeyInfo.getAlgorithm(), pEnc.getOctets()).getEncoded();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to encode EC public key: " + e.getMessage());
+ }
+ }
+
+ public ECParameterSpec getParams()
+ {
+ return ecPublicKey.getParams();
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/JcaJceHelper.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/JcaJceHelper.java
index 4a2e9af2..003c13e1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/JcaJceHelper.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/JcaJceHelper.java
@@ -3,17 +3,25 @@ package com.android.org.bouncycastle.jcajce.util;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Signature;
+import java.security.cert.CertPathBuilder;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreParameters;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.crypto.Cipher;
+import javax.crypto.ExemptionMechanism;
import javax.crypto.KeyAgreement;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
@@ -54,9 +62,13 @@ public interface JcaJceHelper
KeyPairGenerator createKeyPairGenerator(String algorithm)
throws NoSuchAlgorithmException, NoSuchProviderException;
+ /** @deprecated Use createMessageDigest instead */
MessageDigest createDigest(String algorithm)
throws NoSuchAlgorithmException, NoSuchProviderException;
+ MessageDigest createMessageDigest(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
Signature createSignature(String algorithm)
throws NoSuchAlgorithmException, NoSuchProviderException;
@@ -65,4 +77,19 @@ public interface JcaJceHelper
SecureRandom createSecureRandom(String algorithm)
throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ CertPathBuilder createCertPathBuilder(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ CertPathValidator createCertPathValidator(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ CertStore createCertStore(String type, CertStoreParameters params)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchProviderException;
+
+ ExemptionMechanism createExemptionMechanism(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ KeyStore createKeyStore(String type)
+ throws KeyStoreException, NoSuchProviderException;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java
index cb604800..e9166770 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java
@@ -3,17 +3,25 @@ package com.android.org.bouncycastle.jcajce.util;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Signature;
+import java.security.cert.CertPathBuilder;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreParameters;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.crypto.Cipher;
+import javax.crypto.ExemptionMechanism;
import javax.crypto.KeyAgreement;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
@@ -89,12 +97,19 @@ public class NamedJcaJceHelper
return KeyPairGenerator.getInstance(algorithm, providerName);
}
+ /** @deprecated Use createMessageDigest instead */
public MessageDigest createDigest(String algorithm)
throws NoSuchAlgorithmException, NoSuchProviderException
{
return MessageDigest.getInstance(algorithm, providerName);
}
+ public MessageDigest createMessageDigest(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return MessageDigest.getInstance(algorithm, providerName);
+ }
+
public Signature createSignature(String algorithm)
throws NoSuchAlgorithmException, NoSuchProviderException
{
@@ -112,4 +127,34 @@ public class NamedJcaJceHelper
{
return SecureRandom.getInstance(algorithm, providerName);
}
+
+ public CertPathBuilder createCertPathBuilder(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return CertPathBuilder.getInstance(algorithm, providerName);
+ }
+
+ public CertPathValidator createCertPathValidator(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return CertPathValidator.getInstance(algorithm, providerName);
+ }
+
+ public CertStore createCertStore(String type, CertStoreParameters params)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchProviderException
+ {
+ return CertStore.getInstance(type, params, providerName);
+ }
+
+ public ExemptionMechanism createExemptionMechanism(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return ExemptionMechanism.getInstance(algorithm, providerName);
+ }
+
+ public KeyStore createKeyStore(String type)
+ throws KeyStoreException, NoSuchProviderException
+ {
+ return KeyStore.getInstance(type, providerName);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/PrivateKeyAnnotator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/PrivateKeyAnnotator.java
new file mode 100644
index 00000000..312ff254
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/PrivateKeyAnnotator.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jcajce.util;
+
+import java.security.PrivateKey;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Class for instancing AnnotatedPrivateKeys.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PrivateKeyAnnotator
+{
+ /**
+ * Create an AnnotatedPrivateKey with a single annotation using AnnotatedPrivateKey.LABEL as a key.
+ *
+ * @param privKey the private key to be annotated.
+ * @param label the label to be associated with the private key.
+ * @return the newly annotated private key.
+ */
+ public static AnnotatedPrivateKey annotate(PrivateKey privKey, String label)
+ {
+ return new AnnotatedPrivateKey(privKey, label);
+ }
+
+ public static AnnotatedPrivateKey annotate(PrivateKey privKey, Map<String, Object> annotations)
+ {
+ Map savedAnnotations = new HashMap(annotations);
+
+ return new AnnotatedPrivateKey(privKey, Collections.unmodifiableMap(savedAnnotations));
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java
index 2e545938..e347f10d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java
@@ -3,17 +3,25 @@ package com.android.org.bouncycastle.jcajce.util;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Signature;
+import java.security.cert.CertPathBuilder;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreParameters;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.crypto.Cipher;
+import javax.crypto.ExemptionMechanism;
import javax.crypto.KeyAgreement;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
@@ -89,12 +97,19 @@ public class ProviderJcaJceHelper
return KeyPairGenerator.getInstance(algorithm, provider);
}
+ /** @deprecated Use createMessageDigest instead */
public MessageDigest createDigest(String algorithm)
throws NoSuchAlgorithmException
{
return MessageDigest.getInstance(algorithm, provider);
}
+ public MessageDigest createMessageDigest(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return MessageDigest.getInstance(algorithm, provider);
+ }
+
public Signature createSignature(String algorithm)
throws NoSuchAlgorithmException
{
@@ -112,4 +127,34 @@ public class ProviderJcaJceHelper
{
return SecureRandom.getInstance(algorithm, provider);
}
+
+ public CertPathBuilder createCertPathBuilder(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return CertPathBuilder.getInstance(algorithm, provider);
+ }
+
+ public CertPathValidator createCertPathValidator(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return CertPathValidator.getInstance(algorithm, provider);
+ }
+
+ public CertStore createCertStore(String type, CertStoreParameters params)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException
+ {
+ return CertStore.getInstance(type, params, provider);
+ }
+
+ public ExemptionMechanism createExemptionMechanism(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return ExemptionMechanism.getInstance(algorithm, provider);
+ }
+
+ public KeyStore createKeyStore(String type)
+ throws KeyStoreException
+ {
+ return KeyStore.getInstance(type, provider);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/PKCS10CertificationRequest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/PKCS10CertificationRequest.java
index e0adfc55..f03665db 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/PKCS10CertificationRequest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/PKCS10CertificationRequest.java
@@ -180,6 +180,7 @@ public class PKCS10CertificationRequest
noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384);
noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512);
noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1);
+ noParams.add(OIWObjectIdentifiers.dsaWithSHA1);
noParams.add(NISTObjectIdentifiers.dsa_with_sha224);
noParams.add(NISTObjectIdentifiers.dsa_with_sha256);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/X509Principal.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/X509Principal.java
index e6c7b04e..8e136294 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/X509Principal.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/X509Principal.java
@@ -23,7 +23,6 @@ import com.android.org.bouncycastle.asn1.x509.X509Name;
* @deprecated use the X500Name class.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class X509Principal
extends X509Name
implements Principal
@@ -46,7 +45,6 @@ public class X509Principal
* Constructor from an encoded byte array.
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public X509Principal(
byte[] bytes)
throws IOException
@@ -89,7 +87,6 @@ public class X509Principal
* <p>
* it's is assumed the table contains OID/String pairs.
*/
- @libcore.api.CorePlatformApi
public X509Principal(
Vector ordering,
Hashtable attributes)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java
index 35d79dc2..545d42f0 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java
@@ -14,6 +14,11 @@ public class ExtCertPathValidatorException
private Throwable cause;
+ public ExtCertPathValidatorException(String message)
+ {
+ super(message);
+ }
+
public ExtCertPathValidatorException(String message, Throwable cause)
{
super(message);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/netscape/NetscapeCertRequest.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
index 4f943340..f6bcc662 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
@@ -117,7 +117,7 @@ public class NetscapeCertRequest
pubkeyinfo).getBytes());
keyAlg = pubkeyinfo.getAlgorithm();
- pubkey = KeyFactory.getInstance(keyAlg.getAlgorithm().getId(), "BC")
+ pubkey = KeyFactory.getInstance(keyAlg.getAlgorithm().getId())
.generatePublic(xspec);
}
@@ -205,8 +205,7 @@ public class NetscapeCertRequest
// Verify the signature .. shows the response was generated
// by someone who knew the associated private key
//
- Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId(),
- "BC");
+ Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId());
sig.initVerify(pubkey);
sig.update(content.getBytes());
@@ -225,8 +224,7 @@ public class NetscapeCertRequest
SignatureException, NoSuchProviderException,
InvalidKeySpecException
{
- Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId(),
- "BC");
+ Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId());
if (rand != null)
{
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 c5b996aa..61383ce7 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
@@ -3,15 +3,20 @@ package com.android.org.bouncycastle.jce.provider;
import java.io.IOException;
import java.security.AccessController;
+import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.security.PublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+// import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers;
+// import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
@@ -29,6 +34,7 @@ import com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConver
// import org.bouncycastle.pqc.jcajce.provider.sphincs.Sphincs256KeyFactorySpi;
// import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSKeyFactorySpi;
// import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSMTKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.lms.LMSKeyFactorySpi;
/**
* To add the provider at runtime use:
@@ -55,11 +61,10 @@ import com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConver
* test for getInstance works.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public final class BouncyCastleProvider extends Provider
implements ConfigurableProvider
{
- private static String info = "BouncyCastle Security Provider v1.61";
+ private static String info = "BouncyCastle Security Provider v1.68";
public static final String PROVIDER_NAME = "BC";
@@ -67,6 +72,8 @@ public final class BouncyCastleProvider extends Provider
private static final Map keyInfoConverters = new HashMap();
+ private static final Class revChkClass = ClassUtil.loadClass(BouncyCastleProvider.class, "java.security.cert.PKIXRevocationChecker");
+
/*
* Configurable symmetric ciphers
*/
@@ -105,7 +112,7 @@ public final class BouncyCastleProvider extends Provider
private static final String[] ASYMMETRIC_GENERIC =
{
// Android-changed: Unsupported algorithms
- // "X509", "IES"
+ // "X509", "IES", "COMPOSITE"
"X509"
};
@@ -124,7 +131,8 @@ public final class BouncyCastleProvider extends Provider
{
// Android-changed: Unsupported algorithms
// "GOST3411", "Keccak", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224",
- // "SHA256", "SHA384", "SHA512", "SHA3", "Skein", "SM3", "Tiger", "Whirlpool", "Blake2b", "Blake2s", "DSTU7564"
+ // "SHA256", "SHA384", "SHA512", "SHA3", "Skein", "SM3", "Tiger", "Whirlpool", "Blake2b", "Blake2s", "DSTU7564",
+ // "Haraka"
"MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512",
};
@@ -153,10 +161,9 @@ public final class BouncyCastleProvider extends Provider
* <code>Security.addProvider()</code> mechanism.
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public BouncyCastleProvider()
{
- super(PROVIDER_NAME, 1.61, info);
+ super(PROVIDER_NAME, 1.68, info);
AccessController.doPrivileged(new PrivilegedAction()
{
@@ -189,6 +196,7 @@ public final class BouncyCastleProvider extends Provider
loadAlgorithms(SECURE_RANDOM_PACKAGE, SECURE_RANDOMS);
loadPQCKeys(); // so we can handle certificates containing them.
+
//
// X509Store
//
@@ -201,7 +209,7 @@ public final class BouncyCastleProvider extends Provider
put("X509Store.CRL/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCRLs");
put("X509Store.ATTRIBUTECERTIFICATE/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPAttrCerts");
put("X509Store.CERTIFICATEPAIR/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCertPairs");
-
+
//
// X509StreamParser
//
@@ -225,8 +233,27 @@ public final class BouncyCastleProvider extends Provider
put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
+
+ if (revChkClass != null)
+ {
+ put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
+ put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi_8");
+ put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi_8");
+ put("CertPathValidator.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi_8");
+ put("CertPathBuilder.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi_8");
+ }
+ else
+ {
+ put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi");
+ put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
+ put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
+ put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
+ put("CertPathValidator.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
+ put("CertPathBuilder.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
+ }
*/
// END Android-removed: Unsupported algorithms
+
put("CertPathValidator.PKIX", "com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
put("CertPathBuilder.PKIX", "com.android.org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
put("CertStore.Collection", "com.android.org.bouncycastle.jce.provider.CertStoreCollectionSpi");
@@ -265,15 +292,15 @@ public final class BouncyCastleProvider extends Provider
addKeyInfoConverter(PQCObjectIdentifiers.sphincs256, new Sphincs256KeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.newHope, new NHKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.xmss, new XMSSKeyFactorySpi());
+ addKeyInfoConverter(IsaraObjectIdentifiers.id_alg_xmss, new XMSSKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.xmss_mt, new XMSSMTKeyFactorySpi());
+ addKeyInfoConverter(IsaraObjectIdentifiers.id_alg_xmssmt, new XMSSMTKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.mcEliece, new McElieceKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.mcElieceCca2, new McElieceCCA2KeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.rainbow, new RainbowKeyFactorySpi());
- addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_I, new QTESLAKeyFactorySpi());
- addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_III_size, new QTESLAKeyFactorySpi());
- addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_III_speed, new QTESLAKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_I, new QTESLAKeyFactorySpi());
addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_III, new QTESLAKeyFactorySpi());
+ addKeyInfoConverter(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, new LMSKeyFactorySpi());
}
*/
// END Android-removed: Unsupported algorithms
@@ -315,6 +342,11 @@ public final class BouncyCastleProvider extends Provider
}
}
+ public AsymmetricKeyInfoConverter getKeyInfoConverter(ASN1ObjectIdentifier oid)
+ {
+ return (AsymmetricKeyInfoConverter)keyInfoConverters.get(oid);
+ }
+
public void addAttributes(String key, Map<String, String> attributeMap)
{
for (Iterator it = attributeMap.keySet().iterator(); it.hasNext();)
@@ -341,6 +373,22 @@ public final class BouncyCastleProvider extends Provider
public static PublicKey getPublicKey(SubjectPublicKeyInfo publicKeyInfo)
throws IOException
{
+ // Android-added: BC KeyFactories have been removed, so load them the standard way
+ try {
+ return KeyFactory
+ .getInstance(
+ publicKeyInfo.getAlgorithmId().getAlgorithm().getId())
+ .generatePublic(
+ new X509EncodedKeySpec(publicKeyInfo.getEncoded()));
+ } catch (java.security.NoSuchAlgorithmException ex) {
+ // Maintaining compatibility with upstream logic: if appropriate algorithm not found
+ // ("converter" in Android-removed section) return null instead of throwing.
+ return null;
+ } catch (java.security.spec.InvalidKeySpecException ex) {
+ throw new IOException(ex);
+ }
+ // Android-removed: see above
+ /*
AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(publicKeyInfo.getAlgorithm().getAlgorithm());
if (converter == null)
@@ -349,11 +397,28 @@ public final class BouncyCastleProvider extends Provider
}
return converter.generatePublic(publicKeyInfo);
+ */
}
public static PrivateKey getPrivateKey(PrivateKeyInfo privateKeyInfo)
throws IOException
{
+ // Android-added: BC KeyFactories have been removed, so load them the standard way
+ try {
+ return KeyFactory
+ .getInstance(
+ privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm().getId())
+ .generatePrivate(
+ new PKCS8EncodedKeySpec(privateKeyInfo.getEncoded()));
+ } catch (java.security.NoSuchAlgorithmException ex) {
+ // Maintaining compatibility with upstream logic: if appropriate algorithm not found
+ // ("converter" in Android-removed section) return null instead of throwing.
+ return null;
+ } catch (java.security.spec.InvalidKeySpecException ex) {
+ throw new IOException(ex);
+ }
+ // Android-removed: see above
+ /*
AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm());
if (converter == null)
@@ -362,5 +427,6 @@ public final class BouncyCastleProvider extends Provider
}
return converter.generatePrivate(privateKeyInfo);
+ */
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java
index 640cc47a..c313d731 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java
@@ -64,7 +64,7 @@ class BouncyCastleProviderConfiguration
}
else // assume java.security.spec
{
- curveSpec = EC5Util.convertSpec((java.security.spec.ECParameterSpec)parameter, false);
+ curveSpec = EC5Util.convertSpec((java.security.spec.ECParameterSpec)parameter);
}
if (curveSpec == null)
@@ -89,7 +89,7 @@ class BouncyCastleProviderConfiguration
}
else // assume java.security.spec
{
- ecImplicitCaParams = EC5Util.convertSpec((java.security.spec.ECParameterSpec)parameter, false);
+ ecImplicitCaParams = EC5Util.convertSpec((java.security.spec.ECParameterSpec)parameter);
}
}
else if (parameterName.equals(ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS))
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertBlacklist.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertBlocklist.java
index 3a3d53ed..a7689e08 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertBlacklist.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertBlocklist.java
@@ -37,27 +37,28 @@ import com.android.org.bouncycastle.util.encoders.Hex;
/**
* @hide This class is not part of the Android public SDK API
*/
-public class CertBlacklist {
- private static final Logger logger = Logger.getLogger(CertBlacklist.class.getName());
+public class CertBlocklist {
+ private static final Logger logger = Logger.getLogger(CertBlocklist.class.getName());
// public for testing
- public final Set<BigInteger> serialBlacklist;
- public final Set<byte[]> pubkeyBlacklist;
+ public final Set<BigInteger> serialBlocklist;
+ public final Set<byte[]> pubkeyBlocklist;
- public CertBlacklist() {
+ public CertBlocklist() {
String androidData = System.getenv("ANDROID_DATA");
- String blacklistRoot = androidData + "/misc/keychain/";
- String defaultPubkeyBlacklistPath = blacklistRoot + "pubkey_blacklist.txt";
- String defaultSerialBlacklistPath = blacklistRoot + "serial_blacklist.txt";
+ String blocklistRoot = androidData + "/misc/keychain/";
+ // TODO(b/162575432): change these paths to use inclusive language
+ String defaultPubkeyBlocklistPath = blocklistRoot + "pubkey_blacklist.txt";
+ String defaultSerialBlocklistPath = blocklistRoot + "serial_blacklist.txt";
- pubkeyBlacklist = readPublicKeyBlackList(defaultPubkeyBlacklistPath);
- serialBlacklist = readSerialBlackList(defaultSerialBlacklistPath);
+ pubkeyBlocklist = readPublicKeyBlockList(defaultPubkeyBlocklistPath);
+ serialBlocklist = readSerialBlockList(defaultSerialBlocklistPath);
}
/** Test only interface, not for public use */
- public CertBlacklist(String pubkeyBlacklistPath, String serialBlacklistPath) {
- pubkeyBlacklist = readPublicKeyBlackList(pubkeyBlacklistPath);
- serialBlacklist = readSerialBlackList(serialBlacklistPath);
+ public CertBlocklist(String pubkeyBlocklistPath, String serialBlocklistPath) {
+ pubkeyBlocklist = readPublicKeyBlockList(pubkeyBlocklistPath);
+ serialBlocklist = readSerialBlockList(serialBlocklistPath);
}
private static boolean isHex(String value) {
@@ -78,12 +79,12 @@ public class CertBlacklist {
return isHex(value);
}
- private static String readBlacklist(String path) {
+ private static String readBlocklist(String path) {
try {
return readFileAsString(path);
} catch (FileNotFoundException ignored) {
} catch (IOException e) {
- logger.log(Level.WARNING, "Could not read blacklist", e);
+ logger.log(Level.WARNING, "Could not read blocklist", e);
}
return "";
}
@@ -124,7 +125,7 @@ public class CertBlacklist {
}
}
- private static final Set<BigInteger> readSerialBlackList(String path) {
+ private static Set<BigInteger> readSerialBlockList(String path) {
/* Start out with a base set of known bad values.
*
@@ -151,13 +152,13 @@ public class CertBlacklist {
));
// attempt to augment it with values taken from gservices
- String serialBlacklist = readBlacklist(path);
- if (!serialBlacklist.equals("")) {
- for(String value : serialBlacklist.split(",")) {
+ String serialBlocklist = readBlocklist(path);
+ if (!serialBlocklist.equals("")) {
+ for(String value : serialBlocklist.split(",")) {
try {
bl.add(new BigInteger(value, 16));
} catch (NumberFormatException e) {
- logger.log(Level.WARNING, "Tried to blacklist invalid serial number " + value, e);
+ logger.log(Level.WARNING, "Tried to blocklist invalid serial number " + value, e);
}
}
}
@@ -166,7 +167,7 @@ public class CertBlacklist {
return Collections.unmodifiableSet(bl);
}
- private static final Set<byte[]> readPublicKeyBlackList(String path) {
+ private static Set<byte[]> readPublicKeyBlockList(String path) {
// start out with a base set of known bad values
Set<byte[]> bl = new HashSet<byte[]>(Arrays.asList(
@@ -201,14 +202,14 @@ public class CertBlacklist {
));
// attempt to augment it with values taken from gservices
- String pubkeyBlacklist = readBlacklist(path);
- if (!pubkeyBlacklist.equals("")) {
- for (String value : pubkeyBlacklist.split(",")) {
+ String pubkeyBlocklist = readBlocklist(path);
+ if (!pubkeyBlocklist.equals("")) {
+ for (String value : pubkeyBlocklist.split(",")) {
value = value.trim();
if (isPubkeyHash(value)) {
bl.add(value.getBytes());
} else {
- logger.log(Level.WARNING, "Tried to blacklist invalid pubkey " + value);
+ logger.log(Level.WARNING, "Tried to blocklist invalid pubkey " + value);
}
}
}
@@ -216,22 +217,22 @@ public class CertBlacklist {
return bl;
}
- public boolean isPublicKeyBlackListed(PublicKey publicKey) {
+ public boolean isPublicKeyBlockListed(PublicKey publicKey) {
byte[] encoded = publicKey.getEncoded();
Digest digest = AndroidDigestFactory.getSHA1();
digest.update(encoded, 0, encoded.length);
byte[] out = new byte[digest.getDigestSize()];
digest.doFinal(out, 0);
- for (byte[] blacklisted : pubkeyBlacklist) {
- if (Arrays.equals(blacklisted, Hex.encode(out))) {
+ for (byte[] blocklisted : pubkeyBlocklist) {
+ if (Arrays.equals(blocklisted, Hex.encode(out))) {
return true;
}
}
return false;
}
- public boolean isSerialNumberBlackListed(BigInteger serial) {
- return serialBlacklist.contains(serial);
+ public boolean isSerialNumberBlockListed(BigInteger serial) {
+ return serialBlocklist.contains(serial);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
index 24826611..80bf4e92 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
@@ -4,15 +4,18 @@ package com.android.org.bouncycastle.jce.provider;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
+import java.net.URI;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.cert.CRLException;
import java.security.cert.CertPath;
+import java.security.cert.CertPathBuilderException;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertStore;
import java.security.cert.CertStoreException;
import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
import java.security.cert.CertificateParsingException;
import java.security.cert.PolicyQualifierInfo;
import java.security.cert.TrustAnchor;
@@ -49,6 +52,7 @@ import com.android.org.bouncycastle.asn1.ASN1OctetString;
import com.android.org.bouncycastle.asn1.ASN1OutputStream;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.ASN1String;
import com.android.org.bouncycastle.asn1.DEROctetString;
import com.android.org.bouncycastle.asn1.DERSequence;
import com.android.org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers;
@@ -67,11 +71,15 @@ import com.android.org.bouncycastle.asn1.x509.PolicyInformation;
import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import com.android.org.bouncycastle.jcajce.PKIXCRLStore;
import com.android.org.bouncycastle.jcajce.PKIXCRLStoreSelector;
+import com.android.org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
import com.android.org.bouncycastle.jcajce.PKIXCertStore;
import com.android.org.bouncycastle.jcajce.PKIXCertStoreSelector;
+import com.android.org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
import com.android.org.bouncycastle.jcajce.PKIXExtendedParameters;
import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.org.bouncycastle.jce.exception.ExtCertPathBuilderException;
import com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException;
+import com.android.org.bouncycastle.util.Properties;
import com.android.org.bouncycastle.util.Selector;
import com.android.org.bouncycastle.util.Store;
import com.android.org.bouncycastle.util.StoreException;
@@ -80,8 +88,6 @@ import com.android.org.bouncycastle.x509.extension.X509ExtensionUtil;
class CertPathValidatorUtilities
{
- protected static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil();
-
protected static final String CERTIFICATE_POLICIES = Extension.certificatePolicies.getId();
protected static final String BASIC_CONSTRAINTS = Extension.basicConstraints.getId();
protected static final String POLICY_MAPPINGS = Extension.policyMappings.getId();
@@ -119,6 +125,36 @@ class CertPathValidatorUtilities
"privilegeWithdrawn",
"aACompromise"};
+ static Collection findTargets(PKIXExtendedBuilderParameters paramsPKIX) throws CertPathBuilderException
+ {
+ PKIXExtendedParameters baseParams = paramsPKIX.getBaseParameters();
+ PKIXCertStoreSelector certSelect = baseParams.getTargetConstraints();
+ LinkedHashSet targets = new LinkedHashSet();
+
+ try
+ {
+ CertPathValidatorUtilities.findCertificates(targets, certSelect, baseParams.getCertificateStores());
+ CertPathValidatorUtilities.findCertificates(targets, certSelect, baseParams.getCertStores());
+ }
+ catch (AnnotatedException e)
+ {
+ throw new ExtCertPathBuilderException("Error finding target certificate.", e);
+ }
+
+ if (!targets.isEmpty())
+ {
+ return targets;
+ }
+
+ Certificate target = certSelect.getCertificate();
+ if (null == target)
+ {
+ throw new CertPathBuilderException("No certificate found matching targetConstraints.");
+ }
+
+ return Collections.singleton(target);
+ }
+
/**
* Search the given Set of TrustAnchor's for one that is the
* issuer of the given X509 certificate. Uses the default provider
@@ -164,16 +200,11 @@ class CertPathValidatorUtilities
Exception invalidKeyEx = null;
X509CertSelector certSelectX509 = new X509CertSelector();
- X500Name certIssuer = PrincipalUtils.getEncodedIssuerPrincipal(cert);
- try
- {
- certSelectX509.setSubject(certIssuer.getEncoded());
- }
- catch (IOException ex)
- {
- throw new AnnotatedException("Cannot set subject search criteria for trust anchor.", ex);
- }
+ final X500Principal certIssuerPrincipal = cert.getIssuerX500Principal();
+ certSelectX509.setSubject(certIssuerPrincipal);
+
+ X500Name certIssuerName = null;
Iterator iter = trustAnchors.iterator();
while (iter.hasNext() && trust == null)
@@ -190,13 +221,20 @@ class CertPathValidatorUtilities
trust = null;
}
}
- else if (trust.getCAName() != null
+ else if (trust.getCA() != null
+ && trust.getCAName() != null
&& trust.getCAPublicKey() != null)
{
+ if (certIssuerName == null)
+ {
+ certIssuerName = X500Name.getInstance(certIssuerPrincipal.getEncoded());
+ }
+
try
{
- X500Name caName = PrincipalUtils.getCA(trust);
- if (certIssuer.equals(caName))
+ X500Name caName = X500Name.getInstance(trust.getCA().getEncoded());
+
+ if (certIssuerName.equals(caName))
{
trustPublicKey = trust.getCAPublicKey();
}
@@ -261,43 +299,35 @@ class CertPathValidatorUtilities
{
// if in the IssuerAltName extension an URI
// is given, add an additional X.509 store
- if (issuerAlternativeName != null)
+ if (issuerAlternativeName == null)
{
- GeneralNames issuerAltName = GeneralNames.getInstance(ASN1OctetString.getInstance(issuerAlternativeName).getOctets());
+ return Collections.EMPTY_LIST;
+ }
- GeneralName[] names = issuerAltName.getNames();
- List<PKIXCertStore> stores = new ArrayList<PKIXCertStore>();
+ GeneralNames issuerAltName = GeneralNames.getInstance(ASN1OctetString.getInstance(issuerAlternativeName).getOctets());
- for (int i = 0; i != names.length; i++)
- {
- GeneralName altName = names[i];
+ GeneralName[] names = issuerAltName.getNames();
+ List<PKIXCertStore> stores = new ArrayList<PKIXCertStore>();
- PKIXCertStore altStore = altNameCertStoreMap.get(altName);
+ for (int i = 0; i != names.length; i++)
+ {
+ GeneralName altName = names[i];
- if (altStore != null)
- {
- stores.add(altStore);
- }
+ PKIXCertStore altStore = altNameCertStoreMap.get(altName);
+ if (altStore != null)
+ {
+ stores.add(altStore);
}
-
- return stores;
- }
- else
- {
- return Collections.EMPTY_LIST;
}
+
+ return stores;
}
- protected static Date getValidDate(PKIXExtendedParameters paramsPKIX)
+ protected static Date getValidityDate(PKIXExtendedParameters paramsPKIX, Date currentDate)
{
- Date validDate = paramsPKIX.getDate();
+ Date validityDate = paramsPKIX.getValidityDate();
- if (validDate == null)
- {
- validDate = new Date();
- }
-
- return validDate;
+ return null == validityDate ? currentDate : validityDate;
}
protected static boolean isSelfIssued(X509Certificate cert)
@@ -305,7 +335,6 @@ class CertPathValidatorUtilities
return cert.getSubjectDN().equals(cert.getIssuerDN());
}
-
/**
* Extract the value of the given extension, if it exists.
*
@@ -313,32 +342,21 @@ class CertPathValidatorUtilities
* @param oid The object identifier to obtain.
* @throws AnnotatedException if the extension cannot be read.
*/
- protected static ASN1Primitive getExtensionValue(
- java.security.cert.X509Extension ext,
- String oid)
+ protected static ASN1Primitive getExtensionValue(java.security.cert.X509Extension ext, String oid)
throws AnnotatedException
{
byte[] bytes = ext.getExtensionValue(oid);
- if (bytes == null)
- {
- return null;
- }
- return getObject(oid, bytes);
+ return null == bytes ? null : getObject(oid, bytes);
}
- private static ASN1Primitive getObject(
- String oid,
- byte[] ext)
- throws AnnotatedException
+ private static ASN1Primitive getObject(String oid, byte[] ext) throws AnnotatedException
{
try
{
- ASN1InputStream aIn = new ASN1InputStream(ext);
- ASN1OctetString octs = (ASN1OctetString)aIn.readObject();
+ ASN1OctetString octs = ASN1OctetString.getInstance(ext);
- aIn = new ASN1InputStream(octs.getOctets());
- return aIn.readObject();
+ return ASN1Primitive.fromByteArray(octs.getOctets());
}
catch (Exception e)
{
@@ -346,17 +364,11 @@ class CertPathValidatorUtilities
}
}
- protected static AlgorithmIdentifier getAlgorithmIdentifier(
- PublicKey key)
- throws CertPathValidatorException
+ protected static AlgorithmIdentifier getAlgorithmIdentifier(PublicKey key) throws CertPathValidatorException
{
try
{
- ASN1InputStream aIn = new ASN1InputStream(key.getEncoded());
-
- SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(aIn.readObject());
-
- return info.getAlgorithm();
+ return SubjectPublicKeyInfo.getInstance(key.getEncoded()).getAlgorithm();
}
catch (Exception e)
{
@@ -382,10 +394,9 @@ class CertPathValidatorUtilities
}
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
+ ASN1OutputStream aOut = ASN1OutputStream.create(bOut);
Enumeration e = qualifiers.getObjects();
-
while (e.hasMoreElements())
{
try
@@ -651,23 +662,23 @@ class CertPathValidatorUtilities
}
/**
- * Return a Collection of all certificates or attribute certificates found
- * in the X509Store's that are matching the certSelect criteriums.
+ * Return a Collection of all certificates or attribute certificates found in the X509Store's
+ * that are matching the certSelect criteriums.
*
- * @param certSelect a {@link Selector} object that will be used to select
- * the certificates
- * @param certStores a List containing only {@link Store} objects. These
- * are used to search for certificates.
- * @return a Collection of all found {@link X509Certificate}
- * May be empty but never <code>null</code>.
+ * @param certs
+ * a {@link LinkedHashSet} to which the certificates will be added.
+ * @param certSelect
+ * a {@link Selector} object that will be used to select the certificates
+ * @param certStores
+ * a List containing only {@link Store} objects. These are used to search for
+ * certificates.
+ * @return a Collection of all found {@link X509Certificate} May be empty but never
+ * <code>null</code>.
*/
- protected static Collection findCertificates(PKIXCertStoreSelector certSelect,
- List certStores)
+ protected static void findCertificates(LinkedHashSet certs, PKIXCertStoreSelector certSelect, List certStores)
throws AnnotatedException
{
- Set certs = new LinkedHashSet();
Iterator iter = certStores.iterator();
-
while (iter.hasNext())
{
Object obj = iter.next();
@@ -683,8 +694,7 @@ class CertPathValidatorUtilities
}
catch (StoreException e)
{
- throw new AnnotatedException(
- "Problem while picking certificates from X.509 store.", e);
+ throw new AnnotatedException("Problem while picking certificates from X.509 store.", e);
}
}
else
@@ -692,68 +702,109 @@ class CertPathValidatorUtilities
// END Android-removed: Unknown reason
{
CertStore certStore = (CertStore)obj;
-
try
{
certs.addAll(PKIXCertStoreSelector.getCertificates(certSelect, certStore));
}
catch (CertStoreException e)
{
- throw new AnnotatedException(
- "Problem while picking certificates from certificate store.",
- e);
+ throw new AnnotatedException("Problem while picking certificates from certificate store.", e);
}
}
}
- return certs;
}
- static List<PKIXCRLStore> getAdditionalStoresFromCRLDistributionPoint(CRLDistPoint crldp, Map<GeneralName, PKIXCRLStore> namedCRLStoreMap)
+ static List<PKIXCRLStore> getAdditionalStoresFromCRLDistributionPoint(
+ CRLDistPoint crldp, Map<GeneralName, PKIXCRLStore> namedCRLStoreMap, Date validDate, JcaJceHelper helper)
throws AnnotatedException
{
- if (crldp != null)
+ if (null == crldp)
+ {
+ return Collections.EMPTY_LIST;
+ }
+
+ DistributionPoint dps[];
+ try
+ {
+ dps = crldp.getDistributionPoints();
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("Distribution points could not be read.", e);
+ }
+
+ List<PKIXCRLStore> stores = new ArrayList<PKIXCRLStore>();
+
+ for (int i = 0; i < dps.length; i++)
{
- DistributionPoint dps[] = null;
+ DistributionPointName dpn = dps[i].getDistributionPoint();
+ // look for URIs in fullName
+ if (dpn != null && dpn.getType() == DistributionPointName.FULL_NAME)
+ {
+ GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames();
+
+ for (int j = 0; j < genNames.length; j++)
+ {
+ PKIXCRLStore store = namedCRLStoreMap.get(genNames[j]);
+ if (store != null)
+ {
+ stores.add(store);
+ }
+ }
+ }
+ }
+
+ // if the named CRL store is empty, and we're told to check with CRLDP
+ if (stores.isEmpty() && Properties.isOverrideSet("com.android.org.bouncycastle.x509.enableCRLDP"))
+ {
+ CertificateFactory certFact;
try
{
- dps = crldp.getDistributionPoints();
+ certFact = helper.createCertificateFactory("X.509");
}
catch (Exception e)
{
- throw new AnnotatedException(
- "Distribution points could not be read.", e);
+ throw new AnnotatedException("cannot create certificate factory: " + e.getMessage(), e);
}
- List<PKIXCRLStore> stores = new ArrayList<PKIXCRLStore>();
for (int i = 0; i < dps.length; i++)
{
DistributionPointName dpn = dps[i].getDistributionPoint();
// look for URIs in fullName
- if (dpn != null)
+ if (dpn != null && dpn.getType() == DistributionPointName.FULL_NAME)
{
- if (dpn.getType() == DistributionPointName.FULL_NAME)
- {
- GeneralName[] genNames = GeneralNames.getInstance(
- dpn.getName()).getNames();
+ GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames();
- for (int j = 0; j < genNames.length; j++)
+ for (int j = 0; j < genNames.length; j++)
+ {
+ GeneralName name = genNames[i];
+ if (name.getTagNo() == GeneralName.uniformResourceIdentifier)
{
- PKIXCRLStore store = namedCRLStoreMap.get(genNames[j]);
- if (store != null)
+ try
{
- stores.add(store);
+ // BEGIN Android-removed
+ /*
+ URI distributionPoint = new URI(((ASN1String)name.getName()).getString());
+ PKIXCRLStore store = CrlCache.getCrl(certFact, validDate, distributionPoint);
+ if (store != null)
+ {
+ stores.add(store);
+ }
+ */
+ // END Android-removed
+ break;
+ }
+ catch (Exception e)
+ {
+ // ignore... TODO: maybe log
}
}
}
}
}
-
- return stores;
- }
- else
- {
- return Collections.EMPTY_LIST;
}
+
+ return stores;
}
/**
@@ -790,14 +841,12 @@ class CertPathValidatorUtilities
{
try
{
- issuers.add(X500Name.getInstance(genNames[j].getName()
- .toASN1Primitive().getEncoded()));
+ issuers.add(X500Name.getInstance(genNames[j].getName().toASN1Primitive().getEncoded()));
}
catch (IOException e)
{
throw new AnnotatedException(
- "CRL issuer information from distribution point cannot be decoded.",
- e);
+ "CRL issuer information from distribution point cannot be decoded.", e);
}
}
}
@@ -878,8 +927,7 @@ class CertPathValidatorUtilities
}
}
- private static BigInteger getSerialNumber(
- Object cert)
+ private static BigInteger getSerialNumber(Object cert)
{
return ((X509Certificate)cert).getSerialNumber();
}
@@ -891,8 +939,6 @@ class CertPathValidatorUtilities
CertStatus certStatus)
throws AnnotatedException
{
- X509CRLEntry crl_entry = null;
-
boolean isIndirect;
try
{
@@ -903,6 +949,7 @@ class CertPathValidatorUtilities
throw new AnnotatedException("Failed check for indirect CRL.", exception);
}
+ X509CRLEntry crl_entry;
if (isIndirect)
{
crl_entry = crl.getRevokedCertificate(getSerialNumber(cert));
@@ -921,15 +968,15 @@ class CertPathValidatorUtilities
}
else
{
- certIssuer = X500Name.getInstance(certificateIssuer.getEncoded());
+ certIssuer = PrincipalUtils.getX500Name(certificateIssuer);
}
- if (! PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(certIssuer))
+ if (!PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(certIssuer))
{
return;
}
}
- else if (! PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(PrincipalUtils.getIssuerPrincipal(crl)))
+ else if (!PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(PrincipalUtils.getIssuerPrincipal(crl)))
{
return; // not for our issuer, ignore
}
@@ -946,41 +993,35 @@ class CertPathValidatorUtilities
ASN1Enumerated reasonCode = null;
if (crl_entry.hasExtensions())
{
+ if (crl_entry.hasUnsupportedCriticalExtension())
+ {
+ throw new AnnotatedException("CRL entry has unsupported critical extensions.");
+ }
+
try
{
reasonCode = ASN1Enumerated
- .getInstance(CertPathValidatorUtilities
- .getExtensionValue(crl_entry,
- Extension.reasonCode.getId()));
+ .getInstance(CertPathValidatorUtilities.getExtensionValue(crl_entry, Extension.reasonCode.getId()));
}
catch (Exception e)
{
- throw new AnnotatedException(
- "Reason code CRL entry extension could not be decoded.",
- e);
+ throw new AnnotatedException("Reason code CRL entry extension could not be decoded.", e);
}
}
- // for reason keyCompromise, caCompromise, aACompromise or
- // unspecified
+ int reasonCodeValue = (null == reasonCode)
+ ? CRLReason.unspecified
+ : reasonCode.intValueExact();
+
+ // for reason keyCompromise, caCompromise, aACompromise or unspecified
if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime())
- || reasonCode == null
- || reasonCode.getValue().intValue() == 0
- || reasonCode.getValue().intValue() == 1
- || reasonCode.getValue().intValue() == 2
- || reasonCode.getValue().intValue() == 8)
+ || reasonCodeValue == CRLReason.unspecified
+ || reasonCodeValue == CRLReason.keyCompromise
+ || reasonCodeValue == CRLReason.cACompromise
+ || reasonCodeValue == CRLReason.aACompromise)
{
-
- // (i) or (j) (1)
- if (reasonCode != null)
- {
- certStatus.setCertStatus(reasonCode.getValue().intValue());
- }
- // (i) or (j) (2)
- else
- {
- certStatus.setCertStatus(CRLReason.unspecified);
- }
+ // (i) or (j)
+ certStatus.setCertStatus(reasonCodeValue);
certStatus.setRevocationDate(crl_entry.getRevocationDate());
}
}
@@ -995,7 +1036,10 @@ class CertPathValidatorUtilities
* CRLs.
*/
protected static Set getDeltaCRLs(Date validityDate,
- X509CRL completeCRL, List<CertStore> certStores, List<PKIXCRLStore> pkixCrlStores)
+ X509CRL completeCRL,
+ List<CertStore> certStores,
+ List<PKIXCRLStore> pkixCrlStores,
+ JcaJceHelper helper)
throws AnnotatedException
{
X509CRLSelector baseDeltaSelect = new X509CRLSelector();
@@ -1009,13 +1053,10 @@ class CertPathValidatorUtilities
throw new AnnotatedException("Cannot extract issuer from CRL.", e);
}
-
-
BigInteger completeCRLNumber = null;
try
{
- ASN1Primitive derObject = CertPathValidatorUtilities.getExtensionValue(completeCRL,
- CRL_NUMBER);
+ ASN1Primitive derObject = CertPathValidatorUtilities.getExtensionValue(completeCRL, CRL_NUMBER);
if (derObject != null)
{
completeCRLNumber = ASN1Integer.getInstance(derObject).getPositiveValue();
@@ -1028,22 +1069,19 @@ class CertPathValidatorUtilities
}
// 5.2.4 (b)
- byte[] idp = null;
+ byte[] idp;
try
{
idp = completeCRL.getExtensionValue(ISSUING_DISTRIBUTION_POINT);
}
catch (Exception e)
{
- throw new AnnotatedException(
- "Issuing distribution point extension value could not be read.",
- e);
+ throw new AnnotatedException("Issuing distribution point extension value could not be read.", e);
}
// 5.2.4 (d)
- baseDeltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber
- .add(BigInteger.valueOf(1)));
+ baseDeltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber.add(BigInteger.valueOf(1)));
PKIXCRLStoreSelector.Builder selBuilder = new PKIXCRLStoreSelector.Builder(baseDeltaSelect);
@@ -1056,8 +1094,61 @@ class CertPathValidatorUtilities
PKIXCRLStoreSelector deltaSelect = selBuilder.build();
// find delta CRLs
- Set temp = CRL_UTIL.findCRLs(deltaSelect, validityDate, certStores, pkixCrlStores);
+ Set temp = PKIXCRLUtil.findCRLs(deltaSelect, validityDate, certStores, pkixCrlStores);
+ // if the named CRL store is empty, and we're told to check with CRLDP
+ if (temp.isEmpty() && Properties.isOverrideSet("com.android.org.bouncycastle.x509.enableCRLDP"))
+ {
+ CertificateFactory certFact;
+ try
+ {
+ certFact = helper.createCertificateFactory("X.509");
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("cannot create certificate factory: " + e.getMessage(), e);
+ }
+
+ CRLDistPoint id = CRLDistPoint.getInstance(idp);
+ DistributionPoint[] dps = id.getDistributionPoints();
+ for (int i = 0; i < dps.length; i++)
+ {
+ DistributionPointName dpn = dps[i].getDistributionPoint();
+ // look for URIs in fullName
+ if (dpn != null && dpn.getType() == DistributionPointName.FULL_NAME)
+ {
+ GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames();
+
+ for (int j = 0; j < genNames.length; j++)
+ {
+ GeneralName name = genNames[i];
+ if (name.getTagNo() == GeneralName.uniformResourceIdentifier)
+ {
+ try
+ {
+ // BEGIN Android-removed
+ /*
+ PKIXCRLStore store = CrlCache.getCrl(certFact, validityDate,
+ new URI(((ASN1String)name.getName()).getString()));
+ if (store != null)
+ {
+ temp = PKIXCRLUtil.findCRLs(deltaSelect, validityDate, Collections.EMPTY_LIST,
+ Collections.singletonList(store));
+ }
+ */
+ // END Android-removed
+ break;
+ }
+ catch (Exception e)
+ {
+ // ignore... TODO: maybe log
+ }
+ }
+ }
+ }
+ }
+ }
+
Set result = new HashSet();
for (Iterator it = temp.iterator(); it.hasNext(); )
@@ -1098,24 +1189,22 @@ class CertPathValidatorUtilities
* @throws AnnotatedException if an exception occurs while picking the CRLs
* or no CRLs are found.
*/
- protected static Set getCompleteCRLs(DistributionPoint dp, Object cert,
- Date currentDate, PKIXExtendedParameters paramsPKIX)
- throws AnnotatedException
+ protected static Set getCompleteCRLs(PKIXCertRevocationCheckerParameters params, DistributionPoint dp, Object cert,
+ PKIXExtendedParameters paramsPKIX, Date validityDate)
+ throws AnnotatedException, RecoverableCertPathValidatorException
{
X509CRLSelector baseCrlSelect = new X509CRLSelector();
try
{
Set issuers = new HashSet();
-
issuers.add(PrincipalUtils.getEncodedIssuerPrincipal(cert));
CertPathValidatorUtilities.getCRLIssuersFromDistributionPoint(dp, issuers, baseCrlSelect);
}
catch (AnnotatedException e)
{
- throw new AnnotatedException(
- "Could not get issuer information from distribution point.", e);
+ throw new AnnotatedException("Could not get issuer information from distribution point.", e);
}
if (cert instanceof X509Certificate)
@@ -1123,84 +1212,62 @@ class CertPathValidatorUtilities
baseCrlSelect.setCertificateChecking((X509Certificate)cert);
}
- PKIXCRLStoreSelector crlSelect = new PKIXCRLStoreSelector.Builder(baseCrlSelect).setCompleteCRLEnabled(true).build();
+ PKIXCRLStoreSelector crlSelect = new PKIXCRLStoreSelector.Builder(baseCrlSelect).setCompleteCRLEnabled(true)
+ .build();
- Date validityDate = currentDate;
+ Set crls = PKIXCRLUtil.findCRLs(crlSelect, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores());
- if (paramsPKIX.getDate() != null)
- {
- validityDate = paramsPKIX.getDate();
- }
-
- Set crls = CRL_UTIL.findCRLs(crlSelect, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores());
-
- checkCRLsNotEmpty(crls, cert);
+ checkCRLsNotEmpty(params, crls, cert);
return crls;
}
- protected static Date getValidCertDateFromValidityModel(
- PKIXExtendedParameters paramsPKIX, CertPath certPath, int index)
- throws AnnotatedException
+ protected static Date getValidCertDateFromValidityModel(Date validityDate, int validityModel, CertPath certPath,
+ int index) throws AnnotatedException
{
- if (paramsPKIX.getValidityModel() == PKIXExtendedParameters.CHAIN_VALIDITY_MODEL)
+ if (PKIXExtendedParameters.CHAIN_VALIDITY_MODEL != validityModel || index <= 0)
{
- // if end cert use given signing/encryption/... time
- if (index <= 0)
+ // use given signing/encryption/... time (or current date)
+ return validityDate;
+ }
+
+ X509Certificate issuedCert = (X509Certificate)certPath.getCertificates().get(index - 1);
+
+ if (index - 1 == 0)
+ {
+ // use time when cert was issued, if available
+ ASN1GeneralizedTime dateOfCertgen = null;
+ try
+ {
+ byte[] extBytes = ((X509Certificate)certPath.getCertificates().get(index - 1))
+ .getExtensionValue(ISISMTTObjectIdentifiers.id_isismtt_at_dateOfCertGen.getId());
+ if (extBytes != null)
+ {
+ dateOfCertgen = ASN1GeneralizedTime.getInstance(ASN1Primitive.fromByteArray(extBytes));
+ }
+ }
+ catch (IOException e)
{
- return CertPathValidatorUtilities.getValidDate(paramsPKIX);
- // else use time when previous cert was created
+ throw new AnnotatedException("Date of cert gen extension could not be read.");
}
- else
+ catch (IllegalArgumentException e)
+ {
+ throw new AnnotatedException("Date of cert gen extension could not be read.");
+ }
+ if (dateOfCertgen != null)
{
- if (index - 1 == 0)
+ try
{
- ASN1GeneralizedTime dateOfCertgen = null;
- try
- {
- byte[] extBytes = ((X509Certificate)certPath.getCertificates().get(index - 1)).getExtensionValue(ISISMTTObjectIdentifiers.id_isismtt_at_dateOfCertGen.getId());
- if (extBytes != null)
- {
- dateOfCertgen = ASN1GeneralizedTime.getInstance(ASN1Primitive.fromByteArray(extBytes));
- }
- }
- catch (IOException e)
- {
- throw new AnnotatedException(
- "Date of cert gen extension could not be read.");
- }
- catch (IllegalArgumentException e)
- {
- throw new AnnotatedException(
- "Date of cert gen extension could not be read.");
- }
- if (dateOfCertgen != null)
- {
- try
- {
- return dateOfCertgen.getDate();
- }
- catch (ParseException e)
- {
- throw new AnnotatedException(
- "Date from date of cert gen extension could not be parsed.",
- e);
- }
- }
- return ((X509Certificate)certPath.getCertificates().get(
- index - 1)).getNotBefore();
+ return dateOfCertgen.getDate();
}
- else
+ catch (ParseException e)
{
- return ((X509Certificate)certPath.getCertificates().get(
- index - 1)).getNotBefore();
+ throw new AnnotatedException("Date from date of cert gen extension could not be parsed.", e);
}
}
}
- else
- {
- return getValidDate(paramsPKIX);
- }
+
+ return issuedCert.getNotBefore();
}
/**
@@ -1288,10 +1355,10 @@ class CertPathValidatorUtilities
{
selector.setSubject(PrincipalUtils.getIssuerPrincipal(cert).getEncoded());
}
- catch (IOException e)
+ catch (Exception e)
{
throw new AnnotatedException(
- "Subject criteria for certificate selector to find issuer certificate could not be set.", e);
+ "Subject criteria for certificate selector to find issuer certificate could not be set.", e);
}
try
@@ -1313,37 +1380,24 @@ class CertPathValidatorUtilities
}
PKIXCertStoreSelector certSelect = new PKIXCertStoreSelector.Builder(selector).build();
- Set certs = new LinkedHashSet();
-
- Iterator iter;
+ LinkedHashSet certs = new LinkedHashSet();
try
{
- List matches = new ArrayList();
-
- matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, certStores));
- matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixCertStores));
-
- iter = matches.iterator();
+ CertPathValidatorUtilities.findCertificates(certs, certSelect, certStores);
+ CertPathValidatorUtilities.findCertificates(certs, certSelect, pkixCertStores);
}
catch (AnnotatedException e)
{
throw new AnnotatedException("Issuer certificate cannot be searched.", e);
}
- X509Certificate issuer = null;
- while (iter.hasNext())
- {
- issuer = (X509Certificate)iter.next();
- // issuer cannot be verified because possible DSA inheritance
- // parameters are missing
- certs.add(issuer);
- }
+ // issuers cannot be verified because possible DSA inheritance parameters are missing
+
return certs;
}
- protected static void verifyX509Certificate(X509Certificate cert, PublicKey publicKey,
- String sigProvider)
+ protected static void verifyX509Certificate(X509Certificate cert, PublicKey publicKey, String sigProvider)
throws GeneralSecurityException
{
if (sigProvider == null)
@@ -1356,8 +1410,8 @@ class CertPathValidatorUtilities
}
}
- static void checkCRLsNotEmpty(Set crls, Object cert)
- throws AnnotatedException
+ static void checkCRLsNotEmpty(PKIXCertRevocationCheckerParameters params, Set crls, Object cert)
+ throws RecoverableCertPathValidatorException
{
if (crls.isEmpty())
{
@@ -1365,13 +1419,15 @@ class CertPathValidatorUtilities
{
X509AttributeCertificate aCert = (X509AttributeCertificate)cert;
- throw new AnnotatedException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\"");
+ throw new RecoverableCertPathValidatorException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\"", null,
+ params.getCertPath(), params.getIndex());
}
else
{
X509Certificate xCert = (X509Certificate)cert;
- throw new AnnotatedException("No CRLs found for issuer \"" + RFC4519Style.INSTANCE.toString(PrincipalUtils.getIssuerPrincipal(xCert)) + "\"");
+ throw new RecoverableCertPathValidatorException("No CRLs found for issuer \"" + RFC4519Style.INSTANCE.toString(PrincipalUtils.getIssuerPrincipal(xCert)) + "\"", null,
+ params.getCertPath(), params.getIndex());
}
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPrivateKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPrivateKey.java
index 711240c4..5a165bd1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPrivateKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPrivateKey.java
@@ -29,6 +29,7 @@ import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import com.android.org.bouncycastle.asn1.x9.X962Parameters;
import com.android.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.org.bouncycastle.asn1.x9.X9ECPoint;
import com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import com.android.org.bouncycastle.crypto.params.ECDomainParameters;
import com.android.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
@@ -193,7 +194,7 @@ public class JCEECPrivateKey
private void populateFromPrivKeyInfo(PrivateKeyInfo info)
throws IOException
{
- X962Parameters params = new X962Parameters((ASN1Primitive)info.getPrivateKeyAlgorithm().getParameters());
+ X962Parameters params = X962Parameters.getInstance(info.getPrivateKeyAlgorithm().getParameters());
if (params.isNamedCurve())
{
@@ -304,7 +305,7 @@ public class JCEECPrivateKey
X9ECParameters ecP = new X9ECParameters(
curve,
- EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression),
+ new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), withCompression),
ecSpec.getOrder(),
BigInteger.valueOf(ecSpec.getCofactor()),
ecSpec.getCurve().getSeed());
@@ -358,14 +359,14 @@ public class JCEECPrivateKey
return null;
}
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
com.android.org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec()
{
if (ecSpec != null)
{
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPublicKey.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPublicKey.java
index 15b07d1b..8fcdeb07 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPublicKey.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/JCEECPublicKey.java
@@ -15,7 +15,6 @@ import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1OctetString;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
-import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.DERBitString;
import com.android.org.bouncycastle.asn1.DERNull;
import com.android.org.bouncycastle.asn1.DEROctetString;
@@ -42,8 +41,6 @@ import com.android.org.bouncycastle.jce.interfaces.ECPointEncoder;
// import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import com.android.org.bouncycastle.jce.spec.ECNamedCurveSpec;
import com.android.org.bouncycastle.math.ec.ECCurve;
-import com.android.org.bouncycastle.math.ec.custom.sec.SecP256K1Point;
-import com.android.org.bouncycastle.math.ec.custom.sec.SecP256R1Point;
import com.android.org.bouncycastle.util.Strings;
/**
@@ -77,7 +74,7 @@ public class JCEECPublicKey
{
this.algorithm = algorithm;
this.ecSpec = spec.getParams();
- this.q = EC5Util.convertPoint(ecSpec, spec.getW(), false);
+ this.q = EC5Util.convertPoint(ecSpec, spec.getW());
}
public JCEECPublicKey(
@@ -100,7 +97,7 @@ public class JCEECPublicKey
{
com.android.org.bouncycastle.jce.spec.ECParameterSpec s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
- q = s.getCurve().createPoint(q.getAffineXCoord().toBigInteger(), q.getAffineYCoord().toBigInteger(), false);
+ q = s.getCurve().createPoint(q.getAffineXCoord().toBigInteger(), q.getAffineYCoord().toBigInteger());
}
this.ecSpec = null;
}
@@ -178,7 +175,7 @@ public class JCEECPublicKey
{
this.algorithm = key.getAlgorithm();
this.ecSpec = key.getParams();
- this.q = EC5Util.convertPoint(this.ecSpec, key.getW(), false);
+ this.q = EC5Util.convertPoint(this.ecSpec, key.getW());
}
JCEECPublicKey(
@@ -189,9 +186,11 @@ public class JCEECPublicKey
private void populateFromPubKeyInfo(SubjectPublicKeyInfo info)
{
+ AlgorithmIdentifier algID = info.getAlgorithm();
// BEGIN Android-removed: Unsupported algorithms
/*
- if (info.getAlgorithmId().getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3410_2001))
+
+ if (algID.getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3410_2001))
{
DERBitString bits = info.getPublicKeyData();
ASN1OctetString key;
@@ -216,7 +215,7 @@ public class JCEECPublicKey
x9Encoding[i + 32] = keyEnc[64 - i];
}
- gostParams = new GOST3410PublicKeyAlgParameters((ASN1Sequence)info.getAlgorithmId().getParameters());
+ gostParams = GOST3410PublicKeyAlgParameters.getInstance(algID.getParameters());
ECNamedCurveParameterSpec spec = ECGOST3410NamedCurveTable.getParameterSpec(ECGOST3410NamedCurves.getName(gostParams.getPublicKeyParamSet()));
@@ -236,7 +235,7 @@ public class JCEECPublicKey
*/
// END Android-removed: Unsupported algorithms
{
- X962Parameters params = new X962Parameters((ASN1Primitive)info.getAlgorithmId().getParameters());
+ X962Parameters params = X962Parameters.getInstance(algID.getParameters());
ECCurve curve;
EllipticCurve ellipticCurve;
@@ -341,7 +340,7 @@ public class JCEECPublicKey
X9ECParameters ecP = new X9ECParameters(
curve,
- EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression),
+ new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), withCompression),
ecSpec.getOrder(),
BigInteger.valueOf(ecSpec.getCofactor()),
ecSpec.getCurve().getSeed());
@@ -350,10 +349,10 @@ public class JCEECPublicKey
}
}
- BigInteger bX = this.q.getAffineXCoord().toBigInteger();
- BigInteger bY = this.q.getAffineYCoord().toBigInteger();
- byte[] encKey = new byte[64];
+ BigInteger bX = this.q.getAffineXCoord().toBigInteger();
+ BigInteger bY = this.q.getAffineYCoord().toBigInteger();
+ byte[] encKey = new byte[64];
extractBytes(encKey, 0, bX);
extractBytes(encKey, 32, bY);
@@ -389,7 +388,7 @@ public class JCEECPublicKey
X9ECParameters ecP = new X9ECParameters(
curve,
- EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression),
+ new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), withCompression),
ecSpec.getOrder(),
BigInteger.valueOf(ecSpec.getCofactor()),
ecSpec.getCurve().getSeed());
@@ -397,11 +396,9 @@ public class JCEECPublicKey
params = new X962Parameters(ecP);
}
- ECCurve curve = this.engineGetQ().getCurve();
- ASN1OctetString p = (ASN1OctetString)
- new X9ECPoint(curve.createPoint(this.getQ().getAffineXCoord().toBigInteger(), this.getQ().getAffineYCoord().toBigInteger(), withCompression)).toASN1Primitive();
+ byte[] pubKeyOctets = this.getQ().getEncoded(withCompression);
- info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets());
+ info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), pubKeyOctets);
}
return KeyUtil.getEncodedSubjectPublicKeyInfo(info);
@@ -435,7 +432,7 @@ public class JCEECPublicKey
return null;
}
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
public ECPoint getW()
@@ -462,7 +459,7 @@ public class JCEECPublicKey
{
if (ecSpec != null)
{
- return EC5Util.convertSpec(ecSpec, withCompression);
+ return EC5Util.convertSpec(ecSpec);
}
return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCRLUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCRLUtil.java
index 04fd1947..897d0ce2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCRLUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCRLUtil.java
@@ -17,18 +17,18 @@ import com.android.org.bouncycastle.jcajce.PKIXCRLStoreSelector;
import com.android.org.bouncycastle.util.Store;
import com.android.org.bouncycastle.util.StoreException;
-class PKIXCRLUtil
+abstract class PKIXCRLUtil
{
- public Set findCRLs(PKIXCRLStoreSelector crlselect, Date validityDate, List certStores, List pkixCrlStores)
+ static Set findCRLs(PKIXCRLStoreSelector crlselect, Date validityDate, List certStores, List pkixCrlStores)
throws AnnotatedException
{
- Set initialSet = new HashSet();
+ HashSet initialSet = new HashSet();
// get complete CRL(s)
try
{
- initialSet.addAll(findCRLs(crlselect, pkixCrlStores));
- initialSet.addAll(findCRLs(crlselect, certStores));
+ findCRLs(initialSet, crlselect, pkixCrlStores);
+ findCRLs(initialSet, crlselect, certStores);
}
catch (AnnotatedException e)
{
@@ -46,14 +46,7 @@ class PKIXCRLUtil
{
X509Certificate cert = crlselect.getCertificateChecking();
- if (cert != null)
- {
- if (crl.getThisUpdate().before(cert.getNotAfter()))
- {
- finalSet.add(crl);
- }
- }
- else
+ if (null == cert || crl.getThisUpdate().before(cert.getNotAfter()))
{
finalSet.add(crl);
}
@@ -64,27 +57,23 @@ class PKIXCRLUtil
}
/**
- * Return a Collection of all CRLs found in the X509Store's that are
- * matching the crlSelect criteriums.
+ * Add to a HashSet any and all CRLs found in the X509Store's that are matching the crlSelect
+ * critera.
*
- * @param crlSelect a {@link com.android.org.bouncycastle.jcajce.PKIXCRLStoreSelector} object that will be used
- * to select the CRLs
- * @param crlStores a List containing only
- * {@link Store} objects.
- * These are used to search for CRLs
- *
- * @return a Collection of all found {@link java.security.cert.X509CRL X509CRL} objects. May be
- * empty but never <code>null</code>.
+ * @param crls
+ * the {@link HashSet} to add the CRLs to.
+ * @param crlSelect
+ * a {@link com.android.org.bouncycastle.jcajce.PKIXCRLStoreSelector} object that will be used to
+ * select the CRLs
+ * @param crlStores
+ * a List containing only {@link Store} objects. These are used to search for CRLs
*/
- private final Collection findCRLs(PKIXCRLStoreSelector crlSelect,
- List crlStores) throws AnnotatedException
+ private static void findCRLs(HashSet crls, PKIXCRLStoreSelector crlSelect, List crlStores) throws AnnotatedException
{
- Set crls = new HashSet();
- Iterator iter = crlStores.iterator();
-
AnnotatedException lastException = null;
boolean foundValidStore = false;
+ Iterator iter = crlStores.iterator();
while (iter.hasNext())
{
Object obj = iter.next();
@@ -102,8 +91,7 @@ class PKIXCRLUtil
}
catch (StoreException e)
{
- lastException = new AnnotatedException(
- "Exception searching in X.509 CRL store.", e);
+ lastException = new AnnotatedException("Exception searching in X.509 CRL store.", e);
}
}
else
@@ -119,16 +107,14 @@ class PKIXCRLUtil
}
catch (CertStoreException e)
{
- lastException = new AnnotatedException(
- "Exception searching in X.509 CRL store.", e);
+ lastException = new AnnotatedException("Exception searching in X.509 CRL store.", e);
}
}
}
+
if (!foundValidStore && lastException != null)
{
throw lastException;
}
- return crls;
}
-
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java
index 1340c7b1..a97454c4 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java
@@ -20,11 +20,9 @@ import java.util.List;
import com.android.org.bouncycastle.asn1.x509.Extension;
import com.android.org.bouncycastle.jcajce.PKIXCertStore;
-import com.android.org.bouncycastle.jcajce.PKIXCertStoreSelector;
import com.android.org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
import com.android.org.bouncycastle.jcajce.PKIXExtendedParameters;
import com.android.org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory;
-import com.android.org.bouncycastle.jce.exception.ExtCertPathBuilderException;
import com.android.org.bouncycastle.x509.ExtendedPKIXBuilderParameters;
import com.android.org.bouncycastle.x509.ExtendedPKIXParameters;
@@ -37,6 +35,18 @@ import com.android.org.bouncycastle.x509.ExtendedPKIXParameters;
public class PKIXCertPathBuilderSpi
extends CertPathBuilderSpi
{
+ private final boolean isForCRLCheck;
+
+ public PKIXCertPathBuilderSpi()
+ {
+ this(false);
+ }
+
+ PKIXCertPathBuilderSpi(boolean isForCRLCheck)
+ {
+ this.isForCRLCheck = isForCRLCheck;
+ }
+
/**
* Build and validate a CertPath using the given parameter.
*
@@ -90,26 +100,7 @@ public class PKIXCertPathBuilderSpi
X509Certificate cert;
// search target certificates
-
- PKIXCertStoreSelector certSelect = paramsPKIX.getBaseParameters().getTargetConstraints();
-
- try
- {
- targets = CertPathValidatorUtilities.findCertificates(certSelect, paramsPKIX.getBaseParameters().getCertificateStores());
- targets.addAll(CertPathValidatorUtilities.findCertificates(certSelect, paramsPKIX.getBaseParameters().getCertStores()));
- }
- catch (AnnotatedException e)
- {
- throw new ExtCertPathBuilderException(
- "Error finding target certificate.", e);
- }
-
- if (targets.isEmpty())
- {
-
- throw new CertPathBuilderException(
- "No certificate found matching targetContraints.");
- }
+ targets = CertPathValidatorUtilities.findTargets(paramsPKIX);
CertPathBuilderResult result = null;
@@ -177,7 +168,7 @@ public class PKIXCertPathBuilderSpi
try
{
cFact = new CertificateFactory();
- validator = new PKIXCertPathValidatorSpi();
+ validator = new PKIXCertPathValidatorSpi(isForCRLCheck);
}
catch (Exception e)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
index f9491f76..497d7d6d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
@@ -16,6 +16,7 @@ import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
+import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -29,6 +30,8 @@ import com.android.org.bouncycastle.asn1.x509.Extension;
import com.android.org.bouncycastle.asn1.x509.TBSCertificate;
import com.android.org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
import com.android.org.bouncycastle.jcajce.PKIXExtendedParameters;
+// BEGIN Android-removed:
+// import org.bouncycastle.jcajce.interfaces.BCX509Certificate;
import com.android.org.bouncycastle.jcajce.util.BCJcaJceHelper;
import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
import com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException;
@@ -43,15 +46,22 @@ public class PKIXCertPathValidatorSpi
extends CertPathValidatorSpi
{
private final JcaJceHelper helper = new BCJcaJceHelper();
+ private final boolean isForCRLCheck;
public PKIXCertPathValidatorSpi()
{
+ this(false);
}
- // BEGIN Android-added: Avoid loading blacklist during class init
+
+ public PKIXCertPathValidatorSpi(boolean isForCRLCheck)
+ {
+ this.isForCRLCheck = isForCRLCheck;
+ }
+ // BEGIN Android-added: Avoid loading blocklist during class init
private static class NoPreloadHolder {
- private final static CertBlacklist blacklist = new CertBlacklist();
+ private final static CertBlocklist blocklist = new CertBlocklist();
}
- // END Android-added: Avoid loading blacklist during class init
+ // END Android-added: Avoid loading blocklist during class init
public CertPathValidatorResult engineValidate(
CertPath certPath,
@@ -107,13 +117,13 @@ public class PKIXCertPathValidatorSpi
{
throw new CertPathValidatorException("Certification path is empty.", null, certPath, -1);
}
- // BEGIN Android-added: Support blacklisting known-bad certs
+ // BEGIN Android-added: Support blocklisting known-bad certs
{
X509Certificate cert = (X509Certificate) certs.get(0);
if (cert != null) {
BigInteger serial = cert.getSerialNumber();
- if (NoPreloadHolder.blacklist.isSerialNumberBlackListed(serial)) {
+ if (NoPreloadHolder.blocklist.isSerialNumberBlockListed(serial)) {
// emulate CRL exception message in RFC3280CertPathUtilities.checkCRLs
String message = "Certificate revocation of serial 0x" + serial.toString(16);
System.out.println(message);
@@ -122,12 +132,13 @@ public class PKIXCertPathValidatorSpi
}
}
}
- // END Android-added: Support blacklisting known-bad certs
+ // END Android-added: Support blocklisting known-bad certs
//
// (b)
//
- // Date validDate = CertPathValidatorUtilities.getValidDate(paramsPKIX);
+ final Date currentDate = new Date();
+ final Date validityDate = CertPathValidatorUtilities.getValidityDate(paramsPKIX, currentDate);
//
// (c)
@@ -255,7 +266,7 @@ public class PKIXCertPathValidatorSpi
workingPublicKey = trust.getCAPublicKey();
}
}
- catch (IllegalArgumentException ex)
+ catch (RuntimeException ex)
{
throw new ExtCertPathValidatorException("Subject of trust anchor could not be (re)encoded.", ex, certPath,
-1);
@@ -300,19 +311,32 @@ public class PKIXCertPathValidatorSpi
((PKIXCertPathChecker) certIter.next()).init(false);
}
+ //
+ // initialize RevocationChecker
+ //
+ ProvCrlRevocationChecker revocationChecker;
+ if (paramsPKIX.isRevocationEnabled())
+ {
+ revocationChecker = new ProvCrlRevocationChecker(helper);
+ }
+ else
+ {
+ revocationChecker = null;
+ }
+
X509Certificate cert = null;
for (index = certs.size() - 1; index >= 0; index--)
{
- // BEGIN Android-added: Support blacklisting known-bad certs
- if (NoPreloadHolder.blacklist.isPublicKeyBlackListed(workingPublicKey)) {
+ // BEGIN Android-added: Support blocklisting known-bad certs
+ if (NoPreloadHolder.blocklist.isPublicKeyBlockListed(workingPublicKey)) {
// emulate CRL exception message in RFC3280CertPathUtilities.checkCRLs
String message = "Certificate revocation of public key " + workingPublicKey;
System.out.println(message);
AnnotatedException e = new AnnotatedException(message);
throw new CertPathValidatorException(e.getMessage(), e, certPath, index);
}
- // END Android-added: Support blacklisting known-bad certs
+ // END Android-added: Support blocklisting known-bad certs
// try
// {
//
@@ -342,13 +366,13 @@ public class PKIXCertPathValidatorSpi
// 6.1.3
//
- RFC3280CertPathUtilities.processCertA(certPath, paramsPKIX, index, workingPublicKey,
- verificationAlreadyPerformed, workingIssuerName, sign, helper);
+ RFC3280CertPathUtilities.processCertA(certPath, paramsPKIX, validityDate, revocationChecker, index,
+ workingPublicKey, verificationAlreadyPerformed, workingIssuerName, sign);
- RFC3280CertPathUtilities.processCertBC(certPath, index, nameConstraintValidator);
+ RFC3280CertPathUtilities.processCertBC(certPath, index, nameConstraintValidator, isForCRLCheck);
validPolicyTree = RFC3280CertPathUtilities.processCertD(certPath, index, acceptablePolicies,
- validPolicyTree, policyNodes, inhibitAnyPolicy);
+ validPolicyTree, policyNodes, inhibitAnyPolicy, isForCRLCheck);
validPolicyTree = RFC3280CertPathUtilities.processCertE(certPath, index, validPolicyTree);
@@ -507,6 +531,27 @@ public class PKIXCertPathValidatorSpi
static void checkCertificate(X509Certificate cert)
throws AnnotatedException
{
+ // BEGIN Android-removed:
+ /*
+ if (cert instanceof BCX509Certificate)
+ {
+ RuntimeException cause = null;
+ try
+ {
+ if (null != ((BCX509Certificate)cert).getTBSCertificateNative())
+ {
+ return;
+ }
+ }
+ catch (RuntimeException e)
+ {
+ cause = e;
+ }
+
+ throw new AnnotatedException("unable to process TBSCertificate", cause);
+ }
+ */
+ // END Android-removed:
try
{
TBSCertificate.getInstance(cert.getTBSCertificate());
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java
index 82550b73..4ad8f714 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java
@@ -1,1459 +1,62 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.jce.provider;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import com.android.org.bouncycastle.asn1.ASN1OctetString;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.org.bouncycastle.asn1.DERIA5String;
+import com.android.org.bouncycastle.asn1.x500.X500Name;
import com.android.org.bouncycastle.asn1.x509.GeneralName;
import com.android.org.bouncycastle.asn1.x509.GeneralSubtree;
-import com.android.org.bouncycastle.util.Arrays;
-import com.android.org.bouncycastle.util.Integers;
-import com.android.org.bouncycastle.util.Strings;
+import com.android.org.bouncycastle.asn1.x509.NameConstraintValidatorException;
/**
* @hide This class is not part of the Android public SDK API
*/
public class PKIXNameConstraintValidator
{
- private Set excludedSubtreesDN = new HashSet();
-
- private Set excludedSubtreesDNS = new HashSet();
-
- private Set excludedSubtreesEmail = new HashSet();
-
- private Set excludedSubtreesURI = new HashSet();
-
- private Set excludedSubtreesIP = new HashSet();
-
- private Set permittedSubtreesDN;
-
- private Set permittedSubtreesDNS;
-
- private Set permittedSubtreesEmail;
-
- private Set permittedSubtreesURI;
-
- private Set permittedSubtreesIP;
+ com.android.org.bouncycastle.asn1.x509.PKIXNameConstraintValidator validator = new com.android.org.bouncycastle.asn1.x509.PKIXNameConstraintValidator();
public PKIXNameConstraintValidator()
{
}
- private static boolean withinDNSubtree(
- ASN1Sequence dns,
- ASN1Sequence subtree)
- {
- if (subtree.size() < 1)
- {
- return false;
- }
-
- if (subtree.size() > dns.size())
- {
- return false;
- }
-
- for (int j = subtree.size() - 1; j >= 0; j--)
- {
- if (!subtree.getObjectAt(j).equals(dns.getObjectAt(j)))
- {
- return false;
- }
- }
-
- return true;
- }
-
- public void checkPermittedDN(ASN1Sequence dns)
- throws PKIXNameConstraintValidatorException
- {
- checkPermittedDN(permittedSubtreesDN, dns);
- }
-
- public void checkExcludedDN(ASN1Sequence dns)
- throws PKIXNameConstraintValidatorException
- {
- checkExcludedDN(excludedSubtreesDN, dns);
- }
-
- private void checkPermittedDN(Set permitted, ASN1Sequence dns)
- throws PKIXNameConstraintValidatorException
- {
- if (permitted == null)
- {
- return;
- }
-
- if (permitted.isEmpty() && dns.size() == 0)
- {
- return;
- }
- Iterator it = permitted.iterator();
-
- while (it.hasNext())
- {
- ASN1Sequence subtree = (ASN1Sequence)it.next();
-
- if (withinDNSubtree(dns, subtree))
- {
- return;
- }
- }
-
- throw new PKIXNameConstraintValidatorException(
- "Subject distinguished name is not from a permitted subtree");
- }
-
- private void checkExcludedDN(Set excluded, ASN1Sequence dns)
- throws PKIXNameConstraintValidatorException
- {
- if (excluded.isEmpty())
- {
- return;
- }
-
- Iterator it = excluded.iterator();
-
- while (it.hasNext())
- {
- ASN1Sequence subtree = (ASN1Sequence)it.next();
-
- if (withinDNSubtree(dns, subtree))
- {
- throw new PKIXNameConstraintValidatorException(
- "Subject distinguished name is from an excluded subtree");
- }
- }
- }
-
- private Set intersectDN(Set permitted, Set dns)
- {
- Set intersect = new HashSet();
- for (Iterator it = dns.iterator(); it.hasNext();)
- {
- ASN1Sequence dn = ASN1Sequence.getInstance(((GeneralSubtree)it
- .next()).getBase().getName().toASN1Primitive());
- if (permitted == null)
- {
- if (dn != null)
- {
- intersect.add(dn);
- }
- }
- else
- {
- Iterator _iter = permitted.iterator();
- while (_iter.hasNext())
- {
- ASN1Sequence subtree = (ASN1Sequence)_iter.next();
-
- if (withinDNSubtree(dn, subtree))
- {
- intersect.add(dn);
- }
- else if (withinDNSubtree(subtree, dn))
- {
- intersect.add(subtree);
- }
- }
- }
- }
- return intersect;
- }
-
- private Set unionDN(Set excluded, ASN1Sequence dn)
- {
- if (excluded.isEmpty())
- {
- if (dn == null)
- {
- return excluded;
- }
- excluded.add(dn);
-
- return excluded;
- }
- else
- {
- Set intersect = new HashSet();
-
- Iterator it = excluded.iterator();
- while (it.hasNext())
- {
- ASN1Sequence subtree = (ASN1Sequence)it.next();
-
- if (withinDNSubtree(dn, subtree))
- {
- intersect.add(subtree);
- }
- else if (withinDNSubtree(subtree, dn))
- {
- intersect.add(dn);
- }
- else
- {
- intersect.add(subtree);
- intersect.add(dn);
- }
- }
-
- return intersect;
- }
- }
-
- private Set intersectEmail(Set permitted, Set emails)
- {
- Set intersect = new HashSet();
- for (Iterator it = emails.iterator(); it.hasNext();)
- {
- String email = extractNameAsString(((GeneralSubtree)it.next())
- .getBase());
-
- if (permitted == null)
- {
- if (email != null)
- {
- intersect.add(email);
- }
- }
- else
- {
- Iterator it2 = permitted.iterator();
- while (it2.hasNext())
- {
- String _permitted = (String)it2.next();
-
- intersectEmail(email, _permitted, intersect);
- }
- }
- }
- return intersect;
- }
-
- private Set unionEmail(Set excluded, String email)
- {
- if (excluded.isEmpty())
- {
- if (email == null)
- {
- return excluded;
- }
- excluded.add(email);
- return excluded;
- }
- else
- {
- Set union = new HashSet();
-
- Iterator it = excluded.iterator();
- while (it.hasNext())
- {
- String _excluded = (String)it.next();
-
- unionEmail(_excluded, email, union);
- }
-
- return union;
- }
- }
-
- /**
- * Returns the intersection of the permitted IP ranges in
- * <code>permitted</code> with <code>ip</code>.
- *
- * @param permitted A <code>Set</code> of permitted IP addresses with
- * their subnet mask as byte arrays.
- * @param ips The IP address with its subnet mask.
- * @return The <code>Set</code> of permitted IP ranges intersected with
- * <code>ip</code>.
- */
- private Set intersectIP(Set permitted, Set ips)
- {
- Set intersect = new HashSet();
- for (Iterator it = ips.iterator(); it.hasNext();)
- {
- byte[] ip = ASN1OctetString.getInstance(
- ((GeneralSubtree)it.next()).getBase().getName()).getOctets();
- if (permitted == null)
- {
- if (ip != null)
- {
- intersect.add(ip);
- }
- }
- else
- {
- Iterator it2 = permitted.iterator();
- while (it2.hasNext())
- {
- byte[] _permitted = (byte[])it2.next();
- intersect.addAll(intersectIPRange(_permitted, ip));
- }
- }
- }
- return intersect;
- }
-
- /**
- * Returns the union of the excluded IP ranges in <code>excluded</code>
- * with <code>ip</code>.
- *
- * @param excluded A <code>Set</code> of excluded IP addresses with their
- * subnet mask as byte arrays.
- * @param ip The IP address with its subnet mask.
- * @return The <code>Set</code> of excluded IP ranges unified with
- * <code>ip</code> as byte arrays.
- */
- private Set unionIP(Set excluded, byte[] ip)
- {
- if (excluded.isEmpty())
- {
- if (ip == null)
- {
- return excluded;
- }
- excluded.add(ip);
-
- return excluded;
- }
- else
- {
- Set union = new HashSet();
-
- Iterator it = excluded.iterator();
- while (it.hasNext())
- {
- byte[] _excluded = (byte[])it.next();
- union.addAll(unionIPRange(_excluded, ip));
- }
-
- return union;
- }
- }
-
- /**
- * Calculates the union if two IP ranges.
- *
- * @param ipWithSubmask1 The first IP address with its subnet mask.
- * @param ipWithSubmask2 The second IP address with its subnet mask.
- * @return A <code>Set</code> with the union of both addresses.
- */
- private Set unionIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2)
- {
- Set set = new HashSet();
-
- // difficult, adding always all IPs is not wrong
- if (Arrays.areEqual(ipWithSubmask1, ipWithSubmask2))
- {
- set.add(ipWithSubmask1);
- }
- else
- {
- set.add(ipWithSubmask1);
- set.add(ipWithSubmask2);
- }
- return set;
- }
-
- /**
- * Calculates the interesction if two IP ranges.
- *
- * @param ipWithSubmask1 The first IP address with its subnet mask.
- * @param ipWithSubmask2 The second IP address with its subnet mask.
- * @return A <code>Set</code> with the single IP address with its subnet
- * mask as a byte array or an empty <code>Set</code>.
- */
- private Set intersectIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2)
- {
- if (ipWithSubmask1.length != ipWithSubmask2.length)
- {
- return Collections.EMPTY_SET;
- }
- byte[][] temp = extractIPsAndSubnetMasks(ipWithSubmask1, ipWithSubmask2);
- byte ip1[] = temp[0];
- byte subnetmask1[] = temp[1];
- byte ip2[] = temp[2];
- byte subnetmask2[] = temp[3];
-
- byte minMax[][] = minMaxIPs(ip1, subnetmask1, ip2, subnetmask2);
- byte[] min;
- byte[] max;
- max = min(minMax[1], minMax[3]);
- min = max(minMax[0], minMax[2]);
-
- // minimum IP address must be bigger than max
- if (compareTo(min, max) == 1)
- {
- return Collections.EMPTY_SET;
- }
- // OR keeps all significant bits
- byte[] ip = or(minMax[0], minMax[2]);
- byte[] subnetmask = or(subnetmask1, subnetmask2);
- return Collections.singleton(ipWithSubnetMask(ip, subnetmask));
- }
-
- /**
- * Concatenates the IP address with its subnet mask.
- *
- * @param ip The IP address.
- * @param subnetMask Its subnet mask.
- * @return The concatenated IP address with its subnet mask.
- */
- private byte[] ipWithSubnetMask(byte[] ip, byte[] subnetMask)
- {
- int ipLength = ip.length;
- byte[] temp = new byte[ipLength * 2];
- System.arraycopy(ip, 0, temp, 0, ipLength);
- System.arraycopy(subnetMask, 0, temp, ipLength, ipLength);
- return temp;
- }
-
- /**
- * Splits the IP addresses and their subnet mask.
- *
- * @param ipWithSubmask1 The first IP address with the subnet mask.
- * @param ipWithSubmask2 The second IP address with the subnet mask.
- * @return An array with two elements. Each element contains the IP address
- * and the subnet mask in this order.
- */
- private byte[][] extractIPsAndSubnetMasks(
- byte[] ipWithSubmask1,
- byte[] ipWithSubmask2)
- {
- int ipLength = ipWithSubmask1.length / 2;
- byte ip1[] = new byte[ipLength];
- byte subnetmask1[] = new byte[ipLength];
- System.arraycopy(ipWithSubmask1, 0, ip1, 0, ipLength);
- System.arraycopy(ipWithSubmask1, ipLength, subnetmask1, 0, ipLength);
-
- byte ip2[] = new byte[ipLength];
- byte subnetmask2[] = new byte[ipLength];
- System.arraycopy(ipWithSubmask2, 0, ip2, 0, ipLength);
- System.arraycopy(ipWithSubmask2, ipLength, subnetmask2, 0, ipLength);
- return new byte[][]
- {ip1, subnetmask1, ip2, subnetmask2};
- }
-
- /**
- * Based on the two IP addresses and their subnet masks the IP range is
- * computed for each IP address - subnet mask pair and returned as the
- * minimum IP address and the maximum address of the range.
- *
- * @param ip1 The first IP address.
- * @param subnetmask1 The subnet mask of the first IP address.
- * @param ip2 The second IP address.
- * @param subnetmask2 The subnet mask of the second IP address.
- * @return A array with two elements. The first/second element contains the
- * min and max IP address of the first/second IP address and its
- * subnet mask.
- */
- private byte[][] minMaxIPs(
- byte[] ip1,
- byte[] subnetmask1,
- byte[] ip2,
- byte[] subnetmask2)
- {
- int ipLength = ip1.length;
- byte[] min1 = new byte[ipLength];
- byte[] max1 = new byte[ipLength];
-
- byte[] min2 = new byte[ipLength];
- byte[] max2 = new byte[ipLength];
-
- for (int i = 0; i < ipLength; i++)
- {
- min1[i] = (byte)(ip1[i] & subnetmask1[i]);
- max1[i] = (byte)(ip1[i] & subnetmask1[i] | ~subnetmask1[i]);
-
- min2[i] = (byte)(ip2[i] & subnetmask2[i]);
- max2[i] = (byte)(ip2[i] & subnetmask2[i] | ~subnetmask2[i]);
- }
-
- return new byte[][]{min1, max1, min2, max2};
- }
-
- private void checkPermittedEmail(Set permitted, String email)
- throws PKIXNameConstraintValidatorException
- {
- if (permitted == null)
- {
- return;
- }
-
- Iterator it = permitted.iterator();
-
- while (it.hasNext())
- {
- String str = ((String)it.next());
-
- if (emailIsConstrained(email, str))
- {
- return;
- }
- }
-
- if (email.length() == 0 && permitted.size() == 0)
- {
- return;
- }
-
- throw new PKIXNameConstraintValidatorException(
- "Subject email address is not from a permitted subtree.");
- }
-
- private void checkExcludedEmail(Set excluded, String email)
- throws PKIXNameConstraintValidatorException
- {
- if (excluded.isEmpty())
- {
- return;
- }
-
- Iterator it = excluded.iterator();
-
- while (it.hasNext())
- {
- String str = (String)it.next();
-
- if (emailIsConstrained(email, str))
- {
- throw new PKIXNameConstraintValidatorException(
- "Email address is from an excluded subtree.");
- }
- }
- }
-
- /**
- * Checks if the IP <code>ip</code> is included in the permitted set
- * <code>permitted</code>.
- *
- * @param permitted A <code>Set</code> of permitted IP addresses with
- * their subnet mask as byte arrays.
- * @param ip The IP address.
- * @throws PKIXNameConstraintValidatorException
- * if the IP is not permitted.
- */
- private void checkPermittedIP(Set permitted, byte[] ip)
- throws PKIXNameConstraintValidatorException
- {
- if (permitted == null)
- {
- return;
- }
-
- Iterator it = permitted.iterator();
-
- while (it.hasNext())
- {
- byte[] ipWithSubnet = (byte[])it.next();
-
- if (isIPConstrained(ip, ipWithSubnet))
- {
- return;
- }
- }
- if (ip.length == 0 && permitted.size() == 0)
- {
- return;
- }
- throw new PKIXNameConstraintValidatorException(
- "IP is not from a permitted subtree.");
- }
-
- /**
- * Checks if the IP <code>ip</code> is included in the excluded set
- * <code>excluded</code>.
- *
- * @param excluded A <code>Set</code> of excluded IP addresses with their
- * subnet mask as byte arrays.
- * @param ip The IP address.
- * @throws PKIXNameConstraintValidatorException
- * if the IP is excluded.
- */
- private void checkExcludedIP(Set excluded, byte[] ip)
- throws PKIXNameConstraintValidatorException
- {
- if (excluded.isEmpty())
- {
- return;
- }
-
- Iterator it = excluded.iterator();
-
- while (it.hasNext())
- {
- byte[] ipWithSubnet = (byte[])it.next();
-
- if (isIPConstrained(ip, ipWithSubnet))
- {
- throw new PKIXNameConstraintValidatorException(
- "IP is from an excluded subtree.");
- }
- }
- }
-
- /**
- * Checks if the IP address <code>ip</code> is constrained by
- * <code>constraint</code>.
- *
- * @param ip The IP address.
- * @param constraint The constraint. This is an IP address concatenated with
- * its subnetmask.
- * @return <code>true</code> if constrained, <code>false</code>
- * otherwise.
- */
- private boolean isIPConstrained(byte ip[], byte[] constraint)
- {
- int ipLength = ip.length;
-
- if (ipLength != (constraint.length / 2))
- {
- return false;
- }
-
- byte[] subnetMask = new byte[ipLength];
- System.arraycopy(constraint, ipLength, subnetMask, 0, ipLength);
-
- byte[] permittedSubnetAddress = new byte[ipLength];
-
- byte[] ipSubnetAddress = new byte[ipLength];
-
- // the resulting IP address by applying the subnet mask
- for (int i = 0; i < ipLength; i++)
- {
- permittedSubnetAddress[i] = (byte)(constraint[i] & subnetMask[i]);
- ipSubnetAddress[i] = (byte)(ip[i] & subnetMask[i]);
- }
-
- return Arrays.areEqual(permittedSubnetAddress, ipSubnetAddress);
- }
-
- private boolean emailIsConstrained(String email, String constraint)
+ public int hashCode()
{
- String sub = email.substring(email.indexOf('@') + 1);
- // a particular mailbox or @domain
- if (constraint.indexOf('@') != -1)
- {
- if (email.equalsIgnoreCase(constraint))
- {
- return true;
- }
- if (sub.equalsIgnoreCase(constraint.substring(1)))
- {
- return true;
- }
- }
- // on particular host
- else if (!(constraint.charAt(0) == '.'))
- {
- if (sub.equalsIgnoreCase(constraint))
- {
- return true;
- }
- }
- // address in sub domain
- else if (withinDomain(sub, constraint))
- {
- return true;
- }
- return false;
+ return validator.hashCode();
}
- private boolean withinDomain(String testDomain, String domain)
+ public boolean equals(Object o)
{
- String tempDomain = domain;
- if (tempDomain.startsWith("."))
- {
- tempDomain = tempDomain.substring(1);
- }
- String[] domainParts = Strings.split(tempDomain, '.');
- String[] testDomainParts = Strings.split(testDomain, '.');
- // must have at least one subdomain
- if (testDomainParts.length <= domainParts.length)
+ if (!(o instanceof PKIXNameConstraintValidator))
{
return false;
}
- int d = testDomainParts.length - domainParts.length;
- for (int i = -1; i < domainParts.length; i++)
- {
- if (i == -1)
- {
- if (testDomainParts[i + d].equals(""))
- {
- return false;
- }
- }
- else if (!domainParts[i].equalsIgnoreCase(testDomainParts[i + d]))
- {
- return false;
- }
- }
- return true;
- }
-
- private void checkPermittedDNS(Set permitted, String dns)
- throws PKIXNameConstraintValidatorException
- {
- if (permitted == null)
- {
- return;
- }
-
- Iterator it = permitted.iterator();
-
- while (it.hasNext())
- {
- String str = ((String)it.next());
-
- // is sub domain
- if (withinDomain(dns, str) || dns.equalsIgnoreCase(str))
- {
- return;
- }
- }
- if (dns.length() == 0 && permitted.size() == 0)
- {
- return;
- }
- throw new PKIXNameConstraintValidatorException(
- "DNS is not from a permitted subtree.");
- }
-
- private void checkExcludedDNS(Set excluded, String dns)
- throws PKIXNameConstraintValidatorException
- {
- if (excluded.isEmpty())
- {
- return;
- }
-
- Iterator it = excluded.iterator();
-
- while (it.hasNext())
- {
- String str = ((String)it.next());
-
- // is sub domain or the same
- if (withinDomain(dns, str) || dns.equalsIgnoreCase(str))
- {
- throw new PKIXNameConstraintValidatorException(
- "DNS is from an excluded subtree.");
- }
- }
- }
-
- /**
- * The common part of <code>email1</code> and <code>email2</code> is
- * added to the union <code>union</code>. If <code>email1</code> and
- * <code>email2</code> have nothing in common they are added both.
- *
- * @param email1 Email address constraint 1.
- * @param email2 Email address constraint 2.
- * @param union The union.
- */
- private void unionEmail(String email1, String email2, Set union)
- {
- // email1 is a particular address
- if (email1.indexOf('@') != -1)
- {
- String _sub = email1.substring(email1.indexOf('@') + 1);
- // both are a particular mailbox
- if (email2.indexOf('@') != -1)
- {
- if (email1.equalsIgnoreCase(email2))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(_sub, email2))
- {
- union.add(email2);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (_sub.equalsIgnoreCase(email2))
- {
- union.add(email2);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- }
- // email1 specifies a domain
- else if (email1.startsWith("."))
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email1.indexOf('@') + 1);
- if (withinDomain(_sub, email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2)
- || email1.equalsIgnoreCase(email2))
- {
- union.add(email2);
- }
- else if (withinDomain(email2, email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- else
- {
- if (withinDomain(email2, email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- }
- // email specifies a host
- else
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email1.indexOf('@') + 1);
- if (_sub.equalsIgnoreCase(email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2))
- {
- union.add(email2);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (email1.equalsIgnoreCase(email2))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- }
- }
-
- private void unionURI(String email1, String email2, Set union)
- {
- // email1 is a particular address
- if (email1.indexOf('@') != -1)
- {
- String _sub = email1.substring(email1.indexOf('@') + 1);
- // both are a particular mailbox
- if (email2.indexOf('@') != -1)
- {
- if (email1.equalsIgnoreCase(email2))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(_sub, email2))
- {
- union.add(email2);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (_sub.equalsIgnoreCase(email2))
- {
- union.add(email2);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- }
- // email1 specifies a domain
- else if (email1.startsWith("."))
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email1.indexOf('@') + 1);
- if (withinDomain(_sub, email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2)
- || email1.equalsIgnoreCase(email2))
- {
- union.add(email2);
- }
- else if (withinDomain(email2, email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- else
- {
- if (withinDomain(email2, email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- }
- // email specifies a host
- else
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email1.indexOf('@') + 1);
- if (_sub.equalsIgnoreCase(email1))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2))
- {
- union.add(email2);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (email1.equalsIgnoreCase(email2))
- {
- union.add(email1);
- }
- else
- {
- union.add(email1);
- union.add(email2);
- }
- }
- }
- }
-
- private Set intersectDNS(Set permitted, Set dnss)
- {
- Set intersect = new HashSet();
- for (Iterator it = dnss.iterator(); it.hasNext();)
- {
- String dns = extractNameAsString(((GeneralSubtree)it.next())
- .getBase());
- if (permitted == null)
- {
- if (dns != null)
- {
- intersect.add(dns);
- }
- }
- else
- {
- Iterator _iter = permitted.iterator();
- while (_iter.hasNext())
- {
- String _permitted = (String)_iter.next();
-
- if (withinDomain(_permitted, dns))
- {
- intersect.add(_permitted);
- }
- else if (withinDomain(dns, _permitted))
- {
- intersect.add(dns);
- }
- }
- }
- }
-
- return intersect;
- }
-
- protected Set unionDNS(Set excluded, String dns)
- {
- if (excluded.isEmpty())
- {
- if (dns == null)
- {
- return excluded;
- }
- excluded.add(dns);
-
- return excluded;
- }
- else
- {
- Set union = new HashSet();
-
- Iterator _iter = excluded.iterator();
- while (_iter.hasNext())
- {
- String _permitted = (String)_iter.next();
-
- if (withinDomain(_permitted, dns))
- {
- union.add(dns);
- }
- else if (withinDomain(dns, _permitted))
- {
- union.add(_permitted);
- }
- else
- {
- union.add(_permitted);
- union.add(dns);
- }
- }
-
- return union;
- }
- }
-
- /**
- * The most restricting part from <code>email1</code> and
- * <code>email2</code> is added to the intersection <code>intersect</code>.
- *
- * @param email1 Email address constraint 1.
- * @param email2 Email address constraint 2.
- * @param intersect The intersection.
- */
- private void intersectEmail(String email1, String email2, Set intersect)
- {
- // email1 is a particular address
- if (email1.indexOf('@') != -1)
- {
- String _sub = email1.substring(email1.indexOf('@') + 1);
- // both are a particular mailbox
- if (email2.indexOf('@') != -1)
- {
- if (email1.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(_sub, email2))
- {
- intersect.add(email1);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (_sub.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- }
- }
- // email specifies a domain
- else if (email1.startsWith("."))
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email1.indexOf('@') + 1);
- if (withinDomain(_sub, email1))
- {
- intersect.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2)
- || email1.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- else if (withinDomain(email2, email1))
- {
- intersect.add(email2);
- }
- }
- else
- {
- if (withinDomain(email2, email1))
- {
- intersect.add(email2);
- }
- }
- }
- // email1 specifies a host
- else
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email2.indexOf('@') + 1);
- if (_sub.equalsIgnoreCase(email1))
- {
- intersect.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2))
- {
- intersect.add(email1);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (email1.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- }
- }
+ PKIXNameConstraintValidator constraintValidator = (PKIXNameConstraintValidator)o;
+ return this.validator.equals(constraintValidator.validator);
}
- private void checkExcludedURI(Set excluded, String uri)
+ public void checkPermittedDN(ASN1Sequence dns)
throws PKIXNameConstraintValidatorException
{
- if (excluded.isEmpty())
+ try
{
- return;
+ this.validator.checkPermittedDN(X500Name.getInstance(dns));
}
-
- Iterator it = excluded.iterator();
-
- while (it.hasNext())
+ catch (NameConstraintValidatorException e)
{
- String str = ((String)it.next());
-
- if (isUriConstrained(uri, str))
- {
- throw new PKIXNameConstraintValidatorException(
- "URI is from an excluded subtree.");
- }
+ throw new PKIXNameConstraintValidatorException(e.getMessage(), e);
}
}
- private Set intersectURI(Set permitted, Set uris)
- {
- Set intersect = new HashSet();
- for (Iterator it = uris.iterator(); it.hasNext();)
- {
- String uri = extractNameAsString(((GeneralSubtree)it.next())
- .getBase());
- if (permitted == null)
- {
- if (uri != null)
- {
- intersect.add(uri);
- }
- }
- else
- {
- Iterator _iter = permitted.iterator();
- while (_iter.hasNext())
- {
- String _permitted = (String)_iter.next();
- intersectURI(_permitted, uri, intersect);
- }
- }
- }
- return intersect;
- }
-
- private Set unionURI(Set excluded, String uri)
- {
- if (excluded.isEmpty())
- {
- if (uri == null)
- {
- return excluded;
- }
- excluded.add(uri);
-
- return excluded;
- }
- else
- {
- Set union = new HashSet();
-
- Iterator _iter = excluded.iterator();
- while (_iter.hasNext())
- {
- String _excluded = (String)_iter.next();
-
- unionURI(_excluded, uri, union);
- }
-
- return union;
- }
- }
-
- private void intersectURI(String email1, String email2, Set intersect)
- {
- // email1 is a particular address
- if (email1.indexOf('@') != -1)
- {
- String _sub = email1.substring(email1.indexOf('@') + 1);
- // both are a particular mailbox
- if (email2.indexOf('@') != -1)
- {
- if (email1.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(_sub, email2))
- {
- intersect.add(email1);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (_sub.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- }
- }
- // email specifies a domain
- else if (email1.startsWith("."))
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email1.indexOf('@') + 1);
- if (withinDomain(_sub, email1))
- {
- intersect.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2)
- || email1.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- else if (withinDomain(email2, email1))
- {
- intersect.add(email2);
- }
- }
- else
- {
- if (withinDomain(email2, email1))
- {
- intersect.add(email2);
- }
- }
- }
- // email1 specifies a host
- else
- {
- if (email2.indexOf('@') != -1)
- {
- String _sub = email2.substring(email2.indexOf('@') + 1);
- if (_sub.equalsIgnoreCase(email1))
- {
- intersect.add(email2);
- }
- }
- // email2 specifies a domain
- else if (email2.startsWith("."))
- {
- if (withinDomain(email1, email2))
- {
- intersect.add(email1);
- }
- }
- // email2 specifies a particular host
- else
- {
- if (email1.equalsIgnoreCase(email2))
- {
- intersect.add(email1);
- }
- }
- }
- }
-
- private void checkPermittedURI(Set permitted, String uri)
+ public void checkExcludedDN(ASN1Sequence dns)
throws PKIXNameConstraintValidatorException
{
- if (permitted == null)
+ try
{
- return;
+ this.validator.checkExcludedDN(X500Name.getInstance(dns));
}
-
- Iterator it = permitted.iterator();
-
- while (it.hasNext())
+ catch (NameConstraintValidatorException e)
{
- String str = ((String)it.next());
-
- if (isUriConstrained(uri, str))
- {
- return;
- }
- }
- if (uri.length() == 0 && permitted.size() == 0)
- {
- return;
- }
- throw new PKIXNameConstraintValidatorException(
- "URI is not from a permitted subtree.");
- }
-
- private boolean isUriConstrained(String uri, String constraint)
- {
- String host = extractHostFromURL(uri);
- // a host
- if (!constraint.startsWith("."))
- {
- if (host.equalsIgnoreCase(constraint))
- {
- return true;
- }
- }
-
- // in sub domain or domain
- else if (withinDomain(host, constraint))
- {
- return true;
- }
-
- return false;
- }
-
- private static String extractHostFromURL(String url)
- {
- // see RFC 1738
- // remove ':' after protocol, e.g. http:
- String sub = url.substring(url.indexOf(':') + 1);
- // extract host from Common Internet Scheme Syntax, e.g. http://
- if (sub.indexOf("//") != -1)
- {
- sub = sub.substring(sub.indexOf("//") + 2);
- }
- // first remove port, e.g. http://test.com:21
- if (sub.lastIndexOf(':') != -1)
- {
- sub = sub.substring(0, sub.lastIndexOf(':'));
- }
- // remove user and password, e.g. http://john:password@test.com
- sub = sub.substring(sub.indexOf(':') + 1);
- sub = sub.substring(sub.indexOf('@') + 1);
- // remove local parts, e.g. http://test.com/bla
- if (sub.indexOf('/') != -1)
- {
- sub = sub.substring(0, sub.indexOf('/'));
+ throw new PKIXNameConstraintValidatorException(e.getMessage(), e);
}
- return sub;
}
/**
@@ -1466,28 +69,13 @@ public class PKIXNameConstraintValidator
public void checkPermitted(GeneralName name)
throws PKIXNameConstraintValidatorException
{
- switch (name.getTagNo())
+ try
{
- case 1:
- checkPermittedEmail(permittedSubtreesEmail,
- extractNameAsString(name));
- break;
- case 2:
- checkPermittedDNS(permittedSubtreesDNS, DERIA5String.getInstance(
- name.getName()).getString());
- break;
- case 4:
- checkPermittedDN(ASN1Sequence.getInstance(name.getName()
- .toASN1Primitive()));
- break;
- case 6:
- checkPermittedURI(permittedSubtreesURI, DERIA5String.getInstance(
- name.getName()).getString());
- break;
- case 7:
- byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets();
-
- checkPermittedIP(permittedSubtreesIP, ip);
+ validator.checkPermitted(name);
+ }
+ catch (NameConstraintValidatorException e)
+ {
+ throw new PKIXNameConstraintValidatorException(e.getMessage(), e);
}
}
@@ -1502,33 +90,19 @@ public class PKIXNameConstraintValidator
public void checkExcluded(GeneralName name)
throws PKIXNameConstraintValidatorException
{
- switch (name.getTagNo())
+ try
{
- case 1:
- checkExcludedEmail(excludedSubtreesEmail, extractNameAsString(name));
- break;
- case 2:
- checkExcludedDNS(excludedSubtreesDNS, DERIA5String.getInstance(
- name.getName()).getString());
- break;
- case 4:
- checkExcludedDN(ASN1Sequence.getInstance(name.getName()
- .toASN1Primitive()));
- break;
- case 6:
- checkExcludedURI(excludedSubtreesURI, DERIA5String.getInstance(
- name.getName()).getString());
- break;
- case 7:
- byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets();
-
- checkExcludedIP(excludedSubtreesIP, ip);
+ validator.checkExcluded(name);
+ }
+ catch (NameConstraintValidatorException e)
+ {
+ throw new PKIXNameConstraintValidatorException(e.getMessage(), e);
}
}
public void intersectPermittedSubtree(GeneralSubtree permitted)
{
- intersectPermittedSubtree(new GeneralSubtree[] { permitted });
+ validator.intersectPermittedSubtree(permitted);
}
/**
@@ -1540,396 +114,26 @@ public class PKIXNameConstraintValidator
public void intersectPermittedSubtree(GeneralSubtree[] permitted)
{
- Map subtreesMap = new HashMap();
-
- // group in sets in a map ordered by tag no.
- for (int i = 0; i != permitted.length; i++)
- {
- GeneralSubtree subtree = permitted[i];
- Integer tagNo = Integers.valueOf(subtree.getBase().getTagNo());
- if (subtreesMap.get(tagNo) == null)
- {
- subtreesMap.put(tagNo, new HashSet());
- }
- ((Set)subtreesMap.get(tagNo)).add(subtree);
- }
-
- for (Iterator it = subtreesMap.entrySet().iterator(); it.hasNext();)
- {
- Map.Entry entry = (Map.Entry)it.next();
-
- // go through all subtree groups
- switch (((Integer)entry.getKey()).intValue())
- {
- case 1:
- permittedSubtreesEmail = intersectEmail(permittedSubtreesEmail,
- (Set)entry.getValue());
- break;
- case 2:
- permittedSubtreesDNS = intersectDNS(permittedSubtreesDNS,
- (Set)entry.getValue());
- break;
- case 4:
- permittedSubtreesDN = intersectDN(permittedSubtreesDN,
- (Set)entry.getValue());
- break;
- case 6:
- permittedSubtreesURI = intersectURI(permittedSubtreesURI,
- (Set)entry.getValue());
- break;
- case 7:
- permittedSubtreesIP = intersectIP(permittedSubtreesIP,
- (Set)entry.getValue());
- }
- }
- }
-
- private String extractNameAsString(GeneralName name)
- {
- return DERIA5String.getInstance(name.getName()).getString();
+ validator.intersectPermittedSubtree(permitted);
}
public void intersectEmptyPermittedSubtree(int nameType)
{
- switch (nameType)
- {
- case 1:
- permittedSubtreesEmail = new HashSet();
- break;
- case 2:
- permittedSubtreesDNS = new HashSet();
- break;
- case 4:
- permittedSubtreesDN = new HashSet();
- break;
- case 6:
- permittedSubtreesURI = new HashSet();
- break;
- case 7:
- permittedSubtreesIP = new HashSet();
- }
+ validator.intersectEmptyPermittedSubtree(nameType);
}
-
- /**
+
+ /**
* Adds a subtree to the excluded set of these name constraints.
*
* @param subtree A subtree with an excluded GeneralName.
*/
public void addExcludedSubtree(GeneralSubtree subtree)
{
- GeneralName base = subtree.getBase();
-
- switch (base.getTagNo())
- {
- case 1:
- excludedSubtreesEmail = unionEmail(excludedSubtreesEmail,
- extractNameAsString(base));
- break;
- case 2:
- excludedSubtreesDNS = unionDNS(excludedSubtreesDNS,
- extractNameAsString(base));
- break;
- case 4:
- excludedSubtreesDN = unionDN(excludedSubtreesDN,
- (ASN1Sequence)base.getName().toASN1Primitive());
- break;
- case 6:
- excludedSubtreesURI = unionURI(excludedSubtreesURI,
- extractNameAsString(base));
- break;
- case 7:
- excludedSubtreesIP = unionIP(excludedSubtreesIP, ASN1OctetString
- .getInstance(base.getName()).getOctets());
- break;
- }
- }
-
- /**
- * Returns the maximum IP address.
- *
- * @param ip1 The first IP address.
- * @param ip2 The second IP address.
- * @return The maximum IP address.
- */
- private static byte[] max(byte[] ip1, byte[] ip2)
- {
- for (int i = 0; i < ip1.length; i++)
- {
- if ((ip1[i] & 0xFFFF) > (ip2[i] & 0xFFFF))
- {
- return ip1;
- }
- }
- return ip2;
- }
-
- /**
- * Returns the minimum IP address.
- *
- * @param ip1 The first IP address.
- * @param ip2 The second IP address.
- * @return The minimum IP address.
- */
- private static byte[] min(byte[] ip1, byte[] ip2)
- {
- for (int i = 0; i < ip1.length; i++)
- {
- if ((ip1[i] & 0xFFFF) < (ip2[i] & 0xFFFF))
- {
- return ip1;
- }
- }
- return ip2;
- }
-
- /**
- * Compares IP address <code>ip1</code> with <code>ip2</code>. If ip1
- * is equal to ip2 0 is returned. If ip1 is bigger 1 is returned, -1
- * otherwise.
- *
- * @param ip1 The first IP address.
- * @param ip2 The second IP address.
- * @return 0 if ip1 is equal to ip2, 1 if ip1 is bigger, -1 otherwise.
- */
- private static int compareTo(byte[] ip1, byte[] ip2)
- {
- if (Arrays.areEqual(ip1, ip2))
- {
- return 0;
- }
- if (Arrays.areEqual(max(ip1, ip2), ip1))
- {
- return 1;
- }
- return -1;
- }
-
- /**
- * Returns the logical OR of the IP addresses <code>ip1</code> and
- * <code>ip2</code>.
- *
- * @param ip1 The first IP address.
- * @param ip2 The second IP address.
- * @return The OR of <code>ip1</code> and <code>ip2</code>.
- */
- private static byte[] or(byte[] ip1, byte[] ip2)
- {
- byte[] temp = new byte[ip1.length];
- for (int i = 0; i < ip1.length; i++)
- {
- temp[i] = (byte)(ip1[i] | ip2[i]);
- }
- return temp;
- }
-
- public int hashCode()
- {
- return hashCollection(excludedSubtreesDN)
- + hashCollection(excludedSubtreesDNS)
- + hashCollection(excludedSubtreesEmail)
- + hashCollection(excludedSubtreesIP)
- + hashCollection(excludedSubtreesURI)
- + hashCollection(permittedSubtreesDN)
- + hashCollection(permittedSubtreesDNS)
- + hashCollection(permittedSubtreesEmail)
- + hashCollection(permittedSubtreesIP)
- + hashCollection(permittedSubtreesURI);
- }
-
- private int hashCollection(Collection coll)
- {
- if (coll == null)
- {
- return 0;
- }
- int hash = 0;
- Iterator it1 = coll.iterator();
- while (it1.hasNext())
- {
- Object o = it1.next();
- if (o instanceof byte[])
- {
- hash += Arrays.hashCode((byte[])o);
- }
- else
- {
- hash += o.hashCode();
- }
- }
- return hash;
- }
-
- public boolean equals(Object o)
- {
- if (!(o instanceof PKIXNameConstraintValidator))
- {
- return false;
- }
- PKIXNameConstraintValidator constraintValidator = (PKIXNameConstraintValidator)o;
- return collectionsAreEqual(constraintValidator.excludedSubtreesDN, excludedSubtreesDN)
- && collectionsAreEqual(constraintValidator.excludedSubtreesDNS, excludedSubtreesDNS)
- && collectionsAreEqual(constraintValidator.excludedSubtreesEmail, excludedSubtreesEmail)
- && collectionsAreEqual(constraintValidator.excludedSubtreesIP, excludedSubtreesIP)
- && collectionsAreEqual(constraintValidator.excludedSubtreesURI, excludedSubtreesURI)
- && collectionsAreEqual(constraintValidator.permittedSubtreesDN, permittedSubtreesDN)
- && collectionsAreEqual(constraintValidator.permittedSubtreesDNS, permittedSubtreesDNS)
- && collectionsAreEqual(constraintValidator.permittedSubtreesEmail, permittedSubtreesEmail)
- && collectionsAreEqual(constraintValidator.permittedSubtreesIP, permittedSubtreesIP)
- && collectionsAreEqual(constraintValidator.permittedSubtreesURI, permittedSubtreesURI);
- }
-
- private boolean collectionsAreEqual(Collection coll1, Collection coll2)
- {
- if (coll1 == coll2)
- {
- return true;
- }
- if (coll1 == null || coll2 == null)
- {
- return false;
- }
- if (coll1.size() != coll2.size())
- {
- return false;
- }
- Iterator it1 = coll1.iterator();
-
- while (it1.hasNext())
- {
- Object a = it1.next();
- Iterator it2 = coll2.iterator();
- boolean found = false;
- while (it2.hasNext())
- {
- Object b = it2.next();
- if (equals(a, b))
- {
- found = true;
- break;
- }
- }
- if (!found)
- {
- return false;
- }
- }
- return true;
- }
-
- private boolean equals(Object o1, Object o2)
- {
- if (o1 == o2)
- {
- return true;
- }
- if (o1 == null || o2 == null)
- {
- return false;
- }
- if (o1 instanceof byte[] && o2 instanceof byte[])
- {
- return Arrays.areEqual((byte[])o1, (byte[])o2);
- }
- else
- {
- return o1.equals(o2);
- }
- }
-
- /**
- * Stringifies an IPv4 or v6 address with subnet mask.
- *
- * @param ip The IP with subnet mask.
- * @return The stringified IP address.
- */
- private String stringifyIP(byte[] ip)
- {
- String temp = "";
- for (int i = 0; i < ip.length / 2; i++)
- {
- temp += Integer.toString(ip[i] & 0x00FF) + ".";
- }
- temp = temp.substring(0, temp.length() - 1);
- temp += "/";
- for (int i = ip.length / 2; i < ip.length; i++)
- {
- temp += Integer.toString(ip[i] & 0x00FF) + ".";
- }
- temp = temp.substring(0, temp.length() - 1);
- return temp;
- }
-
- private String stringifyIPCollection(Set ips)
- {
- String temp = "";
- temp += "[";
- for (Iterator it = ips.iterator(); it.hasNext();)
- {
- temp += stringifyIP((byte[])it.next()) + ",";
- }
- if (temp.length() > 1)
- {
- temp = temp.substring(0, temp.length() - 1);
- }
- temp += "]";
- return temp;
+ validator.addExcludedSubtree(subtree);
}
public String toString()
{
- String temp = "";
- temp += "permitted:\n";
- if (permittedSubtreesDN != null)
- {
- temp += "DN:\n";
- temp += permittedSubtreesDN.toString() + "\n";
- }
- if (permittedSubtreesDNS != null)
- {
- temp += "DNS:\n";
- temp += permittedSubtreesDNS.toString() + "\n";
- }
- if (permittedSubtreesEmail != null)
- {
- temp += "Email:\n";
- temp += permittedSubtreesEmail.toString() + "\n";
- }
- if (permittedSubtreesURI != null)
- {
- temp += "URI:\n";
- temp += permittedSubtreesURI.toString() + "\n";
- }
- if (permittedSubtreesIP != null)
- {
- temp += "IP:\n";
- temp += stringifyIPCollection(permittedSubtreesIP) + "\n";
- }
- temp += "excluded:\n";
- if (!excludedSubtreesDN.isEmpty())
- {
- temp += "DN:\n";
- temp += excludedSubtreesDN.toString() + "\n";
- }
- if (!excludedSubtreesDNS.isEmpty())
- {
- temp += "DNS:\n";
- temp += excludedSubtreesDNS.toString() + "\n";
- }
- if (!excludedSubtreesEmail.isEmpty())
- {
- temp += "Email:\n";
- temp += excludedSubtreesEmail.toString() + "\n";
- }
- if (!excludedSubtreesURI.isEmpty())
- {
- temp += "URI:\n";
- temp += excludedSubtreesURI.toString() + "\n";
- }
- if (!excludedSubtreesIP.isEmpty())
- {
- temp += "IP:\n";
- temp += stringifyIPCollection(excludedSubtreesIP) + "\n";
- }
- return temp;
+ return validator.toString();
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java
index 767767c2..7d6ab92b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java
@@ -7,8 +7,22 @@ package com.android.org.bouncycastle.jce.provider;
public class PKIXNameConstraintValidatorException
extends Exception
{
+ private Throwable cause;
+
public PKIXNameConstraintValidatorException(String msg)
{
super(msg);
}
+
+ public PKIXNameConstraintValidatorException(String msg, Throwable e)
+ {
+ super(msg);
+
+ this.cause = e;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PrincipalUtils.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PrincipalUtils.java
index d4a7e466..246c0955 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PrincipalUtils.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/PrincipalUtils.java
@@ -3,34 +3,20 @@ package com.android.org.bouncycastle.jce.provider;
import java.security.cert.TrustAnchor;
import java.security.cert.X509CRL;
-import java.security.cert.X509CRLEntry;
import java.security.cert.X509Certificate;
import javax.security.auth.x500.X500Principal;
import com.android.org.bouncycastle.asn1.x500.X500Name;
+import com.android.org.bouncycastle.asn1.x500.X500NameStyle;
+// import org.bouncycastle.jcajce.interfaces.BCX509Certificate;
import com.android.org.bouncycastle.x509.X509AttributeCertificate;
class PrincipalUtils
{
- static X500Name getSubjectPrincipal(X509Certificate cert)
- {
- return X500Name.getInstance(cert.getSubjectX500Principal().getEncoded());
- }
-
- static X500Name getIssuerPrincipal(X509CRL crl)
- {
- return X500Name.getInstance(crl.getIssuerX500Principal().getEncoded());
- }
-
- static X500Name getIssuerPrincipal(X509Certificate cert)
- {
- return X500Name.getInstance(cert.getIssuerX500Principal().getEncoded());
- }
-
static X500Name getCA(TrustAnchor trustAnchor)
{
- return X500Name.getInstance(trustAnchor.getCA().getEncoded());
+ return getX500Name(notNull(trustAnchor).getCA());
}
/**
@@ -39,8 +25,7 @@ class PrincipalUtils
* @param cert The attribute certificate or certificate.
* @return The issuer as <code>X500Principal</code>.
*/
- static X500Name getEncodedIssuerPrincipal(
- Object cert)
+ static X500Name getEncodedIssuerPrincipal(Object cert)
{
if (cert instanceof X509Certificate)
{
@@ -48,7 +33,110 @@ class PrincipalUtils
}
else
{
- return X500Name.getInstance(((X500Principal)((X509AttributeCertificate)cert).getIssuer().getPrincipals()[0]).getEncoded());
+ return getX500Name((X500Principal)((X509AttributeCertificate)cert).getIssuer().getPrincipals()[0]);
+ }
+ }
+
+ static X500Name getIssuerPrincipal(X509Certificate certificate)
+ {
+ // BEGIN Android-removed: unsupported
+ /*
+ if (certificate instanceof BCX509Certificate)
+ {
+ return notNull(((BCX509Certificate)certificate).getIssuerX500Name());
+ }
+ */
+ // END Android-removed: unsupported
+ return getX500Name(notNull(certificate).getIssuerX500Principal());
+ }
+
+ static X500Name getIssuerPrincipal(X509CRL crl)
+ {
+ return getX500Name(notNull(crl).getIssuerX500Principal());
+ }
+
+ static X500Name getSubjectPrincipal(X509Certificate certificate)
+ {
+ // BEGIN Android-removed: unsupported
+ /*
+ if (certificate instanceof BCX509Certificate)
+ {
+ return notNull(((BCX509Certificate)certificate).getSubjectX500Name());
+ }
+ */
+ // END Android-removed: unsupported
+ return getX500Name(notNull(certificate).getSubjectX500Principal());
+ }
+
+ static X500Name getX500Name(X500Principal principal)
+ {
+ X500Name name = X500Name.getInstance(getEncoded(principal));
+ return notNull(name);
+ }
+
+ static X500Name getX500Name(X500NameStyle style, X500Principal principal)
+ {
+ X500Name name = X500Name.getInstance(style, getEncoded(principal));
+ return notNull(name);
+ }
+
+ private static byte[] getEncoded(X500Principal principal)
+ {
+ byte[] encoding = notNull(principal).getEncoded();
+ return notNull(encoding);
+ }
+
+ private static byte[] notNull(byte[] encoding)
+ {
+ if (null == encoding)
+ {
+ throw new IllegalStateException();
+ }
+ return encoding;
+ }
+
+ private static TrustAnchor notNull(TrustAnchor trustAnchor)
+ {
+ if (null == trustAnchor)
+ {
+ throw new IllegalStateException();
+ }
+ return trustAnchor;
+ }
+
+ private static X509Certificate notNull(X509Certificate certificate)
+ {
+ if (null == certificate)
+ {
+ throw new IllegalStateException();
+ }
+ return certificate;
+ }
+
+ private static X509CRL notNull(X509CRL crl)
+ {
+ if (null == crl)
+ {
+ throw new IllegalStateException();
+ }
+ return crl;
+ }
+
+ private static X500Name notNull(X500Name name)
+ {
+ if (null == name)
+ {
+ throw new IllegalStateException();
+ }
+ return name;
+ }
+
+ private static X500Principal notNull(X500Principal principal)
+ {
+ if (null == principal)
+ {
+ throw new IllegalStateException();
}
+ return principal;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/ProvCrlRevocationChecker.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/ProvCrlRevocationChecker.java
new file mode 100644
index 00000000..04c83b11
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/ProvCrlRevocationChecker.java
@@ -0,0 +1,68 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jce.provider;
+
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+import com.android.org.bouncycastle.jcajce.PKIXCertRevocationChecker;
+import com.android.org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
+import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
+
+class ProvCrlRevocationChecker
+ implements PKIXCertRevocationChecker
+{
+ private final JcaJceHelper helper;
+
+ private PKIXCertRevocationCheckerParameters params;
+ private Date currentDate = null;
+
+ public ProvCrlRevocationChecker(JcaJceHelper helper)
+ {
+ this.helper = helper;
+ }
+
+ public void setParameter(String name, Object value)
+ {
+
+ }
+
+ public void initialize(PKIXCertRevocationCheckerParameters params)
+ {
+ this.params = params;
+ this.currentDate = new Date();
+ }
+
+ public void init(boolean forForward)
+ throws CertPathValidatorException
+ {
+ if (forForward)
+ {
+ throw new CertPathValidatorException("forward checking not supported");
+ }
+
+ this.params = null;
+ this.currentDate = new Date();
+ }
+
+ public void check(Certificate certificate)
+ throws CertPathValidatorException
+ {
+ try
+ {
+ RFC3280CertPathUtilities.checkCRLs(params, params.getParamsPKIX(), currentDate, params.getValidDate(),
+ (X509Certificate)certificate, params.getSigningCert(), params.getWorkingPublicKey(),
+ params.getCertPath().getCertificates(), helper);
+ }
+ catch (AnnotatedException e)
+ {
+ Throwable cause = e;
+ if (null != e.getCause())
+ {
+ cause = e.getCause();
+ }
+ throw new CertPathValidatorException(e.getMessage(), cause, params.getCertPath(), params.getIndex());
+ }
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
index 8256c6da..6df4ad1c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
@@ -7,23 +7,23 @@ import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.security.cert.CertPath;
import java.security.cert.CertPathBuilderException;
+import java.security.cert.CertPathBuilderSpi;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.PKIXCertPathChecker;
import java.security.cert.X509CRL;
-import java.security.cert.X509CRLSelector;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.security.cert.X509Extension;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -31,7 +31,6 @@ import java.util.TimeZone;
import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
-import com.android.org.bouncycastle.asn1.ASN1InputStream;
import com.android.org.bouncycastle.asn1.ASN1Integer;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
@@ -55,17 +54,19 @@ import com.android.org.bouncycastle.asn1.x509.IssuingDistributionPoint;
import com.android.org.bouncycastle.asn1.x509.NameConstraints;
import com.android.org.bouncycastle.asn1.x509.PolicyInformation;
import com.android.org.bouncycastle.jcajce.PKIXCRLStore;
-import com.android.org.bouncycastle.jcajce.PKIXCRLStoreSelector;
+import com.android.org.bouncycastle.jcajce.PKIXCertRevocationChecker;
+import com.android.org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
import com.android.org.bouncycastle.jcajce.PKIXCertStoreSelector;
import com.android.org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
import com.android.org.bouncycastle.jcajce.PKIXExtendedParameters;
+import com.android.org.bouncycastle.jcajce.provider.symmetric.util.ClassUtil;
import com.android.org.bouncycastle.jcajce.util.JcaJceHelper;
import com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException;
import com.android.org.bouncycastle.util.Arrays;
class RFC3280CertPathUtilities
{
- private static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil();
+ private static final Class revChkClass = ClassUtil.loadClass(RFC3280CertPathUtilities.class, "java.security.cert.PKIXRevocationChecker");
/**
* If the complete CRL includes an issuing distribution point (IDP) CRL
@@ -172,8 +173,7 @@ class RFC3280CertPathUtilities
genNames = new GeneralName[1];
try
{
- genNames[0] = new GeneralName(X500Name.getInstance(PrincipalUtils
- .getEncodedIssuerPrincipal(cert).getEncoded()));
+ genNames[0] = new GeneralName(PrincipalUtils.getEncodedIssuerPrincipal(cert));
}
catch (Exception e)
{
@@ -471,11 +471,11 @@ class RFC3280CertPathUtilities
PKIXCertStoreSelector selector = new PKIXCertStoreSelector.Builder(certSelector).build();
// get CRL signing certs
- Collection coll;
+ LinkedHashSet coll = new LinkedHashSet();
try
{
- coll = CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getCertificateStores());
- coll.addAll(CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getCertStores()));
+ CertPathValidatorUtilities.findCertificates(coll, selector, paramsPKIX.getCertificateStores());
+ CertPathValidatorUtilities.findCertificates(coll, selector, paramsPKIX.getCertStores());
}
catch (AnnotatedException e)
{
@@ -505,7 +505,11 @@ class RFC3280CertPathUtilities
}
try
{
- PKIXCertPathBuilderSpi builder = new PKIXCertPathBuilderSpi();
+ // BEGIN Android-changed:
+ // CertPathBuilderSpi builder = (revChkClass != null)
+ // ? new PKIXCertPathBuilderSpi_8(true) : new PKIXCertPathBuilderSpi(true);
+ // END Android-changed:
+ CertPathBuilderSpi builder = new PKIXCertPathBuilderSpi(true);
X509CertSelector tmpCertSelector = new X509CertSelector();
tmpCertSelector.setCertificate(signingCert);
@@ -556,9 +560,9 @@ class RFC3280CertPathUtilities
for (int i = 0; i < validCerts.size(); i++)
{
X509Certificate signCert = (X509Certificate)validCerts.get(i);
- boolean[] keyusage = signCert.getKeyUsage();
+ boolean[] keyUsage = signCert.getKeyUsage();
- if (keyusage != null && (keyusage.length < 7 || !keyusage[CRL_SIGN]))
+ if (keyUsage != null && (keyUsage.length <= CRL_SIGN || !keyUsage[CRL_SIGN]))
{
lastException = new AnnotatedException(
"Issuer certificate key usage extension does not permit CRL signing.");
@@ -631,119 +635,6 @@ class RFC3280CertPathUtilities
return null;
}
- protected static Set processCRLA1i(
- Date currentDate,
- PKIXExtendedParameters paramsPKIX,
- X509Certificate cert,
- X509CRL crl)
- throws AnnotatedException
- {
- Set set = new HashSet();
- if (paramsPKIX.isUseDeltasEnabled())
- {
- CRLDistPoint freshestCRL = null;
- try
- {
- freshestCRL = CRLDistPoint
- .getInstance(CertPathValidatorUtilities.getExtensionValue(cert, FRESHEST_CRL));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Freshest CRL extension could not be decoded from certificate.", e);
- }
- if (freshestCRL == null)
- {
- try
- {
- freshestCRL = CRLDistPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl,
- FRESHEST_CRL));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Freshest CRL extension could not be decoded from CRL.", e);
- }
- }
- if (freshestCRL != null)
- {
- List crlStores = new ArrayList();
-
- crlStores.addAll(paramsPKIX.getCRLStores());
-
- try
- {
- crlStores.addAll(CertPathValidatorUtilities.getAdditionalStoresFromCRLDistributionPoint(freshestCRL, paramsPKIX.getNamedCRLStoreMap()));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException(
- "No new delta CRL locations could be added from Freshest CRL extension.", e);
- }
-
- // get delta CRL(s)
- try
- {
- set.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, crl, paramsPKIX.getCertStores(), crlStores));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Exception obtaining delta CRLs.", e);
- }
- }
- }
- return set;
- }
-
- protected static Set[] processCRLA1ii(
- Date currentDate,
- PKIXExtendedParameters paramsPKIX,
- X509Certificate cert,
- X509CRL crl)
- throws AnnotatedException
- {
- Set deltaSet = new HashSet();
- X509CRLSelector crlselect = new X509CRLSelector();
- crlselect.setCertificateChecking(cert);
-
- try
- {
- crlselect.addIssuerName(PrincipalUtils.getIssuerPrincipal(crl).getEncoded());
- }
- catch (IOException e)
- {
- throw new AnnotatedException("Cannot extract issuer from CRL." + e, e);
- }
-
- PKIXCRLStoreSelector extSelect = new PKIXCRLStoreSelector.Builder(crlselect).setCompleteCRLEnabled(true).build();
-
- Date validityDate = currentDate;
-
- if (paramsPKIX.getDate() != null)
- {
- validityDate = paramsPKIX.getDate();
- }
-
- Set completeSet = CRL_UTIL.findCRLs(extSelect, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores());
-
- if (paramsPKIX.isUseDeltasEnabled())
- {
- // get delta CRL(s)
- try
- {
- deltaSet.addAll(CertPathValidatorUtilities.getDeltaCRLs(validityDate, crl, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores()));
- }
- catch (AnnotatedException e)
- {
- throw new AnnotatedException("Exception obtaining delta CRLs.", e);
- }
- }
- return new Set[]
- {
- completeSet,
- deltaSet};
- }
-
-
-
/**
* If use-deltas is set, verify the issuer and scope of the delta CRL.
*
@@ -762,6 +653,12 @@ class RFC3280CertPathUtilities
{
return;
}
+
+ if (deltaCRL.hasUnsupportedCriticalExtension())
+ {
+ throw new AnnotatedException("delta CRL has unsupported critical extensions");
+ }
+
IssuingDistributionPoint completeidp = null;
try
{
@@ -903,7 +800,7 @@ class RFC3280CertPathUtilities
ASN1Sequence pm = null;
try
{
- pm = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ pm = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.POLICY_MAPPINGS));
}
catch (AnnotatedException ex)
@@ -1086,7 +983,7 @@ class RFC3280CertPathUtilities
ASN1Sequence pm = null;
try
{
- pm = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ pm = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.POLICY_MAPPINGS));
}
catch (AnnotatedException ex)
@@ -1104,7 +1001,7 @@ class RFC3280CertPathUtilities
ASN1ObjectIdentifier subjectDomainPolicy = null;
try
{
- ASN1Sequence mapping = DERSequence.getInstance(mappings.getObjectAt(j));
+ ASN1Sequence mapping = ASN1Sequence.getInstance(mappings.getObjectAt(j));
issuerDomainPolicy = ASN1ObjectIdentifier.getInstance(mapping.getObjectAt(0));
subjectDomainPolicy = ASN1ObjectIdentifier.getInstance(mapping.getObjectAt(1));
@@ -1124,7 +1021,7 @@ class RFC3280CertPathUtilities
if (RFC3280CertPathUtilities.ANY_POLICY.equals(subjectDomainPolicy.getId()))
{
- throw new CertPathValidatorException("SubjectDomainPolicy is anyPolicy,", null, certPath, index);
+ throw new CertPathValidatorException("SubjectDomainPolicy is anyPolicy", null, certPath, index);
}
}
}
@@ -1161,7 +1058,7 @@ class RFC3280CertPathUtilities
ASN1Sequence certPolicies = null;
try
{
- certPolicies = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ certPolicies = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.CERTIFICATE_POLICIES));
}
catch (AnnotatedException e)
@@ -1179,7 +1076,8 @@ class RFC3280CertPathUtilities
protected static void processCertBC(
CertPath certPath,
int index,
- PKIXNameConstraintValidator nameConstraintValidator)
+ PKIXNameConstraintValidator nameConstraintValidator,
+ boolean isForCRLCheck)
throws CertPathValidatorException
{
List certs = certPath.getCertificates();
@@ -1190,14 +1088,19 @@ class RFC3280CertPathUtilities
//
// (b), (c) permitted and excluded subtree checking.
//
- if (!(CertPathValidatorUtilities.isSelfIssued(cert) && (i < n)))
+ // 4.2.1.10 Name constraints are not applied to self-issued certificates (unless
+ // the certificate is the final certificate in the path)
+ // as we use the validator for path CRL checking, we need to flag when the
+ // certificate is self issued, but not really the last one in the path we are actually
+ // checking.
+ if (!(CertPathValidatorUtilities.isSelfIssued(cert) && ((i < n) || isForCRLCheck)))
{
X500Name principal = PrincipalUtils.getSubjectPrincipal(cert);
ASN1Sequence dns;
try
{
- dns = DERSequence.getInstance(principal.getEncoded());
+ dns = ASN1Sequence.getInstance(principal);
}
catch (Exception e)
{
@@ -1280,7 +1183,8 @@ class RFC3280CertPathUtilities
Set acceptablePolicies,
PKIXPolicyNode validPolicyTree,
List[] policyNodes,
- int inhibitAnyPolicy)
+ int inhibitAnyPolicy,
+ boolean isForCRLCheck)
throws CertPathValidatorException
{
List certs = certPath.getCertificates();
@@ -1295,7 +1199,7 @@ class RFC3280CertPathUtilities
ASN1Sequence certPolicies = null;
try
{
- certPolicies = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ certPolicies = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.CERTIFICATE_POLICIES));
}
catch (AnnotatedException e)
@@ -1366,7 +1270,7 @@ class RFC3280CertPathUtilities
//
// (d) (2)
//
- if ((inhibitAnyPolicy > 0) || ((i < n) && CertPathValidatorUtilities.isSelfIssued(cert)))
+ if ((inhibitAnyPolicy > 0) || ((i < n || isForCRLCheck) && CertPathValidatorUtilities.isSelfIssued(cert)))
{
e = certPolicies.getObjects();
@@ -1479,13 +1383,14 @@ class RFC3280CertPathUtilities
protected static void processCertA(
CertPath certPath,
PKIXExtendedParameters paramsPKIX,
+ Date validityDate,
+ PKIXCertRevocationChecker revocationChecker,
int index,
PublicKey workingPublicKey,
boolean verificationAlreadyPerformed,
X500Name workingIssuerName,
- X509Certificate sign,
- JcaJceHelper helper)
- throws ExtCertPathValidatorException
+ X509Certificate sign)
+ throws CertPathValidatorException
{
List certs = certPath.getCertificates();
X509Certificate cert = (X509Certificate)certs.get(index);
@@ -1507,12 +1412,22 @@ class RFC3280CertPathUtilities
}
}
+ final Date validCertDate;
try
{
- // (a) (2)
- //
- cert.checkValidity(CertPathValidatorUtilities
- .getValidCertDateFromValidityModel(paramsPKIX, certPath, index));
+ validCertDate = CertPathValidatorUtilities.getValidCertDateFromValidityModel(validityDate,
+ paramsPKIX.getValidityModel(), certPath, index);
+ }
+ catch (AnnotatedException e)
+ {
+ throw new ExtCertPathValidatorException("Could not validate time of certificate.", e, certPath, index);
+ }
+
+ // (a) (2)
+ //
+ try
+ {
+ cert.checkValidity(validCertDate);
}
catch (CertificateExpiredException e)
{
@@ -1522,40 +1437,26 @@ class RFC3280CertPathUtilities
{
throw new ExtCertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index);
}
- catch (AnnotatedException e)
- {
- throw new ExtCertPathValidatorException("Could not validate time of certificate.", e, certPath, index);
- }
//
// (a) (3)
//
- if (paramsPKIX.isRevocationEnabled())
+ if (revocationChecker != null)
{
- try
- {
- checkCRLs(paramsPKIX, cert, CertPathValidatorUtilities.getValidCertDateFromValidityModel(paramsPKIX,
- certPath, index), sign, workingPublicKey, certs, helper);
- }
- catch (AnnotatedException e)
- {
- Throwable cause = e;
- if (null != e.getCause())
- {
- cause = e.getCause();
- }
- throw new ExtCertPathValidatorException(e.getMessage(), cause, certPath, index);
- }
+ revocationChecker.initialize(new PKIXCertRevocationCheckerParameters(paramsPKIX, validCertDate, certPath,
+ index, sign, workingPublicKey));
+
+ revocationChecker.check(cert);
}
//
// (a) (4) name chaining
//
- if (!PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(workingIssuerName))
+ X500Name issuer = PrincipalUtils.getIssuerPrincipal(cert);
+ if (!issuer.equals(workingIssuerName))
{
- throw new ExtCertPathValidatorException("IssuerName(" + PrincipalUtils.getEncodedIssuerPrincipal(cert)
- + ") does not match SubjectName(" + workingIssuerName + ") of signing certificate.", null,
- certPath, index);
+ throw new ExtCertPathValidatorException("IssuerName(" + issuer + ") does not match SubjectName("
+ + workingIssuerName + ") of signing certificate.", null, certPath, index);
}
}
@@ -1573,7 +1474,7 @@ class RFC3280CertPathUtilities
ASN1Sequence pc = null;
try
{
- pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ pc = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
}
catch (Exception e)
@@ -1592,11 +1493,10 @@ class RFC3280CertPathUtilities
{
try
{
-
ASN1TaggedObject constraint = ASN1TaggedObject.getInstance(policyConstraints.nextElement());
if (constraint.getTagNo() == 0)
{
- tmpInt = ASN1Integer.getInstance(constraint, false).getValue().intValue();
+ tmpInt = ASN1Integer.getInstance(constraint, false).intValueExact();
if (tmpInt < explicitPolicy)
{
return tmpInt;
@@ -1628,7 +1528,7 @@ class RFC3280CertPathUtilities
ASN1Sequence pc = null;
try
{
- pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ pc = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
}
catch (Exception e)
@@ -1650,7 +1550,7 @@ class RFC3280CertPathUtilities
ASN1TaggedObject constraint = ASN1TaggedObject.getInstance(policyConstraints.nextElement());
if (constraint.getTagNo() == 1)
{
- tmpInt = ASN1Integer.getInstance(constraint, false).getValue().intValue();
+ tmpInt = ASN1Integer.getInstance(constraint, false).intValueExact();
if (tmpInt < policyMapping)
{
return tmpInt;
@@ -1682,7 +1582,7 @@ class RFC3280CertPathUtilities
NameConstraints nc = null;
try
{
- ASN1Sequence ncSeq = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ ASN1Sequence ncSeq = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.NAME_CONSTRAINTS));
if (ncSeq != null)
{
@@ -1735,38 +1635,52 @@ class RFC3280CertPathUtilities
}
/**
- * Checks a distribution point for revocation information for the
- * certificate <code>cert</code>.
+ * Checks a distribution point for revocation information for the certificate <code>cert</code>.
*
- * @param dp The distribution point to consider.
- * @param paramsPKIX PKIX parameters.
- * @param cert Certificate to check if it is revoked.
- * @param validDate The date when the certificate revocation status should be
- * checked.
- * @param defaultCRLSignCert The issuer certificate of the certificate <code>cert</code>.
- * @param defaultCRLSignKey The public key of the issuer certificate
- * <code>defaultCRLSignCert</code>.
- * @param certStatus The current certificate revocation status.
- * @param reasonMask The reasons mask which is already checked.
- * @param certPathCerts The certificates of the certification path.
- * @throws AnnotatedException if the certificate is revoked or the status cannot be checked
- * or some error occurs.
+ * @param dp
+ * The distribution point to consider.
+ * @param paramsPKIX
+ * PKIX parameters.
+ * @param currentDate
+ * The date at which this check is being run.
+ * @param validityDate
+ * The date when the certificate revocation status should be checked.
+ * @param cert
+ * Certificate to check if it is revoked.
+ * @param defaultCRLSignCert
+ * The issuer certificate of the certificate <code>cert</code>.
+ * @param defaultCRLSignKey
+ * The public key of the issuer certificate <code>defaultCRLSignCert</code>.
+ * @param certStatus
+ * The current certificate revocation status.
+ * @param reasonMask
+ * The reasons mask which is already checked.
+ * @param certPathCerts
+ * The certificates of the certification path.
+ * @throws AnnotatedException
+ * if the certificate is revoked or the status cannot be checked or some error
+ * occurs.
*/
private static void checkCRL(
+ PKIXCertRevocationCheckerParameters params,
DistributionPoint dp,
PKIXExtendedParameters paramsPKIX,
+ Date currentDate,
+ Date validityDate,
X509Certificate cert,
- Date validDate,
X509Certificate defaultCRLSignCert,
PublicKey defaultCRLSignKey,
CertStatus certStatus,
ReasonsMask reasonMask,
List certPathCerts,
JcaJceHelper helper)
- throws AnnotatedException
+ throws AnnotatedException, RecoverableCertPathValidatorException
{
- Date currentDate = new Date(System.currentTimeMillis());
- if (validDate.getTime() > currentDate.getTime())
+ if (currentDate == null)
+ {
+ boolean debug = true;
+ }
+ if (validityDate.getTime() > currentDate.getTime())
{
throw new AnnotatedException("Validation time is in future.");
}
@@ -1779,7 +1693,7 @@ class RFC3280CertPathUtilities
* getAdditionalStore()
*/
- Set crls = CertPathValidatorUtilities.getCompleteCRLs(dp, cert, currentDate, paramsPKIX);
+ Set crls = CertPathValidatorUtilities.getCompleteCRLs(params, dp, cert, paramsPKIX, validityDate);
boolean validCrlFound = false;
AnnotatedException lastException = null;
Iterator crl_iter = crls.iterator();
@@ -1812,17 +1726,10 @@ class RFC3280CertPathUtilities
X509CRL deltaCRL = null;
- Date validityDate = currentDate;
-
- if (paramsPKIX.getDate() != null)
- {
- validityDate = paramsPKIX.getDate();
- }
-
if (paramsPKIX.isUseDeltasEnabled())
{
// get delta CRLs
- Set deltaCRLs = CertPathValidatorUtilities.getDeltaCRLs(validityDate, crl, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores());
+ Set deltaCRLs = CertPathValidatorUtilities.getDeltaCRLs(validityDate, crl, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores(), helper);
// we only want one valid delta CRL
// (h)
deltaCRL = RFC3280CertPathUtilities.processCRLH(deltaCRLs, key);
@@ -1853,7 +1760,7 @@ class RFC3280CertPathUtilities
throw new AnnotatedException("No valid CRL for current time found.");
}
}
-
+
RFC3280CertPathUtilities.processCRLB1(dp, cert, crl);
// (b) (2)
@@ -1863,10 +1770,10 @@ class RFC3280CertPathUtilities
RFC3280CertPathUtilities.processCRLC(deltaCRL, crl, paramsPKIX);
// (i)
- RFC3280CertPathUtilities.processCRLI(validDate, deltaCRL, cert, certStatus, paramsPKIX);
+ RFC3280CertPathUtilities.processCRLI(validityDate, deltaCRL, cert, certStatus, paramsPKIX);
// (j)
- RFC3280CertPathUtilities.processCRLJ(validDate, crl, cert, certStatus);
+ RFC3280CertPathUtilities.processCRLJ(validityDate, crl, cert, certStatus);
// (k)
if (certStatus.getCertStatus() == CRLReason.removeFromCRL)
@@ -1921,25 +1828,35 @@ class RFC3280CertPathUtilities
/**
* Checks a certificate if it is revoked.
*
- * @param paramsPKIX PKIX parameters.
- * @param cert Certificate to check if it is revoked.
- * @param validDate The date when the certificate revocation status should be
- * checked.
- * @param sign The issuer certificate of the certificate <code>cert</code>.
- * @param workingPublicKey The public key of the issuer certificate <code>sign</code>.
- * @param certPathCerts The certificates of the certification path.
- * @throws AnnotatedException if the certificate is revoked or the status cannot be checked
- * or some error occurs.
+ * @param paramsPKIX
+ * PKIX parameters.
+ * @param currentDate
+ * The date at which this check is being run.
+ * @param validityDate
+ * The date when the certificate revocation status should be checked.
+ * @param cert
+ * Certificate to check if it is revoked.
+ * @param sign
+ * The issuer certificate of the certificate <code>cert</code>.
+ * @param workingPublicKey
+ * The public key of the issuer certificate <code>sign</code>.
+ * @param certPathCerts
+ * The certificates of the certification path.
+ * @throws AnnotatedException
+ * if the certificate is revoked or the status cannot be checked or some error
+ * occurs.
*/
protected static void checkCRLs(
+ PKIXCertRevocationCheckerParameters params,
PKIXExtendedParameters paramsPKIX,
+ Date currentDate,
+ Date validityDate,
X509Certificate cert,
- Date validDate,
X509Certificate sign,
PublicKey workingPublicKey,
List certPathCerts,
JcaJceHelper helper)
- throws AnnotatedException
+ throws AnnotatedException, RecoverableCertPathValidatorException
{
AnnotatedException lastException = null;
CRLDistPoint crldp = null;
@@ -1956,7 +1873,8 @@ class RFC3280CertPathUtilities
PKIXExtendedParameters.Builder paramsBldr = new PKIXExtendedParameters.Builder(paramsPKIX);
try
{
- List extras = CertPathValidatorUtilities.getAdditionalStoresFromCRLDistributionPoint(crldp, paramsPKIX.getNamedCRLStoreMap());
+ List extras = CertPathValidatorUtilities.getAdditionalStoresFromCRLDistributionPoint(crldp,
+ paramsPKIX.getNamedCRLStoreMap(), validityDate, helper);
for (Iterator it = extras.iterator(); it.hasNext();)
{
paramsBldr.addCRLStore((PKIXCRLStore)it.next());
@@ -1990,7 +1908,8 @@ class RFC3280CertPathUtilities
{
try
{
- checkCRL(dps[i], finalParams, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts, helper);
+ checkCRL(params, dps[i], finalParams, currentDate, validityDate, cert, sign, workingPublicKey,
+ certStatus, reasonsMask, certPathCerts, helper);
validCrlFound = true;
}
catch (AnnotatedException e)
@@ -2016,21 +1935,20 @@ class RFC3280CertPathUtilities
* omitted and a distribution point name of the certificate
* issuer.
*/
- ASN1Primitive issuer = null;
+ X500Name issuer;
try
{
- issuer = new ASN1InputStream(PrincipalUtils.getEncodedIssuerPrincipal(cert).getEncoded())
- .readObject();
+ issuer = PrincipalUtils.getIssuerPrincipal(cert);
}
- catch (Exception e)
+ catch (RuntimeException e)
{
throw new AnnotatedException("Issuer from certificate for CRL could not be reencoded.", e);
}
DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames(
new GeneralName(GeneralName.directoryName, issuer))), null, null);
PKIXExtendedParameters paramsPKIXClone = (PKIXExtendedParameters)paramsPKIX.clone();
- checkCRL(dp, paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask,
- certPathCerts, helper);
+ checkCRL(params, dp, paramsPKIXClone, currentDate, validityDate, cert, sign, workingPublicKey,
+ certStatus, reasonsMask, certPathCerts, helper);
validCrlFound = true;
}
catch (AnnotatedException e)
@@ -2091,7 +2009,7 @@ class RFC3280CertPathUtilities
if (iap != null)
{
- int _inhibitAnyPolicy = iap.getValue().intValue();
+ int _inhibitAnyPolicy = iap.intValueExact();
if (_inhibitAnyPolicy < inhibitAnyPolicy)
{
@@ -2126,12 +2044,12 @@ class RFC3280CertPathUtilities
{
if (!(bc.isCA()))
{
- throw new CertPathValidatorException("Not a CA certificate");
+ throw new CertPathValidatorException("Not a CA certificate", null, certPath, index);
}
}
else
{
- throw new CertPathValidatorException("Intermediate certificate lacks BasicConstraints");
+ throw new CertPathValidatorException("Intermediate certificate lacks BasicConstraints", null, certPath, index);
}
}
@@ -2209,9 +2127,9 @@ class RFC3280CertPathUtilities
//
// (n)
//
- boolean[] _usage = cert.getKeyUsage();
+ boolean[] keyUsage = cert.getKeyUsage();
- if ((_usage != null) && !_usage[RFC3280CertPathUtilities.KEY_CERT_SIGN])
+ if (keyUsage != null && (keyUsage.length <= KEY_CERT_SIGN || !keyUsage[KEY_CERT_SIGN]))
{
throw new ExtCertPathValidatorException(
"Issuer certificate keyusage extension is critical and does not permit key signing.", null,
@@ -2364,7 +2282,7 @@ class RFC3280CertPathUtilities
ASN1Sequence pc = null;
try
{
- pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ pc = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
}
catch (AnnotatedException e)
@@ -2383,7 +2301,7 @@ class RFC3280CertPathUtilities
case 0:
try
{
- tmpInt = ASN1Integer.getInstance(constraint, false).getValue().intValue();
+ tmpInt = ASN1Integer.getInstance(constraint, false).intValueExact();
}
catch (Exception e)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/RecoverableCertPathValidatorException.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/RecoverableCertPathValidatorException.java
new file mode 100644
index 00000000..f6173de4
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/RecoverableCertPathValidatorException.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jce.provider;
+
+import java.security.cert.CertPath;
+import java.security.cert.CertPathValidatorException;
+
+class RecoverableCertPathValidatorException
+ extends CertPathValidatorException
+{
+ public RecoverableCertPathValidatorException(String msg, Throwable cause, CertPath certPath, int index)
+ {
+ super(msg, cause, certPath, index);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/WrappedRevocationChecker.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/WrappedRevocationChecker.java
new file mode 100644
index 00000000..ac4898b0
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/WrappedRevocationChecker.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.jce.provider;
+
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.Certificate;
+import java.security.cert.PKIXCertPathChecker;
+
+import com.android.org.bouncycastle.jcajce.PKIXCertRevocationChecker;
+import com.android.org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
+
+class WrappedRevocationChecker
+ implements PKIXCertRevocationChecker
+{
+ private final PKIXCertPathChecker checker;
+
+ public WrappedRevocationChecker(PKIXCertPathChecker checker)
+ {
+ this.checker = checker;
+ }
+
+ public void setParameter(String name, Object value)
+ {
+ // ignore.
+ }
+
+ public void initialize(PKIXCertRevocationCheckerParameters params)
+ throws CertPathValidatorException
+ {
+ checker.init(false);
+ }
+
+ public void check(Certificate cert)
+ throws CertPathValidatorException
+ {
+ checker.check(cert);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CRLObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CRLObject.java
index 20e24477..d4b2e990 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CRLObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CRLObject.java
@@ -348,7 +348,7 @@ public class X509CRLObject
{
TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement();
- if (serialNumber.equals(entry.getUserCertificate().getValue()))
+ if (entry.getUserCertificate().hasValue(serialNumber))
{
return new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer);
}
@@ -585,7 +585,7 @@ public class X509CRLObject
}
}
- if (entry.getUserCertificate().getValue().equals(serial))
+ if (entry.getUserCertificate().hasValue(serial))
{
X500Name issuer;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CertificateObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CertificateObject.java
index 89cb96c1..ad690b62 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CertificateObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/X509CertificateObject.java
@@ -1,7 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.org.bouncycastle.jce.provider;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.net.InetAddress;
@@ -38,7 +37,6 @@ import com.android.org.bouncycastle.asn1.ASN1Encodable;
import com.android.org.bouncycastle.asn1.ASN1Encoding;
import com.android.org.bouncycastle.asn1.ASN1InputStream;
import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import com.android.org.bouncycastle.asn1.ASN1OutputStream;
import com.android.org.bouncycastle.asn1.ASN1Primitive;
import com.android.org.bouncycastle.asn1.ASN1Sequence;
import com.android.org.bouncycastle.asn1.ASN1String;
@@ -74,7 +72,6 @@ import com.android.org.bouncycastle.util.encoders.Hex;
* @deprecated Do not use this class directly - either use org.bouncycastle.cert (bcpkix) or CertificateFactory.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class X509CertificateObject
extends X509Certificate
implements PKCS12BagAttributeCarrier
@@ -88,7 +85,6 @@ public class X509CertificateObject
private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl();
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public X509CertificateObject(
com.android.org.bouncycastle.asn1.x509.Certificate c)
throws CertificateParsingException
@@ -170,26 +166,14 @@ public class X509CertificateObject
public Principal getIssuerDN()
{
- try
- {
- return new X509Principal(X500Name.getInstance(c.getIssuer().getEncoded()));
- }
- catch (IOException e)
- {
- return null;
- }
+ return new X509Principal(c.getIssuer());
}
public X500Principal getIssuerX500Principal()
{
try
{
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
- aOut.writeObject(c.getIssuer());
-
- return new X500Principal(bOut.toByteArray());
+ return new X500Principal(c.getIssuer().getEncoded());
}
catch (IOException e)
{
@@ -199,19 +183,14 @@ public class X509CertificateObject
public Principal getSubjectDN()
{
- return new X509Principal(X500Name.getInstance(c.getSubject().toASN1Primitive()));
+ return new X509Principal(c.getSubject());
}
public X500Principal getSubjectX500Principal()
{
try
{
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
- aOut.writeObject(c.getSubject());
-
- return new X500Principal(bOut.toByteArray());
+ return new X500Principal(c.getSubject().getEncoded());
}
catch (IOException e)
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/AbstractECLookupTable.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/AbstractECLookupTable.java
new file mode 100644
index 00000000..4288f6a8
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/AbstractECLookupTable.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.math.ec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class AbstractECLookupTable
+ implements ECLookupTable
+{
+ public ECPoint lookupVar(int index)
+ {
+ return lookup(index);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECAlgorithms.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECAlgorithms.java
index c04cf502..563e1883 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECAlgorithms.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECAlgorithms.java
@@ -4,9 +4,11 @@ package com.android.org.bouncycastle.math.ec;
import java.math.BigInteger;
import com.android.org.bouncycastle.math.ec.endo.ECEndomorphism;
+import com.android.org.bouncycastle.math.ec.endo.EndoUtil;
import com.android.org.bouncycastle.math.ec.endo.GLVEndomorphism;
import com.android.org.bouncycastle.math.field.FiniteField;
import com.android.org.bouncycastle.math.field.PolynomialExtensionField;
+import com.android.org.bouncycastle.math.raw.Nat;
/**
* @hide This class is not part of the Android public SDK API
@@ -179,8 +181,9 @@ public class ECAlgorithms
}
/**
- * Simple shift-and-add multiplication. Serves as reference implementation
- * to verify (possibly faster) implementations, and for very small scalars.
+ * Simple shift-and-add multiplication. Serves as reference implementation to verify (possibly
+ * faster) implementations, and for very small scalars. CAUTION: This implementation is NOT
+ * constant-time in any way. It is only intended to be used for diagnostics.
*
* @param p
* The point to multiply.
@@ -284,46 +287,63 @@ public class ECAlgorithms
{
boolean negK = k.signum() < 0, negL = l.signum() < 0;
- k = k.abs();
- l = l.abs();
+ BigInteger kAbs = k.abs(), lAbs = l.abs();
+
+ int minWidthP = WNafUtil.getWindowSize(kAbs.bitLength(), 8);
+ int minWidthQ = WNafUtil.getWindowSize(lAbs.bitLength(), 8);
- int widthP = Math.max(2, Math.min(16, WNafUtil.getWindowSize(k.bitLength())));
- int widthQ = Math.max(2, Math.min(16, WNafUtil.getWindowSize(l.bitLength())));
+ WNafPreCompInfo infoP = WNafUtil.precompute(P, minWidthP, true);
+ WNafPreCompInfo infoQ = WNafUtil.precompute(Q, minWidthQ, true);
+
+ // When P, Q are 'promoted' (i.e. reused several times), switch to fixed-point algorithm
+ {
+ ECCurve c = P.getCurve();
+ int combSize = FixedPointUtil.getCombSize(c);
+ if (!negK && !negL
+ && k.bitLength() <= combSize && l.bitLength() <= combSize
+ && infoP.isPromoted() && infoQ.isPromoted())
+ {
+ return implShamirsTrickFixedPoint(P, k, Q, l);
+ }
+ }
- WNafPreCompInfo infoP = WNafUtil.precompute(P, widthP, true);
- WNafPreCompInfo infoQ = WNafUtil.precompute(Q, widthQ, true);
+ int widthP = Math.min(8, infoP.getWidth());
+ int widthQ = Math.min(8, infoQ.getWidth());
ECPoint[] preCompP = negK ? infoP.getPreCompNeg() : infoP.getPreComp();
ECPoint[] preCompQ = negL ? infoQ.getPreCompNeg() : infoQ.getPreComp();
ECPoint[] preCompNegP = negK ? infoP.getPreComp() : infoP.getPreCompNeg();
ECPoint[] preCompNegQ = negL ? infoQ.getPreComp() : infoQ.getPreCompNeg();
- byte[] wnafP = WNafUtil.generateWindowNaf(widthP, k);
- byte[] wnafQ = WNafUtil.generateWindowNaf(widthQ, l);
+ byte[] wnafP = WNafUtil.generateWindowNaf(widthP, kAbs);
+ byte[] wnafQ = WNafUtil.generateWindowNaf(widthQ, lAbs);
return implShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ);
}
- static ECPoint implShamirsTrickWNaf(ECPoint P, BigInteger k, ECPointMap pointMapQ, BigInteger l)
+ static ECPoint implShamirsTrickWNaf(ECEndomorphism endomorphism, ECPoint P, BigInteger k, BigInteger l)
{
boolean negK = k.signum() < 0, negL = l.signum() < 0;
k = k.abs();
l = l.abs();
- int width = Math.max(2, Math.min(16, WNafUtil.getWindowSize(Math.max(k.bitLength(), l.bitLength()))));
+ int minWidth = WNafUtil.getWindowSize(Math.max(k.bitLength(), l.bitLength()), 8);
+
+ WNafPreCompInfo infoP = WNafUtil.precompute(P, minWidth, true);
+ ECPoint Q = EndoUtil.mapPoint(endomorphism, P);
+ WNafPreCompInfo infoQ = WNafUtil.precomputeWithPointMap(Q, endomorphism.getPointMap(), infoP, true);
- ECPoint Q = WNafUtil.mapPointWithPrecomp(P, width, true, pointMapQ);
- WNafPreCompInfo infoP = WNafUtil.getWNafPreCompInfo(P);
- WNafPreCompInfo infoQ = WNafUtil.getWNafPreCompInfo(Q);
+ int widthP = Math.min(8, infoP.getWidth());
+ int widthQ = Math.min(8, infoQ.getWidth());
ECPoint[] preCompP = negK ? infoP.getPreCompNeg() : infoP.getPreComp();
ECPoint[] preCompQ = negL ? infoQ.getPreCompNeg() : infoQ.getPreComp();
ECPoint[] preCompNegP = negK ? infoP.getPreComp() : infoP.getPreCompNeg();
ECPoint[] preCompNegQ = negL ? infoQ.getPreComp() : infoQ.getPreCompNeg();
- byte[] wnafP = WNafUtil.generateWindowNaf(width, k);
- byte[] wnafQ = WNafUtil.generateWindowNaf(width, l);
+ byte[] wnafP = WNafUtil.generateWindowNaf(widthP, k);
+ byte[] wnafQ = WNafUtil.generateWindowNaf(widthQ, l);
return implShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ);
}
@@ -392,8 +412,12 @@ public class ECAlgorithms
{
BigInteger ki = ks[i]; negs[i] = ki.signum() < 0; ki = ki.abs();
- int width = Math.max(2, Math.min(16, WNafUtil.getWindowSize(ki.bitLength())));
- infos[i] = WNafUtil.precompute(ps[i], width, true);
+ int minWidth = WNafUtil.getWindowSize(ki.bitLength(), 8);
+ WNafPreCompInfo info = WNafUtil.precompute(ps[i], minWidth, true);
+
+ int width = Math.min(8, info.getWidth());
+
+ infos[i] = info;
wnafs[i] = WNafUtil.generateWindowNaf(width, ki);
}
@@ -414,25 +438,24 @@ public class ECAlgorithms
abs[j++] = ab[1];
}
- ECPointMap pointMap = glvEndomorphism.getPointMap();
if (glvEndomorphism.hasEfficientPointMap())
{
- return ECAlgorithms.implSumOfMultiplies(ps, pointMap, abs);
+ return implSumOfMultiplies(glvEndomorphism, ps, abs);
}
ECPoint[] pqs = new ECPoint[len << 1];
for (int i = 0, j = 0; i < len; ++i)
{
- ECPoint p = ps[i], q = pointMap.map(p);
+ ECPoint p = ps[i];
+ ECPoint q = EndoUtil.mapPoint(glvEndomorphism, p);
pqs[j++] = p;
pqs[j++] = q;
}
-
- return ECAlgorithms.implSumOfMultiplies(pqs, abs);
+ return implSumOfMultiplies(pqs, abs);
}
- static ECPoint implSumOfMultiplies(ECPoint[] ps, ECPointMap pointMap, BigInteger[] ks)
+ static ECPoint implSumOfMultiplies(ECEndomorphism endomorphism, ECPoint[] ps, BigInteger[] ks)
{
int halfCount = ps.length, fullCount = halfCount << 1;
@@ -440,6 +463,8 @@ public class ECAlgorithms
WNafPreCompInfo[] infos = new WNafPreCompInfo[fullCount];
byte[][] wnafs = new byte[fullCount][];
+ ECPointMap pointMap = endomorphism.getPointMap();
+
for (int i = 0; i < halfCount; ++i)
{
int j0 = i << 1, j1 = j0 + 1;
@@ -447,13 +472,20 @@ public class ECAlgorithms
BigInteger kj0 = ks[j0]; negs[j0] = kj0.signum() < 0; kj0 = kj0.abs();
BigInteger kj1 = ks[j1]; negs[j1] = kj1.signum() < 0; kj1 = kj1.abs();
- int width = Math.max(2, Math.min(16, WNafUtil.getWindowSize(Math.max(kj0.bitLength(), kj1.bitLength()))));
+ int minWidth = WNafUtil.getWindowSize(Math.max(kj0.bitLength(), kj1.bitLength()), 8);
+
+ ECPoint P = ps[i];
+ WNafPreCompInfo infoP = WNafUtil.precompute(P, minWidth, true);
+ ECPoint Q = EndoUtil.mapPoint(endomorphism, P);
+ WNafPreCompInfo infoQ = WNafUtil.precomputeWithPointMap(Q, pointMap, infoP, true);
+
+ int widthP = Math.min(8, infoP.getWidth());
+ int widthQ = Math.min(8, infoQ.getWidth());
- ECPoint P = ps[i], Q = WNafUtil.mapPointWithPrecomp(P, width, true, pointMap);
- infos[j0] = WNafUtil.getWNafPreCompInfo(P);
- infos[j1] = WNafUtil.getWNafPreCompInfo(Q);
- wnafs[j0] = WNafUtil.generateWindowNaf(width, kj0);
- wnafs[j1] = WNafUtil.generateWindowNaf(width, kj1);
+ infos[j0] = infoP;
+ infos[j1] = infoQ;
+ wnafs[j0] = WNafUtil.generateWindowNaf(widthP, kj0);
+ wnafs[j1] = WNafUtil.generateWindowNaf(widthQ, kj1);
}
return implSumOfMultiplies(negs, infos, wnafs);
@@ -512,4 +544,77 @@ public class ECAlgorithms
return R;
}
+
+ private static ECPoint implShamirsTrickFixedPoint(ECPoint p, BigInteger k, ECPoint q, BigInteger l)
+ {
+ ECCurve c = p.getCurve();
+ int combSize = FixedPointUtil.getCombSize(c);
+
+ if (k.bitLength() > combSize || l.bitLength() > combSize)
+ {
+ /*
+ * TODO The comb works best when the scalars are less than the (possibly unknown) order.
+ * Still, if we want to handle larger scalars, we could allow customization of the comb
+ * size, or alternatively we could deal with the 'extra' bits either by running the comb
+ * multiple times as necessary, or by using an alternative multiplier as prelude.
+ */
+ throw new IllegalStateException("fixed-point comb doesn't support scalars larger than the curve order");
+ }
+
+ FixedPointPreCompInfo infoP = FixedPointUtil.precompute(p);
+ FixedPointPreCompInfo infoQ = FixedPointUtil.precompute(q);
+
+ ECLookupTable lookupTableP = infoP.getLookupTable();
+ ECLookupTable lookupTableQ = infoQ.getLookupTable();
+
+ int widthP = infoP.getWidth();
+ int widthQ = infoQ.getWidth();
+
+ // TODO This shouldn't normally happen, but a better "solution" is desirable anyway
+ if (widthP != widthQ)
+ {
+ FixedPointCombMultiplier m = new FixedPointCombMultiplier();
+ ECPoint r1 = m.multiply(p, k);
+ ECPoint r2 = m.multiply(q, l);
+ return r1.add(r2);
+ }
+
+ int width = widthP;
+
+ int d = (combSize + width - 1) / width;
+
+ ECPoint R = c.getInfinity();
+
+ int fullComb = d * width;
+ int[] K = Nat.fromBigInteger(fullComb, k);
+ int[] L = Nat.fromBigInteger(fullComb, l);
+
+ int top = fullComb - 1;
+ for (int i = 0; i < d; ++i)
+ {
+ int secretIndexK = 0, secretIndexL = 0;
+
+ for (int j = top - i; j >= 0; j -= d)
+ {
+ int secretBitK = K[j >>> 5] >>> (j & 0x1F);
+ secretIndexK ^= secretBitK >>> 1;
+ secretIndexK <<= 1;
+ secretIndexK ^= secretBitK;
+
+ int secretBitL = L[j >>> 5] >>> (j & 0x1F);
+ secretIndexL ^= secretBitL >>> 1;
+ secretIndexL <<= 1;
+ secretIndexL ^= secretBitL;
+ }
+
+ ECPoint addP = lookupTableP.lookupVar(secretIndexK);
+ ECPoint addQ = lookupTableQ.lookupVar(secretIndexL);
+
+ ECPoint T = addP.add(addQ);
+
+ R = R.twicePlus(T);
+ }
+
+ return R.add(infoP.getOffset()).add(infoQ.getOffset());
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECCurve.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECCurve.java
index bc088013..1d0c04ea 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECCurve.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECCurve.java
@@ -2,6 +2,7 @@
package com.android.org.bouncycastle.math.ec;
import java.math.BigInteger;
+import java.security.SecureRandom;
import java.util.Hashtable;
import java.util.Random;
@@ -112,6 +113,10 @@ public abstract class ECCurve
public abstract boolean isValidFieldElement(BigInteger x);
+ public abstract ECFieldElement randomFieldElement(SecureRandom r);
+
+ public abstract ECFieldElement randomFieldElementMult(SecureRandom r);
+
public synchronized Config configure()
{
return new Config(this.coord, this.endomorphism, this.multiplier);
@@ -127,39 +132,16 @@ public abstract class ECCurve
return p;
}
- /**
- * @deprecated per-point compression property will be removed, use {@link #validatePoint(BigInteger, BigInteger)}
- * and refer {@link ECPoint#getEncoded(boolean)}
- */
- public ECPoint validatePoint(BigInteger x, BigInteger y, boolean withCompression)
- {
- ECPoint p = createPoint(x, y, withCompression);
- if (!p.isValid())
- {
- throw new IllegalArgumentException("Invalid point coordinates");
- }
- return p;
- }
-
public ECPoint createPoint(BigInteger x, BigInteger y)
{
- return createPoint(x, y, false);
- }
-
- /**
- * @deprecated per-point compression property will be removed, use {@link #createPoint(BigInteger, BigInteger)}
- * and refer {@link ECPoint#getEncoded(boolean)}
- */
- public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression)
- {
- return createRawPoint(fromBigInteger(x), fromBigInteger(y), withCompression);
+ return createRawPoint(fromBigInteger(x), fromBigInteger(y));
}
protected abstract ECCurve cloneCurve();
- protected abstract ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression);
+ protected abstract ECPoint createRawPoint(ECFieldElement x, ECFieldElement y);
- protected abstract ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression);
+ protected abstract ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs);
protected ECMultiplier createDefaultMultiplier()
{
@@ -251,7 +233,7 @@ public abstract class ECCurve
// TODO Default behaviour could be improved if the two curves have the same coordinate system by copying any Z coordinates.
p = p.normalize();
- return createPoint(p.getXCoord().toBigInteger(), p.getYCoord().toBigInteger(), p.withCompression);
+ return createPoint(p.getXCoord().toBigInteger(), p.getYCoord().toBigInteger());
}
/**
@@ -374,9 +356,11 @@ public abstract class ECCurve
}
/**
- * Sets the default <code>ECMultiplier</code>, unless already set.
+ * Sets the default <code>ECMultiplier</code>, unless already set.
+ *
+ * We avoid synchronizing for performance reasons, so there is no uniqueness guarantee.
*/
- public synchronized ECMultiplier getMultiplier()
+ public ECMultiplier getMultiplier()
{
if (this.multiplier == null)
{
@@ -497,7 +481,7 @@ public abstract class ECCurve
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -522,7 +506,26 @@ public abstract class ECCurve
pos += (FE_BYTES * 2);
}
- return createRawPoint(fromBigInteger(new BigInteger(1, x)), fromBigInteger(new BigInteger(1, y)), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ byte[] x = new byte[FE_BYTES], y = new byte[FE_BYTES];
+ int pos = index * FE_BYTES * 2;
+
+ for (int j = 0; j < FE_BYTES; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_BYTES + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(byte[] x, byte[] y)
+ {
+ return createRawPoint(fromBigInteger(new BigInteger(1, x)), fromBigInteger(new BigInteger(1, y)));
}
};
}
@@ -597,6 +600,30 @@ public abstract class ECCurve
return x != null && x.signum() >= 0 && x.compareTo(this.getField().getCharacteristic()) < 0;
}
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ BigInteger p = getField().getCharacteristic();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElement(r, p));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElement(r, p));
+ return fe1.multiply(fe2);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ BigInteger p = getField().getCharacteristic();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElementMult(r, p));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElementMult(r, p));
+ return fe1.multiply(fe2);
+ }
+
protected ECPoint decompressPoint(int yTilde, BigInteger X1)
{
ECFieldElement x = this.fromBigInteger(X1);
@@ -617,7 +644,29 @@ public abstract class ECCurve
y = y.negate();
}
- return this.createRawPoint(x, y, true);
+ return this.createRawPoint(x, y);
+ }
+
+ private static BigInteger implRandomFieldElement(SecureRandom r, BigInteger p)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(p.bitLength(), r);
+ }
+ while (x.compareTo(p) >= 0);
+ return x;
+ }
+
+ private static BigInteger implRandomFieldElementMult(SecureRandom r, BigInteger p)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(p.bitLength(), r);
+ }
+ while (x.signum() <= 0 || x.compareTo(p) >= 0);
+ return x;
}
}
@@ -646,7 +695,7 @@ public abstract class ECCurve
this.q = q;
this.r = ECFieldElement.Fp.calculateResidue(q);
- this.infinity = new ECPoint.Fp(this, null, null, false);
+ this.infinity = new ECPoint.Fp(this, null, null);
this.a = fromBigInteger(a);
this.b = fromBigInteger(b);
@@ -655,21 +704,13 @@ public abstract class ECCurve
this.coord = FP_DEFAULT_COORDS;
}
- /**
- * @deprecated use constructor taking order/cofactor
- */
- protected Fp(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b)
- {
- this(q, r, a, b, null, null);
- }
-
protected Fp(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor)
{
super(q);
this.q = q;
this.r = r;
- this.infinity = new ECPoint.Fp(this, null, null, false);
+ this.infinity = new ECPoint.Fp(this, null, null);
this.a = a;
this.b = b;
@@ -712,14 +753,14 @@ public abstract class ECCurve
return new ECFieldElement.Fp(this.q, this.r, x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new ECPoint.Fp(this, x, y, withCompression);
+ return new ECPoint.Fp(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new ECPoint.Fp(this, x, y, zs, withCompression);
+ return new ECPoint.Fp(this, x, y, zs);
}
public ECPoint importPoint(ECPoint p)
@@ -734,8 +775,7 @@ public abstract class ECCurve
return new ECPoint.Fp(this,
fromBigInteger(p.x.toBigInteger()),
fromBigInteger(p.y.toBigInteger()),
- new ECFieldElement[]{ fromBigInteger(p.zs[0].toBigInteger()) },
- p.withCompression);
+ new ECFieldElement[]{ fromBigInteger(p.zs[0].toBigInteger()) });
default:
break;
}
@@ -802,12 +842,7 @@ public abstract class ECCurve
super(buildField(m, k1, k2, k3));
}
- public boolean isValidFieldElement(BigInteger x)
- {
- return x != null && x.signum() >= 0 && x.bitLength() <= this.getFieldSize();
- }
-
- public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression)
+ public ECPoint createPoint(BigInteger x, BigInteger y)
{
ECFieldElement X = this.fromBigInteger(x), Y = this.fromBigInteger(y);
@@ -834,7 +869,7 @@ public abstract class ECCurve
// ECFieldElement Z = X;
// X = X.square();
// Y = Y.add(X);
-// return createRawPoint(X, Y, new ECFieldElement[]{ Z }, withCompression);
+// return createRawPoint(X, Y, new ECFieldElement[]{ Z });
// }
else
{
@@ -849,7 +884,30 @@ public abstract class ECCurve
}
}
- return this.createRawPoint(X, Y, withCompression);
+ return this.createRawPoint(X, Y);
+ }
+
+ public boolean isValidFieldElement(BigInteger x)
+ {
+ return x != null && x.signum() >= 0 && x.bitLength() <= this.getFieldSize();
+ }
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int m = getFieldSize();
+ return fromBigInteger(BigIntegers.createRandomBigInteger(m, r));
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ int m = getFieldSize();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElementMult(r, m));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElementMult(r, m));
+ return fe1.multiply(fe2);
}
/**
@@ -901,7 +959,7 @@ public abstract class ECCurve
throw new IllegalArgumentException("Invalid point compression");
}
- return this.createRawPoint(x, y, true);
+ return this.createRawPoint(x, y);
}
/**
@@ -915,6 +973,27 @@ public abstract class ECCurve
*/
protected ECFieldElement solveQuadraticEquation(ECFieldElement beta)
{
+ ECFieldElement.AbstractF2m betaF2m = (ECFieldElement.AbstractF2m)beta;
+
+ boolean fastTrace = betaF2m.hasFastTrace();
+ if (fastTrace && 0 != betaF2m.trace())
+ {
+ return null;
+ }
+
+ int m = this.getFieldSize();
+
+ // For odd m, use the half-trace
+ if (0 != (m & 1))
+ {
+ ECFieldElement r = betaF2m.halfTrace();
+ if (fastTrace || r.square().add(r).add(beta).isZero())
+ {
+ return r;
+ }
+ return null;
+ }
+
if (beta.isZero())
{
return beta;
@@ -922,7 +1001,6 @@ public abstract class ECCurve
ECFieldElement gamma, z, zeroElement = this.fromBigInteger(ECConstants.ZERO);
- int m = this.getFieldSize();
Random rand = new Random();
do
{
@@ -968,6 +1046,17 @@ public abstract class ECCurve
{
return this.order != null && this.cofactor != null && this.b.isOne() && (this.a.isZero() || this.a.isOne());
}
+
+ private static BigInteger implRandomFieldElementMult(SecureRandom r, int m)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(m, r);
+ }
+ while (x.signum() <= 0);
+ return x;
+ }
}
/**
@@ -1141,7 +1230,7 @@ public abstract class ECCurve
this.order = order;
this.cofactor = cofactor;
- this.infinity = new ECPoint.F2m(this, null, null, false);
+ this.infinity = new ECPoint.F2m(this, null, null);
this.a = fromBigInteger(a);
this.b = fromBigInteger(b);
this.coord = F2M_DEFAULT_COORDS;
@@ -1158,7 +1247,7 @@ public abstract class ECCurve
this.order = order;
this.cofactor = cofactor;
- this.infinity = new ECPoint.F2m(this, null, null, false);
+ this.infinity = new ECPoint.F2m(this, null, null);
this.a = a;
this.b = b;
this.coord = F2M_DEFAULT_COORDS;
@@ -1202,14 +1291,14 @@ public abstract class ECCurve
return new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new ECPoint.F2m(this, x, y, withCompression);
+ return new ECPoint.F2m(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new ECPoint.F2m(this, x, y, zs, withCompression);
+ return new ECPoint.F2m(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -1263,7 +1352,7 @@ public abstract class ECCurve
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -1288,7 +1377,28 @@ public abstract class ECCurve
pos += (FE_LONGS * 2);
}
- return createRawPoint(new ECFieldElement.F2m(m, ks, new LongArray(x)), new ECFieldElement.F2m(m, ks, new LongArray(y)), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ long[] x = Nat.create64(FE_LONGS), y = Nat.create64(FE_LONGS);
+ int pos = index * FE_LONGS * 2;
+
+ for (int j = 0; j < FE_LONGS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_LONGS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(long[] x, long[] y)
+ {
+ ECFieldElement.F2m X = new ECFieldElement.F2m(m, ks, new LongArray(x));
+ ECFieldElement.F2m Y = new ECFieldElement.F2m(m, ks, new LongArray(y));
+ return createRawPoint(X, Y);
}
};
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECFieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECFieldElement.java
index 4ef6a4a4..84b197cc 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECFieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECFieldElement.java
@@ -4,10 +4,9 @@ package com.android.org.bouncycastle.math.ec;
import java.math.BigInteger;
import java.util.Random;
-import com.android.org.bouncycastle.math.raw.Mod;
-import com.android.org.bouncycastle.math.raw.Nat;
import com.android.org.bouncycastle.util.Arrays;
import com.android.org.bouncycastle.util.BigIntegers;
+import com.android.org.bouncycastle.util.Integers;
/**
* @hide This class is not part of the Android public SDK API
@@ -427,13 +426,7 @@ public abstract class ECFieldElement
protected BigInteger modInverse(BigInteger x)
{
- int bits = getFieldSize();
- int len = (bits + 31) >> 5;
- int[] p = Nat.fromBigInteger(bits, q);
- int[] n = Nat.fromBigInteger(bits, x);
- int[] z = Nat.create(len);
- Mod.invert(p, n, z);
- return Nat.toBigInteger(len, z);
+ return BigIntegers.modOddInverse(q, x);
}
protected BigInteger modMult(BigInteger x1, BigInteger x2)
@@ -523,27 +516,59 @@ public abstract class ECFieldElement
throw new IllegalStateException("Half-trace only defined for odd m");
}
- ECFieldElement fe = this;
- ECFieldElement ht = fe;
- for (int i = 2; i < m; i += 2)
+// ECFieldElement ht = this;
+// for (int i = 1; i < m; i += 2)
+// {
+// ht = ht.squarePow(2).add(this);
+// }
+
+ int n = (m + 1) >>> 1;
+ int k = 31 - Integers.numberOfLeadingZeros(n);
+ int nk = 1;
+
+ ECFieldElement ht = this;
+ while (k > 0)
{
- fe = fe.squarePow(2);
- ht = ht.add(fe);
+ ht = ht.squarePow(nk << 1).add(ht);
+ nk = n >>> --k;
+ if (0 != (nk & 1))
+ {
+ ht = ht.squarePow(2).add(this);
+ }
}
return ht;
}
+ public boolean hasFastTrace()
+ {
+ return false;
+ }
+
public int trace()
{
int m = this.getFieldSize();
- ECFieldElement fe = this;
- ECFieldElement tr = fe;
- for (int i = 1; i < m; ++i)
+
+// ECFieldElement tr = this;
+// for (int i = 1; i < m; ++i)
+// {
+// tr = tr.square().add(this);
+// }
+
+ int k = 31 - Integers.numberOfLeadingZeros(m);
+ int mk = 1;
+
+ ECFieldElement tr = this;
+ while (k > 0)
{
- fe = fe.square();
- tr = tr.add(fe);
+ tr = tr.squarePow(mk).add(tr);
+ mk = m >>> --k;
+ if (0 != (mk & 1))
+ {
+ tr = tr.square().add(this);
+ }
}
+
if (tr.isZero())
{
return 0;
@@ -697,42 +722,6 @@ public abstract class ECFieldElement
return m;
}
- /**
- * Checks, if the ECFieldElements <code>a</code> and <code>b</code>
- * are elements of the same field <code>F<sub>2<sup>m</sup></sub></code>
- * (having the same representation).
- * @param a field element.
- * @param b field element to be compared.
- * @throws IllegalArgumentException if <code>a</code> and <code>b</code>
- * are not elements of the same field
- * <code>F<sub>2<sup>m</sup></sub></code> (having the same
- * representation).
- */
- public static void checkFieldElements(
- ECFieldElement a,
- ECFieldElement b)
- {
- if ((!(a instanceof F2m)) || (!(b instanceof F2m)))
- {
- throw new IllegalArgumentException("Field elements are not "
- + "both instances of ECFieldElement.F2m");
- }
-
- ECFieldElement.F2m aF2m = (ECFieldElement.F2m)a;
- ECFieldElement.F2m bF2m = (ECFieldElement.F2m)b;
-
- if (aF2m.representation != bF2m.representation)
- {
- // Should never occur
- throw new IllegalArgumentException("One of the F2m field elements has incorrect representation");
- }
-
- if ((aF2m.m != bF2m.m) || !Arrays.areEqual(aF2m.ks, bF2m.ks))
- {
- throw new IllegalArgumentException("Field elements are not elements of the same field F2m");
- }
- }
-
public ECFieldElement add(final ECFieldElement b)
{
// No check performed here for performance reasons. Instead the
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECLookupTable.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECLookupTable.java
index bc9e5058..772e66f2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECLookupTable.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECLookupTable.java
@@ -8,4 +8,5 @@ public interface ECLookupTable
{
int getSize();
ECPoint lookup(int index);
+ ECPoint lookupVar(int index);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECPoint.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECPoint.java
index 5505f042..097c0194 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECPoint.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ECPoint.java
@@ -2,8 +2,11 @@
package com.android.org.bouncycastle.math.ec;
import java.math.BigInteger;
+import java.security.SecureRandom;
import java.util.Hashtable;
+import com.android.org.bouncycastle.crypto.CryptoServicesRegistrar;
+
/**
* base class for points on elliptic curves.
* @hide This class is not part of the Android public SDK API
@@ -48,8 +51,6 @@ public abstract class ECPoint
protected ECFieldElement y;
protected ECFieldElement[] zs;
- protected boolean withCompression;
-
// Hashtable is (String -> PreCompInfo)
protected Hashtable preCompTable = null;
@@ -226,13 +227,31 @@ public abstract class ECPoint
}
default:
{
- ECFieldElement Z1 = getZCoord(0);
- if (Z1.isOne())
+ ECFieldElement z = getZCoord(0);
+ if (z.isOne())
{
return this;
}
- return normalize(Z1.invert());
+ if (null == curve)
+ {
+ throw new IllegalStateException("Detached points must be in affine coordinates");
+ }
+
+ /*
+ * Use blinding to avoid the side-channel leak identified and analyzed in the paper
+ * "Yet another GCD based inversion side-channel affecting ECC implementations" by Nir
+ * Drucker and Shay Gueron.
+ *
+ * To blind the calculation of z^-1, choose a multiplicative (i.e. non-zero) field
+ * element 'b' uniformly at random, then calculate the result instead as (z * b)^-1 * b.
+ * Any side-channel in the implementation of 'inverse' now only leaks information about
+ * the value (z * b), and no longer reveals information about 'z' itself.
+ */
+ SecureRandom r = CryptoServicesRegistrar.getSecureRandom();
+ ECFieldElement b = curve.randomFieldElementMult(r);
+ ECFieldElement zInv = z.multiply(b).invert().multiply(b);
+ return normalize(zInv);
}
}
}
@@ -262,7 +281,7 @@ public abstract class ECPoint
protected ECPoint createScaledPoint(ECFieldElement sx, ECFieldElement sy)
{
- return this.getCurve().createRawPoint(getRawXCoord().multiply(sx), getRawYCoord().multiply(sy), this.withCompression);
+ return this.getCurve().createRawPoint(getRawXCoord().multiply(sx), getRawYCoord().multiply(sy));
}
public boolean isInfinity()
@@ -270,14 +289,6 @@ public abstract class ECPoint
return x == null || y == null || (zs.length > 0 && zs[0].isZero());
}
- /**
- * @deprecated per-point compression property will be removed, refer {@link #getEncoded(boolean)}
- */
- public boolean isCompressed()
- {
- return this.withCompression;
- }
-
public boolean isValid()
{
return implIsValid(false, true);
@@ -338,14 +349,28 @@ public abstract class ECPoint
{
return isInfinity()
? this
- : getCurve().createRawPoint(getRawXCoord().multiply(scale), getRawYCoord(), getRawZCoords(), this.withCompression);
+ : getCurve().createRawPoint(getRawXCoord().multiply(scale), getRawYCoord(), getRawZCoords());
+ }
+
+ public ECPoint scaleXNegateY(ECFieldElement scale)
+ {
+ return isInfinity()
+ ? this
+ : getCurve().createRawPoint(getRawXCoord().multiply(scale), getRawYCoord().negate(), getRawZCoords());
}
public ECPoint scaleY(ECFieldElement scale)
{
return isInfinity()
? this
- : getCurve().createRawPoint(getRawXCoord(), getRawYCoord().multiply(scale), getRawZCoords(), this.withCompression);
+ : getCurve().createRawPoint(getRawXCoord(), getRawYCoord().multiply(scale), getRawZCoords());
+ }
+
+ public ECPoint scaleYNegateX(ECFieldElement scale)
+ {
+ return isInfinity()
+ ? this
+ : getCurve().createRawPoint(getRawXCoord().negate(), getRawYCoord().multiply(scale), getRawZCoords());
}
public boolean equals(ECPoint other)
@@ -452,15 +477,6 @@ public abstract class ECPoint
}
/**
- * @deprecated per-point compression property will be removed, refer {@link #getEncoded(boolean)}
- * @return a byte encoding.
- */
- public byte[] getEncoded()
- {
- return getEncoded(this.withCompression);
- }
-
- /**
* Get an encoding of the point value, optionally in compressed format.
*
* @param compressed whether to generate a compressed point encoding.
@@ -619,38 +635,19 @@ public abstract class ECPoint
*/
public static class Fp extends AbstractFp
{
- /**
- * Create a point that encodes with or without point compression.
- *
- * @param curve the curve to use
- * @param x affine x co-ordinate
- * @param y affine y co-ordinate
- * @param withCompression if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer {@link #getEncoded(boolean)}
- */
- public Fp(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ Fp(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- Fp(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ Fp(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
{
- return new ECPoint.Fp(null, this.getAffineXCoord(), this.getAffineYCoord(), false);
+ return new ECPoint.Fp(null, this.getAffineXCoord(), this.getAffineYCoord());
}
public ECFieldElement getZCoord(int index)
@@ -707,7 +704,7 @@ public abstract class ECPoint
ECFieldElement X3 = gamma.square().subtract(X1).subtract(X2);
ECFieldElement Y3 = gamma.multiply(X1.subtract(X3)).subtract(Y1);
- return new ECPoint.Fp(curve, X3, Y3, this.withCompression);
+ return new ECPoint.Fp(curve, X3, Y3);
}
case ECCurve.COORD_HOMOGENEOUS:
@@ -749,7 +746,7 @@ public abstract class ECPoint
ECFieldElement Y3 = vSquaredV2.subtract(A).multiplyMinusProduct(u, u2, vCubed);
ECFieldElement Z3 = vCubed.multiply(w);
- return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
case ECCurve.COORD_JACOBIAN:
@@ -872,7 +869,7 @@ public abstract class ECPoint
zs = new ECFieldElement[]{ Z3 };
}
- return new ECPoint.Fp(curve, X3, Y3, zs, this.withCompression);
+ return new ECPoint.Fp(curve, X3, Y3, zs);
}
default:
@@ -911,7 +908,7 @@ public abstract class ECPoint
ECFieldElement X3 = gamma.square().subtract(two(X1));
ECFieldElement Y3 = gamma.multiply(X1.subtract(X3)).subtract(Y1);
- return new ECPoint.Fp(curve, X3, Y3, this.withCompression);
+ return new ECPoint.Fp(curve, X3, Y3);
}
case ECCurve.COORD_HOMOGENEOUS:
@@ -941,7 +938,7 @@ public abstract class ECPoint
ECFieldElement _4sSquared = Z1IsOne ? two(_2t) : _2s.square();
ECFieldElement Z3 = two(_4sSquared).multiply(s);
- return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
case ECCurve.COORD_JACOBIAN:
@@ -1000,7 +997,7 @@ public abstract class ECPoint
// Alternative calculation of Z3 using fast square
// ECFieldElement Z3 = doubleProductFromSquares(Y1, Z1, Y1Squared, Z1Squared);
- return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
case ECCurve.COORD_JACOBIAN_MODIFIED:
@@ -1079,7 +1076,7 @@ public abstract class ECPoint
ECFieldElement X4 = (L2.subtract(L1)).multiply(L1.add(L2)).add(X2);
ECFieldElement Y4 = (X1.subtract(X4)).multiply(L2).subtract(Y1);
- return new ECPoint.Fp(curve, X4, Y4, this.withCompression);
+ return new ECPoint.Fp(curve, X4, Y4);
}
case ECCurve.COORD_JACOBIAN_MODIFIED:
{
@@ -1132,7 +1129,7 @@ public abstract class ECPoint
ECFieldElement X4 = (L2.subtract(L1)).multiply(L1.add(L2)).add(X1);
ECFieldElement Y4 = (X1.subtract(X4)).multiply(L2).subtract(Y1);
- return new ECPoint.Fp(curve, X4, Y4, this.withCompression);
+ return new ECPoint.Fp(curve, X4, Y4);
}
case ECCurve.COORD_JACOBIAN_MODIFIED:
{
@@ -1228,15 +1225,15 @@ public abstract class ECPoint
{
case ECCurve.COORD_AFFINE:
ECFieldElement zInv = Z1.invert(), zInv2 = zInv.square(), zInv3 = zInv2.multiply(zInv);
- return new Fp(curve, X1.multiply(zInv2), Y1.multiply(zInv3), this.withCompression);
+ return new Fp(curve, X1.multiply(zInv2), Y1.multiply(zInv3));
case ECCurve.COORD_HOMOGENEOUS:
X1 = X1.multiply(Z1);
Z1 = Z1.multiply(Z1.square());
- return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1 }, this.withCompression);
+ return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1 });
case ECCurve.COORD_JACOBIAN:
- return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1 }, this.withCompression);
+ return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1 });
case ECCurve.COORD_JACOBIAN_MODIFIED:
- return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1, W1 }, this.withCompression);
+ return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1, W1 });
default:
throw new IllegalStateException("unsupported coordinate system");
}
@@ -1284,10 +1281,10 @@ public abstract class ECPoint
if (ECCurve.COORD_AFFINE != coord)
{
- return new ECPoint.Fp(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new ECPoint.Fp(curve, this.x, this.y.negate(), this.zs);
}
- return new ECPoint.Fp(curve, this.x, this.y.negate(), this.withCompression);
+ return new ECPoint.Fp(curve, this.x, this.y.negate());
}
protected ECFieldElement calculateJacobianModifiedW(ECFieldElement Z, ECFieldElement ZSquared)
@@ -1343,7 +1340,7 @@ public abstract class ECPoint
ECFieldElement W3 = calculateW ? two(_8T.multiply(W1)) : null;
ECFieldElement Z3 = Z1.isOne() ? _2Y1 : _2Y1.multiply(Z1);
- return new ECPoint.Fp(this.getCurve(), X3, Y3, new ECFieldElement[]{ Z3, W3 }, this.withCompression);
+ return new ECPoint.Fp(this.getCurve(), X3, Y3, new ECFieldElement[]{ Z3, W3 });
}
}
@@ -1436,35 +1433,46 @@ public abstract class ECPoint
if (ECConstants.TWO.equals(cofactor))
{
/*
- * Check that the trace of (X + A) is 0, then there exists a solution to L^2 + L = X + A,
- * and so a halving is possible, so this point is the double of another.
+ * Check that 0 == Tr(X + A); then there exists a solution to L^2 + L = X + A, and
+ * so a halving is possible, so this point is the double of another.
+ *
+ * Note: Tr(A) == 1 for cofactor 2 curves.
*/
ECPoint N = this.normalize();
ECFieldElement X = N.getAffineXCoord();
- ECFieldElement rhs = X.add(curve.getA());
- return ((ECFieldElement.AbstractF2m)rhs).trace() == 0;
+ return 0 != ((ECFieldElement.AbstractF2m)X).trace();
}
if (ECConstants.FOUR.equals(cofactor))
{
/*
* Solve L^2 + L = X + A to find the half of this point, if it exists (fail if not).
- * Generate both possibilities for the square of the half-point's x-coordinate (w),
- * and check if Tr(w + A) == 0 for at least one; then a second halving is possible
- * (see comments for cofactor 2 above), so this point is four times another.
*
- * Note: Tr(x^2) == Tr(x).
+ * Note: Tr(A) == 0 for cofactor 4 curves.
*/
ECPoint N = this.normalize();
ECFieldElement X = N.getAffineXCoord();
- ECFieldElement lambda = ((ECCurve.AbstractF2m)curve).solveQuadraticEquation(X.add(curve.getA()));
- if (lambda == null)
+ ECFieldElement L = ((ECCurve.AbstractF2m)curve).solveQuadraticEquation(X.add(curve.getA()));
+ if (null == L)
{
return false;
}
- ECFieldElement w = X.multiply(lambda).add(N.getAffineYCoord());
- ECFieldElement t = w.add(curve.getA());
- return ((ECFieldElement.AbstractF2m)t).trace() == 0
- || ((ECFieldElement.AbstractF2m)(t.add(X))).trace() == 0;
+
+ /*
+ * A solution exists, therefore 0 == Tr(X + A) == Tr(X).
+ */
+ ECFieldElement Y = N.getAffineYCoord();
+ ECFieldElement T = X.multiply(L).add(Y);
+
+ /*
+ * Either T or (T + X) is the square of a half-point's x coordinate (hx). In either
+ * case, the half-point can be halved again when 0 == Tr(hx + A).
+ *
+ * Note: Tr(hx + A) == Tr(hx) == Tr(hx^2) == Tr(T) == Tr(T + X)
+ *
+ * Check that 0 == Tr(T); then there exists a solution to L^2 + L = hx + A, and so a
+ * second halving is possible and this point is four times some other.
+ */
+ return 0 == ((ECFieldElement.AbstractF2m)T).trace();
}
return super.satisfiesOrder();
@@ -1489,7 +1497,7 @@ public abstract class ECPoint
ECFieldElement X2 = X.multiply(scale);
ECFieldElement L2 = L.add(X).divide(scale).add(X2);
- return this.getCurve().createRawPoint(X, L2, this.getRawZCoords(), this.withCompression); // earlier JDK
+ return this.getCurve().createRawPoint(X, L2, this.getRawZCoords()); // earlier JDK
}
case ECCurve.COORD_LAMBDA_PROJECTIVE:
{
@@ -1501,7 +1509,7 @@ public abstract class ECPoint
ECFieldElement L2 = L.add(X).add(X2);
ECFieldElement Z2 = Z.multiply(scale);
- return this.getCurve().createRawPoint(X2, L2, new ECFieldElement[]{ Z2 }, this.withCompression); // earlier JDK
+ return this.getCurve().createRawPoint(X2, L2, new ECFieldElement[]{ Z2 }); // earlier JDK
}
default:
{
@@ -1510,6 +1518,11 @@ public abstract class ECPoint
}
}
+ public ECPoint scaleXNegateY(ECFieldElement scale)
+ {
+ return scaleX(scale);
+ }
+
public ECPoint scaleY(ECFieldElement scale)
{
if (this.isInfinity())
@@ -1529,7 +1542,7 @@ public abstract class ECPoint
// Y is actually Lambda (X + Y/X) here
ECFieldElement L2 = L.add(X).multiply(scale).add(X);
- return this.getCurve().createRawPoint(X, L2, this.getRawZCoords(), this.withCompression); // earlier JDK
+ return this.getCurve().createRawPoint(X, L2, this.getRawZCoords()); // earlier JDK
}
default:
{
@@ -1538,6 +1551,11 @@ public abstract class ECPoint
}
}
+ public ECPoint scaleYNegateX(ECFieldElement scale)
+ {
+ return scaleY(scale);
+ }
+
public ECPoint subtract(ECPoint b)
{
if (b.isInfinity())
@@ -1567,14 +1585,14 @@ public abstract class ECPoint
case ECCurve.COORD_LAMBDA_AFFINE:
{
ECFieldElement Y1 = this.y;
- return (ECPoint.AbstractF2m)curve.createRawPoint(X1.square(), Y1.square(), this.withCompression);
+ return (ECPoint.AbstractF2m)curve.createRawPoint(X1.square(), Y1.square());
}
case ECCurve.COORD_HOMOGENEOUS:
case ECCurve.COORD_LAMBDA_PROJECTIVE:
{
ECFieldElement Y1 = this.y, Z1 = this.zs[0];
return (ECPoint.AbstractF2m)curve.createRawPoint(X1.square(), Y1.square(),
- new ECFieldElement[]{ Z1.square() }, this.withCompression);
+ new ECFieldElement[]{ Z1.square() });
}
default:
{
@@ -1601,14 +1619,14 @@ public abstract class ECPoint
case ECCurve.COORD_LAMBDA_AFFINE:
{
ECFieldElement Y1 = this.y;
- return (ECPoint.AbstractF2m)curve.createRawPoint(X1.squarePow(pow), Y1.squarePow(pow), this.withCompression);
+ return (ECPoint.AbstractF2m)curve.createRawPoint(X1.squarePow(pow), Y1.squarePow(pow));
}
case ECCurve.COORD_HOMOGENEOUS:
case ECCurve.COORD_LAMBDA_PROJECTIVE:
{
ECFieldElement Y1 = this.y, Z1 = this.zs[0];
return (ECPoint.AbstractF2m)curve.createRawPoint(X1.squarePow(pow), Y1.squarePow(pow),
- new ECFieldElement[]{ Z1.squarePow(pow) }, this.withCompression);
+ new ECFieldElement[]{ Z1.squarePow(pow) });
}
default:
{
@@ -1624,52 +1642,23 @@ public abstract class ECPoint
*/
public static class F2m extends AbstractF2m
{
- /**
- * @param curve base curve
- * @param x x point
- * @param y y point
- * @param withCompression true if encode with point compression.
- *
- * @deprecated per-point compression property will be removed, refer {@link #getEncoded(boolean)}
- */
- public F2m(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ F2m(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- if (x != null)
- {
- // Check if x and y are elements of the same field
- ECFieldElement.F2m.checkFieldElements(this.x, this.y);
-
- // Check if x and a are elements of the same field
- if (curve != null)
- {
- ECFieldElement.F2m.checkFieldElements(this.x, this.curve.getA());
- }
- }
-
- this.withCompression = withCompression;
-
// checkCurveEquation();
}
- F2m(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ F2m(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
- this.withCompression = withCompression;
-
// checkCurveEquation();
}
protected ECPoint detach()
{
- return new ECPoint.F2m(null, this.getAffineXCoord(), this.getAffineYCoord(), false); // earlier JDK
+ return new ECPoint.F2m(null, this.getAffineXCoord(), this.getAffineYCoord()); // earlier JDK
}
public ECFieldElement getYCoord()
@@ -1772,7 +1761,7 @@ public abstract class ECPoint
ECFieldElement X3 = L.square().add(L).add(dx).add(curve.getA());
ECFieldElement Y3 = L.multiply(X1.add(X3)).add(X3).add(Y1);
- return new ECPoint.F2m(curve, X3, Y3, this.withCompression);
+ return new ECPoint.F2m(curve, X3, Y3);
}
case ECCurve.COORD_HOMOGENEOUS:
{
@@ -1809,7 +1798,7 @@ public abstract class ECPoint
ECFieldElement Y3 = U.multiplyPlusProduct(X1, V, Y1).multiplyPlusProduct(VSqZ2, uv, A);
ECFieldElement Z3 = VCu.multiply(W);
- return new ECPoint.F2m(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.F2m(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
case ECCurve.COORD_LAMBDA_PROJECTIVE:
{
@@ -1869,7 +1858,7 @@ public abstract class ECPoint
X3 = L.square().add(L).add(X1).add(curve.getA());
if (X3.isZero())
{
- return new ECPoint.F2m(curve, X3, curve.getB().sqrt(), this.withCompression);
+ return new ECPoint.F2m(curve, X3, curve.getB().sqrt());
}
ECFieldElement Y3 = L.multiply(X1.add(X3)).add(X3).add(Y1);
@@ -1886,7 +1875,7 @@ public abstract class ECPoint
X3 = AU1.multiply(AU2);
if (X3.isZero())
{
- return new ECPoint.F2m(curve, X3, curve.getB().sqrt(), this.withCompression);
+ return new ECPoint.F2m(curve, X3, curve.getB().sqrt());
}
ECFieldElement ABZ2 = A.multiply(B);
@@ -1904,7 +1893,7 @@ public abstract class ECPoint
}
}
- return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 });
}
default:
{
@@ -1925,7 +1914,7 @@ public abstract class ECPoint
ECFieldElement X1 = this.x;
if (X1.isZero())
{
- // A point with X == 0 is it's own additive inverse
+ // A point with X == 0 is its own additive inverse
return curve.getInfinity();
}
@@ -1942,7 +1931,7 @@ public abstract class ECPoint
ECFieldElement X3 = L1.square().add(L1).add(curve.getA());
ECFieldElement Y3 = X1.squarePlusProduct(X3, L1.addOne());
- return new ECPoint.F2m(curve, X3, Y3, this.withCompression);
+ return new ECPoint.F2m(curve, X3, Y3);
}
case ECCurve.COORD_HOMOGENEOUS:
{
@@ -1963,7 +1952,7 @@ public abstract class ECPoint
ECFieldElement Y3 = X1Sq.square().multiplyPlusProduct(V, h, sv);
ECFieldElement Z3 = V.multiply(vSquared);
- return new ECPoint.F2m(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.F2m(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
case ECCurve.COORD_LAMBDA_PROJECTIVE:
{
@@ -1977,7 +1966,7 @@ public abstract class ECPoint
ECFieldElement T = L1.square().add(L1Z1).add(aZ1Sq);
if (T.isZero())
{
- return new ECPoint.F2m(curve, T, curve.getB().sqrt(), withCompression);
+ return new ECPoint.F2m(curve, T, curve.getB().sqrt());
}
ECFieldElement X3 = T.square();
@@ -2014,7 +2003,7 @@ public abstract class ECPoint
L3 = X1Z1.squarePlusProduct(T, L1Z1).add(X3).add(Z3);
}
- return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 });
}
default:
{
@@ -2039,7 +2028,7 @@ public abstract class ECPoint
ECFieldElement X1 = this.x;
if (X1.isZero())
{
- // A point with X == 0 is it's own additive inverse
+ // A point with X == 0 is its own additive inverse
return b;
}
@@ -2082,14 +2071,14 @@ public abstract class ECPoint
if (A.isZero())
{
- return new ECPoint.F2m(curve, A, curve.getB().sqrt(), withCompression);
+ return new ECPoint.F2m(curve, A, curve.getB().sqrt());
}
ECFieldElement X3 = A.square().multiply(X2Z1Sq);
ECFieldElement Z3 = A.multiply(B).multiply(Z1Sq);
ECFieldElement L3 = A.add(B).square().multiplyPlusProduct(T, L2plus1, Z3);
- return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 });
}
default:
{
@@ -2116,23 +2105,23 @@ public abstract class ECPoint
case ECCurve.COORD_AFFINE:
{
ECFieldElement Y = this.y;
- return new ECPoint.F2m(curve, X, Y.add(X), this.withCompression);
+ return new ECPoint.F2m(curve, X, Y.add(X));
}
case ECCurve.COORD_HOMOGENEOUS:
{
ECFieldElement Y = this.y, Z = this.zs[0];
- return new ECPoint.F2m(curve, X, Y.add(X), new ECFieldElement[]{ Z }, this.withCompression);
+ return new ECPoint.F2m(curve, X, Y.add(X), new ECFieldElement[]{ Z });
}
case ECCurve.COORD_LAMBDA_AFFINE:
{
ECFieldElement L = this.y;
- return new ECPoint.F2m(curve, X, L.addOne(), this.withCompression);
+ return new ECPoint.F2m(curve, X, L.addOne());
}
case ECCurve.COORD_LAMBDA_PROJECTIVE:
{
// L is actually Lambda (X + Y/X) here
ECFieldElement L = this.y, Z = this.zs[0];
- return new ECPoint.F2m(curve, X, L.add(Z), new ECFieldElement[]{ Z }, this.withCompression);
+ return new ECPoint.F2m(curve, X, L.add(Z), new ECFieldElement[]{ Z });
}
default:
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/GLVMultiplier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/GLVMultiplier.java
index 9aa1fa8b..67f05b17 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/GLVMultiplier.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/GLVMultiplier.java
@@ -3,6 +3,7 @@ package com.android.org.bouncycastle.math.ec;
import java.math.BigInteger;
+import com.android.org.bouncycastle.math.ec.endo.EndoUtil;
import com.android.org.bouncycastle.math.ec.endo.GLVEndomorphism;
/**
@@ -35,12 +36,13 @@ public class GLVMultiplier extends AbstractECMultiplier
BigInteger[] ab = glvEndomorphism.decomposeScalar(k.mod(n));
BigInteger a = ab[0], b = ab[1];
- ECPointMap pointMap = glvEndomorphism.getPointMap();
if (glvEndomorphism.hasEfficientPointMap())
{
- return ECAlgorithms.implShamirsTrickWNaf(p, a, pointMap, b);
+ return ECAlgorithms.implShamirsTrickWNaf(glvEndomorphism, p, a, b);
}
- return ECAlgorithms.implShamirsTrickWNaf(p, a, pointMap.map(p), b);
+ ECPoint q = EndoUtil.mapPoint(glvEndomorphism, p);
+
+ return ECAlgorithms.implShamirsTrickWNaf(p, a, q, b);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ScaleXNegateYPointMap.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ScaleXNegateYPointMap.java
new file mode 100644
index 00000000..68328c57
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ScaleXNegateYPointMap.java
@@ -0,0 +1,20 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.math.ec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ScaleXNegateYPointMap implements ECPointMap
+{
+ protected final ECFieldElement scale;
+
+ public ScaleXNegateYPointMap(ECFieldElement scale)
+ {
+ this.scale = scale;
+ }
+
+ public ECPoint map(ECPoint p)
+ {
+ return p.scaleXNegateY(scale);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ScaleYNegateXPointMap.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ScaleYNegateXPointMap.java
new file mode 100644
index 00000000..8febd6fa
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/ScaleYNegateXPointMap.java
@@ -0,0 +1,20 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.math.ec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ScaleYNegateXPointMap implements ECPointMap
+{
+ protected final ECFieldElement scale;
+
+ public ScaleYNegateXPointMap(ECFieldElement scale)
+ {
+ this.scale = scale;
+ }
+
+ public ECPoint map(ECPoint p)
+ {
+ return p.scaleYNegateX(scale);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafL2RMultiplier.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafL2RMultiplier.java
index f6b67d10..1f515abc 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafL2RMultiplier.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafL2RMultiplier.java
@@ -3,6 +3,8 @@ package com.android.org.bouncycastle.math.ec;
import java.math.BigInteger;
+import com.android.org.bouncycastle.util.Integers;
+
/**
* Class implementing the WNAF (Window Non-Adjacent Form) multiplication
* algorithm.
@@ -19,12 +21,12 @@ public class WNafL2RMultiplier extends AbstractECMultiplier
*/
protected ECPoint multiplyPositive(ECPoint p, BigInteger k)
{
- // Clamp the window width in the range [2, 16]
- int width = Math.max(2, Math.min(16, getWindowSize(k.bitLength())));
+ int minWidth = WNafUtil.getWindowSize(k.bitLength());
- WNafPreCompInfo wnafPreCompInfo = WNafUtil.precompute(p, width, true);
- ECPoint[] preComp = wnafPreCompInfo.getPreComp();
- ECPoint[] preCompNeg = wnafPreCompInfo.getPreCompNeg();
+ WNafPreCompInfo info = WNafUtil.precompute(p, minWidth, true);
+ ECPoint[] preComp = info.getPreComp();
+ ECPoint[] preCompNeg = info.getPreCompNeg();
+ int width = info.getWidth();
int[] wnaf = WNafUtil.generateCompactWindowNaf(width, k);
@@ -47,7 +49,7 @@ public class WNafL2RMultiplier extends AbstractECMultiplier
// Optimization can only be used for values in the lower half of the table
if ((n << 2) < (1 << width))
{
- int highest = LongArray.bitLengths[n];
+ int highest = 32 - Integers.numberOfLeadingZeros(n);
// TODO Get addition/doubling cost ratio from curve and compare to 'scale' to see if worth substituting?
int scale = width - highest;
@@ -84,15 +86,4 @@ public class WNafL2RMultiplier extends AbstractECMultiplier
return R;
}
-
- /**
- * Determine window width to use for a scalar multiplication of the given size.
- *
- * @param bits the bit-length of the scalar to multiply by
- * @return the window size to use
- */
- protected int getWindowSize(int bits)
- {
- return WNafUtil.getWindowSize(bits);
- }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafPreCompInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafPreCompInfo.java
index 08953799..2e0038d7 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafPreCompInfo.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafPreCompInfo.java
@@ -8,6 +8,10 @@ package com.android.org.bouncycastle.math.ec;
*/
public class WNafPreCompInfo implements PreCompInfo
{
+ volatile int promotionCountdown = 4;
+
+ protected int confWidth = -1;
+
/**
* Array holding the precomputed <code>ECPoint</code>s used for a Window
* NAF multiplication.
@@ -26,6 +30,43 @@ public class WNafPreCompInfo implements PreCompInfo
*/
protected ECPoint twice = null;
+ protected int width = -1;
+
+ int decrementPromotionCountdown()
+ {
+ int t = promotionCountdown;
+ if (t > 0)
+ {
+ promotionCountdown = --t;
+ }
+ return t;
+ }
+
+ int getPromotionCountdown()
+ {
+ return promotionCountdown;
+ }
+
+ void setPromotionCountdown(int promotionCountdown)
+ {
+ this.promotionCountdown = promotionCountdown;
+ }
+
+ public boolean isPromoted()
+ {
+ return promotionCountdown <= 0;
+ }
+
+ public int getConfWidth()
+ {
+ return confWidth;
+ }
+
+ public void setConfWidth(int confWidth)
+ {
+ this.confWidth = confWidth;
+ }
+
public ECPoint[] getPreComp()
{
return preComp;
@@ -55,4 +96,14 @@ public class WNafPreCompInfo implements PreCompInfo
{
this.twice = twice;
}
+
+ public int getWidth()
+ {
+ return width;
+ }
+
+ public void setWidth(int width)
+ {
+ this.width = width;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafUtil.java
index 018d1498..5811927e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafUtil.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/WNafUtil.java
@@ -11,11 +11,54 @@ public abstract class WNafUtil
public static final String PRECOMP_NAME = "bc_wnaf";
private static final int[] DEFAULT_WINDOW_SIZE_CUTOFFS = new int[]{ 13, 41, 121, 337, 897, 2305 };
+ private static final int MAX_WIDTH = 16;
private static final byte[] EMPTY_BYTES = new byte[0];
private static final int[] EMPTY_INTS = new int[0];
private static final ECPoint[] EMPTY_POINTS = new ECPoint[0];
+ public static void configureBasepoint(ECPoint p)
+ {
+ final ECCurve c = p.getCurve();
+ if (null == c)
+ {
+ return;
+ }
+
+ BigInteger n = c.getOrder();
+ int bits = (null == n) ? c.getFieldSize() + 1 : n.bitLength();
+ final int confWidth = Math.min(MAX_WIDTH, getWindowSize(bits) + 3);
+
+ c.precompute(p, PRECOMP_NAME, new PreCompCallback()
+ {
+ public PreCompInfo precompute(PreCompInfo existing)
+ {
+ WNafPreCompInfo existingWNaf = (existing instanceof WNafPreCompInfo) ? (WNafPreCompInfo)existing : null;
+
+ if (null != existingWNaf && existingWNaf.getConfWidth() == confWidth)
+ {
+ existingWNaf.setPromotionCountdown(0);
+ return existingWNaf;
+ }
+
+ WNafPreCompInfo result = new WNafPreCompInfo();
+
+ result.setPromotionCountdown(0);
+ result.setConfWidth(confWidth);
+
+ if (null != existingWNaf)
+ {
+ result.setPreComp(existingWNaf.getPreComp());
+ result.setPreCompNeg(existingWNaf.getPreCompNeg());
+ result.setTwice(existingWNaf.getTwice());
+ result.setWidth(existingWNaf.getWidth());
+ }
+
+ return result;
+ }
+ });
+ }
+
public static int[] generateCompactNaf(BigInteger k)
{
if ((k.bitLength() >>> 16) != 0)
@@ -319,7 +362,19 @@ public abstract class WNafUtil
*/
public static int getWindowSize(int bits)
{
- return getWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS);
+ return getWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS, MAX_WIDTH);
+ }
+
+ /**
+ * Determine window width to use for a scalar multiplication of the given size.
+ *
+ * @param bits the bit-length of the scalar to multiply by
+ * @param maxWidth the maximum window width to return
+ * @return the window size to use
+ */
+ public static int getWindowSize(int bits, int maxWidth)
+ {
+ return getWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS, maxWidth);
}
/**
@@ -331,6 +386,19 @@ public abstract class WNafUtil
*/
public static int getWindowSize(int bits, int[] windowSizeCutoffs)
{
+ return getWindowSize(bits, windowSizeCutoffs, MAX_WIDTH);
+ }
+
+ /**
+ * Determine window width to use for a scalar multiplication of the given size.
+ *
+ * @param bits the bit-length of the scalar to multiply by
+ * @param windowSizeCutoffs a monotonically increasing list of bit sizes at which to increment the window width
+ * @param maxWidth the maximum window width to return
+ * @return the window size to use
+ */
+ public static int getWindowSize(int bits, int[] windowSizeCutoffs, int maxWidth)
+ {
int w = 0;
for (; w < windowSizeCutoffs.length; ++w)
{
@@ -339,55 +407,11 @@ public abstract class WNafUtil
break;
}
}
- return w + 2;
- }
-
- public static ECPoint mapPointWithPrecomp(ECPoint p, final int width, final boolean includeNegated,
- final ECPointMap pointMap)
- {
- final ECCurve c = p.getCurve();
- final WNafPreCompInfo wnafPreCompP = precompute(p, width, includeNegated);
-
- ECPoint q = pointMap.map(p);
- c.precompute(q, PRECOMP_NAME, new PreCompCallback()
- {
- public PreCompInfo precompute(PreCompInfo existing)
- {
- WNafPreCompInfo result = new WNafPreCompInfo();
-
- ECPoint twiceP = wnafPreCompP.getTwice();
- if (twiceP != null)
- {
- ECPoint twiceQ = pointMap.map(twiceP);
- result.setTwice(twiceQ);
- }
-
- ECPoint[] preCompP = wnafPreCompP.getPreComp();
- ECPoint[] preCompQ = new ECPoint[preCompP.length];
- for (int i = 0; i < preCompP.length; ++i)
- {
- preCompQ[i] = pointMap.map(preCompP[i]);
- }
- result.setPreComp(preCompQ);
- if (includeNegated)
- {
- ECPoint[] preCompNegQ = new ECPoint[preCompQ.length];
- for (int i = 0; i < preCompNegQ.length; ++i)
- {
- preCompNegQ[i] = preCompQ[i].negate();
- }
- result.setPreCompNeg(preCompNegQ);
- }
-
- return result;
- }
- });
-
- return q;
+ return Math.max(2, Math.min(maxWidth, w + 2));
}
- public static WNafPreCompInfo precompute(final ECPoint p, final int width, final boolean includeNegated)
+ public static WNafPreCompInfo precompute(final ECPoint p, final int minWidth, final boolean includeNegated)
{
final ECCurve c = p.getCurve();
@@ -397,25 +421,38 @@ public abstract class WNafUtil
{
WNafPreCompInfo existingWNaf = (existing instanceof WNafPreCompInfo) ? (WNafPreCompInfo)existing : null;
- int reqPreCompLen = 1 << Math.max(0, width - 2);
+ int width = Math.max(2, Math.min(MAX_WIDTH, minWidth));
+ int reqPreCompLen = 1 << (width - 2);
- if (checkExisting(existingWNaf, reqPreCompLen, includeNegated))
+ if (checkExisting(existingWNaf, width, reqPreCompLen, includeNegated))
{
+ existingWNaf.decrementPromotionCountdown();
return existingWNaf;
}
+ WNafPreCompInfo result = new WNafPreCompInfo();
+
ECPoint[] preComp = null, preCompNeg = null;
ECPoint twiceP = null;
- if (existingWNaf != null)
+ if (null != existingWNaf)
{
+ int promotionCountdown = existingWNaf.decrementPromotionCountdown();
+ result.setPromotionCountdown(promotionCountdown);
+
+ int confWidth = existingWNaf.getConfWidth();
+ result.setConfWidth(confWidth);
+
preComp = existingWNaf.getPreComp();
preCompNeg = existingWNaf.getPreCompNeg();
twiceP = existingWNaf.getTwice();
}
+ width = Math.min(MAX_WIDTH, Math.max(result.getConfWidth(), width));
+ reqPreCompLen = 1 << (width - 2);
+
int iniPreCompLen = 0;
- if (preComp == null)
+ if (null == preComp)
{
preComp = EMPTY_POINTS;
}
@@ -450,7 +487,7 @@ public abstract class WNafUtil
else
{
ECPoint isoTwiceP = twiceP, last = preComp[curPreCompLen - 1];
- if (isoTwiceP == null)
+ if (null == isoTwiceP)
{
isoTwiceP = preComp[0].twice();
twiceP = isoTwiceP;
@@ -510,7 +547,7 @@ public abstract class WNafUtil
if (includeNegated)
{
int pos;
- if (preCompNeg == null)
+ if (null == preCompNeg)
{
pos = 0;
preCompNeg = new ECPoint[reqPreCompLen];
@@ -531,23 +568,96 @@ public abstract class WNafUtil
}
}
- WNafPreCompInfo result = new WNafPreCompInfo();
result.setPreComp(preComp);
result.setPreCompNeg(preCompNeg);
result.setTwice(twiceP);
+ result.setWidth(width);
+ return result;
+ }
+
+ private boolean checkExisting(WNafPreCompInfo existingWNaf, int width, int reqPreCompLen, boolean includeNegated)
+ {
+ return null != existingWNaf
+ && existingWNaf.getWidth() >= Math.max(existingWNaf.getConfWidth(), width)
+ && checkTable(existingWNaf.getPreComp(), reqPreCompLen)
+ && (!includeNegated || checkTable(existingWNaf.getPreCompNeg(), reqPreCompLen));
+ }
+
+ private boolean checkTable(ECPoint[] table, int reqLen)
+ {
+ return null != table && table.length >= reqLen;
+ }
+ });
+ }
+
+ public static WNafPreCompInfo precomputeWithPointMap(final ECPoint p, final ECPointMap pointMap, final WNafPreCompInfo fromWNaf,
+ final boolean includeNegated)
+ {
+ final ECCurve c = p.getCurve();
+
+ return (WNafPreCompInfo)c.precompute(p, PRECOMP_NAME, new PreCompCallback()
+ {
+ public PreCompInfo precompute(PreCompInfo existing)
+ {
+ WNafPreCompInfo existingWNaf = (existing instanceof WNafPreCompInfo) ? (WNafPreCompInfo)existing : null;
+
+ int width = fromWNaf.getWidth();
+ int reqPreCompLen = fromWNaf.getPreComp().length;
+
+ if (checkExisting(existingWNaf, width, reqPreCompLen, includeNegated))
+ {
+ existingWNaf.decrementPromotionCountdown();
+ return existingWNaf;
+ }
+
+ /*
+ * TODO Ideally this method would support incremental calculation, but given the
+ * existing use-cases it would be of little-to-no benefit.
+ */
+ WNafPreCompInfo result = new WNafPreCompInfo();
+
+ result.setPromotionCountdown(fromWNaf.getPromotionCountdown());
+
+ ECPoint twiceFrom = fromWNaf.getTwice();
+ if (null != twiceFrom)
+ {
+ ECPoint twice = pointMap.map(twiceFrom);
+ result.setTwice(twice);
+ }
+
+ ECPoint[] preCompFrom = fromWNaf.getPreComp();
+ ECPoint[] preComp = new ECPoint[preCompFrom.length];
+ for (int i = 0; i < preCompFrom.length; ++i)
+ {
+ preComp[i] = pointMap.map(preCompFrom[i]);
+ }
+ result.setPreComp(preComp);
+ result.setWidth(width);
+
+ if (includeNegated)
+ {
+ ECPoint[] preCompNeg = new ECPoint[preComp.length];
+ for (int i = 0; i < preCompNeg.length; ++i)
+ {
+ preCompNeg[i] = preComp[i].negate();
+ }
+ result.setPreCompNeg(preCompNeg);
+ }
+
return result;
}
- private boolean checkExisting(WNafPreCompInfo existingWNaf, int reqPreCompLen, boolean includeNegated)
+ private boolean checkExisting(WNafPreCompInfo existingWNaf, int width, int reqPreCompLen, boolean includeNegated)
{
- return existingWNaf != null
+ return null != existingWNaf
+ && existingWNaf.getWidth() >= width
&& checkTable(existingWNaf.getPreComp(), reqPreCompLen)
&& (!includeNegated || checkTable(existingWNaf.getPreCompNeg(), reqPreCompLen));
}
private boolean checkTable(ECPoint[] table, int reqLen)
{
- return table != null && table.length >= reqLen;
+ return null != table && table.length >= reqLen;
}
});
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java
index daffd90c..0524bb32 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java
@@ -2,7 +2,9 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.ec.AbstractECLookupTable;
import com.android.org.bouncycastle.math.ec.ECConstants;
import com.android.org.bouncycastle.math.ec.ECCurve;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
@@ -16,10 +18,10 @@ import com.android.org.bouncycastle.util.encoders.Hex;
*/
public class SecP192K1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"));
+ public static final BigInteger q = SecP192K1FieldElement.Q;
- private static final int SecP192K1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final int SECP192K1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP192K1_AFFINE_ZS = new ECFieldElement[] { new SecP192K1FieldElement(ECConstants.ONE) };
protected SecP192K1Point infinity;
@@ -31,10 +33,10 @@ public class SecP192K1Curve extends ECCurve.AbstractFp
this.a = fromBigInteger(ECConstants.ZERO);
this.b = fromBigInteger(BigInteger.valueOf(3));
- this.order = new BigInteger(1, Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"));
this.cofactor = BigInteger.valueOf(1);
- this.coord = SecP192K1_DEFAULT_COORDS;
+ this.coord = SECP192K1_DEFAULT_COORDS;
}
protected ECCurve cloneCurve()
@@ -68,14 +70,14 @@ public class SecP192K1Curve extends ECCurve.AbstractFp
return new SecP192K1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP192K1Point(this, x, y, withCompression);
+ return new SecP192K1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP192K1Point(this, x, y, zs, withCompression);
+ return new SecP192K1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -98,7 +100,7 @@ public class SecP192K1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -123,8 +125,41 @@ public class SecP192K1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP192K1FieldElement(x), new SecP192K1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat192.create(), y = Nat192.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP192K1FieldElement(x), new SecP192K1FieldElement(y), SECP192K1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat192.create();
+ SecP192K1Field.random(r, x);
+ return new SecP192K1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat192.create();
+ SecP192K1Field.randomMult(r, x);
+ return new SecP192K1FieldElement(x);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java
index 585259c1..82947f0b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java
@@ -2,9 +2,12 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat;
import com.android.org.bouncycastle.math.raw.Nat192;
+import com.android.org.bouncycastle.util.Pack;
/**
* @hide This class is not part of the Android public SDK API
@@ -13,8 +16,8 @@ public class SecP192K1Field
{
// 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1
static final int[] P = new int[]{ 0xFFFFEE37, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- static final int[] PExt = new int[]{ 0x013C4FD1, 0x00002392, 0x00000001, 0x00000000, 0x00000000,
- 0x00000000, 0xFFFFDC6E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x013C4FD1, 0x00002392, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0xFFFFDC6E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
private static final int[] PExtInv = new int[]{ 0xFEC3B02F, 0xFFFFDC6D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0x00002391, 0x00000002 };
private static final int P5 = 0xFFFFFFFF;
@@ -74,6 +77,22 @@ public class SecP192K1Field
}
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 6; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat192.createExt();
@@ -95,9 +114,9 @@ public class SecP192K1Field
public static void negate(int[] x, int[] z)
{
- if (Nat192.isZero(x))
+ if (0 != isZero(x))
{
- Nat192.zero(z);
+ Nat192.sub(P, P, z);
}
else
{
@@ -105,6 +124,26 @@ public class SecP192K1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[6 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 6);
+ }
+ while (0 == Nat.lessThan(6, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
long cc = Nat192.mul33Add(PInv33, xx, 6, xx, 0, z, 0);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java
index e01c34df..2cdc9dc3 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java
@@ -4,16 +4,17 @@ package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
-import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat192;
import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.encoders.Hex;
/**
* @hide This class is not part of the Android public SDK API
*/
public class SecP192K1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP192K1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"));
protected int[] x;
@@ -99,7 +100,7 @@ public class SecP192K1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat192.create();
- Mod.invert(SecP192K1Field.P, ((SecP192K1FieldElement)b).x, z);
+ SecP192K1Field.inv(((SecP192K1FieldElement)b).x, z);
SecP192K1Field.multiply(z, x, z);
return new SecP192K1FieldElement(z);
}
@@ -122,7 +123,7 @@ public class SecP192K1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP192K1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat192.create();
- Mod.invert(SecP192K1Field.P, x, z);
+ SecP192K1Field.inv(x, z);
return new SecP192K1FieldElement(z);
}
@@ -136,7 +137,7 @@ public class SecP192K1FieldElement extends ECFieldElement.AbstractFp
* Raise this element to the exponent 2^190 - 2^30 - 2^10 - 2^6 - 2^5 - 2^4 - 2^1
*
* Breaking up the exponent's binary representation into "repunits", we get:
- * { 159 1s } { 1 0s } { 19 1s } { 1 0s } { 3 1s } { 3 0s} { 3 1s } { 1 0s }
+ * { 159 1s } { 1 0s } { 19 1s } { 1 0s } { 3 1s } { 3 0s } { 3 1s } { 1 0s }
*
* Therefore we need an addition chain containing 3, 19, 159 (the lengths of the repunits)
* We use: 1, 2, [3], 6, 8, 16, [19], 35, 70, 140, [159]
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java
index 521b09ff..5f865f00 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java
@@ -12,56 +12,14 @@ import com.android.org.bouncycastle.math.raw.Nat192;
*/
public class SecP192K1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs,
- boolean withCompression)
+ SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -192,7 +150,7 @@ public class SecP192K1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
- return new SecP192K1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP192K1Point(curve, X3, Y3, zs);
}
// B.3 pg 62
@@ -252,7 +210,7 @@ public class SecP192K1Point extends ECPoint.AbstractFp
SecP192K1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP192K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, this.withCompression);
+ return new SecP192K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -297,6 +255,6 @@ public class SecP192K1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP192K1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP192K1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java
index ba69eedd..8905a3b8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java
@@ -2,7 +2,10 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.ec.AbstractECLookupTable;
+import com.android.org.bouncycastle.math.ec.ECConstants;
import com.android.org.bouncycastle.math.ec.ECCurve;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
import com.android.org.bouncycastle.math.ec.ECLookupTable;
@@ -15,10 +18,10 @@ import com.android.org.bouncycastle.util.encoders.Hex;
*/
public class SecP192R1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"));
+ public static final BigInteger q = SecP192R1FieldElement.Q;
- private static final int SecP192R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final int SECP192R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP192R1_AFFINE_ZS = new ECFieldElement[] { new SecP192R1FieldElement(ECConstants.ONE) };
protected SecP192R1Point infinity;
@@ -29,13 +32,13 @@ public class SecP192R1Curve extends ECCurve.AbstractFp
this.infinity = new SecP192R1Point(this, null, null);
this.a = fromBigInteger(new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")));
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")));
this.b = fromBigInteger(new BigInteger(1,
- Hex.decode("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")));
- this.order = new BigInteger(1, Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"));
+ Hex.decodeStrict("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"));
this.cofactor = BigInteger.valueOf(1);
- this.coord = SecP192R1_DEFAULT_COORDS;
+ this.coord = SECP192R1_DEFAULT_COORDS;
}
protected ECCurve cloneCurve()
@@ -69,14 +72,14 @@ public class SecP192R1Curve extends ECCurve.AbstractFp
return new SecP192R1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP192R1Point(this, x, y, withCompression);
+ return new SecP192R1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP192R1Point(this, x, y, zs, withCompression);
+ return new SecP192R1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -99,7 +102,7 @@ public class SecP192R1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -124,8 +127,41 @@ public class SecP192R1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP192R1FieldElement(x), new SecP192R1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat192.create(), y = Nat192.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP192R1FieldElement(x), new SecP192R1FieldElement(y), SECP192R1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat192.create();
+ SecP192R1Field.random(r, x);
+ return new SecP192R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat192.create();
+ SecP192R1Field.randomMult(r, x);
+ return new SecP192R1FieldElement(x);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java
index 0efd6f6b..39363547 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java
@@ -2,9 +2,12 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat;
import com.android.org.bouncycastle.math.raw.Nat192;
+import com.android.org.bouncycastle.util.Pack;
/**
* @hide This class is not part of the Android public SDK API
@@ -15,8 +18,8 @@ public class SecP192R1Field
// 2^192 - 2^64 - 1
static final int[] P = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001,
- 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000,
+ 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFE,
0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000002 };
private static final int P5 = 0xFFFFFFFF;
@@ -75,6 +78,22 @@ public class SecP192R1Field
}
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 6; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat192.createExt();
@@ -96,9 +115,9 @@ public class SecP192R1Field
public static void negate(int[] x, int[] z)
{
- if (Nat192.isZero(x))
+ if (0 != isZero(x))
{
- Nat192.zero(z);
+ Nat192.sub(P, P, z);
}
else
{
@@ -106,6 +125,26 @@ public class SecP192R1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[6 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 6);
+ }
+ while (0 == Nat.lessThan(6, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
long xx06 = xx[6] & M, xx07 = xx[7] & M, xx08 = xx[8] & M;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java
index d5c2b776..380a216b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java
@@ -4,16 +4,17 @@ package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
-import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat192;
import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.encoders.Hex;
/**
* @hide This class is not part of the Android public SDK API
*/
public class SecP192R1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP192R1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"));
protected int[] x;
@@ -99,7 +100,7 @@ public class SecP192R1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat192.create();
- Mod.invert(SecP192R1Field.P, ((SecP192R1FieldElement)b).x, z);
+ SecP192R1Field.inv(((SecP192R1FieldElement)b).x, z);
SecP192R1Field.multiply(z, x, z);
return new SecP192R1FieldElement(z);
}
@@ -122,7 +123,7 @@ public class SecP192R1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP192R1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat192.create();
- Mod.invert(SecP192R1Field.P, x, z);
+ SecP192R1Field.inv(x, z);
return new SecP192R1FieldElement(z);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java
index 70e50c7c..8fa1ef6a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java
@@ -12,55 +12,14 @@ import com.android.org.bouncycastle.math.raw.Nat192;
*/
public class SecP192R1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -191,7 +150,7 @@ public class SecP192R1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
- return new SecP192R1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP192R1Point(curve, X3, Y3, zs);
}
// B.3 pg 62
@@ -264,7 +223,7 @@ public class SecP192R1Point extends ECPoint.AbstractFp
SecP192R1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP192R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new SecP192R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -309,6 +268,6 @@ public class SecP192R1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP192R1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP192R1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java
index fd6814f9..1d3fa44b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java
@@ -2,7 +2,9 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.ec.AbstractECLookupTable;
import com.android.org.bouncycastle.math.ec.ECConstants;
import com.android.org.bouncycastle.math.ec.ECCurve;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
@@ -16,10 +18,10 @@ import com.android.org.bouncycastle.util.encoders.Hex;
*/
public class SecP224K1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D"));
+ public static final BigInteger q = SecP224K1FieldElement.Q;
private static final int SECP224K1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP224K1_AFFINE_ZS = new ECFieldElement[] { new SecP224K1FieldElement(ECConstants.ONE) };
protected SecP224K1Point infinity;
@@ -31,7 +33,7 @@ public class SecP224K1Curve extends ECCurve.AbstractFp
this.a = fromBigInteger(ECConstants.ZERO);
this.b = fromBigInteger(BigInteger.valueOf(5));
- this.order = new BigInteger(1, Hex.decode("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7"));
+ this.order = new BigInteger(1, Hex.decodeStrict("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7"));
this.cofactor = BigInteger.valueOf(1);
this.coord = SECP224K1_DEFAULT_COORDS;
}
@@ -67,14 +69,14 @@ public class SecP224K1Curve extends ECCurve.AbstractFp
return new SecP224K1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP224K1Point(this, x, y, withCompression);
+ return new SecP224K1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP224K1Point(this, x, y, zs, withCompression);
+ return new SecP224K1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -97,7 +99,7 @@ public class SecP224K1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -122,8 +124,48 @@ public class SecP224K1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP224K1FieldElement(x), new SecP224K1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat224.create(), y = Nat224.create();
+ int pos = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ int MASK = ((i ^ index) - 1) >> 31;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] ^= table[pos + j] & MASK;
+ y[j] ^= table[pos + FE_INTS + j] & MASK;
+ }
+
+ pos += (FE_INTS * 2);
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP224K1FieldElement(x), new SecP224K1FieldElement(y), SECP224K1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat224.create();
+ SecP224K1Field.random(r, x);
+ return new SecP224K1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat224.create();
+ SecP224K1Field.randomMult(r, x);
+ return new SecP224K1FieldElement(x);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java
index 0b102d2b..4bf4c314 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java
@@ -2,9 +2,12 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat;
import com.android.org.bouncycastle.math.raw.Nat224;
+import com.android.org.bouncycastle.util.Pack;
/**
* @hide This class is not part of the Android public SDK API
@@ -14,8 +17,8 @@ public class SecP224K1Field
// 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1
static final int[] P = new int[]{ 0xFFFFE56D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF };
- static final int[] PExt = new int[]{ 0x02C23069, 0x00003526, 0x00000001, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0xFFFFCADA, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x02C23069, 0x00003526, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xFFFFCADA, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
private static final int[] PExtInv = new int[]{ 0xFD3DCF97, 0xFFFFCAD9, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0x00003525, 0x00000002 };
private static final int P6 = 0xFFFFFFFF;
@@ -75,6 +78,22 @@ public class SecP224K1Field
}
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 7; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat224.createExt();
@@ -96,9 +115,9 @@ public class SecP224K1Field
public static void negate(int[] x, int[] z)
{
- if (Nat224.isZero(x))
+ if (0 != isZero(x))
{
- Nat224.zero(z);
+ Nat224.sub(P, P, z);
}
else
{
@@ -106,6 +125,26 @@ public class SecP224K1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[7 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 7);
+ }
+ while (0 == Nat.lessThan(7, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
long cc = Nat224.mul33Add(PInv33, xx, 7, xx, 0, z, 0);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java
index 966a766b..eefbf17d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java
@@ -4,16 +4,17 @@ package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
-import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat224;
import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.encoders.Hex;
/**
* @hide This class is not part of the Android public SDK API
*/
public class SecP224K1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP224K1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D"));
// Calculated as ECConstants.TWO.modPow(Q.shiftRight(2), Q)
private static final int[] PRECOMP_POW2 = new int[]{ 0x33bfd202, 0xdcfad133, 0x2287624a, 0xc3811ba8,
@@ -103,7 +104,7 @@ public class SecP224K1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat224.create();
- Mod.invert(SecP224K1Field.P, ((SecP224K1FieldElement)b).x, z);
+ SecP224K1Field.inv(((SecP224K1FieldElement)b).x, z);
SecP224K1Field.multiply(z, x, z);
return new SecP224K1FieldElement(z);
}
@@ -126,7 +127,7 @@ public class SecP224K1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP224K1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat224.create();
- Mod.invert(SecP224K1Field.P, x, z);
+ SecP224K1Field.inv(x, z);
return new SecP224K1FieldElement(z);
}
@@ -143,7 +144,7 @@ public class SecP224K1FieldElement extends ECFieldElement.AbstractFp
* First, raise this element to the exponent 2^221 - 2^29 - 2^9 - 2^8 - 2^6 - 2^4 - 2^1 (i.e. m + 1)
*
* Breaking up the exponent's binary representation into "repunits", we get:
- * { 191 1s } { 1 0s } { 19 1s } { 2 0s } { 1 1s } { 1 0s} { 1 1s } { 1 0s} { 3 1s } { 1 0s}
+ * { 191 1s } { 1 0s } { 19 1s } { 2 0s } { 1 1s } { 1 0s } { 1 1s } { 1 0s } { 3 1s } { 1 0s }
*
* Therefore we need an addition chain containing 1, 3, 19, 191 (the lengths of the repunits)
* We use: [1], 2, [3], 4, 8, 11, [19], 23, 42, 84, 107, [191]
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java
index 2b24c569..6c79c271 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java
@@ -12,56 +12,14 @@ import com.android.org.bouncycastle.math.raw.Nat224;
*/
public class SecP224K1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs,
- boolean withCompression)
+ SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -192,7 +150,7 @@ public class SecP224K1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
- return new SecP224K1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP224K1Point(curve, X3, Y3, zs);
}
// B.3 pg 62
@@ -252,7 +210,7 @@ public class SecP224K1Point extends ECPoint.AbstractFp
SecP224K1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP224K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, this.withCompression);
+ return new SecP224K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -297,6 +255,6 @@ public class SecP224K1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP224K1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP224K1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java
index c231ae77..cadc4e55 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java
@@ -2,7 +2,10 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.ec.AbstractECLookupTable;
+import com.android.org.bouncycastle.math.ec.ECConstants;
import com.android.org.bouncycastle.math.ec.ECCurve;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
import com.android.org.bouncycastle.math.ec.ECLookupTable;
@@ -15,10 +18,10 @@ import com.android.org.bouncycastle.util.encoders.Hex;
*/
public class SecP224R1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"));
+ public static final BigInteger q = SecP224R1FieldElement.Q;
- private static final int SecP224R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final int SECP224R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP224R1_AFFINE_ZS = new ECFieldElement[] { new SecP224R1FieldElement(ECConstants.ONE) };
protected SecP224R1Point infinity;
@@ -29,13 +32,13 @@ public class SecP224R1Curve extends ECCurve.AbstractFp
this.infinity = new SecP224R1Point(this, null, null);
this.a = fromBigInteger(new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")));
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")));
this.b = fromBigInteger(new BigInteger(1,
- Hex.decode("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")));
- this.order = new BigInteger(1, Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"));
+ Hex.decodeStrict("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"));
this.cofactor = BigInteger.valueOf(1);
- this.coord = SecP224R1_DEFAULT_COORDS;
+ this.coord = SECP224R1_DEFAULT_COORDS;
}
protected ECCurve cloneCurve()
@@ -69,14 +72,14 @@ public class SecP224R1Curve extends ECCurve.AbstractFp
return new SecP224R1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP224R1Point(this, x, y, withCompression);
+ return new SecP224R1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP224R1Point(this, x, y, zs, withCompression);
+ return new SecP224R1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -99,7 +102,7 @@ public class SecP224R1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -124,8 +127,41 @@ public class SecP224R1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP224R1FieldElement(x), new SecP224R1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat224.create(), y = Nat224.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP224R1FieldElement(x), new SecP224R1FieldElement(y), SECP224R1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat224.create();
+ SecP224R1Field.random(r, x);
+ return new SecP224R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat224.create();
+ SecP224R1Field.randomMult(r, x);
+ return new SecP224R1FieldElement(x);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java
index c8d247e7..44182ebe 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java
@@ -2,9 +2,12 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat;
import com.android.org.bouncycastle.math.raw.Nat224;
+import com.android.org.bouncycastle.util.Pack;
/**
* @hide This class is not part of the Android public SDK API
@@ -14,9 +17,10 @@ public class SecP224R1Field
private static final long M = 0xFFFFFFFFL;
// 2^224 - 2^96 + 1
- static final int[] P = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
- 0xFFFFFFFF, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ static final int[] P = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0x00000000,
0x00000000, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001 };
private static final int P6 = 0xFFFFFFFF;
@@ -75,6 +79,22 @@ public class SecP224R1Field
}
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 7; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat224.createExt();
@@ -96,9 +116,9 @@ public class SecP224R1Field
public static void negate(int[] x, int[] z)
{
- if (Nat224.isZero(x))
+ if (0 != isZero(x))
{
- Nat224.zero(z);
+ Nat224.sub(P, P, z);
}
else
{
@@ -106,6 +126,26 @@ public class SecP224R1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[7 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 7);
+ }
+ while (0 == Nat.lessThan(7, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
long xx10 = xx[10] & M, xx11 = xx[11] & M, xx12 = xx[12] & M, xx13 = xx[13] & M;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java
index 35b79dbe..1239a973 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java
@@ -8,13 +8,15 @@ import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat;
import com.android.org.bouncycastle.math.raw.Nat224;
import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.encoders.Hex;
/**
* @hide This class is not part of the Android public SDK API
*/
public class SecP224R1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP224R1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"));
protected int[] x;
@@ -100,7 +102,7 @@ public class SecP224R1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat224.create();
- Mod.invert(SecP224R1Field.P, ((SecP224R1FieldElement)b).x, z);
+ SecP224R1Field.inv(((SecP224R1FieldElement)b).x, z);
SecP224R1Field.multiply(z, x, z);
return new SecP224R1FieldElement(z);
}
@@ -123,7 +125,7 @@ public class SecP224R1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP224R1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat224.create();
- Mod.invert(SecP224R1Field.P, x, z);
+ SecP224R1Field.inv(x, z);
return new SecP224R1FieldElement(z);
}
@@ -266,7 +268,7 @@ public class SecP224R1FieldElement extends ECFieldElement.AbstractFp
if (Nat224.isZero(d1))
{
- Mod.invert(SecP224R1Field.P, e0, t);
+ SecP224R1Field.inv(e0, t);
SecP224R1Field.multiply(t, d0, t);
return true;
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java
index ae83d369..f93c7e2b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java
@@ -12,55 +12,14 @@ import com.android.org.bouncycastle.math.raw.Nat224;
*/
public class SecP224R1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -190,7 +149,7 @@ public class SecP224R1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
- return new SecP224R1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP224R1Point(curve, X3, Y3, zs);
}
public ECPoint twice()
@@ -262,7 +221,7 @@ public class SecP224R1Point extends ECPoint.AbstractFp
SecP224R1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP224R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new SecP224R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -307,6 +266,6 @@ public class SecP224R1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP224R1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP224R1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java
index fd9f8b0c..e596ae36 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java
@@ -2,7 +2,9 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.ec.AbstractECLookupTable;
import com.android.org.bouncycastle.math.ec.ECConstants;
import com.android.org.bouncycastle.math.ec.ECCurve;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
@@ -16,10 +18,10 @@ import com.android.org.bouncycastle.util.encoders.Hex;
*/
public class SecP256K1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"));
+ public static final BigInteger q = SecP256K1FieldElement.Q;
private static final int SECP256K1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP256K1_AFFINE_ZS = new ECFieldElement[] { new SecP256K1FieldElement(ECConstants.ONE) };
protected SecP256K1Point infinity;
@@ -31,7 +33,7 @@ public class SecP256K1Curve extends ECCurve.AbstractFp
this.a = fromBigInteger(ECConstants.ZERO);
this.b = fromBigInteger(BigInteger.valueOf(7));
- this.order = new BigInteger(1, Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"));
this.cofactor = BigInteger.valueOf(1);
this.coord = SECP256K1_DEFAULT_COORDS;
}
@@ -67,14 +69,14 @@ public class SecP256K1Curve extends ECCurve.AbstractFp
return new SecP256K1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP256K1Point(this, x, y, withCompression);
+ return new SecP256K1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP256K1Point(this, x, y, zs, withCompression);
+ return new SecP256K1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -97,7 +99,7 @@ public class SecP256K1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -122,8 +124,41 @@ public class SecP256K1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP256K1FieldElement(x), new SecP256K1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat256.create(), y = Nat256.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP256K1FieldElement(x), new SecP256K1FieldElement(y), SECP256K1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat256.create();
+ SecP256K1Field.random(r, x);
+ return new SecP256K1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat256.create();
+ SecP256K1Field.randomMult(r, x);
+ return new SecP256K1FieldElement(x);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
index c60248f7..0d2ca9c8 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
@@ -2,9 +2,12 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat;
import com.android.org.bouncycastle.math.raw.Nat256;
+import com.android.org.bouncycastle.util.Pack;
/**
* @hide This class is not part of the Android public SDK API
@@ -14,9 +17,9 @@ public class SecP256K1Field
// 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
static final int[] P = new int[]{ 0xFFFFFC2F, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF };
- static final int[] PExt = new int[]{ 0x000E90A1, 0x000007A2, 0x00000001, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0xFFFFF85E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x000E90A1, 0x000007A2, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xFFFFF85E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF };
private static final int[] PExtInv = new int[]{ 0xFFF16F5F, 0xFFFFF85D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000007A1, 0x00000002 };
private static final int P7 = 0xFFFFFFFF;
@@ -76,6 +79,22 @@ public class SecP256K1Field
}
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 8; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat256.createExt();
@@ -97,9 +116,9 @@ public class SecP256K1Field
public static void negate(int[] x, int[] z)
{
- if (Nat256.isZero(x))
+ if (0 != isZero(x))
{
- Nat256.zero(z);
+ Nat256.sub(P, P, z);
}
else
{
@@ -107,6 +126,26 @@ public class SecP256K1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[8 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 8);
+ }
+ while (0 == Nat.lessThan(8, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
long cc = Nat256.mul33Add(PInv33, xx, 8, xx, 0, z, 0);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
index 7d8f2945..f5077bef 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
@@ -4,16 +4,17 @@ package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
-import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat256;
import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.encoders.Hex;
/**
* @hide This class is not part of the Android public SDK API
*/
public class SecP256K1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP256K1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"));
protected int[] x;
@@ -99,7 +100,7 @@ public class SecP256K1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat256.create();
- Mod.invert(SecP256K1Field.P, ((SecP256K1FieldElement)b).x, z);
+ SecP256K1Field.inv(((SecP256K1FieldElement)b).x, z);
SecP256K1Field.multiply(z, x, z);
return new SecP256K1FieldElement(z);
}
@@ -122,7 +123,7 @@ public class SecP256K1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP256K1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat256.create();
- Mod.invert(SecP256K1Field.P, x, z);
+ SecP256K1Field.inv(x, z);
return new SecP256K1FieldElement(z);
}
@@ -137,7 +138,7 @@ public class SecP256K1FieldElement extends ECFieldElement.AbstractFp
* Raise this element to the exponent 2^254 - 2^30 - 2^7 - 2^6 - 2^5 - 2^4 - 2^2
*
* Breaking up the exponent's binary representation into "repunits", we get:
- * { 223 1s } { 1 0s } { 22 1s } { 4 0s } { 2 1s } { 2 0s}
+ * { 223 1s } { 1 0s } { 22 1s } { 4 0s } { 2 1s } { 2 0s }
*
* Therefore we need an addition chain containing 2, 22, 223 (the lengths of the repunits)
* We use: 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223]
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
index f08984d9..733663c7 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
@@ -12,56 +12,14 @@ import com.android.org.bouncycastle.math.raw.Nat256;
*/
public class SecP256K1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs,
- boolean withCompression)
+ SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -192,7 +150,7 @@ public class SecP256K1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
- return new SecP256K1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP256K1Point(curve, X3, Y3, zs);
}
// B.3 pg 62
@@ -252,7 +210,7 @@ public class SecP256K1Point extends ECPoint.AbstractFp
SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP256K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, this.withCompression);
+ return new SecP256K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -297,6 +255,6 @@ public class SecP256K1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP256K1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP256K1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java
index 1cfc5dd3..3d315cc2 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java
@@ -2,7 +2,10 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.ec.AbstractECLookupTable;
+import com.android.org.bouncycastle.math.ec.ECConstants;
import com.android.org.bouncycastle.math.ec.ECCurve;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
import com.android.org.bouncycastle.math.ec.ECLookupTable;
@@ -15,10 +18,10 @@ import com.android.org.bouncycastle.util.encoders.Hex;
*/
public class SecP256R1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"));
+ public static final BigInteger q = SecP256R1FieldElement.Q;
- private static final int SecP256R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final int SECP256R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP256R1_AFFINE_ZS = new ECFieldElement[] { new SecP256R1FieldElement(ECConstants.ONE) };
protected SecP256R1Point infinity;
@@ -29,13 +32,13 @@ public class SecP256R1Curve extends ECCurve.AbstractFp
this.infinity = new SecP256R1Point(this, null, null);
this.a = fromBigInteger(new BigInteger(1,
- Hex.decode("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")));
+ Hex.decodeStrict("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")));
this.b = fromBigInteger(new BigInteger(1,
- Hex.decode("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")));
- this.order = new BigInteger(1, Hex.decode("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"));
+ Hex.decodeStrict("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"));
this.cofactor = BigInteger.valueOf(1);
- this.coord = SecP256R1_DEFAULT_COORDS;
+ this.coord = SECP256R1_DEFAULT_COORDS;
}
protected ECCurve cloneCurve()
@@ -69,14 +72,14 @@ public class SecP256R1Curve extends ECCurve.AbstractFp
return new SecP256R1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP256R1Point(this, x, y, withCompression);
+ return new SecP256R1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP256R1Point(this, x, y, zs, withCompression);
+ return new SecP256R1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -99,7 +102,7 @@ public class SecP256R1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -124,8 +127,41 @@ public class SecP256R1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP256R1FieldElement(x), new SecP256R1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat256.create(), y = Nat256.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP256R1FieldElement(x), new SecP256R1FieldElement(y), SECP256R1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat256.create();
+ SecP256R1Field.random(r, x);
+ return new SecP256R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat256.create();
+ SecP256R1Field.randomMult(r, x);
+ return new SecP256R1FieldElement(x);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
index 0c3405b3..9d3b8980 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
@@ -2,9 +2,12 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat;
import com.android.org.bouncycastle.math.raw.Nat256;
+import com.android.org.bouncycastle.util.Pack;
/**
* @hide This class is not part of the Android public SDK API
@@ -16,9 +19,9 @@ public class SecP256R1Field
// 2^256 - 2^224 + 2^192 + 2^96 - 1
static final int[] P = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,
0x00000001, 0xFFFFFFFF };
- static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0x00000001, 0xFFFFFFFE,
- 0x00000002, 0xFFFFFFFE };
+ private static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0x00000001, 0xFFFFFFFE, 0x00000002,
+ 0xFFFFFFFE };
private static final int P7 = 0xFFFFFFFF;
private static final int PExt15s1 = 0xFFFFFFFE >>> 1;
@@ -72,6 +75,22 @@ public class SecP256R1Field
}
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 8; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat256.createExt();
@@ -90,9 +109,9 @@ public class SecP256R1Field
public static void negate(int[] x, int[] z)
{
- if (Nat256.isZero(x))
+ if (0 != isZero(x))
{
- Nat256.zero(z);
+ Nat256.sub(P, P, z);
}
else
{
@@ -100,6 +119,26 @@ public class SecP256R1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[8 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 8);
+ }
+ while (0 == Nat.lessThan(8, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
long xx08 = xx[8] & M, xx09 = xx[9] & M, xx10 = xx[10] & M, xx11 = xx[11] & M;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
index d43c0e13..e84cd477 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
@@ -4,16 +4,17 @@ package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
-import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat256;
import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.encoders.Hex;
/**
* @hide This class is not part of the Android public SDK API
*/
public class SecP256R1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP256R1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"));
protected int[] x;
@@ -99,7 +100,7 @@ public class SecP256R1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat256.create();
- Mod.invert(SecP256R1Field.P, ((SecP256R1FieldElement)b).x, z);
+ SecP256R1Field.inv(((SecP256R1FieldElement)b).x, z);
SecP256R1Field.multiply(z, x, z);
return new SecP256R1FieldElement(z);
}
@@ -122,7 +123,7 @@ public class SecP256R1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP256R1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat256.create();
- Mod.invert(SecP256R1Field.P, x, z);
+ SecP256R1Field.inv(x, z);
return new SecP256R1FieldElement(z);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
index 89e8083f..74627cad 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
@@ -12,55 +12,14 @@ import com.android.org.bouncycastle.math.raw.Nat256;
*/
public class SecP256R1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -190,7 +149,7 @@ public class SecP256R1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
- return new SecP256R1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP256R1Point(curve, X3, Y3, zs);
}
public ECPoint twice()
@@ -262,7 +221,7 @@ public class SecP256R1Point extends ECPoint.AbstractFp
SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP256R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new SecP256R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -307,6 +266,6 @@ public class SecP256R1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP256R1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP256R1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java
index 21254374..1342081b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java
@@ -2,7 +2,10 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.ec.AbstractECLookupTable;
+import com.android.org.bouncycastle.math.ec.ECConstants;
import com.android.org.bouncycastle.math.ec.ECCurve;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
import com.android.org.bouncycastle.math.ec.ECLookupTable;
@@ -15,10 +18,10 @@ import com.android.org.bouncycastle.util.encoders.Hex;
*/
public class SecP384R1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"));
+ public static final BigInteger q = SecP384R1FieldElement.Q;
- private static final int SecP384R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final int SECP384R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP384R1_AFFINE_ZS = new ECFieldElement[] { new SecP384R1FieldElement(ECConstants.ONE) };
protected SecP384R1Point infinity;
@@ -29,13 +32,13 @@ public class SecP384R1Curve extends ECCurve.AbstractFp
this.infinity = new SecP384R1Point(this, null, null);
this.a = fromBigInteger(new BigInteger(1,
- Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")));
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")));
this.b = fromBigInteger(new BigInteger(1,
- Hex.decode("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")));
- this.order = new BigInteger(1, Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"));
+ Hex.decodeStrict("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"));
this.cofactor = BigInteger.valueOf(1);
- this.coord = SecP384R1_DEFAULT_COORDS;
+ this.coord = SECP384R1_DEFAULT_COORDS;
}
protected ECCurve cloneCurve()
@@ -69,14 +72,14 @@ public class SecP384R1Curve extends ECCurve.AbstractFp
return new SecP384R1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP384R1Point(this, x, y, withCompression);
+ return new SecP384R1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP384R1Point(this, x, y, zs, withCompression);
+ return new SecP384R1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -99,7 +102,7 @@ public class SecP384R1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -124,8 +127,41 @@ public class SecP384R1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP384R1FieldElement(x), new SecP384R1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat.create(FE_INTS), y = Nat.create(FE_INTS);
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP384R1FieldElement(x), new SecP384R1FieldElement(y), SECP384R1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat.create(12);
+ SecP384R1Field.random(r, x);
+ return new SecP384R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat.create(12);
+ SecP384R1Field.randomMult(r, x);
+ return new SecP384R1FieldElement(x);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
index d632e030..8115b8e5 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
@@ -2,9 +2,12 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat;
import com.android.org.bouncycastle.math.raw.Nat384;
+import com.android.org.bouncycastle.util.Pack;
/**
* @hide This class is not part of the Android public SDK API
@@ -16,12 +19,12 @@ public class SecP384R1Field
// 2^384 - 2^128 - 2^96 + 2^32 - 1
static final int[] P = new int[]{ 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- static final int[] PExt = new int[]{ 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE,
+ private static final int[] PExt = new int[]{ 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE,
0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x00000001, 0x00000000,
0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0x00000001,
- 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0xFFFFFFFE, 0xFFFFFFFF,
- 0x00000001, 0x00000002 };
+ private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF,
+ 0x00000001, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0xFFFFFFFE,
+ 0xFFFFFFFF, 0x00000001, 0x00000002 };
private static final int P11 = 0xFFFFFFFF;
private static final int PExt23 = 0xFFFFFFFF;
@@ -78,6 +81,22 @@ public class SecP384R1Field
}
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 12; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat.create(24);
@@ -87,9 +106,9 @@ public class SecP384R1Field
public static void negate(int[] x, int[] z)
{
- if (Nat.isZero(12, x))
+ if (0 != isZero(x))
{
- Nat.zero(12, z);
+ Nat.sub(12, P, P, z);
}
else
{
@@ -97,6 +116,26 @@ public class SecP384R1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[12 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 12);
+ }
+ while (0 == Nat.lessThan(12, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
long xx16 = xx[16] & M, xx17 = xx[17] & M, xx18 = xx[18] & M, xx19 = xx[19] & M;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
index fd5f8c19..2c7cd14a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
@@ -4,16 +4,17 @@ package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
-import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat;
import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.encoders.Hex;
/**
* @hide This class is not part of the Android public SDK API
*/
public class SecP384R1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP384R1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"));
protected int[] x;
@@ -99,7 +100,7 @@ public class SecP384R1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat.create(12);
- Mod.invert(SecP384R1Field.P, ((SecP384R1FieldElement)b).x, z);
+ SecP384R1Field.inv(((SecP384R1FieldElement)b).x, z);
SecP384R1Field.multiply(z, x, z);
return new SecP384R1FieldElement(z);
}
@@ -122,7 +123,7 @@ public class SecP384R1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP384R1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat.create(12);
- Mod.invert(SecP384R1Field.P, x, z);
+ SecP384R1Field.inv(x, z);
return new SecP384R1FieldElement(z);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
index 662a909b..c0ccd530 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
@@ -12,55 +12,14 @@ import com.android.org.bouncycastle.math.raw.Nat384;
*/
public class SecP384R1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -191,7 +150,7 @@ public class SecP384R1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
- return new SecP384R1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP384R1Point(curve, X3, Y3, zs);
}
public ECPoint twice()
@@ -263,7 +222,7 @@ public class SecP384R1Point extends ECPoint.AbstractFp
SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP384R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new SecP384R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -308,6 +267,6 @@ public class SecP384R1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP384R1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP384R1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java
index a727578e..4802d40a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java
@@ -2,7 +2,10 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.ec.AbstractECLookupTable;
+import com.android.org.bouncycastle.math.ec.ECConstants;
import com.android.org.bouncycastle.math.ec.ECCurve;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
import com.android.org.bouncycastle.math.ec.ECLookupTable;
@@ -15,10 +18,10 @@ import com.android.org.bouncycastle.util.encoders.Hex;
*/
public class SecP521R1Curve extends ECCurve.AbstractFp
{
- public static final BigInteger q = new BigInteger(1,
- Hex.decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
+ public static final BigInteger q = SecP521R1FieldElement.Q;
- private static final int SecP521R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final int SECP521R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP521R1_AFFINE_ZS = new ECFieldElement[] { new SecP521R1FieldElement(ECConstants.ONE) };
protected SecP521R1Point infinity;
@@ -29,13 +32,13 @@ public class SecP521R1Curve extends ECCurve.AbstractFp
this.infinity = new SecP521R1Point(this, null, null);
this.a = fromBigInteger(new BigInteger(1,
- Hex.decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC")));
+ Hex.decodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC")));
this.b = fromBigInteger(new BigInteger(1,
- Hex.decode("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00")));
- this.order = new BigInteger(1, Hex.decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"));
+ Hex.decodeStrict("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00")));
+ this.order = new BigInteger(1, Hex.decodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"));
this.cofactor = BigInteger.valueOf(1);
- this.coord = SecP521R1_DEFAULT_COORDS;
+ this.coord = SECP521R1_DEFAULT_COORDS;
}
protected ECCurve cloneCurve()
@@ -69,14 +72,14 @@ public class SecP521R1Curve extends ECCurve.AbstractFp
return new SecP521R1FieldElement(x);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
{
- return new SecP521R1Point(this, x, y, withCompression);
+ return new SecP521R1Point(this, x, y);
}
- protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
- return new SecP521R1Point(this, x, y, zs, withCompression);
+ return new SecP521R1Point(this, x, y, zs);
}
public ECPoint getInfinity()
@@ -99,7 +102,7 @@ public class SecP521R1Curve extends ECCurve.AbstractFp
}
}
- return new ECLookupTable()
+ return new AbstractECLookupTable()
{
public int getSize()
{
@@ -124,8 +127,41 @@ public class SecP521R1Curve extends ECCurve.AbstractFp
pos += (FE_INTS * 2);
}
- return createRawPoint(new SecP521R1FieldElement(x), new SecP521R1FieldElement(y), false);
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat.create(FE_INTS), y = Nat.create(FE_INTS);
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] ^= table[pos + j];
+ y[j] ^= table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP521R1FieldElement(x), new SecP521R1FieldElement(y), SECP521R1_AFFINE_ZS);
}
};
}
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat.create(17);
+ SecP521R1Field.random(r, x);
+ return new SecP521R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat.create(17);
+ SecP521R1Field.randomMult(r, x);
+ return new SecP521R1FieldElement(x);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
index 83cf10e3..0e4431d7 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
@@ -2,9 +2,12 @@
package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
+import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat;
import com.android.org.bouncycastle.math.raw.Nat512;
+import com.android.org.bouncycastle.util.Pack;
/**
* @hide This class is not part of the Android public SDK API
@@ -55,6 +58,22 @@ public class SecP521R1Field
z[16] = (x16 >>> 1) | (c >>> 23);
}
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 17; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static void multiply(int[] x, int[] y, int[] z)
{
int[] tt = Nat.create(33);
@@ -64,9 +83,9 @@ public class SecP521R1Field
public static void negate(int[] x, int[] z)
{
- if (Nat.isZero(17, x))
+ if (0 != isZero(x))
{
- Nat.zero(17, z);
+ Nat.sub(17, P, P, z);
}
else
{
@@ -74,6 +93,27 @@ public class SecP521R1Field
}
}
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[17 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 17);
+ z[16] &= P16;
+ }
+ while (0 == Nat.lessThan(17, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
public static void reduce(int[] xx, int[] z)
{
// assert xx[32] >>> 18 == 0;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
index 633692bc..8f502932 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
@@ -4,16 +4,17 @@ package com.android.org.bouncycastle.math.ec.custom.sec;
import java.math.BigInteger;
import com.android.org.bouncycastle.math.ec.ECFieldElement;
-import com.android.org.bouncycastle.math.raw.Mod;
import com.android.org.bouncycastle.math.raw.Nat;
import com.android.org.bouncycastle.util.Arrays;
+import com.android.org.bouncycastle.util.encoders.Hex;
/**
* @hide This class is not part of the Android public SDK API
*/
public class SecP521R1FieldElement extends ECFieldElement.AbstractFp
{
- public static final BigInteger Q = SecP521R1Curve.q;
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
protected int[] x;
@@ -99,7 +100,7 @@ public class SecP521R1FieldElement extends ECFieldElement.AbstractFp
{
// return multiply(b.invert());
int[] z = Nat.create(17);
- Mod.invert(SecP521R1Field.P, ((SecP521R1FieldElement)b).x, z);
+ SecP521R1Field.inv(((SecP521R1FieldElement)b).x, z);
SecP521R1Field.multiply(z, x, z);
return new SecP521R1FieldElement(z);
}
@@ -122,7 +123,7 @@ public class SecP521R1FieldElement extends ECFieldElement.AbstractFp
{
// return new SecP521R1FieldElement(toBigInteger().modInverse(Q));
int[] z = Nat.create(17);
- Mod.invert(SecP521R1Field.P, x, z);
+ SecP521R1Field.inv(x, z);
return new SecP521R1FieldElement(z);
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
index f36868c3..6e91cd46 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
@@ -11,55 +11,14 @@ import com.android.org.bouncycastle.math.raw.Nat;
*/
public class SecP521R1Point extends ECPoint.AbstractFp
{
- /**
- * Create a point which encodes with point compression.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- *
- * @deprecated Use ECCurve.createPoint to construct points
- */
- public SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
- {
- this(curve, x, y, false);
- }
-
- /**
- * Create a point that encodes with or without point compresion.
- *
- * @param curve
- * the curve to use
- * @param x
- * affine x co-ordinate
- * @param y
- * affine y co-ordinate
- * @param withCompression
- * if true encode with point compression
- *
- * @deprecated per-point compression property will be removed, refer
- * {@link #getEncoded(boolean)}
- */
- public SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
{
super(curve, x, y);
-
- if ((x == null) != (y == null))
- {
- throw new IllegalArgumentException("Exactly one of the field elements is null");
- }
-
- this.withCompression = withCompression;
}
- SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
{
super(curve, x, y, zs);
-
- this.withCompression = withCompression;
}
protected ECPoint detach()
@@ -186,7 +145,7 @@ public class SecP521R1Point extends ECPoint.AbstractFp
ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
- return new SecP521R1Point(curve, X3, Y3, zs, this.withCompression);
+ return new SecP521R1Point(curve, X3, Y3, zs);
}
public ECPoint twice()
@@ -257,7 +216,7 @@ public class SecP521R1Point extends ECPoint.AbstractFp
SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x);
}
- return new SecP521R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ return new SecP521R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
}
public ECPoint twicePlus(ECPoint b)
@@ -332,6 +291,6 @@ public class SecP521R1Point extends ECPoint.AbstractFp
return this;
}
- return new SecP521R1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ return new SecP521R1Point(curve, this.x, this.y.negate(), this.zs);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/EndoPreCompInfo.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/EndoPreCompInfo.java
new file mode 100644
index 00000000..8b7b03df
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/EndoPreCompInfo.java
@@ -0,0 +1,35 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.math.ec.endo;
+
+import com.android.org.bouncycastle.math.ec.ECPoint;
+import com.android.org.bouncycastle.math.ec.PreCompInfo;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EndoPreCompInfo implements PreCompInfo
+{
+ protected ECEndomorphism endomorphism;
+
+ protected ECPoint mappedPoint;
+
+ public ECEndomorphism getEndomorphism()
+ {
+ return endomorphism;
+ }
+
+ public void setEndomorphism(ECEndomorphism endomorphism)
+ {
+ this.endomorphism = endomorphism;
+ }
+
+ public ECPoint getMappedPoint()
+ {
+ return mappedPoint;
+ }
+
+ public void setMappedPoint(ECPoint mappedPoint)
+ {
+ this.mappedPoint = mappedPoint;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/EndoUtil.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/EndoUtil.java
new file mode 100644
index 00000000..708f035e
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/EndoUtil.java
@@ -0,0 +1,77 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+import com.android.org.bouncycastle.math.ec.ECConstants;
+import com.android.org.bouncycastle.math.ec.ECCurve;
+import com.android.org.bouncycastle.math.ec.ECPoint;
+import com.android.org.bouncycastle.math.ec.PreCompCallback;
+import com.android.org.bouncycastle.math.ec.PreCompInfo;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class EndoUtil
+{
+ public static final String PRECOMP_NAME = "bc_endo";
+
+ public static BigInteger[] decomposeScalar(ScalarSplitParameters p, BigInteger k)
+ {
+ int bits = p.getBits();
+ BigInteger b1 = calculateB(k, p.getG1(), bits);
+ BigInteger b2 = calculateB(k, p.getG2(), bits);
+
+ BigInteger a = k.subtract((b1.multiply(p.getV1A())).add(b2.multiply(p.getV2A())));
+ BigInteger b = (b1.multiply(p.getV1B())).add(b2.multiply(p.getV2B())).negate();
+
+ return new BigInteger[]{ a, b };
+ }
+
+ public static ECPoint mapPoint(final ECEndomorphism endomorphism, final ECPoint p)
+ {
+ final ECCurve c = p.getCurve();
+
+ EndoPreCompInfo precomp = (EndoPreCompInfo)c.precompute(p, PRECOMP_NAME, new PreCompCallback()
+ {
+ public PreCompInfo precompute(PreCompInfo existing)
+ {
+ EndoPreCompInfo existingEndo = (existing instanceof EndoPreCompInfo) ? (EndoPreCompInfo)existing : null;
+
+ if (checkExisting(existingEndo, endomorphism))
+ {
+ return existingEndo;
+ }
+
+ ECPoint mappedPoint = endomorphism.getPointMap().map(p);
+
+ EndoPreCompInfo result = new EndoPreCompInfo();
+ result.setEndomorphism(endomorphism);
+ result.setMappedPoint(mappedPoint);
+ return result;
+ }
+
+ private boolean checkExisting(EndoPreCompInfo existingEndo, ECEndomorphism endomorphism)
+ {
+ return null != existingEndo
+ && existingEndo.getEndomorphism() == endomorphism
+ && existingEndo.getMappedPoint() != null;
+ }
+ });
+
+ return precomp.getMappedPoint();
+ }
+
+ private static BigInteger calculateB(BigInteger k, BigInteger g, int t)
+ {
+ boolean negative = (g.signum() < 0);
+ BigInteger b = k.multiply(g.abs());
+ boolean extra = b.testBit(t - 1);
+ b = b.shiftRight(t);
+ if (extra)
+ {
+ b = b.add(ECConstants.ONE);
+ }
+ return negative ? b.negate() : b;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeAEndomorphism.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeAEndomorphism.java
new file mode 100644
index 00000000..f15e649a
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeAEndomorphism.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+import com.android.org.bouncycastle.math.ec.ECCurve;
+import com.android.org.bouncycastle.math.ec.ECPointMap;
+import com.android.org.bouncycastle.math.ec.ScaleYNegateXPointMap;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GLVTypeAEndomorphism implements GLVEndomorphism
+{
+ protected final GLVTypeAParameters parameters;
+ protected final ECPointMap pointMap;
+
+ public GLVTypeAEndomorphism(ECCurve curve, GLVTypeAParameters parameters)
+ {
+ /*
+ * NOTE: 'curve' MUST only be used to create a suitable ECFieldElement. Due to the way
+ * ECCurve configuration works, 'curve' will not be the actual instance of ECCurve that the
+ * endomorphism is being used with.
+ */
+
+ this.parameters = parameters;
+ this.pointMap = new ScaleYNegateXPointMap(curve.fromBigInteger(parameters.getI()));
+ }
+
+ public BigInteger[] decomposeScalar(BigInteger k)
+ {
+ return EndoUtil.decomposeScalar(parameters.getSplitParams(), k);
+ }
+
+ public ECPointMap getPointMap()
+ {
+ return pointMap;
+ }
+
+ public boolean hasEfficientPointMap()
+ {
+ return true;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeAParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeAParameters.java
new file mode 100644
index 00000000..858a4a14
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeAParameters.java
@@ -0,0 +1,35 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GLVTypeAParameters
+{
+ protected final BigInteger i, lambda;
+ protected final ScalarSplitParameters splitParams;
+
+ public GLVTypeAParameters(BigInteger i, BigInteger lambda, ScalarSplitParameters splitParams)
+ {
+ this.i = i;
+ this.lambda = lambda;
+ this.splitParams = splitParams;
+ }
+
+ public BigInteger getI()
+ {
+ return i;
+ }
+
+ public BigInteger getLambda()
+ {
+ return lambda;
+ }
+
+ public ScalarSplitParameters getSplitParams()
+ {
+ return splitParams;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java
index 629f0ddf..c3eb8bb6 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java
@@ -3,7 +3,6 @@ package com.android.org.bouncycastle.math.ec.endo;
import java.math.BigInteger;
-import com.android.org.bouncycastle.math.ec.ECConstants;
import com.android.org.bouncycastle.math.ec.ECCurve;
import com.android.org.bouncycastle.math.ec.ECPointMap;
import com.android.org.bouncycastle.math.ec.ScaleXPointMap;
@@ -13,28 +12,24 @@ import com.android.org.bouncycastle.math.ec.ScaleXPointMap;
*/
public class GLVTypeBEndomorphism implements GLVEndomorphism
{
- protected final ECCurve curve;
protected final GLVTypeBParameters parameters;
protected final ECPointMap pointMap;
public GLVTypeBEndomorphism(ECCurve curve, GLVTypeBParameters parameters)
{
- this.curve = curve;
+ /*
+ * NOTE: 'curve' MUST only be used to create a suitable ECFieldElement. Due to the way
+ * ECCurve configuration works, 'curve' will not be the actual instance of ECCurve that the
+ * endomorphism is being used with.
+ */
+
this.parameters = parameters;
this.pointMap = new ScaleXPointMap(curve.fromBigInteger(parameters.getBeta()));
}
public BigInteger[] decomposeScalar(BigInteger k)
{
- int bits = parameters.getBits();
- BigInteger b1 = calculateB(k, parameters.getG1(), bits);
- BigInteger b2 = calculateB(k, parameters.getG2(), bits);
-
- GLVTypeBParameters p = parameters;
- BigInteger a = k.subtract((b1.multiply(p.getV1A())).add(b2.multiply(p.getV2A())));
- BigInteger b = (b1.multiply(p.getV1B())).add(b2.multiply(p.getV2B())).negate();
-
- return new BigInteger[]{ a, b };
+ return EndoUtil.decomposeScalar(parameters.getSplitParams(), k);
}
public ECPointMap getPointMap()
@@ -46,17 +41,4 @@ public class GLVTypeBEndomorphism implements GLVEndomorphism
{
return true;
}
-
- protected BigInteger calculateB(BigInteger k, BigInteger g, int t)
- {
- boolean negative = (g.signum() < 0);
- BigInteger b = k.multiply(g.abs());
- boolean extra = b.testBit(t - 1);
- b = b.shiftRight(t);
- if (extra)
- {
- b = b.add(ECConstants.ONE);
- }
- return negative ? b.negate() : b;
- }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
index 0c558131..e7f3fe02 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
@@ -8,35 +8,25 @@ import java.math.BigInteger;
*/
public class GLVTypeBParameters
{
- private static void checkVector(BigInteger[] v, String name)
- {
- if (v == null || v.length != 2 || v[0] == null || v[1] == null)
- {
- throw new IllegalArgumentException("'" + name + "' must consist of exactly 2 (non-null) values");
- }
- }
-
- protected final BigInteger beta;
- protected final BigInteger lambda;
- protected final BigInteger v1A, v1B, v2A, v2B;
- protected final BigInteger g1, g2;
- protected final int bits;
+ protected final BigInteger beta, lambda;
+ protected final ScalarSplitParameters splitParams;
+ /**
+ * @deprecated Use constructor taking a {@link ScalarSplitParameters} instead.
+ */
public GLVTypeBParameters(BigInteger beta, BigInteger lambda, BigInteger[] v1, BigInteger[] v2, BigInteger g1,
BigInteger g2, int bits)
{
- checkVector(v1, "v1");
- checkVector(v2, "v2");
+ this.beta = beta;
+ this.lambda = lambda;
+ this.splitParams = new ScalarSplitParameters(v1, v2, g1, g2, bits);
+ }
+ public GLVTypeBParameters(BigInteger beta, BigInteger lambda, ScalarSplitParameters splitParams)
+ {
this.beta = beta;
this.lambda = lambda;
- this.v1A = v1[0];
- this.v1B = v1[1];
- this.v2A = v2[0];
- this.v2B = v2[1];
- this.g1 = g1;
- this.g2 = g2;
- this.bits = bits;
+ this.splitParams = splitParams;
}
public BigInteger getBeta()
@@ -49,54 +39,64 @@ public class GLVTypeBParameters
return lambda;
}
- /**
- * @deprecated Use {@link #getV1A()} and {@link #getV1B()} instead.
- */
- public BigInteger[] getV1()
+ public ScalarSplitParameters getSplitParams()
{
- return new BigInteger[]{ v1A, v1B };
+ return splitParams;
}
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
public BigInteger getV1A()
{
- return v1A;
+ return getSplitParams().getV1A();
}
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
public BigInteger getV1B()
{
- return v1B;
+ return getSplitParams().getV1B();
}
/**
- * @deprecated Use {@link #getV2A()} and {@link #getV2B()} instead.
+ * @deprecated Access via {@link #getSplitParams()} instead.
*/
- public BigInteger[] getV2()
- {
- return new BigInteger[]{ v2A, v2B };
- }
-
public BigInteger getV2A()
{
- return v2A;
+ return getSplitParams().getV2A();
}
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
public BigInteger getV2B()
{
- return v2B;
+ return getSplitParams().getV2B();
}
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
public BigInteger getG1()
{
- return g1;
+ return getSplitParams().getG1();
}
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
public BigInteger getG2()
{
- return g2;
+ return getSplitParams().getG2();
}
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
public int getBits()
{
- return bits;
+ return getSplitParams().getBits();
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/ScalarSplitParameters.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/ScalarSplitParameters.java
new file mode 100644
index 00000000..5b6b0489
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/ec/endo/ScalarSplitParameters.java
@@ -0,0 +1,72 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ScalarSplitParameters
+{
+ private static void checkVector(BigInteger[] v, String name)
+ {
+ if (v == null || v.length != 2 || v[0] == null || v[1] == null)
+ {
+ throw new IllegalArgumentException("'" + name + "' must consist of exactly 2 (non-null) values");
+ }
+ }
+
+ protected final BigInteger v1A, v1B, v2A, v2B;
+ protected final BigInteger g1, g2;
+ protected final int bits;
+
+ public ScalarSplitParameters(BigInteger[] v1, BigInteger[] v2, BigInteger g1,
+ BigInteger g2, int bits)
+ {
+ checkVector(v1, "v1");
+ checkVector(v2, "v2");
+
+ this.v1A = v1[0];
+ this.v1B = v1[1];
+ this.v2A = v2[0];
+ this.v2B = v2[1];
+ this.g1 = g1;
+ this.g2 = g2;
+ this.bits = bits;
+ }
+
+ public BigInteger getV1A()
+ {
+ return v1A;
+ }
+
+ public BigInteger getV1B()
+ {
+ return v1B;
+ }
+
+ public BigInteger getV2A()
+ {
+ return v2A;
+ }
+
+ public BigInteger getV2B()
+ {
+ return v2B;
+ }
+
+ public BigInteger getG1()
+ {
+ return g1;
+ }
+
+ public BigInteger getG2()
+ {
+ return g2;
+ }
+
+ public int getBits()
+ {
+ return bits;
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/field/FiniteFields.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/field/FiniteFields.java
index b9597e25..3b2f6177 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/field/FiniteFields.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/field/FiniteFields.java
@@ -21,7 +21,7 @@ public abstract class FiniteFields
{
if (exponents[i] <= exponents[i - 1])
{
- throw new IllegalArgumentException("Polynomial exponents must be montonically increasing");
+ throw new IllegalArgumentException("Polynomial exponents must be monotonically increasing");
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Bits.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Bits.java
new file mode 100644
index 00000000..c172ca7b
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Bits.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.math.raw;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class Bits
+{
+ public static int bitPermuteStep(int x, int m, int s)
+ {
+ int t = (x ^ (x >>> s)) & m;
+ return (t ^ (t << s)) ^ x;
+ }
+
+ public static long bitPermuteStep(long x, long m, int s)
+ {
+ long t = (x ^ (x >>> s)) & m;
+ return (t ^ (t << s)) ^ x;
+ }
+
+ public static int bitPermuteStepSimple(int x, int m, int s)
+ {
+ return ((x & m) << s) | ((x >>> s) & m);
+ }
+
+ public static long bitPermuteStepSimple(long x, long m, int s)
+ {
+ return ((x & m) << s) | ((x >>> s) & m);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Interleave.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Interleave.java
index dc6ab5df..9771ae31 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Interleave.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Interleave.java
@@ -74,11 +74,10 @@ public class Interleave
public static long expand32to64(int x)
{
// "shuffle" low half to even bits and high half to odd bits
- int t;
- t = (x ^ (x >>> 8)) & 0x0000FF00; x ^= (t ^ (t << 8));
- t = (x ^ (x >>> 4)) & 0x00F000F0; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 2)) & 0x0C0C0C0C; x ^= (t ^ (t << 2));
- t = (x ^ (x >>> 1)) & 0x22222222; x ^= (t ^ (t << 1));
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C, 2);
+ x = Bits.bitPermuteStep(x, 0x22222222, 1);
return ((x >>> 1) & M32) << 32 | (x & M32);
}
@@ -86,26 +85,33 @@ public class Interleave
public static void expand64To128(long x, long[] z, int zOff)
{
// "shuffle" low half to even bits and high half to odd bits
- long t;
- t = (x ^ (x >>> 16)) & 0x00000000FFFF0000L; x ^= (t ^ (t << 16));
- t = (x ^ (x >>> 8)) & 0x0000FF000000FF00L; x ^= (t ^ (t << 8));
- t = (x ^ (x >>> 4)) & 0x00F000F000F000F0L; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 2)) & 0x0C0C0C0C0C0C0C0CL; x ^= (t ^ (t << 2));
- t = (x ^ (x >>> 1)) & 0x2222222222222222L; x ^= (t ^ (t << 1));
+ x = Bits.bitPermuteStep(x, 0x00000000FFFF0000L, 16);
+ x = Bits.bitPermuteStep(x, 0x0000FF000000FF00L, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F000F000F0L, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C0C0C0C0CL, 2);
+ x = Bits.bitPermuteStep(x, 0x2222222222222222L, 1);
z[zOff ] = (x ) & M64;
z[zOff + 1] = (x >>> 1) & M64;
}
+ public static void expand64To128(long[] xs, int xsOff, int xsLen, long[] zs, int zsOff)
+ {
+ for (int i = 0; i < xsLen; ++i)
+ {
+ expand64To128(xs[xsOff + i], zs, zsOff);
+ zsOff += 2;
+ }
+ }
+
public static void expand64To128Rev(long x, long[] z, int zOff)
{
// "shuffle" low half to even bits and high half to odd bits
- long t;
- t = (x ^ (x >>> 16)) & 0x00000000FFFF0000L; x ^= (t ^ (t << 16));
- t = (x ^ (x >>> 8)) & 0x0000FF000000FF00L; x ^= (t ^ (t << 8));
- t = (x ^ (x >>> 4)) & 0x00F000F000F000F0L; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 2)) & 0x0C0C0C0C0C0C0C0CL; x ^= (t ^ (t << 2));
- t = (x ^ (x >>> 1)) & 0x2222222222222222L; x ^= (t ^ (t << 1));
+ x = Bits.bitPermuteStep(x, 0x00000000FFFF0000L, 16);
+ x = Bits.bitPermuteStep(x, 0x0000FF000000FF00L, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F000F000F0L, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C0C0C0C0CL, 2);
+ x = Bits.bitPermuteStep(x, 0x2222222222222222L, 1);
z[zOff ] = (x ) & M64R;
z[zOff + 1] = (x << 1) & M64R;
@@ -114,68 +120,97 @@ public class Interleave
public static int shuffle(int x)
{
// "shuffle" low half to even bits and high half to odd bits
- int t;
- t = (x ^ (x >>> 8)) & 0x0000FF00; x ^= (t ^ (t << 8));
- t = (x ^ (x >>> 4)) & 0x00F000F0; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 2)) & 0x0C0C0C0C; x ^= (t ^ (t << 2));
- t = (x ^ (x >>> 1)) & 0x22222222; x ^= (t ^ (t << 1));
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C, 2);
+ x = Bits.bitPermuteStep(x, 0x22222222, 1);
return x;
}
public static long shuffle(long x)
{
// "shuffle" low half to even bits and high half to odd bits
- long t;
- t = (x ^ (x >>> 16)) & 0x00000000FFFF0000L; x ^= (t ^ (t << 16));
- t = (x ^ (x >>> 8)) & 0x0000FF000000FF00L; x ^= (t ^ (t << 8));
- t = (x ^ (x >>> 4)) & 0x00F000F000F000F0L; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 2)) & 0x0C0C0C0C0C0C0C0CL; x ^= (t ^ (t << 2));
- t = (x ^ (x >>> 1)) & 0x2222222222222222L; x ^= (t ^ (t << 1));
+ x = Bits.bitPermuteStep(x, 0x00000000FFFF0000L, 16);
+ x = Bits.bitPermuteStep(x, 0x0000FF000000FF00L, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F000F000F0L, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C0C0C0C0CL, 2);
+ x = Bits.bitPermuteStep(x, 0x2222222222222222L, 1);
return x;
}
public static int shuffle2(int x)
{
// "shuffle" (twice) low half to even bits and high half to odd bits
- int t;
- t = (x ^ (x >>> 7)) & 0x00AA00AA; x ^= (t ^ (t << 7));
- t = (x ^ (x >>> 14)) & 0x0000CCCC; x ^= (t ^ (t << 14));
- t = (x ^ (x >>> 4)) & 0x00F000F0; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 8)) & 0x0000FF00; x ^= (t ^ (t << 8));
+ x = Bits.bitPermuteStep(x, 0x00AA00AA, 7);
+ x = Bits.bitPermuteStep(x, 0x0000CCCC, 14);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
+ return x;
+ }
+
+ public static long shuffle2(long x)
+ {
+ // "shuffle" (twice) low half to even bits and high half to odd bits
+ x = Bits.bitPermuteStep(x, 0x00000000FF00FF00L, 24);
+ x = Bits.bitPermuteStep(x, 0x00CC00CC00CC00CCL, 6);
+ x = Bits.bitPermuteStep(x, 0x0000F0F00000F0F0L, 12);
+ x = Bits.bitPermuteStep(x, 0x0A0A0A0A0A0A0A0AL, 3);
+ return x;
+ }
+
+ public static long shuffle3(long x)
+ {
+ // "shuffle" (thrice) low half to even bits and high half to odd bits
+ x = Bits.bitPermuteStep(x, 0x00AA00AA00AA00AAL, 7);
+ x = Bits.bitPermuteStep(x, 0x0000CCCC0000CCCCL, 14);
+ x = Bits.bitPermuteStep(x, 0x00000000F0F0F0F0L, 28);
return x;
}
public static int unshuffle(int x)
{
// "unshuffle" even bits to low half and odd bits to high half
- int t;
- t = (x ^ (x >>> 1)) & 0x22222222; x ^= (t ^ (t << 1));
- t = (x ^ (x >>> 2)) & 0x0C0C0C0C; x ^= (t ^ (t << 2));
- t = (x ^ (x >>> 4)) & 0x00F000F0; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 8)) & 0x0000FF00; x ^= (t ^ (t << 8));
+ x = Bits.bitPermuteStep(x, 0x22222222, 1);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C, 2);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
return x;
}
public static long unshuffle(long x)
{
// "unshuffle" even bits to low half and odd bits to high half
- long t;
- t = (x ^ (x >>> 1)) & 0x2222222222222222L; x ^= (t ^ (t << 1));
- t = (x ^ (x >>> 2)) & 0x0C0C0C0C0C0C0C0CL; x ^= (t ^ (t << 2));
- t = (x ^ (x >>> 4)) & 0x00F000F000F000F0L; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 8)) & 0x0000FF000000FF00L; x ^= (t ^ (t << 8));
- t = (x ^ (x >>> 16)) & 0x00000000FFFF0000L; x ^= (t ^ (t << 16));
+ x = Bits.bitPermuteStep(x, 0x2222222222222222L, 1);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C0C0C0C0CL, 2);
+ x = Bits.bitPermuteStep(x, 0x00F000F000F000F0L, 4);
+ x = Bits.bitPermuteStep(x, 0x0000FF000000FF00L, 8);
+ x = Bits.bitPermuteStep(x, 0x00000000FFFF0000L, 16);
return x;
}
public static int unshuffle2(int x)
{
// "unshuffle" (twice) even bits to low half and odd bits to high half
- int t;
- t = (x ^ (x >>> 8)) & 0x0000FF00; x ^= (t ^ (t << 8));
- t = (x ^ (x >>> 4)) & 0x00F000F0; x ^= (t ^ (t << 4));
- t = (x ^ (x >>> 14)) & 0x0000CCCC; x ^= (t ^ (t << 14));
- t = (x ^ (x >>> 7)) & 0x00AA00AA; x ^= (t ^ (t << 7));
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0000CCCC, 14);
+ x = Bits.bitPermuteStep(x, 0x00AA00AA, 7);
+ return x;
+ }
+
+ public static long unshuffle2(long x)
+ {
+ // "unshuffle" (twice) even bits to low half and odd bits to high half
+ x = Bits.bitPermuteStep(x, 0x0A0A0A0A0A0A0A0AL, 3);
+ x = Bits.bitPermuteStep(x, 0x0000F0F00000F0F0L, 12);
+ x = Bits.bitPermuteStep(x, 0x00CC00CC00CC00CCL, 6);
+ x = Bits.bitPermuteStep(x, 0x00000000FF00FF00L, 24);
return x;
}
+
+ public static long unshuffle3(long x)
+ {
+ // "unshuffle" (thrice) even bits to low half and odd bits to high half
+ return shuffle3(x);
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Mod.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Mod.java
index 7d0c48d7..80e45ca1 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Mod.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Mod.java
@@ -3,15 +3,51 @@ package com.android.org.bouncycastle.math.raw;
import java.util.Random;
-import com.android.org.bouncycastle.util.Pack;
+import com.android.org.bouncycastle.util.Integers;
+
+/*
+ * Modular inversion as implemented in this class is based on the paper "Fast constant-time gcd
+ * computation and modular inversion" by Daniel J. Bernstein and Bo-Yin Yang.
+ */
/**
* @hide This class is not part of the Android public SDK API
*/
public abstract class Mod
{
+ private static final int M30 = 0x3FFFFFFF;
+ private static final long M32L = 0xFFFFFFFFL;
+
+ /** @deprecated Will be removed. */
+ public static void add(int[] p, int[] x, int[] y, int[] z)
+ {
+ int len = p.length;
+ int c = Nat.add(len, x, y, z);
+ if (c != 0)
+ {
+ Nat.subFrom(len, p, z);
+ }
+ }
+
+ public static void checkedModOddInverse(int[] m, int[] x, int[] z)
+ {
+ if (0 == modOddInverse(m, x, z))
+ {
+ throw new ArithmeticException("Inverse does not exist.");
+ }
+ }
+
+ public static void checkedModOddInverseVar(int[] m, int[] x, int[] z)
+ {
+ if (!modOddInverseVar(m, x, z))
+ {
+ throw new ArithmeticException("Inverse does not exist.");
+ }
+ }
+
public static int inverse32(int d)
{
+// assert (d & 1) == 1;
// int x = d + (((d + 1) & 4) << 1); // d.x == 1 mod 2**4
int x = d; // d.x == 1 mod 2**3
x *= 2 - d * x; // d.x == 1 mod 2**6
@@ -22,72 +58,152 @@ public abstract class Mod
return x;
}
- public static void invert(int[] p, int[] x, int[] z)
+ /** @deprecated Use {@link #checkedModOddInverseVar(int[], int[], int[])} instead. */
+ public static void invert(int[] m, int[] x, int[] z)
{
- int len = p.length;
- if (Nat.isZero(len, x))
- {
- throw new IllegalArgumentException("'x' cannot be 0");
- }
- if (Nat.isOne(len, x))
- {
- System.arraycopy(x, 0, z, 0, len);
- return;
- }
+ checkedModOddInverseVar(m, x, z);
+ }
- int[] u = Nat.copy(len, x);
- int[] a = Nat.create(len);
- a[0] = 1;
- int ac = 0;
+ public static int modOddInverse(int[] m, int[] x, int[] z)
+ {
+ int len32 = m.length;
+// assert len32 > 0;
+// assert (m[0] & 1) != 0;
+// assert m[len32 - 1] != 0;
- if ((u[0] & 1) == 0)
- {
- ac = inversionStep(p, u, len, a, ac);
- }
- if (Nat.isOne(len, u))
+ int bits = (len32 << 5) - Integers.numberOfLeadingZeros(m[len32 - 1]);
+ int len30 = (bits + 29) / 30;
+
+ int[] t = new int[4];
+ int[] D = new int[len30];
+ int[] E = new int[len30];
+ int[] F = new int[len30];
+ int[] G = new int[len30];
+ int[] M = new int[len30];
+
+ E[0] = 1;
+ encode30(bits, x, 0, G, 0);
+ encode30(bits, m, 0, M, 0);
+ System.arraycopy(M, 0, F, 0, len30);
+
+ int eta = -1;
+ int m0Inv32 = inverse32(M[0]);
+ int maxDivsteps = getMaximumDivsteps(bits);
+
+ for (int divSteps = 0; divSteps < maxDivsteps; divSteps += 30)
{
- inversionResult(p, ac, a, z);
- return;
+ eta = divsteps30(eta, F[0], G[0], t);
+ updateDE30(len30, D, E, t, m0Inv32, M);
+ updateFG30(len30, F, G, t);
}
- int[] v = Nat.copy(len, p);
- int[] b = Nat.create(len);
- int bc = 0;
+ int signF = F[len30 - 1] >> 31;
+ cnegate30(len30, signF, F);
- int uvLen = len;
+ /*
+ * D is in the range (-2.M, M). First, conditionally add M if D is negative, to bring it
+ * into the range (-M, M). Then normalize by conditionally negating (according to signF)
+ * and/or then adding M, to bring it into the range [0, M).
+ */
+ cnormalize30(len30, signF, D, M);
- for (;;)
+ decode30(bits, D, 0, z, 0);
+// assert 0 != Nat.lessThan(len32, z, m);
+
+ return Nat.equalTo(len30, F, 1) & Nat.equalToZero(len30, G);
+ }
+
+ public static boolean modOddInverseVar(int[] m, int[] x, int[] z)
+ {
+ int len32 = m.length;
+// assert len32 > 0;
+// assert (m[0] & 1) != 0;
+// assert m[len32 - 1] != 0;
+
+ int bits = (len32 << 5) - Integers.numberOfLeadingZeros(m[len32 - 1]);
+ int len30 = (bits + 29) / 30;
+
+ int[] t = new int[4];
+ int[] D = new int[len30];
+ int[] E = new int[len30];
+ int[] F = new int[len30];
+ int[] G = new int[len30];
+ int[] M = new int[len30];
+
+ E[0] = 1;
+ encode30(bits, x, 0, G, 0);
+ encode30(bits, m, 0, M, 0);
+ System.arraycopy(M, 0, F, 0, len30);
+
+ int clzG = Integers.numberOfLeadingZeros(G[len30 - 1] | 1) - (len30 * 30 + 2 - bits);
+ int eta = -1 - clzG;
+ int lenDE = len30, lenFG = len30;
+ int m0Inv32 = inverse32(M[0]);
+ int maxDivsteps = getMaximumDivsteps(bits);
+
+ int divsteps = 0;
+ while (!Nat.isZero(lenFG, G))
{
- while (u[uvLen - 1] == 0 && v[uvLen - 1] == 0)
+ if (divsteps >= maxDivsteps)
{
- --uvLen;
+ return false;
}
- if (Nat.gte(uvLen, u, v))
- {
- Nat.subFrom(uvLen, v, u);
-// assert (u[0] & 1) == 0;
- ac += Nat.subFrom(len, b, a) - bc;
- ac = inversionStep(p, u, uvLen, a, ac);
- if (Nat.isOne(uvLen, u))
- {
- inversionResult(p, ac, a, z);
- return;
- }
- }
- else
+ divsteps += 30;
+
+ eta = divsteps30Var(eta, F[0], G[0], t);
+ updateDE30(lenDE, D, E, t, m0Inv32, M);
+ updateFG30(lenFG, F, G, t);
+
+ int fn = F[lenFG - 1];
+ int gn = G[lenFG - 1];
+
+ int cond = (lenFG - 2) >> 31;
+ cond |= fn ^ (fn >> 31);
+ cond |= gn ^ (gn >> 31);
+
+ if (cond == 0)
{
- Nat.subFrom(uvLen, u, v);
-// assert (v[0] & 1) == 0;
- bc += Nat.subFrom(len, a, b) - ac;
- bc = inversionStep(p, v, uvLen, b, bc);
- if (Nat.isOne(uvLen, v))
- {
- inversionResult(p, bc, b, z);
- return;
- }
+ F[lenFG - 2] |= fn << 30;
+ G[lenFG - 2] |= gn << 30;
+ --lenFG;
}
}
+
+ int signF = F[lenFG - 1] >> 31;
+
+ /*
+ * D is in the range (-2.M, M). First, conditionally add M if D is negative, to bring it
+ * into the range (-M, M). Then normalize by conditionally negating (according to signF)
+ * and/or then adding M, to bring it into the range [0, M).
+ */
+ int signD = D[lenDE - 1] >> 31;
+ if (signD < 0)
+ {
+ signD = add30(lenDE, D, M);
+ }
+ if (signF < 0)
+ {
+ signD = negate30(lenDE, D);
+ signF = negate30(lenFG, F);
+ }
+// assert 0 == signF;
+
+ if (!Nat.isOne(lenFG, F))
+ {
+ return false;
+ }
+
+ if (signD < 0)
+ {
+ signD = add30(lenDE, D, M);
+ }
+// assert 0 == signD;
+
+ decode30(bits, D, 0, z, 0);
+// assert !Nat.gte(len32, z, m);
+
+ return true;
}
public static int[] random(int[] p)
@@ -116,88 +232,358 @@ public abstract class Mod
return s;
}
- public static void add(int[] p, int[] x, int[] y, int[] z)
+ /** @deprecated Will be removed. */
+ public static void subtract(int[] p, int[] x, int[] y, int[] z)
{
int len = p.length;
- int c = Nat.add(len, x, y, z);
+ int c = Nat.sub(len, x, y, z);
if (c != 0)
{
- Nat.subFrom(len, p, z);
+ Nat.addTo(len, p, z);
}
}
- public static void subtract(int[] p, int[] x, int[] y, int[] z)
+ private static int add30(int len30, int[] D, int[] M)
{
- int len = p.length;
- int c = Nat.sub(len, x, y, z);
- if (c != 0)
+// assert len30 > 0;
+// assert D.length >= len30;
+// assert M.length >= len30;
+
+ int c = 0, last = len30 - 1;
+ for (int i = 0; i < last; ++i)
{
- Nat.addTo(len, p, z);
+ c += D[i] + M[i];
+ D[i] = c & M30; c >>= 30;
}
+ c += D[last] + M[last];
+ D[last] = c; c >>= 30;
+ return c;
}
- private static void inversionResult(int[] p, int ac, int[] a, int[] z)
+ private static void cnegate30(int len30, int cond, int[] D)
{
- if (ac < 0)
+// assert len30 > 0;
+// assert D.length >= len30;
+
+ int c = 0, last = len30 - 1;
+ for (int i = 0; i < last; ++i)
{
- Nat.add(p.length, a, p, z);
+ c += (D[i] ^ cond) - cond;
+ D[i] = c & M30; c >>= 30;
}
- else
+ c += (D[last] ^ cond) - cond;
+ D[last] = c;
+ }
+
+ private static void cnormalize30(int len30, int condNegate, int[] D, int[] M)
+ {
+// assert len30 > 0;
+// assert D.length >= len30;
+// assert M.length >= len30;
+
+ int last = len30 - 1;
+
{
- System.arraycopy(a, 0, z, 0, p.length);
+ int c = 0, condAdd = D[last] >> 31;
+ for (int i = 0; i < last; ++i)
+ {
+ int di = D[i] + (M[i] & condAdd);
+ di = (di ^ condNegate) - condNegate;
+ c += di; D[i] = c & M30; c >>= 30;
+ }
+ {
+ int di = D[last] + (M[last] & condAdd);
+ di = (di ^ condNegate) - condNegate;
+ c += di; D[last] = c;
+ }
+ }
+
+ {
+ int c = 0, condAdd = D[last] >> 31;
+ for (int i = 0; i < last; ++i)
+ {
+ int di = D[i] + (M[i] & condAdd);
+ c += di; D[i] = c & M30; c >>= 30;
+ }
+ {
+ int di = D[last] + (M[last] & condAdd);
+ c += di; D[last] = c;
+ }
+// assert c >> 30 == 0;
}
}
- private static int inversionStep(int[] p, int[] u, int uLen, int[] x, int xc)
+ private static void decode30(int bits, int[] x, int xOff, int[] z, int zOff)
{
- int len = p.length;
- int count = 0;
- while (u[0] == 0)
+// assert bits > 0;
+// assert x != z;
+
+ int avail = 0;
+ long data = 0L;
+
+ while (bits > 0)
{
- Nat.shiftDownWord(uLen, u, 0);
- count += 32;
+ while (avail < Math.min(32, bits))
+ {
+ data |= (long)x[xOff++] << avail;
+ avail += 30;
+ }
+
+ z[zOff++] = (int)data; data >>>= 32;
+ avail -= 32;
+ bits -= 32;
+ }
+ }
+
+ private static int divsteps30(int eta, int f0, int g0, int[] t)
+ {
+ int u = 1, v = 0, q = 0, r = 1;
+ int f = f0, g = g0;
+
+ for (int i = 0; i < 30; ++i)
+ {
+// assert (f & 1) == 1;
+// assert (u * f0 + v * g0) == f << i;
+// assert (q * f0 + r * g0) == g << i;
+
+ int c1 = eta >> 31;
+ int c2 = -(g & 1);
+
+ int x = (f ^ c1) - c1;
+ int y = (u ^ c1) - c1;
+ int z = (v ^ c1) - c1;
+
+ g += x & c2;
+ q += y & c2;
+ r += z & c2;
+
+ c1 &= c2;
+ eta = (eta ^ c1) - (c1 + 1);
+
+ f += g & c1;
+ u += q & c1;
+ v += r & c1;
+
+ g >>= 1;
+ u <<= 1;
+ v <<= 1;
}
+ t[0] = u;
+ t[1] = v;
+ t[2] = q;
+ t[3] = r;
+
+ return eta;
+ }
+
+ private static int divsteps30Var(int eta, int f0, int g0, int[] t)
+ {
+ int u = 1, v = 0, q = 0, r = 1;
+ int f = f0, g = g0, m, w, x, y, z;
+ int i = 30, limit, zeros;
+
+ for (;;)
{
- int zeroes = getTrailingZeroes(u[0]);
- if (zeroes > 0)
+ // Use a sentinel bit to count zeros only up to i.
+ zeros = Integers.numberOfTrailingZeros(g | (-1 << i));
+
+ g >>= zeros;
+ u <<= zeros;
+ v <<= zeros;
+ eta -= zeros;
+ i -= zeros;
+
+ if (i <= 0)
+ {
+ break;
+ }
+
+// assert (f & 1) == 1;
+// assert (g & 1) == 1;
+// assert (u * f0 + v * g0) == f << (30 - i);
+// assert (q * f0 + r * g0) == g << (30 - i);
+
+ if (eta < 0)
{
- Nat.shiftDownBits(uLen, u, zeroes, 0);
- count += zeroes;
+ eta = -eta;
+ x = f; f = g; g = -x;
+ y = u; u = q; q = -y;
+ z = v; v = r; r = -z;
+
+ // Handle up to 6 divsteps at once, subject to eta and i.
+ limit = (eta + 1) > i ? i : (eta + 1);
+ m = (-1 >>> (32 - limit)) & 63;
+
+ w = (f * g * (f * f - 2)) & m;
+ }
+ else
+ {
+ // Handle up to 4 divsteps at once, subject to eta and i.
+ limit = (eta + 1) > i ? i : (eta + 1);
+ m = (-1 >>> (32 - limit)) & 15;
+
+ w = f + (((f + 1) & 4) << 1);
+ w = (-w * g) & m;
}
+
+ g += f * w;
+ q += u * w;
+ r += v * w;
+
+// assert (g & m) == 0;
}
- for (int i = 0; i < count; ++i)
+ t[0] = u;
+ t[1] = v;
+ t[2] = q;
+ t[3] = r;
+
+ return eta;
+ }
+
+ private static void encode30(int bits, int[] x, int xOff, int[] z, int zOff)
+ {
+// assert bits > 0;
+// assert x != z;
+
+ int avail = 0;
+ long data = 0L;
+
+ while (bits > 0)
{
- if ((x[0] & 1) != 0)
+ if (avail < Math.min(30, bits))
{
- if (xc < 0)
- {
- xc += Nat.addTo(len, p, x);
- }
- else
- {
- xc += Nat.subFrom(len, p, x);
- }
+ data |= (x[xOff++] & M32L) << avail;
+ avail += 32;
}
-// assert xc == 0 || xc == 1;
- Nat.shiftDownBit(len, x, xc);
+ z[zOff++] = (int)data & M30; data >>>= 30;
+ avail -= 30;
+ bits -= 30;
}
-
- return xc;
}
- private static int getTrailingZeroes(int x)
+ private static int getMaximumDivsteps(int bits)
+ {
+ return (49 * bits + (bits < 46 ? 80 : 47)) / 17;
+ }
+
+ private static int negate30(int len30, int[] D)
{
-// assert x != 0;
+// assert len30 > 0;
+// assert D.length >= len30;
- int count = 0;
- while ((x & 1) == 0)
+ int c = 0, last = len30 - 1;
+ for (int i = 0; i < last; ++i)
{
- x >>>= 1;
- ++count;
+ c -= D[i];
+ D[i] = c & M30; c >>= 30;
}
- return count;
+ c -= D[last];
+ D[last] = c; c >>= 30;
+ return c;
+ }
+
+ private static void updateDE30(int len30, int[] D, int[] E, int[] t, int m0Inv32, int[] M)
+ {
+// assert len30 > 0;
+// assert D.length >= len30;
+// assert E.length >= len30;
+// assert M.length >= len30;
+// assert m0Inv32 * M[0] == 1;
+
+ final int u = t[0], v = t[1], q = t[2], r = t[3];
+ int di, ei, i, md, me, mi, sd, se;
+ long cd, ce;
+
+ /*
+ * We accept D (E) in the range (-2.M, M) and conceptually add the modulus to the input
+ * value if it is initially negative. Instead of adding it explicitly, we add u and/or v (q
+ * and/or r) to md (me).
+ */
+ sd = D[len30 - 1] >> 31;
+ se = E[len30 - 1] >> 31;
+
+ md = (u & sd) + (v & se);
+ me = (q & sd) + (r & se);
+
+ mi = M[0];
+ di = D[0];
+ ei = E[0];
+
+ cd = (long)u * di + (long)v * ei;
+ ce = (long)q * di + (long)r * ei;
+
+ /*
+ * Subtract from md/me an extra term in the range [0, 2^30) such that the low 30 bits of the
+ * intermediate D/E values will be 0, allowing clean division by 2^30. The final D/E are
+ * thus in the range (-2.M, M), consistent with the input constraint.
+ */
+ md -= (m0Inv32 * (int)cd + md) & M30;
+ me -= (m0Inv32 * (int)ce + me) & M30;
+
+ cd += (long)mi * md;
+ ce += (long)mi * me;
+
+// assert ((int)cd & M30) == 0;
+// assert ((int)ce & M30) == 0;
+
+ cd >>= 30;
+ ce >>= 30;
+
+ for (i = 1; i < len30; ++i)
+ {
+ mi = M[i];
+ di = D[i];
+ ei = E[i];
+
+ cd += (long)u * di + (long)v * ei + (long)mi * md;
+ ce += (long)q * di + (long)r * ei + (long)mi * me;
+
+ D[i - 1] = (int)cd & M30; cd >>= 30;
+ E[i - 1] = (int)ce & M30; ce >>= 30;
+ }
+
+ D[len30 - 1] = (int)cd;
+ E[len30 - 1] = (int)ce;
+ }
+
+ private static void updateFG30(int len30, int[] F, int[] G, int[] t)
+ {
+// assert len30 > 0;
+// assert F.length >= len30;
+// assert G.length >= len30;
+
+ final int u = t[0], v = t[1], q = t[2], r = t[3];
+ int fi, gi, i;
+ long cf, cg;
+
+ fi = F[0];
+ gi = G[0];
+
+ cf = (long)u * fi + (long)v * gi;
+ cg = (long)q * fi + (long)r * gi;
+
+// assert ((int)cf & M30) == 0;
+// assert ((int)cg & M30) == 0;
+
+ cf >>= 30;
+ cg >>= 30;
+
+ for (i = 1; i < len30; ++i)
+ {
+ fi = F[i];
+ gi = G[i];
+
+ cf += (long)u * fi + (long)v * gi;
+ cg += (long)q * fi + (long)r * gi;
+
+ F[i - 1] = (int)cf & M30; cf >>= 30;
+ G[i - 1] = (int)cg & M30; cg >>= 30;
+ }
+
+ F[len30 - 1] = (int)cf;
+ G[len30 - 1] = (int)cg;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat.java
index 61becdce..cb15aeac 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat.java
@@ -164,6 +164,31 @@ public abstract class Nat
return (int)c;
}
+ public static int addTo(int len, int[] x, int xOff, int[] z, int zOff, int cIn)
+ {
+ long c = cIn & M;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[xOff + i] & M) + (z[zOff + i] & M);
+ z[zOff + i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int addToEachOther(int len, int[] u, int uOff, int[] v, int vOff)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (u[uOff + i] & M) + (v[vOff + i] & M);
+ u[uOff + i] = (int)c;
+ v[vOff + i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
public static int addWordAt(int len, int x, int[] z, int zPos)
{
// assert zPos <= (len - 1);
@@ -233,6 +258,34 @@ public abstract class Nat
// }
}
+ public static int compare(int len, int[] x, int[] y)
+ {
+ for (int i = len - 1; i >= 0; --i)
+ {
+ int x_i = x[i] ^ Integer.MIN_VALUE;
+ int y_i = y[i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return -1;
+ if (x_i > y_i)
+ return 1;
+ }
+ return 0;
+ }
+
+ public static int compare(int len, int[] x, int xOff, int[] y, int yOff)
+ {
+ for (int i = len - 1; i >= 0; --i)
+ {
+ int x_i = x[xOff + i] ^ Integer.MIN_VALUE;
+ int y_i = y[yOff + i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return -1;
+ if (x_i > y_i)
+ return 1;
+ }
+ return 0;
+ }
+
public static int[] copy(int len, int[] x)
{
int[] z = new int[len];
@@ -250,6 +303,23 @@ public abstract class Nat
System.arraycopy(x, xOff, z, zOff, len);
}
+ public static long[] copy64(int len, long[] x)
+ {
+ long[] z = new long[len];
+ System.arraycopy(x, 0, z, 0, len);
+ return z;
+ }
+
+ public static void copy64(int len, long[] x, long[] z)
+ {
+ System.arraycopy(x, 0, z, 0, len);
+ }
+
+ public static void copy64(int len, long[] x, int xOff, long[] z, int zOff)
+ {
+ System.arraycopy(x, xOff, z, zOff, len);
+ }
+
public static int[] create(int len)
{
return new int[len];
@@ -273,6 +343,19 @@ public abstract class Nat
return (int)c;
}
+ public static int csub(int len, int mask, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long MASK = -(mask & 1) & M;
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[xOff + i] & M) - (y[yOff + i] & MASK);
+ z[zOff + i] = (int)c;
+ c >>= 32;
+ }
+ return (int)c;
+ }
+
public static int dec(int len, int[] z)
{
for (int i = 0; i < len; ++i)
@@ -332,6 +415,20 @@ public abstract class Nat
return -1;
}
+ public static boolean diff(int len, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ boolean pos = gte(len, x, xOff, y, yOff);
+ if (pos)
+ {
+ sub(len, x, xOff, y, yOff, z, zOff);
+ }
+ else
+ {
+ sub(len, y, yOff, x, xOff, z, zOff);
+ }
+ return pos;
+ }
+
public static boolean eq(int len, int[] x, int[] y)
{
for (int i = len - 1; i >= 0; --i)
@@ -344,6 +441,72 @@ public abstract class Nat
return true;
}
+ public static int equalTo(int len, int[] x, int y)
+ {
+ int d = x[0] ^ y;
+ for (int i = 1; i < len; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalTo(int len, int[] x, int xOff, int y)
+ {
+ int d = x[xOff] ^ y;
+ for (int i = 1; i < len; ++i)
+ {
+ d |= x[xOff + i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalTo(int len, int[] x, int[] y)
+ {
+ int d = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ d |= x[i] ^ y[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalTo(int len, int[] x, int xOff, int[] y, int yOff)
+ {
+ int d = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ d |= x[xOff + i] ^ y[yOff + i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalToZero(int len, int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalToZero(int len, int[] x, int xOff)
+ {
+ int d = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ d |= x[xOff + i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
public static int[] fromBigInteger(int bits, BigInteger x)
{
if (x.signum() < 0 || x.bitLength() > bits)
@@ -353,15 +516,35 @@ public abstract class Nat
int len = (bits + 31) >> 5;
int[] z = create(len);
- int i = 0;
- while (x.signum() != 0)
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < len; ++i)
{
- z[i++] = x.intValue();
+ z[i] = x.intValue();
x = x.shiftRight(32);
}
return z;
}
+ public static long[] fromBigInteger64(int bits, BigInteger x)
+ {
+ if (x.signum() < 0 || x.bitLength() > bits)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ int len = (bits + 63) >> 6;
+ long[] z = create64(len);
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < len; ++i)
+ {
+ z[i] = x.longValue();
+ x = x.shiftRight(64);
+ }
+ return z;
+ }
+
public static int getBit(int[] x, int bit)
{
if (bit == 0)
@@ -391,6 +574,20 @@ public abstract class Nat
return true;
}
+ public static boolean gte(int len, int[] x, int xOff, int[] y, int yOff)
+ {
+ for (int i = len - 1; i >= 0; --i)
+ {
+ int x_i = x[xOff + i] ^ Integer.MIN_VALUE;
+ int y_i = y[yOff + i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return false;
+ if (x_i > y_i)
+ return true;
+ }
+ return true;
+ }
+
public static int inc(int len, int[] z)
{
for (int i = 0; i < len; ++i)
@@ -478,6 +675,30 @@ public abstract class Nat
return true;
}
+ public static int lessThan(int len, int[] x, int[] y)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[i] & M) - (y[i] & M);
+ c >>= 32;
+ }
+// assert c == 0L || c == -1L;
+ return (int)c;
+ }
+
+ public static int lessThan(int len, int[] x, int xOff, int[] y, int yOff)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[xOff + i] & M) - (y[yOff + i] & M);
+ c >>= 32;
+ }
+// assert c == 0L || c == -1L;
+ return (int)c;
+ }
+
public static void mul(int len, int[] x, int[] y, int[] zz)
{
zz[len] = mulWord(len, x[0], y, zz);
@@ -513,10 +734,10 @@ public abstract class Nat
long zc = 0;
for (int i = 0; i < len; ++i)
{
- long c = mulWordAddTo(len, x[i], y, 0, zz, i) & M;
- c += zc + (zz[i + len] & M);
- zz[i + len] = (int)c;
- zc = c >>> 32;
+ zc += mulWordAddTo(len, x[i], y, 0, zz, i) & M;
+ zc += zz[i + len] & M;
+ zz[i + len] = (int)zc;
+ zc >>>= 32;
}
return (int)zc;
}
@@ -526,10 +747,10 @@ public abstract class Nat
long zc = 0;
for (int i = 0; i < len; ++i)
{
- long c = mulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff) & M;
- c += zc + (zz[zzOff + len] & M);
- zz[zzOff + len] = (int)c;
- zc = c >>> 32;
+ zc += mulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff) & M;
+ zc += zz[zzOff + len] & M;
+ zz[zzOff + len] = (int)zc;
+ zc >>>= 32;
++zzOff;
}
return (int)zc;
@@ -861,11 +1082,18 @@ public abstract class Nat
}
while (j > 0);
+ long d = 0L;
+ int zzPos = 2;
+
for (int i = 1; i < len; ++i)
{
- c = squareWordAdd(x, i, zz);
- addWordAt(extLen, c, zz, i << 1);
+ d += squareWordAddTo(x, i, zz) & M;
+ d += zz[zzPos] & M;
+ zz[zzPos++] = (int)d; d >>>= 32;
+ d += zz[zzPos] & M;
+ zz[zzPos++] = (int)d; d >>>= 32;
}
+// assert 0L == d;
shiftUpBit(extLen, zz, x[0] << 31);
}
@@ -885,15 +1113,25 @@ public abstract class Nat
}
while (j > 0);
+ long d = 0L;
+ int zzPos = zzOff + 2;
+
for (int i = 1; i < len; ++i)
{
- c = squareWordAdd(x, xOff, i, zz, zzOff);
- addWordAt(extLen, c, zz, zzOff, i << 1);
+ d += squareWordAddTo(x, xOff, i, zz, zzOff) & M;
+ d += zz[zzPos] & M;
+ zz[zzPos++] = (int)d; d >>>= 32;
+ d += zz[zzPos] & M;
+ zz[zzPos++] = (int)d; d >>>= 32;
}
+// assert 0L == d;
shiftUpBit(extLen, zz, zzOff, x[xOff] << 31);
}
+ /**
+ * @deprecated Use {@link #squareWordAddTo(int[], int, int[])} instead.
+ */
public static int squareWordAdd(int[] x, int xPos, int[] z)
{
long c = 0, xVal = x[xPos] & M;
@@ -908,6 +1146,9 @@ public abstract class Nat
return (int)c;
}
+ /**
+ * @deprecated Use {@link #squareWordAddTo(int[], int, int, int[], int)} instead.
+ */
public static int squareWordAdd(int[] x, int xOff, int xPos, int[] z, int zOff)
{
long c = 0, xVal = x[xOff + xPos] & M;
@@ -923,6 +1164,35 @@ public abstract class Nat
return (int)c;
}
+ public static int squareWordAddTo(int[] x, int xPos, int[] z)
+ {
+ long c = 0, xVal = x[xPos] & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (x[i] & M) + (z[xPos + i] & M);
+ z[xPos + i] = (int)c;
+ c >>>= 32;
+ }
+ while (++i < xPos);
+ return (int)c;
+ }
+
+ public static int squareWordAddTo(int[] x, int xOff, int xPos, int[] z, int zOff)
+ {
+ long c = 0, xVal = x[xOff + xPos] & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M);
+ z[xPos + zOff] = (int)c;
+ c >>>= 32;
+ ++zOff;
+ }
+ while (++i < xPos);
+ return (int)c;
+ }
+
public static int sub(int len, int[] x, int[] y, int[] z)
{
long c = 0;
@@ -1143,6 +1413,14 @@ public abstract class Nat
}
}
+ public static void zero(int len, int[] z, int zOff)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[zOff + i] = 0;
+ }
+ }
+
public static void zero64(int len, long[] z)
{
for (int i = 0; i < len; ++i)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat192.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat192.java
index 5de04e7c..642266df 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat192.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat192.java
@@ -238,10 +238,11 @@ public abstract class Nat192
}
int[] z = create();
- int i = 0;
- while (x.signum() != 0)
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 6; ++i)
{
- z[i++] = x.intValue();
+ z[i] = x.intValue();
x = x.shiftRight(32);
}
return z;
@@ -255,10 +256,11 @@ public abstract class Nat192
}
long[] z = create64();
- int i = 0;
- while (x.signum() != 0)
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 3; ++i)
{
- z[i++] = x.longValue();
+ z[i] = x.longValue();
x = x.shiftRight(64);
}
return z;
@@ -509,9 +511,10 @@ public abstract class Nat192
c += x_i * y_5 + (zz[i + 5] & M);
zz[i + 5] = (int)c;
c >>>= 32;
- c += zc + (zz[i + 6] & M);
- zz[i + 6] = (int)c;
- zc = c >>> 32;
+
+ zc += c + (zz[i + 6] & M);
+ zz[i + 6] = (int)zc;
+ zc >>>= 32;
}
return (int)zc;
}
@@ -547,9 +550,10 @@ public abstract class Nat192
c += x_i * y_5 + (zz[zzOff + 5] & M);
zz[zzOff + 5] = (int)c;
c >>>= 32;
- c += zc + (zz[zzOff + 6] & M);
- zz[zzOff + 6] = (int)c;
- zc = c >>> 32;
+
+ zc += c + (zz[zzOff + 6] & M);
+ zz[zzOff + 6] = (int)zc;
+ zc >>>= 32;
++zzOff;
}
return (int)zc;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat224.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat224.java
index f4f0ac8e..9f5b6236 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat224.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat224.java
@@ -274,10 +274,11 @@ public abstract class Nat224
}
int[] z = create();
- int i = 0;
- while (x.signum() != 0)
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 7; ++i)
{
- z[i++] = x.intValue();
+ z[i] = x.intValue();
x = x.shiftRight(32);
}
return z;
@@ -518,9 +519,10 @@ public abstract class Nat224
c += x_i * y_6 + (zz[i + 6] & M);
zz[i + 6] = (int)c;
c >>>= 32;
- c += zc + (zz[i + 7] & M);
- zz[i + 7] = (int)c;
- zc = c >>> 32;
+
+ zc += c + (zz[i + 7] & M);
+ zz[i + 7] = (int)zc;
+ zc >>>= 32;
}
return (int)zc;
}
@@ -560,9 +562,10 @@ public abstract class Nat224
c += x_i * y_6 + (zz[zzOff + 6] & M);
zz[zzOff + 6] = (int)c;
c >>>= 32;
- c += zc + (zz[zzOff + 7] & M);
- zz[zzOff + 7] = (int)c;
- zc = c >>> 32;
+
+ zc += c + (zz[zzOff + 7] & M);
+ zz[zzOff + 7] = (int)zc;
+ zc >>>= 32;
++zzOff;
}
return (int)zc;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat256.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat256.java
index fb946e3e..b38e4303 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat256.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/math/raw/Nat256.java
@@ -336,10 +336,11 @@ public abstract class Nat256
}
int[] z = create();
- int i = 0;
- while (x.signum() != 0)
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 8; ++i)
{
- z[i++] = x.intValue();
+ z[i] = x.intValue();
x = x.shiftRight(32);
}
return z;
@@ -353,10 +354,11 @@ public abstract class Nat256
}
long[] z = create64();
- int i = 0;
- while (x.signum() != 0)
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 4; ++i)
{
- z[i++] = x.longValue();
+ z[i] = x.longValue();
x = x.shiftRight(64);
}
return z;
@@ -643,9 +645,10 @@ public abstract class Nat256
c += x_i * y_7 + (zz[i + 7] & M);
zz[i + 7] = (int)c;
c >>>= 32;
- c += zc + (zz[i + 8] & M);
- zz[i + 8] = (int)c;
- zc = c >>> 32;
+
+ zc += c + (zz[i + 8] & M);
+ zz[i + 8] = (int)zc;
+ zc >>>= 32;
}
return (int)zc;
}
@@ -689,9 +692,10 @@ public abstract class Nat256
c += x_i * y_7 + (zz[zzOff + 7] & M);
zz[zzOff + 7] = (int)c;
c >>>= 32;
- c += zc + (zz[zzOff + 8] & M);
- zz[zzOff + 8] = (int)c;
- zc = c >>> 32;
+
+ zc += c + (zz[zzOff + 8] & M);
+ zz[zzOff + 8] = (int)zc;
+ zc >>>= 32;
++zzOff;
}
return (int)zc;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Arrays.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Arrays.java
index b0b5783a..5c663052 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Arrays.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Arrays.java
@@ -25,88 +25,29 @@ public final class Arrays
return bits == 0;
}
- public static boolean areEqual(
- boolean[] a,
- boolean[] b)
+ public static boolean areEqual(boolean[] a, boolean[] b)
{
- if (a == b)
- {
- return true;
- }
-
- if (a == null || b == null)
- {
- return false;
- }
-
- if (a.length != b.length)
- {
- return false;
- }
-
- for (int i = 0; i != a.length; i++)
- {
- if (a[i] != b[i])
- {
- return false;
- }
- }
-
- return true;
+ return java.util.Arrays.equals(a, b);
}
- public static boolean areEqual(
- char[] a,
- char[] b)
+ public static boolean areEqual(byte[] a, byte[] b)
{
- if (a == b)
- {
- return true;
- }
-
- if (a == null || b == null)
- {
- return false;
- }
-
- if (a.length != b.length)
- {
- return false;
- }
-
- for (int i = 0; i != a.length; i++)
- {
- if (a[i] != b[i])
- {
- return false;
- }
- }
-
- return true;
+ return java.util.Arrays.equals(a, b);
}
- public static boolean areEqual(
- byte[] a,
- byte[] b)
+ public static boolean areEqual(byte[] a, int aFromIndex, int aToIndex, byte[] b, int bFromIndex, int bToIndex)
{
- if (a == b)
- {
- return true;
- }
-
- if (a == null || b == null)
- {
- return false;
- }
+ int aLength = aToIndex - aFromIndex;
+ int bLength = bToIndex - bFromIndex;
- if (a.length != b.length)
+ if (aLength != bLength)
{
return false;
}
- for (int i = 0; i != a.length; i++)
+ for (int i = 0; i < aLength; ++i)
{
- if (a[i] != b[i])
+ if (a[aFromIndex + i] != b[bFromIndex + i])
{
return false;
}
@@ -115,34 +56,29 @@ public final class Arrays
return true;
}
- public static boolean areEqual(
- short[] a,
- short[] b)
+ public static boolean areEqual(char[] a, char[] b)
{
- if (a == b)
- {
- return true;
- }
+ return java.util.Arrays.equals(a, b);
+ }
- if (a == null || b == null)
- {
- return false;
- }
+ public static boolean areEqual(int[] a, int[] b)
+ {
+ return java.util.Arrays.equals(a, b);
+ }
- if (a.length != b.length)
- {
- return false;
- }
+ public static boolean areEqual(long[] a, long[] b)
+ {
+ return java.util.Arrays.equals(a, b);
+ }
- for (int i = 0; i != a.length; i++)
- {
- if (a[i] != b[i])
- {
- return false;
- }
- }
+ public static boolean areEqual(Object[] a, Object[] b)
+ {
+ return java.util.Arrays.equals(a, b);
+ }
- return true;
+ public static boolean areEqual(short[] a, short[] b)
+ {
+ return java.util.Arrays.equals(a, b);
}
/**
@@ -158,121 +94,61 @@ public final class Arrays
byte[] expected,
byte[] supplied)
{
- if (expected == supplied)
- {
- return true;
- }
-
if (expected == null || supplied == null)
{
return false;
}
- if (expected.length != supplied.length)
- {
- return !Arrays.constantTimeAreEqual(expected, expected);
- }
-
- int nonEqual = 0;
-
- for (int i = 0; i != expected.length; i++)
- {
- nonEqual |= (expected[i] ^ supplied[i]);
- }
-
- return nonEqual == 0;
- }
-
- public static boolean areEqual(
- int[] a,
- int[] b)
- {
- if (a == b)
+ if (expected == supplied)
{
return true;
}
- if (a == null || b == null)
- {
- return false;
- }
+ int len = (expected.length < supplied.length) ? expected.length : supplied.length;
- if (a.length != b.length)
+ int nonEqual = expected.length ^ supplied.length;
+
+ for (int i = 0; i != len; i++)
{
- return false;
+ nonEqual |= (expected[i] ^ supplied[i]);
}
-
- for (int i = 0; i != a.length; i++)
+ for (int i = len; i < supplied.length; i++)
{
- if (a[i] != b[i])
- {
- return false;
- }
+ nonEqual |= (supplied[i] ^ ~supplied[i]);
}
- return true;
+ return nonEqual == 0;
}
- public static boolean areEqual(
- long[] a,
- long[] b)
+ public static boolean constantTimeAreEqual(int len, byte[] a, int aOff, byte[] b, int bOff)
{
- if (a == b)
+ if (null == a)
{
- return true;
+ throw new NullPointerException("'a' cannot be null");
}
-
- if (a == null || b == null)
+ if (null == b)
{
- return false;
+ throw new NullPointerException("'b' cannot be null");
}
-
- if (a.length != b.length)
+ if (len < 0)
{
- return false;
+ throw new IllegalArgumentException("'len' cannot be negative");
}
-
- for (int i = 0; i != a.length; i++)
+ if (aOff > (a.length - len))
{
- if (a[i] != b[i])
- {
- return false;
- }
+ throw new IndexOutOfBoundsException("'aOff' value invalid for specified length");
}
-
- return true;
- }
-
- public static boolean areEqual(Object[] a, Object[] b)
- {
- if (a == b)
+ if (bOff > (b.length - len))
{
- return true;
+ throw new IndexOutOfBoundsException("'bOff' value invalid for specified length");
}
- if (a == null || b == null)
- {
- return false;
- }
- if (a.length != b.length)
- {
- return false;
- }
- for (int i = 0; i != a.length; i++)
+
+ int d = 0;
+ for (int i = 0; i < len; ++i)
{
- Object objA = a[i], objB = b[i];
- if (objA == null)
- {
- if (objB != null)
- {
- return false;
- }
- }
- else if (!objA.equals(objB))
- {
- return false;
- }
+ d |= (a[aOff + i] ^ b[bOff + i]);
}
- return true;
+ return 0 == d;
}
public static int compareUnsigned(byte[] a, byte[] b)
@@ -313,11 +189,11 @@ public final class Arrays
return 0;
}
- public static boolean contains(short[] a, short n)
+ public static boolean contains(boolean[] a, boolean val)
{
for (int i = 0; i < a.length; ++i)
{
- if (a[i] == n)
+ if (a[i] == val)
{
return true;
}
@@ -325,11 +201,11 @@ public final class Arrays
return false;
}
- public static boolean contains(int[] a, int n)
+ public static boolean contains(byte[] a, byte val)
{
for (int i = 0; i < a.length; ++i)
{
- if (a[i] == n)
+ if (a[i] == val)
{
return true;
}
@@ -337,122 +213,154 @@ public final class Arrays
return false;
}
- public static void fill(
- byte[] array,
- byte value)
+ public static boolean contains(char[] a, char val)
{
- for (int i = 0; i < array.length; i++)
+ for (int i = 0; i < a.length; ++i)
{
- array[i] = value;
+ if (a[i] == val)
+ {
+ return true;
+ }
}
+ return false;
}
- public static void fill(
- byte[] array,
- int start,
- int finish,
- byte value)
+ public static boolean contains(int[] a, int val)
{
- for (int i = start; i < finish; i++)
+ for (int i = 0; i < a.length; ++i)
{
- array[i] = value;
+ if (a[i] == val)
+ {
+ return true;
+ }
}
+ return false;
}
- public static void fill(
- char[] array,
- char value)
+ public static boolean contains(long[] a, long val)
{
- for (int i = 0; i < array.length; i++)
+ for (int i = 0; i < a.length; ++i)
{
- array[i] = value;
+ if (a[i] == val)
+ {
+ return true;
+ }
}
+ return false;
}
- public static void fill(
- long[] array,
- long value)
+ public static boolean contains(short[] a, short val)
{
- for (int i = 0; i < array.length; i++)
+ for (int i = 0; i < a.length; ++i)
{
- array[i] = value;
+ if (a[i] == val)
+ {
+ return true;
+ }
}
+ return false;
}
- public static void fill(
- short[] array,
- short value)
+ public static void fill(boolean[] a, boolean val)
{
- for (int i = 0; i < array.length; i++)
- {
- array[i] = value;
- }
+ java.util.Arrays.fill(a, val);
}
- public static void fill(
- int[] array,
- int value)
+ public static void fill(boolean[] a, int fromIndex, int toIndex, boolean val)
{
- for (int i = 0; i < array.length; i++)
- {
- array[i] = value;
- }
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
}
- public static void fill(
- byte[] array,
- int out,
- byte value)
+ public static void fill(byte[] a, byte val)
{
- if(out < array.length)
- {
- for (int i = out; i < array.length; i++)
- {
- array[i] = value;
- }
- }
+ java.util.Arrays.fill(a, val);
}
- public static void fill(
- int[] array,
- int out,
- int value)
+ /**
+ * @deprecated Use {@link #fill(byte[], int, int, byte)} instead.
+ */
+ public static void fill(byte[] a, int fromIndex, byte val)
{
- if(out < array.length)
- {
- for (int i = out; i < array.length; i++)
- {
- array[i] = value;
- }
- }
+ fill(a, fromIndex, a.length, val);
}
- public static void fill(
- short[] array,
- int out,
- short value)
+ public static void fill(byte[] a, int fromIndex, int toIndex, byte val)
{
- if(out < array.length)
- {
- for (int i = out; i < array.length; i++)
- {
- array[i] = value;
- }
- }
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
}
- public static void fill(
- long[] array,
- int out,
- long value)
+ public static void fill(char[] a, char val)
{
- if(out < array.length)
- {
- for (int i = out; i < array.length; i++)
- {
- array[i] = value;
- }
- }
+ java.util.Arrays.fill(a, val);
+ }
+
+ public static void fill(char[] a, int fromIndex, int toIndex, char val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static void fill(int[] a, int val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ /**
+ * @deprecated Use {@link #fill(int[], int, int, int)} instead.
+ */
+ public static void fill(int[] a, int fromIndex, int val)
+ {
+ java.util.Arrays.fill(a, fromIndex, a.length, val);
+ }
+
+ public static void fill(int[] a, int fromIndex, int toIndex, int val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static void fill(long[] a, long val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ /**
+ * @deprecated Use {@link #fill(long[], int, int, long)} instead.
+ */
+ public static void fill(long[] a, int fromIndex, long val)
+ {
+ java.util.Arrays.fill(a, fromIndex, a.length, val);
+ }
+
+ public static void fill(long[] a, int fromIndex, int toIndex, long val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static void fill(Object[] a, Object val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ public static void fill(Object[] a, int fromIndex, int toIndex, Object val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static void fill(short[] a, short val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ /**
+ * @deprecated Use {@link #fill(short[], int, int, short)} instead.
+ */
+ public static void fill(short[] a, int fromIndex, short val)
+ {
+ java.util.Arrays.fill(a, fromIndex, a.length, val);
+ }
+
+ public static void fill(short[] a, int fromIndex, int toIndex, short val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
}
public static int hashCode(byte[] data)
@@ -662,36 +570,45 @@ public final class Arrays
while (--i >= 0)
{
hc *= 257;
- hc ^= data[i].hashCode();
+ hc ^= Objects.hashCode(data[i]);
}
return hc;
}
+ public static boolean[] clone(boolean[] data)
+ {
+ return null == data ? null : data.clone();
+ }
+
public static byte[] clone(byte[] data)
{
- if (data == null)
- {
- return null;
- }
- byte[] copy = new byte[data.length];
+ return null == data ? null : data.clone();
+ }
- System.arraycopy(data, 0, copy, 0, data.length);
+ public static char[] clone(char[] data)
+ {
+ return null == data ? null : data.clone();
+ }
- return copy;
+ public static int[] clone(int[] data)
+ {
+ return null == data ? null : data.clone();
}
- public static char[] clone(char[] data)
+ public static long[] clone(long[] data)
{
- if (data == null)
- {
- return null;
- }
- char[] copy = new char[data.length];
+ return null == data ? null : data.clone();
+ }
- System.arraycopy(data, 0, copy, 0, data.length);
+ public static short[] clone(short[] data)
+ {
+ return null == data ? null : data.clone();
+ }
- return copy;
+ public static BigInteger[] clone(BigInteger[] data)
+ {
+ return null == data ? null : data.clone();
}
public static byte[] clone(byte[] data, byte[] existing)
@@ -708,31 +625,28 @@ public final class Arrays
return existing;
}
- public static byte[][] clone(byte[][] data)
+ public static long[] clone(long[] data, long[] existing)
{
if (data == null)
{
return null;
}
-
- byte[][] copy = new byte[data.length][];
-
- for (int i = 0; i != copy.length; i++)
+ if ((existing == null) || (existing.length != data.length))
{
- copy[i] = clone(data[i]);
+ return clone(data);
}
-
- return copy;
+ System.arraycopy(data, 0, existing, 0, existing.length);
+ return existing;
}
- public static byte[][][] clone(byte[][][] data)
+ public static byte[][] clone(byte[][] data)
{
if (data == null)
{
return null;
}
- byte[][][] copy = new byte[data.length][][];
+ byte[][] copy = new byte[data.length][];
for (int i = 0; i != copy.length; i++)
{
@@ -742,233 +656,139 @@ public final class Arrays
return copy;
}
- public static int[] clone(int[] data)
+ public static byte[][][] clone(byte[][][] data)
{
if (data == null)
{
return null;
}
- int[] copy = new int[data.length];
- System.arraycopy(data, 0, copy, 0, data.length);
-
- return copy;
- }
+ byte[][][] copy = new byte[data.length][][];
- public static long[] clone(long[] data)
- {
- if (data == null)
+ for (int i = 0; i != copy.length; i++)
{
- return null;
+ copy[i] = clone(data[i]);
}
- long[] copy = new long[data.length];
-
- System.arraycopy(data, 0, copy, 0, data.length);
return copy;
}
- public static long[] clone(long[] data, long[] existing)
+ public static boolean[] copyOf(boolean[] original, int newLength)
{
- if (data == null)
- {
- return null;
- }
- if ((existing == null) || (existing.length != data.length))
- {
- return clone(data);
- }
- System.arraycopy(data, 0, existing, 0, existing.length);
- return existing;
+ boolean[] copy = new boolean[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
}
- public static short[] clone(short[] data)
+ public static byte[] copyOf(byte[] original, int newLength)
{
- if (data == null)
- {
- return null;
- }
- short[] copy = new short[data.length];
-
- System.arraycopy(data, 0, copy, 0, data.length);
-
+ byte[] copy = new byte[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
return copy;
}
- public static BigInteger[] clone(BigInteger[] data)
+ public static char[] copyOf(char[] original, int newLength)
{
- if (data == null)
- {
- return null;
- }
- BigInteger[] copy = new BigInteger[data.length];
-
- System.arraycopy(data, 0, copy, 0, data.length);
-
+ char[] copy = new char[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
return copy;
}
- public static byte[] copyOf(byte[] data, int newLength)
+ public static int[] copyOf(int[] original, int newLength)
{
- byte[] tmp = new byte[newLength];
-
- if (newLength < data.length)
- {
- System.arraycopy(data, 0, tmp, 0, newLength);
- }
- else
- {
- System.arraycopy(data, 0, tmp, 0, data.length);
- }
-
- return tmp;
+ int[] copy = new int[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
}
- public static char[] copyOf(char[] data, int newLength)
+ public static long[] copyOf(long[] original, int newLength)
{
- char[] tmp = new char[newLength];
-
- if (newLength < data.length)
- {
- System.arraycopy(data, 0, tmp, 0, newLength);
- }
- else
- {
- System.arraycopy(data, 0, tmp, 0, data.length);
- }
-
- return tmp;
+ long[] copy = new long[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
}
- public static int[] copyOf(int[] data, int newLength)
+ public static short[] copyOf(short[] original, int newLength)
{
- int[] tmp = new int[newLength];
-
- if (newLength < data.length)
- {
- System.arraycopy(data, 0, tmp, 0, newLength);
- }
- else
- {
- System.arraycopy(data, 0, tmp, 0, data.length);
- }
-
- return tmp;
+ short[] copy = new short[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
}
- public static long[] copyOf(long[] data, int newLength)
+ public static BigInteger[] copyOf(BigInteger[] original, int newLength)
{
- long[] tmp = new long[newLength];
-
- if (newLength < data.length)
- {
- System.arraycopy(data, 0, tmp, 0, newLength);
- }
- else
- {
- System.arraycopy(data, 0, tmp, 0, data.length);
- }
-
- return tmp;
+ BigInteger[] copy = new BigInteger[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
}
- public static BigInteger[] copyOf(BigInteger[] data, int newLength)
+ public static boolean[] copyOfRange(boolean[] original, int from, int to)
{
- BigInteger[] tmp = new BigInteger[newLength];
-
- if (newLength < data.length)
- {
- System.arraycopy(data, 0, tmp, 0, newLength);
- }
- else
- {
- System.arraycopy(data, 0, tmp, 0, data.length);
- }
-
- return tmp;
+ int newLength = getLength(from, to);
+ boolean[] copy = new boolean[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
}
/**
- * Make a copy of a range of bytes from the passed in data array. The range can
- * extend beyond the end of the input array, in which case the return array will
- * be padded with zeroes.
+ * Make a copy of a range of bytes from the passed in array. The range can extend beyond the end
+ * of the input array, in which case the returned array will be padded with zeroes.
*
- * @param data the array from which the data is to be copied.
- * @param from the start index at which the copying should take place.
- * @param to the final index of the range (exclusive).
+ * @param original
+ * the array from which the data is to be copied.
+ * @param from
+ * the start index at which the copying should take place.
+ * @param to
+ * the final index of the range (exclusive).
*
* @return a new byte array containing the range given.
*/
- public static byte[] copyOfRange(byte[] data, int from, int to)
+ public static byte[] copyOfRange(byte[] original, int from, int to)
{
int newLength = getLength(from, to);
-
- byte[] tmp = new byte[newLength];
-
- if (data.length - from < newLength)
- {
- System.arraycopy(data, from, tmp, 0, data.length - from);
- }
- else
- {
- System.arraycopy(data, from, tmp, 0, newLength);
- }
-
- return tmp;
+ byte[] copy = new byte[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
}
- public static int[] copyOfRange(int[] data, int from, int to)
+ public static char[] copyOfRange(char[] original, int from, int to)
{
int newLength = getLength(from, to);
-
- int[] tmp = new int[newLength];
-
- if (data.length - from < newLength)
- {
- System.arraycopy(data, from, tmp, 0, data.length - from);
- }
- else
- {
- System.arraycopy(data, from, tmp, 0, newLength);
- }
-
- return tmp;
+ char[] copy = new char[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
}
- public static long[] copyOfRange(long[] data, int from, int to)
+ public static int[] copyOfRange(int[] original, int from, int to)
{
int newLength = getLength(from, to);
-
- long[] tmp = new long[newLength];
-
- if (data.length - from < newLength)
- {
- System.arraycopy(data, from, tmp, 0, data.length - from);
- }
- else
- {
- System.arraycopy(data, from, tmp, 0, newLength);
- }
-
- return tmp;
+ int[] copy = new int[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
}
- public static BigInteger[] copyOfRange(BigInteger[] data, int from, int to)
+ public static long[] copyOfRange(long[] original, int from, int to)
{
int newLength = getLength(from, to);
+ long[] copy = new long[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
+ }
- BigInteger[] tmp = new BigInteger[newLength];
-
- if (data.length - from < newLength)
- {
- System.arraycopy(data, from, tmp, 0, data.length - from);
- }
- else
- {
- System.arraycopy(data, from, tmp, 0, newLength);
- }
+ public static short[] copyOfRange(short[] original, int from, int to)
+ {
+ int newLength = getLength(from, to);
+ short[] copy = new short[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
+ }
- return tmp;
+ public static BigInteger[] copyOfRange(BigInteger[] original, int from, int to)
+ {
+ int newLength = getLength(from, to);
+ BigInteger[] copy = new BigInteger[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
}
private static int getLength(int from, int to)
@@ -1039,84 +859,93 @@ public final class Arrays
return result;
}
-
-
public static byte[] concatenate(byte[] a, byte[] b)
{
- if (a != null && b != null)
+ if (null == a)
{
- byte[] rv = new byte[a.length + b.length];
+ // b might also be null
+ return clone(b);
+ }
+ if (null == b)
+ {
+ // a might also be null
+ return clone(a);
+ }
- System.arraycopy(a, 0, rv, 0, a.length);
- System.arraycopy(b, 0, rv, a.length, b.length);
+ byte[] r = new byte[a.length + b.length];
+ System.arraycopy(a, 0, r, 0, a.length);
+ System.arraycopy(b, 0, r, a.length, b.length);
+ return r;
+ }
- return rv;
- }
- else if (b != null)
+ public static short[] concatenate(short[] a, short[] b)
+ {
+ if (null == a)
{
+ // b might also be null
return clone(b);
}
- else
+ if (null == b)
{
+ // a might also be null
return clone(a);
}
+
+ short[] r = new short[a.length + b.length];
+ System.arraycopy(a, 0, r, 0, a.length);
+ System.arraycopy(b, 0, r, a.length, b.length);
+ return r;
}
public static byte[] concatenate(byte[] a, byte[] b, byte[] c)
{
- if (a != null && b != null && c != null)
- {
- byte[] rv = new byte[a.length + b.length + c.length];
-
- System.arraycopy(a, 0, rv, 0, a.length);
- System.arraycopy(b, 0, rv, a.length, b.length);
- System.arraycopy(c, 0, rv, a.length + b.length, c.length);
-
- return rv;
- }
- else if (a == null)
+ if (null == a)
{
return concatenate(b, c);
}
- else if (b == null)
+ if (null == b)
{
return concatenate(a, c);
}
- else
+ if (null == c)
{
return concatenate(a, b);
}
+
+ byte[] r = new byte[a.length + b.length + c.length];
+ int pos = 0;
+ System.arraycopy(a, 0, r, pos, a.length); pos += a.length;
+ System.arraycopy(b, 0, r, pos, b.length); pos += b.length;
+ System.arraycopy(c, 0, r, pos, c.length);
+ return r;
}
public static byte[] concatenate(byte[] a, byte[] b, byte[] c, byte[] d)
{
- if (a != null && b != null && c != null && d != null)
+ if (null == a)
{
- byte[] rv = new byte[a.length + b.length + c.length + d.length];
-
- System.arraycopy(a, 0, rv, 0, a.length);
- System.arraycopy(b, 0, rv, a.length, b.length);
- System.arraycopy(c, 0, rv, a.length + b.length, c.length);
- System.arraycopy(d, 0, rv, a.length + b.length + c.length, d.length);
-
- return rv;
+ return concatenate(b, c, d);
}
- else if (d == null)
+ if (null == b)
{
- return concatenate(a, b, c);
+ return concatenate(a, c, d);
}
- else if (c == null)
+ if (null == c)
{
return concatenate(a, b, d);
}
- else if (b == null)
+ if (null == d)
{
- return concatenate(a, c, d);
- }
- else
- {
- return concatenate(b, c, d);
+ return concatenate(a, b, c);
}
+
+ byte[] r = new byte[a.length + b.length + c.length + d.length];
+ int pos = 0;
+ System.arraycopy(a, 0, r, pos, a.length); pos += a.length;
+ System.arraycopy(b, 0, r, pos, b.length); pos += b.length;
+ System.arraycopy(c, 0, r, pos, c.length); pos += c.length;
+ System.arraycopy(d, 0, r, pos, d.length);
+ return r;
}
public static byte[] concatenate(byte[][] arrays)
@@ -1141,19 +970,21 @@ public final class Arrays
public static int[] concatenate(int[] a, int[] b)
{
- if (a == null)
+ if (null == a)
{
+ // b might also be null
return clone(b);
}
- if (b == null)
+ if (null == b)
{
+ // a might also be null
return clone(a);
}
- int[] c = new int[a.length + b.length];
- System.arraycopy(a, 0, c, 0, a.length);
- System.arraycopy(b, 0, c, a.length, b.length);
- return c;
+ int[] r = new int[a.length + b.length];
+ System.arraycopy(a, 0, r, 0, a.length);
+ System.arraycopy(b, 0, r, a.length, b.length);
+ return r;
}
public static byte[] prepend(byte[] a, byte b)
@@ -1282,16 +1113,53 @@ public final class Arrays
/**
* Fill input array by zeros
*
- * @param array input array
+ * @param data input array
*/
- public static void clear(byte[] array)
+ public static void clear(byte[] data)
+ {
+ if (null != data)
+ {
+ java.util.Arrays.fill(data, (byte)0x00);
+ }
+ }
+
+ public static void clear(int[] data)
{
- if (array != null)
+ if (null != data)
+ {
+ java.util.Arrays.fill(data, 0);
+ }
+ }
+
+ public static boolean isNullOrContainsNull(Object[] array)
+ {
+ if (null == array)
+ {
+ return true;
+ }
+ int count = array.length;
+ for (int i = 0; i < count; ++i)
{
- for (int i = 0; i < array.length; i++)
+ if (null == array[i])
{
- array[i] = 0;
+ return true;
}
}
+ return false;
+ }
+
+ public static boolean isNullOrEmpty(byte[] array)
+ {
+ return null == array || array.length < 1;
+ }
+
+ public static boolean isNullOrEmpty(int[] array)
+ {
+ return null == array || array.length < 1;
+ }
+
+ public static boolean isNullOrEmpty(Object[] array)
+ {
+ return null == array || array.length < 1;
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/BigIntegers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/BigIntegers.java
index 93e1a779..8b06237d 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/BigIntegers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/BigIntegers.java
@@ -4,6 +4,9 @@ package com.android.org.bouncycastle.util;
import java.math.BigInteger;
import java.security.SecureRandom;
+import com.android.org.bouncycastle.math.raw.Mod;
+import com.android.org.bouncycastle.math.raw.Nat;
+
/**
* BigInteger utilities.
* @hide This class is not part of the Android public SDK API
@@ -12,8 +15,8 @@ public final class BigIntegers
{
public static final BigInteger ZERO = BigInteger.valueOf(0);
public static final BigInteger ONE = BigInteger.valueOf(1);
+ public static final BigInteger TWO = BigInteger.valueOf(2);
- private static final BigInteger TWO = BigInteger.valueOf(2);
private static final BigInteger THREE = BigInteger.valueOf(3);
private static final int MAX_ITERATIONS = 1000;
@@ -21,7 +24,7 @@ public final class BigIntegers
/**
* Return the passed in value as an unsigned byte array.
*
- * @param value value to be converted.
+ * @param value the value to be converted.
* @return a byte array without a leading zero byte if present in the signed encoding.
*/
public static byte[] asUnsignedByteArray(
@@ -29,7 +32,7 @@ public final class BigIntegers
{
byte[] bytes = value.toByteArray();
- if (bytes[0] == 0)
+ if (bytes[0] == 0 && bytes.length != 1)
{
byte[] tmp = new byte[bytes.length - 1];
@@ -42,10 +45,14 @@ public final class BigIntegers
}
/**
- * Return the passed in value as an unsigned byte array.
+ * Return the passed in value as an unsigned byte array of the specified length, padded with
+ * leading zeros as necessary..
*
- * @param value value to be converted.
- * @return a byte array without a leading zero byte if present in the signed encoding.
+ * @param length
+ * the fixed length of the result
+ * @param value
+ * the value to be converted.
+ * @return a byte array padded to a fixed length with leading zeros.
*/
public static byte[] asUnsignedByteArray(int length, BigInteger value)
{
@@ -55,7 +62,7 @@ public final class BigIntegers
return bytes;
}
- int start = bytes[0] == 0 ? 1 : 0;
+ int start = (bytes[0] == 0 && bytes.length != 1) ? 1 : 0;
int count = bytes.length - start;
if (count > length)
@@ -69,6 +76,41 @@ public final class BigIntegers
}
/**
+ * Write the passed in value as unsigned bytes to the specified buffer range, padded with
+ * leading zeros as necessary.
+ *
+ * @param value
+ * the value to be converted.
+ * @param buf
+ * the buffer to which the value is written.
+ * @param off
+ * the start offset in array <code>buf</code> at which the data is written.
+ * @param len
+ * the fixed length of data written (possibly padded with leading zeros).
+ */
+ public static void asUnsignedByteArray(BigInteger value, byte[] buf, int off, int len)
+ {
+ byte[] bytes = value.toByteArray();
+ if (bytes.length == len)
+ {
+ System.arraycopy(bytes, 0, buf, off, len);
+ return;
+ }
+
+ int start = (bytes[0] == 0 && bytes.length != 1) ? 1 : 0;
+ int count = bytes.length - start;
+
+ if (count > len)
+ {
+ throw new IllegalArgumentException("standard length exceeded for value");
+ }
+
+ int padLen = len - count;
+ Arrays.fill(buf, off, off + padLen, (byte)0x00);
+ System.arraycopy(bytes, start, buf, off + padLen, count);
+ }
+
+ /**
* Return a random BigInteger not less than 'min' and not greater than 'max'
*
* @param min the least value that may be generated
@@ -126,8 +168,97 @@ public final class BigIntegers
return new BigInteger(1, mag);
}
+ public static int intValueExact(BigInteger x)
+ {
+ // Since Java 1.8 could use BigInteger.intValueExact instead
+ if (x.bitLength() > 31)
+ {
+ throw new ArithmeticException("BigInteger out of int range");
+ }
+
+ return x.intValue();
+ }
+
+ public static long longValueExact(BigInteger x)
+ {
+ // Since Java 1.8 could use BigInteger.longValueExact instead
+ if (x.bitLength() > 63)
+ {
+ throw new ArithmeticException("BigInteger out of long range");
+ }
+
+ return x.longValue();
+ }
+
+ public static BigInteger modOddInverse(BigInteger M, BigInteger X)
+ {
+ if (!M.testBit(0))
+ {
+ throw new IllegalArgumentException("'M' must be odd");
+ }
+ if (M.signum() != 1)
+ {
+ throw new ArithmeticException("BigInteger: modulus not positive");
+ }
+ if (X.signum() < 0 || X.compareTo(M) >= 0)
+ {
+ X = X.mod(M);
+ }
+
+ int bits = M.bitLength();
+ int[] m = Nat.fromBigInteger(bits, M);
+ int[] x = Nat.fromBigInteger(bits, X);
+ int len = m.length;
+ int[] z = Nat.create(len);
+ if (0 == Mod.modOddInverse(m, x, z))
+ {
+ throw new ArithmeticException("BigInteger not invertible.");
+ }
+ return Nat.toBigInteger(len, z);
+ }
+
+ public static BigInteger modOddInverseVar(BigInteger M, BigInteger X)
+ {
+ if (!M.testBit(0))
+ {
+ throw new IllegalArgumentException("'M' must be odd");
+ }
+ if (M.signum() != 1)
+ {
+ throw new ArithmeticException("BigInteger: modulus not positive");
+ }
+ if (M.equals(ONE))
+ {
+ return ZERO;
+ }
+ if (X.signum() < 0 || X.compareTo(M) >= 0)
+ {
+ X = X.mod(M);
+ }
+ if (X.equals(ONE))
+ {
+ return ONE;
+ }
+
+ int bits = M.bitLength();
+ int[] m = Nat.fromBigInteger(bits, M);
+ int[] x = Nat.fromBigInteger(bits, X);
+ int len = m.length;
+ int[] z = Nat.create(len);
+ if (!Mod.modOddInverseVar(m, x, z))
+ {
+ throw new ArithmeticException("BigInteger not invertible.");
+ }
+ return Nat.toBigInteger(len, z);
+ }
+
public static int getUnsignedByteLength(BigInteger n)
{
+ if (n.equals(ZERO))
+ {
+ return 1;
+ }
+
return (n.bitLength() + 7) / 8;
}
@@ -150,7 +281,7 @@ public final class BigIntegers
+ "ce86165a978d719ebf647f362d33fca29cd179fb42401cbaf3df0c614056f9c8"
+ "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f",
16);
- private static final int SQR_MAX_SMALL = 20; // bitlength of 743 * 743
+ private static final int MAX_SMALL = BigInteger.valueOf(743).bitLength(); // bitlength of 743 * 743
/**
* Return a prime number candidate of the specified bit length.
@@ -185,7 +316,7 @@ public final class BigIntegers
base[base.length - 1] |= 0x01;
rv = new BigInteger(1, base);
- if (bitLength > SQR_MAX_SMALL)
+ if (bitLength > MAX_SMALL)
{
while (!rv.gcd(SMALL_PRIMES_PRODUCT).equals(ONE))
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Doubles.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Doubles.java
new file mode 100644
index 00000000..114bcec1
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Doubles.java
@@ -0,0 +1,13 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.util;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Doubles
+{
+ public static Double valueOf(double value)
+ {
+ return Double.valueOf(value);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Integers.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Integers.java
index 70e870d0..b6627eb9 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Integers.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Integers.java
@@ -7,6 +7,26 @@ package com.android.org.bouncycastle.util;
*/
public class Integers
{
+ public static int numberOfLeadingZeros(int i)
+ {
+ return Integer.numberOfLeadingZeros(i);
+ }
+
+ public static int numberOfTrailingZeros(int i)
+ {
+ return Integer.numberOfTrailingZeros(i);
+ }
+
+ public static int reverse(int i)
+ {
+ return Integer.reverse(i);
+ }
+
+ public static int reverseBytes(int i)
+ {
+ return Integer.reverseBytes(i);
+ }
+
public static int rotateLeft(int i, int distance)
{
return Integer.rotateLeft(i, distance);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Iterable.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Iterable.java
index 9231f118..f035d316 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Iterable.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Iterable.java
@@ -7,7 +7,6 @@ import java.util.Iterator;
* Utility class to allow use of Iterable feature in JDK 1.5+
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public interface Iterable<T>
extends java.lang.Iterable<T>
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Longs.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Longs.java
new file mode 100644
index 00000000..2a812f43
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Longs.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.util;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Longs
+{
+ public static long reverse(long i)
+ {
+ return Long.reverse(i);
+ }
+
+ public static long reverseBytes(long i)
+ {
+ return Long.reverseBytes(i);
+ }
+
+ public static long rotateLeft(long i, int distance)
+ {
+ return Long.rotateLeft(i, distance);
+ }
+
+ public static long rotateRight(long i, int distance)
+ {
+ return Long.rotateRight(i, distance);
+ }
+
+ public static Long valueOf(long value)
+ {
+ return Long.valueOf(value);
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Objects.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Objects.java
new file mode 100644
index 00000000..77306cbd
--- /dev/null
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Objects.java
@@ -0,0 +1,18 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.bouncycastle.util;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Objects
+{
+ public static boolean areEqual(Object a, Object b)
+ {
+ return a == b || (null != a && null != b && a.equals(b));
+ }
+
+ public static int hashCode(Object obj)
+ {
+ return null == obj ? 0 : obj.hashCode();
+ }
+}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Pack.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Pack.java
index d4f9db70..7297e859 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Pack.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Pack.java
@@ -9,14 +9,14 @@ public abstract class Pack
{
public static short bigEndianToShort(byte[] bs, int off)
{
- int n = (bs[ off] & 0xff) << 8;
+ int n = (bs[off] & 0xff) << 8;
n |= (bs[++off] & 0xff);
return (short)n;
}
public static int bigEndianToInt(byte[] bs, int off)
{
- int n = bs[ off] << 24;
+ int n = bs[off] << 24;
n |= (bs[++off] & 0xff) << 16;
n |= (bs[++off] & 0xff) << 8;
n |= (bs[++off] & 0xff);
@@ -32,6 +32,15 @@ public abstract class Pack
}
}
+ public static void bigEndianToInt(byte[] bs, int off, int[] ns, int nsOff, int nsLen)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ ns[nsOff + i] = bigEndianToInt(bs, off);
+ off += 4;
+ }
+ }
+
public static byte[] intToBigEndian(int n)
{
byte[] bs = new byte[4];
@@ -41,10 +50,10 @@ public abstract class Pack
public static void intToBigEndian(int n, byte[] bs, int off)
{
- bs[ off] = (byte)(n >>> 24);
+ bs[off] = (byte)(n >>> 24);
bs[++off] = (byte)(n >>> 16);
- bs[++off] = (byte)(n >>> 8);
- bs[++off] = (byte)(n );
+ bs[++off] = (byte)(n >>> 8);
+ bs[++off] = (byte)(n);
}
public static byte[] intToBigEndian(int[] ns)
@@ -63,6 +72,15 @@ public abstract class Pack
}
}
+ public static void intToBigEndian(int[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ intToBigEndian(ns[nsOff + i], bs, bsOff);
+ bsOff += 4;
+ }
+ }
+
public static long bigEndianToLong(byte[] bs, int off)
{
int hi = bigEndianToInt(bs, off);
@@ -79,6 +97,15 @@ public abstract class Pack
}
}
+ public static void bigEndianToLong(byte[] bs, int bsOff, long[] ns, int nsOff, int nsLen)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ ns[nsOff + i] = bigEndianToLong(bs, bsOff);
+ bsOff += 8;
+ }
+ }
+
public static byte[] longToBigEndian(long n)
{
byte[] bs = new byte[8];
@@ -108,16 +135,42 @@ public abstract class Pack
}
}
+ public static void longToBigEndian(long[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ longToBigEndian(ns[nsOff + i], bs, bsOff);
+ bsOff += 8;
+ }
+ }
+
+ /**
+ * @param value The number
+ * @param bs The target.
+ * @param off Position in target to start.
+ * @param bytes number of bytes to write.
+ *
+ * @deprecated Will be removed
+ */
+ public static void longToBigEndian(long value, byte[] bs, int off, int bytes)
+ {
+ for (int i = bytes - 1; i >= 0; i--)
+ {
+ bs[i + off] = (byte)(value & 0xff);
+ value >>>= 8;
+ }
+ }
+
public static short littleEndianToShort(byte[] bs, int off)
{
- int n = bs[ off] & 0xff;
+ int n = bs[off] & 0xff;
n |= (bs[++off] & 0xff) << 8;
return (short)n;
}
public static int littleEndianToInt(byte[] bs, int off)
{
- int n = bs[ off] & 0xff;
+ int n = bs[off] & 0xff;
n |= (bs[++off] & 0xff) << 8;
n |= (bs[++off] & 0xff) << 16;
n |= bs[++off] << 24;
@@ -162,10 +215,25 @@ public abstract class Pack
public static void shortToLittleEndian(short n, byte[] bs, int off)
{
- bs[ off] = (byte)(n );
- bs[++off] = (byte)(n >>> 8);
+ bs[off] = (byte)(n);
+ bs[++off] = (byte)(n >>> 8);
}
+
+ public static byte[] shortToBigEndian(short n)
+ {
+ byte[] r = new byte[2];
+ shortToBigEndian(n, r, 0);
+ return r;
+ }
+
+ public static void shortToBigEndian(short n, byte[] bs, int off)
+ {
+ bs[off] = (byte)(n >>> 8);
+ bs[++off] = (byte)(n);
+ }
+
+
public static byte[] intToLittleEndian(int n)
{
byte[] bs = new byte[4];
@@ -175,8 +243,8 @@ public abstract class Pack
public static void intToLittleEndian(int n, byte[] bs, int off)
{
- bs[ off] = (byte)(n );
- bs[++off] = (byte)(n >>> 8);
+ bs[off] = (byte)(n);
+ bs[++off] = (byte)(n >>> 8);
bs[++off] = (byte)(n >>> 16);
bs[++off] = (byte)(n >>> 24);
}
@@ -197,6 +265,15 @@ public abstract class Pack
}
}
+ public static void intToLittleEndian(int[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ intToLittleEndian(ns[nsOff + i], bs, bsOff);
+ bsOff += 4;
+ }
+ }
+
public static long littleEndianToLong(byte[] bs, int off)
{
int lo = littleEndianToInt(bs, off);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Properties.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Properties.java
index 1fcbd38c..87f5275e 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Properties.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/Properties.java
@@ -5,6 +5,7 @@ import java.math.BigInteger;
import java.security.AccessControlException;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.security.Security;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -20,11 +21,10 @@ public class Properties
{
private Properties()
{
-
}
private static final ThreadLocal threadProperties = new ThreadLocal();
-
+
/**
* Return whether a particular override has been set to true.
*
@@ -35,14 +35,31 @@ public class Properties
{
try
{
- String p = fetchProperty(propertyName);
+ return isSetTrue(getPropertyValue(propertyName));
+ }
+ catch (AccessControlException e)
+ {
+ return false;
+ }
+ }
- if (p != null)
+ /**
+ * Return whether a particular override has been set to false.
+ *
+ * @param propertyName the property name for the override.
+ * @param isTrue true if the override should be true, false otherwise.
+ * @return true if the property is set to the value of isTrue, false otherwise.
+ */
+ public static boolean isOverrideSetTo(String propertyName, boolean isTrue)
+ {
+ try
+ {
+ String propertyValue = getPropertyValue(propertyName);
+ if (isTrue)
{
- return "true".equals(Strings.toLowerCase(p));
+ return isSetTrue(propertyValue);
}
-
- return false;
+ return isSetFalse(propertyValue);
}
catch (AccessControlException e)
{
@@ -55,7 +72,7 @@ public class Properties
*
* @param propertyName the property name for the override.
* @param enable true if the override should be enabled, false if it should be disabled.
- * @return true if the override was already set, false otherwise.
+ * @return true if the override was already set true, false otherwise.
*/
public static boolean setThreadOverride(String propertyName, boolean enable)
{
@@ -65,48 +82,44 @@ public class Properties
if (localProps == null)
{
localProps = new HashMap();
+
+ threadProperties.set(localProps);
}
localProps.put(propertyName, enable ? "true" : "false");
- threadProperties.set(localProps);
-
return isSet;
}
/**
- * Enable the specified override property in the current thread only.
+ * Remove any value for the specified override property for the current thread only.
*
* @param propertyName the property name for the override.
- * @return true if the override set true in thread local, false otherwise.
+ * @return true if the override was already set true in thread local, false otherwise.
*/
public static boolean removeThreadOverride(String propertyName)
{
- boolean isSet = isOverrideSet(propertyName);
-
Map localProps = (Map)threadProperties.get();
- if (localProps == null)
+ if (localProps != null)
{
- return false;
- }
-
- localProps.remove(propertyName);
+ String p = (String)localProps.remove(propertyName);
+ if (p != null)
+ {
+ if (localProps.isEmpty())
+ {
+ threadProperties.remove();
+ }
- if (localProps.isEmpty())
- {
- threadProperties.remove();
- }
- else
- {
- threadProperties.set(localProps);
+ return "true".equals(Strings.toLowerCase(p));
+ }
}
- return isSet;
+ return false;
}
public static BigInteger asBigInteger(String propertyName)
{
- String p = fetchProperty(propertyName);
+ String p = getPropertyValue(propertyName);
if (p != null)
{
@@ -120,7 +133,7 @@ public class Properties
{
Set<String> set = new HashSet<String>();
- String p = fetchProperty(propertyName);
+ String p = getPropertyValue(propertyName);
if (p != null)
{
@@ -134,20 +147,63 @@ public class Properties
return Collections.unmodifiableSet(set);
}
- private static String fetchProperty(final String propertyName)
+ public static String getPropertyValue(final String propertyName)
{
- return (String)AccessController.doPrivileged(new PrivilegedAction()
+ String val = (String)AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
- Map localProps = (Map)threadProperties.get();
- if (localProps != null)
- {
- return localProps.get(propertyName);
- }
+ return Security.getProperty(propertyName);
+ }
+ });
+ if (val != null)
+ {
+ return val;
+ }
+ Map localProps = (Map)threadProperties.get();
+ if (localProps != null)
+ {
+ String p = (String)localProps.get(propertyName);
+ if (p != null)
+ {
+ return p;
+ }
+ }
+
+ return (String)AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
return System.getProperty(propertyName);
}
});
}
+
+ private static boolean isSetFalse(String p)
+ {
+ if (p == null || p.length() != 5)
+ {
+ return false;
+ }
+
+ return (p.charAt(0) == 'f' || p.charAt(0) == 'F')
+ && (p.charAt(1) == 'a' || p.charAt(1) == 'A')
+ && (p.charAt(2) == 'l' || p.charAt(2) == 'L')
+ && (p.charAt(3) == 's' || p.charAt(3) == 'S')
+ && (p.charAt(4) == 'e' || p.charAt(4) == 'E');
+ }
+
+ private static boolean isSetTrue(String p)
+ {
+ if (p == null || p.length() != 4)
+ {
+ return false;
+ }
+
+ return (p.charAt(0) == 't' || p.charAt(0) == 'T')
+ && (p.charAt(1) == 'r' || p.charAt(1) == 'R')
+ && (p.charAt(2) == 'u' || p.charAt(2) == 'U')
+ && (p.charAt(3) == 'e' || p.charAt(3) == 'E');
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base64Encoder.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base64Encoder.java
index f5ed5006..1fee8630 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base64Encoder.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Base64Encoder.java
@@ -51,71 +51,71 @@ public class Base64Encoder
{
initialiseDecodingTable();
}
-
- /**
- * encode the input data producing a base 64 output stream.
- *
- * @return the number of bytes produced.
- */
- public int encode(
- byte[] data,
- int off,
- int length,
- OutputStream out)
- throws IOException
+
+ public int encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) throws IOException
{
- int modulus = length % 3;
- int dataLength = (length - modulus);
- int a1, a2, a3;
-
- for (int i = off; i < off + dataLength; i += 3)
+ int inPos = inOff;
+ int inEnd = inOff + inLen - 2;
+ int outPos = outOff;
+
+ while (inPos < inEnd)
{
- a1 = data[i] & 0xff;
- a2 = data[i + 1] & 0xff;
- a3 = data[i + 2] & 0xff;
-
- out.write(encodingTable[(a1 >>> 2) & 0x3f]);
- out.write(encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f]);
- out.write(encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f]);
- out.write(encodingTable[a3 & 0x3f]);
+ int a1 = inBuf[inPos++];
+ int a2 = inBuf[inPos++] & 0xFF;
+ int a3 = inBuf[inPos++] & 0xFF;
+
+ outBuf[outPos++] = encodingTable[(a1 >>> 2) & 0x3F];
+ outBuf[outPos++] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3F];
+ outBuf[outPos++] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3F];
+ outBuf[outPos++] = encodingTable[a3 & 0x3F];
}
- /*
- * process the tail end.
- */
- int b1, b2, b3;
- int d1, d2;
-
- switch (modulus)
+ switch (inLen - (inPos - inOff))
{
- case 0: /* nothing left to do */
- break;
case 1:
- d1 = data[off + dataLength] & 0xff;
- b1 = (d1 >>> 2) & 0x3f;
- b2 = (d1 << 4) & 0x3f;
-
- out.write(encodingTable[b1]);
- out.write(encodingTable[b2]);
- out.write(padding);
- out.write(padding);
+ {
+ int a1 = inBuf[inPos++] & 0xFF;
+
+ outBuf[outPos++] = encodingTable[(a1 >>> 2) & 0x3F];
+ outBuf[outPos++] = encodingTable[(a1 << 4) & 0x3F];
+ outBuf[outPos++] = padding;
+ outBuf[outPos++] = padding;
break;
+ }
case 2:
- d1 = data[off + dataLength] & 0xff;
- d2 = data[off + dataLength + 1] & 0xff;
-
- b1 = (d1 >>> 2) & 0x3f;
- b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
- b3 = (d2 << 2) & 0x3f;
+ {
+ int a1 = inBuf[inPos++] & 0xFF;
+ int a2 = inBuf[inPos++] & 0xFF;
- out.write(encodingTable[b1]);
- out.write(encodingTable[b2]);
- out.write(encodingTable[b3]);
- out.write(padding);
+ outBuf[outPos++] = encodingTable[(a1 >>> 2) & 0x3F];
+ outBuf[outPos++] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3F];
+ outBuf[outPos++] = encodingTable[(a2 << 2) & 0x3F];
+ outBuf[outPos++] = padding;
break;
}
+ }
- return (dataLength / 3) * 4 + ((modulus == 0) ? 0 : 4);
+ return outPos - outOff;
+ }
+
+ /**
+ * encode the input data producing a base 64 output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public int encode(byte[] buf, int off, int len, OutputStream out)
+ throws IOException
+ {
+ byte[] tmp = new byte[72];
+ while (len > 0)
+ {
+ int inLen = Math.min(54, len);
+ int outLen = encode(buf, off, inLen, tmp, 0);
+ out.write(tmp, 0, outLen);
+ off += inLen;
+ len -= inLen;
+ }
+ return ((len + 2) / 3) * 4;
}
private boolean ignore(
@@ -138,6 +138,8 @@ public class Base64Encoder
throws IOException
{
byte b1, b2, b3, b4;
+ byte[] outBuffer = new byte[54]; // S/MIME standard
+ int bufOff = 0;
int outLen = 0;
int end = off + length;
@@ -193,16 +195,27 @@ public class Base64Encoder
{
throw new IOException("invalid characters encountered in base64 data");
}
+
+ outBuffer[bufOff++] = (byte)((b1 << 2) | (b2 >> 4));
+ outBuffer[bufOff++] = (byte)((b2 << 4) | (b3 >> 2));
+ outBuffer[bufOff++] = (byte)((b3 << 6) | b4);
- out.write((b1 << 2) | (b2 >> 4));
- out.write((b2 << 4) | (b3 >> 2));
- out.write((b3 << 6) | b4);
+ if (bufOff == outBuffer.length)
+ {
+ out.write(outBuffer);
+ bufOff = 0;
+ }
outLen += 3;
i = nextI(data, i, finish);
}
+ if (bufOff > 0)
+ {
+ out.write(outBuffer, 0, bufOff);
+ }
+
int e0 = nextI(data, i, end);
int e1 = nextI(data, e0 + 1, end);
int e2 = nextI(data, e1 + 1, end);
@@ -234,6 +247,8 @@ public class Base64Encoder
throws IOException
{
byte b1, b2, b3, b4;
+ byte[] outBuffer = new byte[54]; // S/MIME standard
+ int bufOff = 0;
int length = 0;
int end = data.length();
@@ -290,15 +305,25 @@ public class Base64Encoder
throw new IOException("invalid characters encountered in base64 data");
}
- out.write((b1 << 2) | (b2 >> 4));
- out.write((b2 << 4) | (b3 >> 2));
- out.write((b3 << 6) | b4);
+ outBuffer[bufOff++] = (byte)((b1 << 2) | (b2 >> 4));
+ outBuffer[bufOff++] = (byte)((b2 << 4) | (b3 >> 2));
+ outBuffer[bufOff++] = (byte)((b3 << 6) | b4);
length += 3;
-
+ if (bufOff == outBuffer.length)
+ {
+ out.write(outBuffer);
+ bufOff = 0;
+ }
+
i = nextI(data, i, finish);
}
+ if (bufOff > 0)
+ {
+ out.write(outBuffer, 0, bufOff);
+ }
+
int e0 = nextI(data, i, end);
int e1 = nextI(data, e0 + 1, end);
int e2 = nextI(data, e1 + 1, end);
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Hex.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Hex.java
index c6292a01..bc662d4c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Hex.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/Hex.java
@@ -13,8 +13,8 @@ import com.android.org.bouncycastle.util.Strings;
*/
public class Hex
{
- private static final Encoder encoder = new HexEncoder();
-
+ private static final HexEncoder encoder = new HexEncoder();
+
public static String toHexString(
byte[] data)
{
@@ -40,7 +40,7 @@ public class Hex
{
return encode(data, 0, data.length);
}
-
+
/**
* encode the input data producing a Hex encoded byte array.
*
@@ -52,7 +52,7 @@ public class Hex
int length)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
+
try
{
encoder.encode(data, off, length, bOut);
@@ -61,7 +61,7 @@ public class Hex
{
throw new EncoderException("exception encoding Hex string: " + e.getMessage(), e);
}
-
+
return bOut.toByteArray();
}
@@ -77,7 +77,7 @@ public class Hex
{
return encoder.encode(data, 0, data.length, out);
}
-
+
/**
* Hex encode the byte data writing it to the given output stream.
*
@@ -92,7 +92,7 @@ public class Hex
{
return encoder.encode(data, off, length, out);
}
-
+
/**
* decode the Hex encoded input data. It is assumed the input data is valid.
*
@@ -102,7 +102,7 @@ public class Hex
byte[] data)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
+
try
{
encoder.decode(data, 0, data.length, bOut);
@@ -114,7 +114,7 @@ public class Hex
return bOut.toByteArray();
}
-
+
/**
* decode the Hex encoded String data - whitespace will be ignored.
*
@@ -124,7 +124,7 @@ public class Hex
String data)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-
+
try
{
encoder.decode(data, bOut);
@@ -133,10 +133,10 @@ public class Hex
{
throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e);
}
-
+
return bOut.toByteArray();
}
-
+
/**
* decode the Hex encoded String data writing it to the given output stream,
* whitespace characters will be ignored.
@@ -150,4 +150,40 @@ public class Hex
{
return encoder.decode(data, out);
}
+
+ /**
+ * Decode the hexadecimal-encoded string strictly i.e. any non-hexadecimal characters will be
+ * considered an error.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decodeStrict(String str)
+ {
+ try
+ {
+ return encoder.decodeStrict(str, 0, str.length());
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Decode the hexadecimal-encoded string strictly i.e. any non-hexadecimal characters will be
+ * considered an error.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decodeStrict(String str, int off, int len)
+ {
+ try
+ {
+ return encoder.decodeStrict(str, off, len);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e);
+ }
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/HexEncoder.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/HexEncoder.java
index e40a2a18..2a376312 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/HexEncoder.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/encoders/HexEncoder.java
@@ -33,7 +33,7 @@ public class HexEncoder
{
decodingTable[encodingTable[i]] = (byte)i;
}
-
+
decodingTable['A'] = decodingTable['a'];
decodingTable['B'] = decodingTable['b'];
decodingTable['C'] = decodingTable['c'];
@@ -41,33 +41,47 @@ public class HexEncoder
decodingTable['E'] = decodingTable['e'];
decodingTable['F'] = decodingTable['f'];
}
-
+
public HexEncoder()
{
initialiseDecodingTable();
}
-
+
+ public int encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) throws IOException
+ {
+ int inPos = inOff;
+ int inEnd = inOff + inLen;
+ int outPos = outOff;
+
+ while (inPos < inEnd)
+ {
+ int b = inBuf[inPos++] & 0xFF;
+
+ outBuf[outPos++] = encodingTable[b >>> 4];
+ outBuf[outPos++] = encodingTable[b & 0xF];
+ }
+
+ return outPos - outOff;
+ }
+
/**
* encode the input data producing a Hex output stream.
*
* @return the number of bytes produced.
*/
- public int encode(
- byte[] data,
- int off,
- int length,
- OutputStream out)
+ public int encode(byte[] buf, int off, int len, OutputStream out)
throws IOException
- {
- for (int i = off; i < (off + length); i++)
+ {
+ byte[] tmp = new byte[72];
+ while (len > 0)
{
- int v = data[i] & 0xff;
-
- out.write(encodingTable[(v >>> 4)]);
- out.write(encodingTable[v & 0xf]);
+ int inLen = Math.min(36, len);
+ int outLen = encode(buf, off, inLen, tmp, 0);
+ out.write(tmp, 0, outLen);
+ off += inLen;
+ len -= inLen;
}
-
- return length * 2;
+ return len * 2;
}
private static boolean ignore(
@@ -91,19 +105,21 @@ public class HexEncoder
{
byte b1, b2;
int outLen = 0;
-
+ byte[] buf = new byte[36];
+ int bufOff = 0;
+
int end = off + length;
-
+
while (end > off)
{
if (!ignore((char)data[end - 1]))
{
break;
}
-
+
end--;
}
-
+
int i = off;
while (i < end)
{
@@ -111,14 +127,14 @@ public class HexEncoder
{
i++;
}
-
+
b1 = decodingTable[data[i++]];
-
+
while (i < end && ignore((char)data[i]))
{
i++;
}
-
+
b2 = decodingTable[data[i++]];
if ((b1 | b2) < 0)
@@ -126,14 +142,24 @@ public class HexEncoder
throw new IOException("invalid characters encountered in Hex data");
}
- out.write((b1 << 4) | b2);
-
+ buf[bufOff++] = (byte)((b1 << 4) | b2);
+
+ if (bufOff == buf.length)
+ {
+ out.write(buf);
+ bufOff = 0;
+ }
outLen++;
}
+ if (bufOff > 0)
+ {
+ out.write(buf, 0, bufOff);
+ }
+
return outLen;
}
-
+
/**
* decode the Hex encoded String data writing it to the given output stream,
* whitespace characters will be ignored.
@@ -147,19 +173,21 @@ public class HexEncoder
{
byte b1, b2;
int length = 0;
+ byte[] buf = new byte[36];
+ int bufOff = 0;
int end = data.length();
-
+
while (end > 0)
{
if (!ignore(data.charAt(end - 1)))
{
break;
}
-
+
end--;
}
-
+
int i = 0;
while (i < end)
{
@@ -167,14 +195,14 @@ public class HexEncoder
{
i++;
}
-
+
b1 = decodingTable[data.charAt(i++)];
-
+
while (i < end && ignore(data.charAt(i)))
{
i++;
}
-
+
b2 = decodingTable[data.charAt(i++)];
if ((b1 | b2) < 0)
@@ -182,11 +210,57 @@ public class HexEncoder
throw new IOException("invalid characters encountered in Hex string");
}
- out.write((b1 << 4) | b2);
-
+ buf[bufOff++] = (byte)((b1 << 4) | b2);
+
+ if (bufOff == buf.length)
+ {
+ out.write(buf);
+ bufOff = 0;
+ }
+
length++;
}
+ if (bufOff > 0)
+ {
+ out.write(buf, 0, bufOff);
+ }
+
return length;
}
+
+ byte[] decodeStrict(String str, int off, int len) throws IOException
+ {
+ if (null == str)
+ {
+ throw new NullPointerException("'str' cannot be null");
+ }
+ if (off < 0 || len < 0 || off > (str.length() - len))
+ {
+ throw new IndexOutOfBoundsException("invalid offset and/or length specified");
+ }
+ if (0 != (len & 1))
+ {
+ throw new IOException("a hexadecimal encoding must have an even number of characters");
+ }
+
+ int resultLen = len >>> 1;
+ byte[] result = new byte[resultLen];
+
+ int strPos = off;
+ for (int i = 0; i < resultLen; ++i)
+ {
+ byte b1 = decodingTable[str.charAt(strPos++)];
+ byte b2 = decodingTable[str.charAt(strPos++)];
+
+ int n = (b1 << 4) | b2;
+ if (n < 0)
+ {
+ throw new IOException("invalid characters encountered in Hex string");
+ }
+
+ result[i] = (byte)n;
+ }
+ return result;
+ }
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/TeeInputStream.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/TeeInputStream.java
index 2405ca47..32eaa329 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/TeeInputStream.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/TeeInputStream.java
@@ -27,6 +27,11 @@ public class TeeInputStream
this.output = output;
}
+ public int available() throws IOException
+ {
+ return input.available();
+ }
+
public int read(byte[] buf)
throws IOException
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemHeader.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemHeader.java
index 8465791f..2829673f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemHeader.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemHeader.java
@@ -5,7 +5,6 @@ package com.android.org.bouncycastle.util.io.pem;
* Class representing a PEM header (name, value) pair.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class PemHeader
{
private String name;
@@ -17,7 +16,6 @@ public class PemHeader
* @param name name of the header property.
* @param value value of the header property.
*/
- @libcore.api.CorePlatformApi
public PemHeader(String name, String value)
{
this.name = name;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemObject.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemObject.java
index 7dcd8324..26bbd203 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemObject.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemObject.java
@@ -9,7 +9,6 @@ import java.util.List;
* A generic PEM object - type, header properties, and byte content.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class PemObject
implements PemObjectGenerator
{
@@ -25,7 +24,6 @@ public class PemObject
* @param type pem object type.
* @param content the binary content of the object.
*/
- @libcore.api.CorePlatformApi
public PemObject(String type, byte[] content)
{
this(type, EMPTY_LIST, content);
@@ -38,7 +36,6 @@ public class PemObject
* @param headers a list of PemHeader objects.
* @param content the binary content of the object.
*/
- @libcore.api.CorePlatformApi
public PemObject(String type, List headers, byte[] content)
{
this.type = type;
@@ -46,7 +43,6 @@ public class PemObject
this.content = content;
}
- @libcore.api.CorePlatformApi
public String getType()
{
return type;
@@ -57,7 +53,6 @@ public class PemObject
return headers;
}
- @libcore.api.CorePlatformApi
public byte[] getContent()
{
return content;
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemObjectGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemObjectGenerator.java
index 3cbc442f..c8bd172f 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemObjectGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemObjectGenerator.java
@@ -5,7 +5,6 @@ package com.android.org.bouncycastle.util.io.pem;
* Base interface for generators of PEM objects.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public interface PemObjectGenerator
{
/**
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemReader.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemReader.java
index 54ca2ef2..5a9ebb26 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemReader.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemReader.java
@@ -13,14 +13,12 @@ import com.android.org.bouncycastle.util.encoders.Base64;
* A generic PEM reader, based on the format outlined in RFC 1421
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class PemReader
extends BufferedReader
{
private static final String BEGIN = "-----BEGIN ";
private static final String END = "-----END ";
- @libcore.api.CorePlatformApi
public PemReader(Reader reader)
{
super(reader);
@@ -32,7 +30,6 @@ public class PemReader
* @return the next object in the stream, null if no objects left.
* @throws IOException in case of a parse error.
*/
- @libcore.api.CorePlatformApi
public PemObject readPemObject()
throws IOException
{
@@ -47,10 +44,11 @@ public class PemReader
{
line = line.substring(BEGIN.length());
int index = line.indexOf('-');
- String type = line.substring(0, index);
- if (index > 0)
+ if (index > 0 && line.endsWith("-----") && (line.length() - index) == 5)
{
+ String type = line.substring(0, index);
+
return loadObject(type);
}
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemWriter.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemWriter.java
index 717434bd..d48ccb01 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemWriter.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemWriter.java
@@ -13,7 +13,6 @@ import com.android.org.bouncycastle.util.encoders.Base64;
* A generic PEM writer, based on RFC 1421
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class PemWriter
extends BufferedWriter
{
@@ -27,7 +26,6 @@ public class PemWriter
*
* @param out output stream to use.
*/
- @libcore.api.CorePlatformApi
public PemWriter(Writer out)
{
super(out);
@@ -75,7 +73,6 @@ public class PemWriter
return size;
}
- @libcore.api.CorePlatformApi
public void writeObject(PemObjectGenerator objGen)
throws IOException
{
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/AttributeCertificateHolder.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/AttributeCertificateHolder.java
index 784aea69..cca1243c 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/AttributeCertificateHolder.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/AttributeCertificateHolder.java
@@ -150,8 +150,7 @@ public class AttributeCertificateHolder
{
if (holder.getObjectDigestInfo() != null)
{
- return holder.getObjectDigestInfo().getDigestedObjectType()
- .getValue().intValue();
+ return holder.getObjectDigestInfo().getDigestedObjectType().intValueExact();
}
return -1;
}
@@ -340,7 +339,7 @@ public class AttributeCertificateHolder
{
if (holder.getBaseCertificateID() != null)
{
- return holder.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber())
+ return holder.getBaseCertificateID().getSerial().hasValue(x509Cert.getSerialNumber())
&& matchesDN(PrincipalUtil.getIssuerX509Principal(x509Cert), holder.getBaseCertificateID().getIssuer());
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/AttributeCertificateIssuer.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/AttributeCertificateIssuer.java
index d3ae5aab..8719ad2a 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/AttributeCertificateIssuer.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/AttributeCertificateIssuer.java
@@ -154,7 +154,7 @@ public class AttributeCertificateIssuer
V2Form issuer = (V2Form)form;
if (issuer.getBaseCertificateID() != null)
{
- return issuer.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber())
+ return issuer.getBaseCertificateID().getSerial().hasValue(x509Cert.getSerialNumber())
&& matchesDN(x509Cert.getIssuerX500Principal(), issuer.getBaseCertificateID().getIssuer());
}
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509Util.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509Util.java
index 4ea85229..5cb7c012 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509Util.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509Util.java
@@ -106,11 +106,13 @@ class X509Util
noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384);
noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512);
noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1);
+ // BEGIN Android-removed:
+ // noParams.add(OIWObjectIdentifiers.dsaWithSHA1);
noParams.add(NISTObjectIdentifiers.dsa_with_sha224);
noParams.add(NISTObjectIdentifiers.dsa_with_sha256);
noParams.add(NISTObjectIdentifiers.dsa_with_sha384);
noParams.add(NISTObjectIdentifiers.dsa_with_sha512);
-
+
//
// RFC 4491
//
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V1CertificateGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V1CertificateGenerator.java
index 0ce75691..2b5b831b 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V1CertificateGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V1CertificateGenerator.java
@@ -41,7 +41,6 @@ import com.android.org.bouncycastle.jce.X509Principal;
* @deprecated use org.bouncycastle.cert.X509v1CertificateBuilder.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class X509V1CertificateGenerator
{
private final JcaJceHelper bcHelper = new BCJcaJceHelper(); // needed to force provider loading
@@ -52,7 +51,6 @@ public class X509V1CertificateGenerator
private AlgorithmIdentifier sigAlgId;
private String signatureAlgorithm;
- @libcore.api.CorePlatformApi
public X509V1CertificateGenerator()
{
tbsGen = new V1TBSCertificateGenerator();
@@ -69,7 +67,6 @@ public class X509V1CertificateGenerator
/**
* set the serial number for the certificate.
*/
- @libcore.api.CorePlatformApi
public void setSerialNumber(
BigInteger serialNumber)
{
@@ -85,7 +82,6 @@ public class X509V1CertificateGenerator
* Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the
* certificate.
*/
- @libcore.api.CorePlatformApi
public void setIssuerDN(
X500Principal issuer)
{
@@ -109,14 +105,12 @@ public class X509V1CertificateGenerator
tbsGen.setIssuer(issuer);
}
- @libcore.api.CorePlatformApi
public void setNotBefore(
Date date)
{
tbsGen.setStartDate(new Time(date));
}
- @libcore.api.CorePlatformApi
public void setNotAfter(
Date date)
{
@@ -126,7 +120,6 @@ public class X509V1CertificateGenerator
/**
* Set the subject distinguished name. The subject describes the entity associated with the public key.
*/
- @libcore.api.CorePlatformApi
public void setSubjectDN(
X500Principal subject)
{
@@ -149,7 +142,6 @@ public class X509V1CertificateGenerator
tbsGen.setSubject(subject);
}
- @libcore.api.CorePlatformApi
public void setPublicKey(
PublicKey key)
{
@@ -169,7 +161,6 @@ public class X509V1CertificateGenerator
*
* @param signatureAlgorithm string representation of the algorithm name.
*/
- @libcore.api.CorePlatformApi
public void setSignatureAlgorithm(
String signatureAlgorithm)
{
@@ -324,7 +315,6 @@ public class X509V1CertificateGenerator
* using the passed in provider for the signing, and the passed in source
* of randomness (if required).
*/
- @libcore.api.CorePlatformApi
public X509Certificate generate(
PrivateKey key,
String provider)
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V2AttributeCertificate.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V2AttributeCertificate.java
index 770fa324..5eac49ac 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V2AttributeCertificate.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V2AttributeCertificate.java
@@ -95,7 +95,7 @@ public class X509V2AttributeCertificate
public int getVersion()
{
- return cert.getAcinfo().getVersion().getValue().intValue() + 1;
+ return cert.getAcinfo().getVersion().intValueExact() + 1;
}
public BigInteger getSerialNumber()
diff --git a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V3CertificateGenerator.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V3CertificateGenerator.java
index 50b5e8b9..516b5224 100644
--- a/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V3CertificateGenerator.java
+++ b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/x509/X509V3CertificateGenerator.java
@@ -46,7 +46,6 @@ import com.android.org.bouncycastle.x509.extension.X509ExtensionUtil;
* @deprecated use org.bouncycastle.cert.X509v3CertificateBuilder.
* @hide This class is not part of the Android public SDK API
*/
-@libcore.api.CorePlatformApi
public class X509V3CertificateGenerator
{
private final JcaJceHelper bcHelper = new BCJcaJceHelper(); // needed to force provider loading
@@ -59,7 +58,6 @@ public class X509V3CertificateGenerator
private X509ExtensionsGenerator extGenerator;
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public X509V3CertificateGenerator()
{
tbsGen = new V3TBSCertificateGenerator();
@@ -79,7 +77,6 @@ public class X509V3CertificateGenerator
* set the serial number for the certificate.
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public void setSerialNumber(
BigInteger serialNumber)
{
@@ -96,7 +93,6 @@ public class X509V3CertificateGenerator
* certificate.
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public void setIssuerDN(
X500Principal issuer)
{
@@ -122,7 +118,6 @@ public class X509V3CertificateGenerator
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public void setNotBefore(
Date date)
{
@@ -130,7 +125,6 @@ public class X509V3CertificateGenerator
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public void setNotAfter(
Date date)
{
@@ -141,7 +135,6 @@ public class X509V3CertificateGenerator
* Set the subject distinguished name. The subject describes the entity associated with the public key.
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public void setSubjectDN(
X500Principal subject)
{
@@ -166,7 +159,6 @@ public class X509V3CertificateGenerator
}
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public void setPublicKey(
PublicKey key)
throws IllegalArgumentException
@@ -189,7 +181,6 @@ public class X509V3CertificateGenerator
* @param signatureAlgorithm string representation of the algorithm name.
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public void setSignatureAlgorithm(
String signatureAlgorithm)
{
@@ -432,7 +423,6 @@ public class X509V3CertificateGenerator
* </p>
*/
@android.compat.annotation.UnsupportedAppUsage
- @libcore.api.CorePlatformApi
public X509Certificate generate(
PrivateKey key)
throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecific.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
new file mode 100644
index 00000000..38a6d582
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
@@ -0,0 +1,248 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * Base class for an ASN.1 ApplicationSpecific object
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1ApplicationSpecific
+ extends ASN1Primitive
+{
+ protected final boolean isConstructed;
+ protected final int tag;
+ protected final byte[] octets;
+
+ ASN1ApplicationSpecific(
+ boolean isConstructed,
+ int tag,
+ byte[] octets)
+ {
+ this.isConstructed = isConstructed;
+ this.tag = tag;
+ this.octets = Arrays.clone(octets);
+ }
+
+ /**
+ * Return an ASN1ApplicationSpecific from the passed in object, which may be a byte array, or null.
+ *
+ * @param obj the object to be converted.
+ * @return obj's representation as an ASN1ApplicationSpecific object.
+ */
+ public static ASN1ApplicationSpecific getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1ApplicationSpecific)
+ {
+ return (ASN1ApplicationSpecific)obj;
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return ASN1ApplicationSpecific.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("Failed to construct object from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
+ }
+
+ protected static int getLengthOfHeader(byte[] data)
+ {
+ int length = data[1] & 0xff; // TODO: assumes 1 byte tag
+
+ if (length == 0x80)
+ {
+ return 2; // indefinite-length encoding
+ }
+
+ if (length > 127)
+ {
+ int size = length & 0x7f;
+
+ // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
+ if (size > 4)
+ {
+ throw new IllegalStateException("DER length more than 4 bytes: " + size);
+ }
+
+ return size + 2;
+ }
+
+ return 2;
+ }
+
+ /**
+ * Return true if the object is marked as constructed, false otherwise.
+ *
+ * @return true if constructed, otherwise false.
+ */
+ public boolean isConstructed()
+ {
+ return isConstructed;
+ }
+
+ /**
+ * Return the contents of this object as a byte[]
+ *
+ * @return the encoded contents of the object.
+ */
+ public byte[] getContents()
+ {
+ return Arrays.clone(octets);
+ }
+
+ /**
+ * Return the tag number associated with this object,
+ *
+ * @return the application tag number.
+ */
+ public int getApplicationTag()
+ {
+ return tag;
+ }
+
+ /**
+ * Return the enclosed object assuming explicit tagging.
+ *
+ * @return the resulting object
+ * @throws IOException if reconstruction fails.
+ */
+ public ASN1Primitive getObject()
+ throws IOException
+ {
+ return ASN1Primitive.fromByteArray(getContents());
+ }
+
+ /**
+ * Return the enclosed object assuming implicit tagging.
+ *
+ * @param derTagNo the type tag that should be applied to the object's contents.
+ * @return the resulting object
+ * @throws IOException if reconstruction fails.
+ */
+ public ASN1Primitive getObject(int derTagNo)
+ throws IOException
+ {
+ if (derTagNo >= 0x1f)
+ {
+ throw new IOException("unsupported tag number");
+ }
+
+ byte[] orig = this.getEncoded();
+ byte[] tmp = replaceTagNumber(derTagNo, orig);
+
+ if ((orig[0] & BERTags.CONSTRUCTED) != 0)
+ {
+ tmp[0] |= BERTags.CONSTRUCTED;
+ }
+
+ return ASN1Primitive.fromByteArray(tmp);
+ }
+
+ int encodedLength()
+ throws IOException
+ {
+ return StreamUtil.calculateTagLength(tag) + StreamUtil.calculateBodyLength(octets.length) + octets.length;
+ }
+
+ /* (non-Javadoc)
+ * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
+ */
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ int flags = BERTags.APPLICATION;
+ if (isConstructed)
+ {
+ flags |= BERTags.CONSTRUCTED;
+ }
+
+ out.writeEncoded(withTag, flags, tag, octets);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof ASN1ApplicationSpecific))
+ {
+ return false;
+ }
+
+ ASN1ApplicationSpecific other = (ASN1ApplicationSpecific)o;
+
+ return isConstructed == other.isConstructed
+ && tag == other.tag
+ && Arrays.areEqual(octets, other.octets);
+ }
+
+ public int hashCode()
+ {
+ return (isConstructed ? 1 : 0) ^ tag ^ Arrays.hashCode(octets);
+ }
+
+ private byte[] replaceTagNumber(int newTag, byte[] input)
+ throws IOException
+ {
+ int tagNo = input[0] & 0x1f;
+ int index = 1;
+ //
+ // with tagged object tag number is bottom 5 bits, or stored at the start of the content
+ //
+ if (tagNo == 0x1f)
+ {
+ int b = input[index++] & 0xff;
+
+ // X.690-0207 8.1.2.4.2
+ // "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
+ if ((b & 0x7f) == 0) // Note: -1 will pass
+ {
+ throw new IOException("corrupted stream - invalid high tag number found");
+ }
+
+ while ((b & 0x80) != 0)
+ {
+ b = input[index++] & 0xff;
+ }
+ }
+
+ byte[] tmp = new byte[input.length - index + 1];
+
+ System.arraycopy(input, index, tmp, 1, tmp.length - 1);
+
+ tmp[0] = (byte)newTag;
+
+ return tmp;
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append("[");
+ if (isConstructed())
+ {
+ sb.append("CONSTRUCTED ");
+ }
+ sb.append("APPLICATION ");
+ sb.append(Integer.toString(getApplicationTag()));
+ sb.append("]");
+ // @todo content encoding somehow?
+ if (this.octets != null)
+ {
+ sb.append(" #");
+ sb.append(Hex.toHexString(this.octets));
+ }
+ else
+ {
+ sb.append(" #null");
+ }
+ sb.append(" ");
+ return sb.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java
new file mode 100644
index 00000000..f4bc6e35
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java
@@ -0,0 +1,21 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Interface to parse ASN.1 ApplicationSpecific objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ASN1ApplicationSpecificParser
+ extends ASN1Encodable, InMemoryRepresentable
+{
+ /**
+ * Read the next object in the parser.
+ *
+ * @return an ASN1Encodable
+ * @throws IOException on a parsing or decoding error.
+ */
+ ASN1Encodable readObject()
+ throws IOException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitString.java
new file mode 100644
index 00000000..001dd61d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitString.java
@@ -0,0 +1,328 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.io.Streams;
+
+/**
+ * Base class for BIT STRING objects
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1BitString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ protected final byte[] data;
+ protected final int padBits;
+
+ /**
+ * @param bitString an int containing the BIT STRING
+ * @return the correct number of pad bits for a bit string defined in
+ * a 32 bit constant
+ */
+ static protected int getPadBits(
+ int bitString)
+ {
+ int val = 0;
+ for (int i = 3; i >= 0; i--)
+ {
+ //
+ // this may look a little odd, but if it isn't done like this pre jdk1.2
+ // JVM's break!
+ //
+ if (i != 0)
+ {
+ if ((bitString >> (i * 8)) != 0)
+ {
+ val = (bitString >> (i * 8)) & 0xFF;
+ break;
+ }
+ }
+ else
+ {
+ if (bitString != 0)
+ {
+ val = bitString & 0xFF;
+ break;
+ }
+ }
+ }
+
+ if (val == 0)
+ {
+ return 0;
+ }
+
+
+ int bits = 1;
+
+ while (((val <<= 1) & 0xFF) != 0)
+ {
+ bits++;
+ }
+
+ return 8 - bits;
+ }
+
+ /**
+ * @param bitString an int containing the BIT STRING
+ * @return the correct number of bytes for a bit string defined in
+ * a 32 bit constant
+ */
+ static protected byte[] getBytes(int bitString)
+ {
+ if (bitString == 0)
+ {
+ return new byte[0];
+ }
+
+ int bytes = 4;
+ for (int i = 3; i >= 1; i--)
+ {
+ if ((bitString & (0xFF << (i * 8))) != 0)
+ {
+ break;
+ }
+ bytes--;
+ }
+
+ byte[] result = new byte[bytes];
+ for (int i = 0; i < bytes; i++)
+ {
+ result[i] = (byte) ((bitString >> (i * 8)) & 0xFF);
+ }
+
+ return result;
+ }
+
+ protected ASN1BitString(byte data, int padBits)
+ {
+ if (padBits > 7 || padBits < 0)
+ {
+ throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
+ }
+
+ this.data = new byte[]{ data };
+ this.padBits = padBits;
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param data the octets making up the bit string.
+ * @param padBits the number of extra bits at the end of the string.
+ */
+ public ASN1BitString(
+ byte[] data,
+ int padBits)
+ {
+ if (data == null)
+ {
+ throw new NullPointerException("'data' cannot be null");
+ }
+ if (data.length == 0 && padBits != 0)
+ {
+ throw new IllegalArgumentException("zero length data with non-zero pad bits");
+ }
+ if (padBits > 7 || padBits < 0)
+ {
+ throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
+ }
+
+ this.data = Arrays.clone(data);
+ this.padBits = padBits;
+ }
+
+ /**
+ * Return a String representation of this BIT STRING
+ *
+ * @return a String representation.
+ */
+ public String getString()
+ {
+ StringBuffer buf = new StringBuffer("#");
+
+ byte[] string;
+ try
+ {
+ string = getEncoded();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("Internal error encoding BitString: " + e.getMessage(), e);
+ }
+
+ for (int i = 0; i != string.length; i++)
+ {
+ buf.append(table[(string[i] >>> 4) & 0xf]);
+ buf.append(table[string[i] & 0xf]);
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * @return the value of the bit string as an int (truncating if necessary)
+ */
+ public int intValue()
+ {
+ int value = 0;
+ int end = Math.min(4, data.length - 1);
+ for (int i = 0; i < end; ++i)
+ {
+ value |= (data[i] & 0xFF) << (8 * i);
+ }
+ if (0 <= end && end < 4)
+ {
+ byte der = (byte)(data[end] & (0xFF << padBits));
+ value |= (der & 0xFF) << (8 * end);
+ }
+ return value;
+ }
+
+ /**
+ * Return the octets contained in this BIT STRING, checking that this BIT STRING really
+ * does represent an octet aligned string. Only use this method when the standard you are
+ * following dictates that the BIT STRING will be octet aligned.
+ *
+ * @return a copy of the octet aligned data.
+ */
+ public byte[] getOctets()
+ {
+ if (padBits != 0)
+ {
+ throw new IllegalStateException("attempt to get non-octet aligned data from BIT STRING");
+ }
+
+ return Arrays.clone(data);
+ }
+
+ public byte[] getBytes()
+ {
+ if (0 == data.length)
+ {
+ return data;
+ }
+
+ byte[] rv = Arrays.clone(data);
+ // DER requires pad bits be zero
+ rv[data.length - 1] &= (0xFF << padBits);
+ return rv;
+ }
+
+ public int getPadBits()
+ {
+ return padBits;
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public int hashCode()
+ {
+ int end = data.length;
+ if (--end < 0)
+ {
+ return 1;
+ }
+
+ byte der = (byte)(data[end] & (0xFF << padBits));
+
+ int hc = Arrays.hashCode(data, 0, end);
+ hc *= 257;
+ hc ^= der;
+ return hc ^ padBits;
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof ASN1BitString))
+ {
+ return false;
+ }
+
+ ASN1BitString other = (ASN1BitString)o;
+ if (padBits != other.padBits)
+ {
+ return false;
+ }
+ byte[] a = data, b = other.data;
+ int end = a.length;
+ if (end != b.length)
+ {
+ return false;
+ }
+ if (--end < 0)
+ {
+ return true;
+ }
+ for (int i = 0; i < end; ++i)
+ {
+ if (a[i] != b[i])
+ {
+ return false;
+ }
+ }
+
+ byte derA = (byte)(a[end] & (0xFF << padBits));
+ byte derB = (byte)(b[end] & (0xFF << padBits));
+
+ return derA == derB;
+ }
+
+ static ASN1BitString fromInputStream(int length, InputStream stream)
+ throws IOException
+ {
+ if (length < 1)
+ {
+ throw new IllegalArgumentException("truncated BIT STRING detected");
+ }
+
+ int padBits = stream.read();
+ byte[] data = new byte[length - 1];
+
+ if (data.length != 0)
+ {
+ if (Streams.readFully(stream, data) != data.length)
+ {
+ throw new EOFException("EOF encountered in middle of BIT STRING");
+ }
+
+ if (padBits > 0 && padBits < 8)
+ {
+ if (data[data.length - 1] != (byte)(data[data.length - 1] & (0xFF << padBits)))
+ {
+ return new DLBitString(data, padBits);
+ }
+ }
+ }
+
+ return new DERBitString(data, padBits);
+ }
+
+ public ASN1Primitive getLoadedObject()
+ {
+ return this.toASN1Primitive();
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return new DERBitString(data, padBits);
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return new DLBitString(data, padBits);
+ }
+
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Boolean.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Boolean.java
new file mode 100644
index 00000000..80d935ac
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Boolean.java
@@ -0,0 +1,182 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Public facade of ASN.1 Boolean data.
+ * <p>
+ * Use following to place a new instance of ASN.1 Boolean in your data:
+ * <ul>
+ * <li> ASN1Boolean.TRUE literal</li>
+ * <li> ASN1Boolean.FALSE literal</li>
+ * <li> {@link ASN1Boolean#getInstance(boolean) ASN1Boolean.getInstance(boolean)}</li>
+ * <li> {@link ASN1Boolean#getInstance(int) ASN1Boolean.getInstance(int)}</li>
+ * </ul>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1Boolean
+ extends ASN1Primitive
+{
+ private static final byte FALSE_VALUE = 0x00;
+ private static final byte TRUE_VALUE = (byte)0xFF;
+
+ public static final ASN1Boolean FALSE = new ASN1Boolean(FALSE_VALUE);
+ public static final ASN1Boolean TRUE = new ASN1Boolean(TRUE_VALUE);
+
+ private final byte value;
+
+ /**
+ * Return a boolean from the passed in object.
+ *
+ * @param obj an ASN1Boolean or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1Boolean instance.
+ */
+ public static ASN1Boolean getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1Boolean)
+ {
+ return (ASN1Boolean)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ byte[] enc = (byte[])obj;
+ try
+ {
+ return (ASN1Boolean)fromByteArray(enc);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct boolean from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return an ASN1Boolean from the passed in boolean.
+ * @param value true or false depending on the ASN1Boolean wanted.
+ * @return an ASN1Boolean instance.
+ */
+ public static ASN1Boolean getInstance(boolean value)
+ {
+ return value ? TRUE : FALSE;
+ }
+
+ /**
+ * Return an ASN1Boolean from the passed in value.
+ * @param value non-zero (true) or zero (false) depending on the ASN1Boolean wanted.
+ * @return an ASN1Boolean instance.
+ */
+ public static ASN1Boolean getInstance(int value)
+ {
+ return value != 0 ? TRUE : FALSE;
+ }
+
+ // BEGIN Android-added: Unknown reason
+ /**
+ * return a ASN1Boolean from the passed in array.
+ */
+ public static ASN1Boolean getInstance(
+ byte[] octets)
+ {
+ return (octets[0] != 0) ? TRUE : FALSE;
+ }
+
+ // END Android-added: Unknown reason
+ /**
+ * Return a Boolean from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1Boolean instance.
+ */
+ public static ASN1Boolean getInstance(ASN1TaggedObject obj, boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof ASN1Boolean)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return ASN1Boolean.fromOctetString(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ private ASN1Boolean(byte value)
+ {
+ this.value = value;
+ }
+
+ public boolean isTrue()
+ {
+ return value != FALSE_VALUE;
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 3;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.BOOLEAN, value);
+ }
+
+ boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1Boolean))
+ {
+ return false;
+ }
+
+ ASN1Boolean that = (ASN1Boolean)other;
+
+ return this.isTrue() == that.isTrue();
+ }
+
+ public int hashCode()
+ {
+ return isTrue() ? 1 : 0;
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return isTrue() ? TRUE : FALSE;
+ }
+
+ public String toString()
+ {
+ return isTrue() ? "TRUE" : "FALSE";
+ }
+
+ static ASN1Boolean fromOctetString(byte[] value)
+ {
+ if (value.length != 1)
+ {
+ throw new IllegalArgumentException("BOOLEAN value should have 1 byte in it");
+ }
+
+ byte b = value[0];
+ switch (b)
+ {
+ case FALSE_VALUE: return FALSE;
+ case TRUE_VALUE: return TRUE;
+ default: return new ASN1Boolean(b);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Choice.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Choice.java
new file mode 100644
index 00000000..eec254fa
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Choice.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+/**
+ * Marker interface for CHOICE objects - if you implement this in a role your
+ * own object any attempt to tag the object implicitly will convert the tag to
+ * an explicit one as the encoding rules require.
+ * <p>
+ * If you use this interface your class should also implement the getInstance()
+ * pattern which takes a tag object and the tagging mode used.
+ * </p>
+ * <p><b>X.690</b></p>
+ * <p><b>8: Basic encoding rules</b></p>
+ * <p><b>8.13 Encoding of a choice value </b></p>
+ * <p>
+ * The encoding of a choice value shall be the same as the encoding of a value of the chosen type.
+ * <blockquote>
+ * NOTE 1 &mdash; The encoding may be primitive or constructed depending on the chosen type.
+ * </blockquote>
+ * <blockquote>
+ * NOTE 2 &mdash; The tag used in the identifier octets is the tag of the chosen type,
+ * as specified in the ASN.1 definition of the choice type.
+ * </blockquote>
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ASN1Choice
+{
+ // marker interface
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Encodable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Encodable.java
new file mode 100644
index 00000000..fd9903c0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Encodable.java
@@ -0,0 +1,15 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+/**
+ * Basic interface to produce serialisers for ASN.1 encodings.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ASN1Encodable
+{
+ /**
+ * Return an object, possibly constructed, of ASN.1 primitives
+ * @return an ASN.1 primitive.
+ */
+ ASN1Primitive toASN1Primitive();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1EncodableVector.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1EncodableVector.java
new file mode 100644
index 00000000..aabcc624
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1EncodableVector.java
@@ -0,0 +1,161 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+/**
+ * Mutable class for building ASN.1 constructed objects such as SETs or SEQUENCEs.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1EncodableVector
+{
+ static final ASN1Encodable[] EMPTY_ELEMENTS = new ASN1Encodable[0];
+
+ private static final int DEFAULT_CAPACITY = 10;
+
+ private ASN1Encodable[] elements;
+ private int elementCount;
+ private boolean copyOnWrite;
+
+ public ASN1EncodableVector()
+ {
+ this(DEFAULT_CAPACITY);
+ }
+
+ public ASN1EncodableVector(int initialCapacity)
+ {
+ if (initialCapacity < 0)
+ {
+ throw new IllegalArgumentException("'initialCapacity' must not be negative");
+ }
+
+ this.elements = (initialCapacity == 0) ? EMPTY_ELEMENTS : new ASN1Encodable[initialCapacity];
+ this.elementCount = 0;
+ this.copyOnWrite = false;
+ }
+
+ public void add(ASN1Encodable element)
+ {
+ if (null == element)
+ {
+ throw new NullPointerException("'element' cannot be null");
+ }
+
+ int capacity = elements.length;
+ int minCapacity = elementCount + 1;
+ if ((minCapacity > capacity) | copyOnWrite)
+ {
+ reallocate(minCapacity);
+ }
+
+ this.elements[elementCount] = element;
+ this.elementCount = minCapacity;
+ }
+
+ public void addAll(ASN1EncodableVector other)
+ {
+ if (null == other)
+ {
+ throw new NullPointerException("'other' cannot be null");
+ }
+
+ int otherElementCount = other.size();
+ if (otherElementCount < 1)
+ {
+ return;
+ }
+
+ int capacity = elements.length;
+ int minCapacity = elementCount + otherElementCount;
+ if ((minCapacity > capacity) | copyOnWrite)
+ {
+ reallocate(minCapacity);
+ }
+
+ int i = 0;
+ do
+ {
+ ASN1Encodable otherElement = other.get(i);
+ if (null == otherElement)
+ {
+ throw new NullPointerException("'other' elements cannot be null");
+ }
+
+ this.elements[elementCount + i] = otherElement;
+ }
+ while (++i < otherElementCount);
+
+ this.elementCount = minCapacity;
+ }
+
+ /**
+ * Return the object at position i in this vector.
+ *
+ * @param i the index of the object of interest.
+ * @return the object at position i.
+ */
+ public ASN1Encodable get(int i)
+ {
+ if (i >= elementCount)
+ {
+ throw new ArrayIndexOutOfBoundsException(i + " >= " + elementCount);
+ }
+
+ return elements[i];
+ }
+
+ /**
+ * Return the size of the vector.
+ *
+ * @return the object count in the vector.
+ */
+ public int size()
+ {
+ return elementCount;
+ }
+
+ ASN1Encodable[] copyElements()
+ {
+ if (0 == elementCount)
+ {
+ return EMPTY_ELEMENTS;
+ }
+
+ ASN1Encodable[] copy = new ASN1Encodable[elementCount];
+ System.arraycopy(elements, 0, copy, 0, elementCount);
+ return copy;
+ }
+
+ ASN1Encodable[] takeElements()
+ {
+ if (0 == elementCount)
+ {
+ return EMPTY_ELEMENTS;
+ }
+
+ if (elements.length == elementCount)
+ {
+ this.copyOnWrite = true;
+ return elements;
+ }
+
+ ASN1Encodable[] copy = new ASN1Encodable[elementCount];
+ System.arraycopy(elements, 0, copy, 0, elementCount);
+ return copy;
+ }
+
+ private void reallocate(int minCapacity)
+ {
+ int oldCapacity = elements.length;
+ int newCapacity = Math.max(oldCapacity, minCapacity + (minCapacity >> 1));
+
+ ASN1Encodable[] copy = new ASN1Encodable[newCapacity];
+ System.arraycopy(elements, 0, copy, 0, elementCount);
+
+ this.elements = copy;
+ this.copyOnWrite = false;
+ }
+
+ static ASN1Encodable[] cloneElements(ASN1Encodable[] elements)
+ {
+ return elements.length < 1 ? EMPTY_ELEMENTS : (ASN1Encodable[])elements.clone();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Encoding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Encoding.java
new file mode 100644
index 00000000..0ea5d58d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Encoding.java
@@ -0,0 +1,24 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+/**
+ * Supported encoding formats.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ASN1Encoding
+{
+ /**
+ * DER - distinguished encoding rules.
+ */
+ static final String DER = "DER";
+
+ /**
+ * DL - definite length encoding.
+ */
+ static final String DL = "DL";
+
+ /**
+ * BER - basic encoding rules.
+ */
+ static final String BER = "BER";
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Enumerated.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Enumerated.java
new file mode 100644
index 00000000..d95d62e7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Enumerated.java
@@ -0,0 +1,213 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Class representing the ASN.1 ENUMERATED type.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1Enumerated
+ extends ASN1Primitive
+{
+ private final byte[] bytes;
+ private final int start;
+
+ /**
+ * return an enumerated from the passed in object
+ *
+ * @param obj an ASN1Enumerated or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1Enumerated instance, or null.
+ */
+ public static ASN1Enumerated getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1Enumerated)
+ {
+ return (ASN1Enumerated)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1Enumerated)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return an Enumerated from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1Enumerated instance, or null.
+ */
+ public static ASN1Enumerated getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof ASN1Enumerated)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ /**
+ * Constructor from int.
+ *
+ * @param value the value of this enumerated.
+ */
+ public ASN1Enumerated(int value)
+ {
+ if (value < 0)
+ {
+ throw new IllegalArgumentException("enumerated must be non-negative");
+ }
+
+ this.bytes = BigInteger.valueOf(value).toByteArray();
+ this.start = 0;
+ }
+
+ /**
+ * Constructor from BigInteger
+ *
+ * @param value the value of this enumerated.
+ */
+ public ASN1Enumerated(BigInteger value)
+ {
+ if (value.signum() < 0)
+ {
+ throw new IllegalArgumentException("enumerated must be non-negative");
+ }
+
+ this.bytes = value.toByteArray();
+ this.start = 0;
+ }
+
+ /**
+ * Constructor from encoded BigInteger.
+ *
+ * @param bytes the value of this enumerated as an encoded BigInteger (signed).
+ */
+ public ASN1Enumerated(byte[] bytes)
+ {
+ if (ASN1Integer.isMalformed(bytes))
+ {
+ throw new IllegalArgumentException("malformed enumerated");
+ }
+ if (0 != (bytes[0] & 0x80))
+ {
+ throw new IllegalArgumentException("enumerated must be non-negative");
+ }
+
+ this.bytes = Arrays.clone(bytes);
+ this.start = ASN1Integer.signBytesToSkip(bytes);
+ }
+
+ public BigInteger getValue()
+ {
+ return new BigInteger(bytes);
+ }
+
+ public boolean hasValue(BigInteger x)
+ {
+ return null != x
+ // Fast check to avoid allocation
+ && ASN1Integer.intValue(bytes, start, ASN1Integer.SIGN_EXT_SIGNED) == x.intValue()
+ && getValue().equals(x);
+ }
+
+ public int intValueExact()
+ {
+ int count = bytes.length - start;
+ if (count > 4)
+ {
+ throw new ArithmeticException("ASN.1 Enumerated out of int range");
+ }
+
+ return ASN1Integer.intValue(bytes, start, ASN1Integer.SIGN_EXT_SIGNED);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.ENUMERATED, bytes);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof ASN1Enumerated))
+ {
+ return false;
+ }
+
+ ASN1Enumerated other = (ASN1Enumerated)o;
+
+ return Arrays.areEqual(this.bytes, other.bytes);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(bytes);
+ }
+
+ private static ASN1Enumerated[] cache = new ASN1Enumerated[12];
+
+ static ASN1Enumerated fromOctetString(byte[] enc)
+ {
+ if (enc.length > 1)
+ {
+ return new ASN1Enumerated(enc);
+ }
+
+ if (enc.length == 0)
+ {
+ throw new IllegalArgumentException("ENUMERATED has zero length");
+ }
+ int value = enc[0] & 0xff;
+
+ if (value >= cache.length)
+ {
+ return new ASN1Enumerated(enc);
+ }
+
+ ASN1Enumerated possibleMatch = cache[value];
+
+ if (possibleMatch == null)
+ {
+ possibleMatch = cache[value] = new ASN1Enumerated(enc);
+ }
+
+ return possibleMatch;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Exception.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Exception.java
new file mode 100644
index 00000000..fc5976e8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Exception.java
@@ -0,0 +1,46 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Exception thrown in cases of corrupted or unexpected data in a stream.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1Exception
+ extends IOException
+{
+ private Throwable cause;
+
+ /**
+ * Base constructor
+ *
+ * @param message a message concerning the exception.
+ */
+ ASN1Exception(String message)
+ {
+ super(message);
+ }
+
+ /**
+ * Constructor when this exception is due to another one.
+ *
+ * @param message a message concerning the exception.
+ * @param cause the exception that caused this exception to be thrown.
+ */
+ ASN1Exception(String message, Throwable cause)
+ {
+ super(message);
+ this.cause = cause;
+ }
+
+ /**
+ * Return the underlying cause of this exception, if any.
+ *
+ * @return the exception causing this one, null if there isn't one.
+ */
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1External.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1External.java
new file mode 100644
index 00000000..4f6aa4c1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1External.java
@@ -0,0 +1,294 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Class representing the DER-type External
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1External
+ extends ASN1Primitive
+{
+ protected ASN1ObjectIdentifier directReference;
+ protected ASN1Integer indirectReference;
+ protected ASN1Primitive dataValueDescriptor;
+ protected int encoding;
+ protected ASN1Primitive externalContent;
+
+ /**
+ * Construct an EXTERNAL object, the input encoding vector must have exactly two elements on it.
+ * <p>
+ * Acceptable input formats are:
+ * <ul>
+ * <li> {@link ASN1ObjectIdentifier} + data {@link DERTaggedObject} (direct reference form)</li>
+ * <li> {@link ASN1Integer} + data {@link DERTaggedObject} (indirect reference form)</li>
+ * <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
+ * </ul>
+ *
+ * @throws IllegalArgumentException if input size is wrong, or
+ */
+ public ASN1External(ASN1EncodableVector vector)
+ {
+ int offset = 0;
+
+ ASN1Primitive enc = getObjFromVector(vector, offset);
+ if (enc instanceof ASN1ObjectIdentifier)
+ {
+ directReference = (ASN1ObjectIdentifier)enc;
+ offset++;
+ enc = getObjFromVector(vector, offset);
+ }
+ if (enc instanceof ASN1Integer)
+ {
+ indirectReference = (ASN1Integer) enc;
+ offset++;
+ enc = getObjFromVector(vector, offset);
+ }
+ if (!(enc instanceof ASN1TaggedObject))
+ {
+ dataValueDescriptor = (ASN1Primitive) enc;
+ offset++;
+ enc = getObjFromVector(vector, offset);
+ }
+
+ if (vector.size() != offset + 1)
+ {
+ throw new IllegalArgumentException("input vector too large");
+ }
+
+ if (!(enc instanceof ASN1TaggedObject))
+ {
+ throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External");
+ }
+ ASN1TaggedObject obj = (ASN1TaggedObject)enc;
+ setEncoding(obj.getTagNo());
+ externalContent = obj.getObject();
+ }
+
+ private ASN1Primitive getObjFromVector(ASN1EncodableVector v, int index)
+ {
+ if (v.size() <= index)
+ {
+ throw new IllegalArgumentException("too few objects in input vector");
+ }
+
+ return v.get(index).toASN1Primitive();
+ }
+
+ /**
+ * Creates a new instance of External
+ * See X.690 for more informations about the meaning of these parameters
+ * @param directReference The direct reference or <code>null</code> if not set.
+ * @param indirectReference The indirect reference or <code>null</code> if not set.
+ * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
+ * @param externalData The external data in its encoded form.
+ */
+ public ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
+ {
+ this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
+ }
+
+ /**
+ * Creates a new instance of External.
+ * See X.690 for more informations about the meaning of these parameters
+ * @param directReference The direct reference or <code>null</code> if not set.
+ * @param indirectReference The indirect reference or <code>null</code> if not set.
+ * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
+ * @param encoding The encoding to be used for the external data
+ * @param externalData The external data
+ */
+ public ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
+ {
+ setDirectReference(directReference);
+ setIndirectReference(indirectReference);
+ setDataValueDescriptor(dataValueDescriptor);
+ setEncoding(encoding);
+ setExternalContent(externalData.toASN1Primitive());
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return new DERExternal(directReference, indirectReference, dataValueDescriptor, encoding, externalContent);
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return new DLExternal(directReference, indirectReference, dataValueDescriptor, encoding, externalContent);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode()
+ {
+ int ret = 0;
+ if (directReference != null)
+ {
+ ret = directReference.hashCode();
+ }
+ if (indirectReference != null)
+ {
+ ret ^= indirectReference.hashCode();
+ }
+ if (dataValueDescriptor != null)
+ {
+ ret ^= dataValueDescriptor.hashCode();
+ }
+ ret ^= externalContent.hashCode();
+ return ret;
+ }
+
+ boolean isConstructed()
+ {
+ return true;
+ }
+
+ int encodedLength()
+ throws IOException
+ {
+ return this.getEncoded().length;
+ }
+
+ /* (non-Javadoc)
+ * @see org.bouncycastle.asn1.ASN1Primitive#asn1Equals(org.bouncycastle.asn1.ASN1Primitive)
+ */
+ boolean asn1Equals(ASN1Primitive o)
+ {
+ if (!(o instanceof ASN1External))
+ {
+ return false;
+ }
+ if (this == o)
+ {
+ return true;
+ }
+ ASN1External other = (ASN1External)o;
+ if (directReference != null)
+ {
+ if (other.directReference == null || !other.directReference.equals(directReference))
+ {
+ return false;
+ }
+ }
+ if (indirectReference != null)
+ {
+ if (other.indirectReference == null || !other.indirectReference.equals(indirectReference))
+ {
+ return false;
+ }
+ }
+ if (dataValueDescriptor != null)
+ {
+ if (other.dataValueDescriptor == null || !other.dataValueDescriptor.equals(dataValueDescriptor))
+ {
+ return false;
+ }
+ }
+ return externalContent.equals(other.externalContent);
+ }
+
+ /**
+ * Returns the data value descriptor
+ * @return The descriptor
+ */
+ public ASN1Primitive getDataValueDescriptor()
+ {
+ return dataValueDescriptor;
+ }
+
+ /**
+ * Returns the direct reference of the external element
+ * @return The reference
+ */
+ public ASN1ObjectIdentifier getDirectReference()
+ {
+ return directReference;
+ }
+
+ /**
+ * Returns the encoding of the content. Valid values are
+ * <ul>
+ * <li><code>0</code> single-ASN1-type</li>
+ * <li><code>1</code> OCTET STRING</li>
+ * <li><code>2</code> BIT STRING</li>
+ * </ul>
+ * @return The encoding
+ */
+ public int getEncoding()
+ {
+ return encoding;
+ }
+
+ /**
+ * Returns the content of this element
+ * @return The content
+ */
+ public ASN1Primitive getExternalContent()
+ {
+ return externalContent;
+ }
+
+ /**
+ * Returns the indirect reference of this element
+ * @return The reference
+ */
+ public ASN1Integer getIndirectReference()
+ {
+ return indirectReference;
+ }
+
+ /**
+ * Sets the data value descriptor
+ * @param dataValueDescriptor The descriptor
+ */
+ private void setDataValueDescriptor(ASN1Primitive dataValueDescriptor)
+ {
+ this.dataValueDescriptor = dataValueDescriptor;
+ }
+
+ /**
+ * Sets the direct reference of the external element
+ * @param directReferemce The reference
+ */
+ private void setDirectReference(ASN1ObjectIdentifier directReferemce)
+ {
+ this.directReference = directReferemce;
+ }
+
+ /**
+ * Sets the encoding of the content. Valid values are
+ * <ul>
+ * <li><code>0</code> single-ASN1-type</li>
+ * <li><code>1</code> OCTET STRING</li>
+ * <li><code>2</code> BIT STRING</li>
+ * </ul>
+ * @param encoding The encoding
+ */
+ private void setEncoding(int encoding)
+ {
+ if (encoding < 0 || encoding > 2)
+ {
+ throw new IllegalArgumentException("invalid encoding value: " + encoding);
+ }
+ this.encoding = encoding;
+ }
+
+ /**
+ * Sets the content of this element
+ * @param externalContent The content
+ */
+ private void setExternalContent(ASN1Primitive externalContent)
+ {
+ this.externalContent = externalContent;
+ }
+
+ /**
+ * Sets the indirect reference of this element
+ * @param indirectReference The reference
+ */
+ private void setIndirectReference(ASN1Integer indirectReference)
+ {
+ this.indirectReference = indirectReference;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralizedTime.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralizedTime.java
new file mode 100644
index 00000000..5e755543
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralizedTime.java
@@ -0,0 +1,510 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+// Android-added: Localization support
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * Base class representing the ASN.1 GeneralizedTime type.
+ * <p>
+ * The main difference between these and UTC time is a 4 digit year.
+ * </p>
+ * <p>
+ * One second resolution date+time on UTC timezone (Z)
+ * with 4 digit year (valid from 0001 to 9999).
+ * </p><p>
+ * Timestamp format is: yyyymmddHHMMSS'Z'
+ * </p><p>
+ * <h2>X.690</h2>
+ * This is what is called "restricted string",
+ * and it uses ASCII characters to encode digits and supplemental data.
+ *
+ * <h3>11: Restrictions on BER employed by both CER and DER</h3>
+ * <h4>11.7 GeneralizedTime </h4>
+ * <p>
+ * <b>11.7.1</b> The encoding shall terminate with a "Z",
+ * as described in the ITU-T Rec. X.680 | ISO/IEC 8824-1 clause on
+ * GeneralizedTime.
+ * </p><p>
+ * <b>11.7.2</b> The seconds element shall always be present.
+ * </p>
+ * <p>
+ * <b>11.7.3</b> The fractional-seconds elements, if present,
+ * shall omit all trailing zeros; if the elements correspond to 0,
+ * they shall be wholly omitted, and the decimal point element also
+ * shall be omitted.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1GeneralizedTime
+ extends ASN1Primitive
+{
+ protected byte[] time;
+
+ /**
+ * return a generalized time from the passed in object
+ *
+ * @param obj an ASN1GeneralizedTime or an object that can be converted into one.
+ * @return an ASN1GeneralizedTime instance, or null.
+ * @throws IllegalArgumentException if the object cannot be converted.
+ */
+ public static ASN1GeneralizedTime getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1GeneralizedTime)
+ {
+ return (ASN1GeneralizedTime)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1GeneralizedTime)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a Generalized Time object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @return an ASN1GeneralizedTime instance.
+ * @throws IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static ASN1GeneralizedTime getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof ASN1GeneralizedTime)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new ASN1GeneralizedTime(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ /**
+ * The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z
+ * for local time, or Z+-HHMM on the end, for difference between local
+ * time and UTC time. The fractional second amount f must consist of at
+ * least one number with trailing zeroes removed.
+ *
+ * @param time the time string.
+ * @throws IllegalArgumentException if String is an illegal format.
+ */
+ public ASN1GeneralizedTime(
+ String time)
+ {
+ this.time = Strings.toByteArray(time);
+ try
+ {
+ this.getDate();
+ }
+ catch (ParseException e)
+ {
+ throw new IllegalArgumentException("invalid date string: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Base constructor from a java.util.date object
+ *
+ * @param time a date object representing the time of interest.
+ */
+ public ASN1GeneralizedTime(
+ Date time)
+ {
+ // Android-changed: Use localized version
+ // SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'", DateUtil.EN_Locale);
+ SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'", Locale.US);
+
+ dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
+
+ this.time = Strings.toByteArray(dateF.format(time));
+ }
+
+ /**
+ * Base constructor from a java.util.date and Locale - you may need to use this if the default locale
+ * doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations.
+ *
+ * @param time a date object representing the time of interest.
+ * @param locale an appropriate Locale for producing an ASN.1 GeneralizedTime value.
+ */
+ public ASN1GeneralizedTime(
+ Date time,
+ Locale locale)
+ {
+ // BEGIN Android-changed: Use localized version
+ // SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'", locale);
+ SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'", Locale.US);
+ dateF.setCalendar(Calendar.getInstance(Locale.US));
+ // END Android-changed: Use localized version
+
+ dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
+
+ this.time = Strings.toByteArray(dateF.format(time));
+ }
+
+ ASN1GeneralizedTime(
+ byte[] bytes)
+ {
+ if (bytes.length < 4)
+ {
+ throw new IllegalArgumentException("GeneralizedTime string too short");
+ }
+ this.time = bytes;
+
+ if (!(isDigit(0) && isDigit(1) && isDigit(2) && isDigit(3)))
+ {
+ throw new IllegalArgumentException("illegal characters in GeneralizedTime string");
+ }
+ }
+
+ /**
+ * Return the time.
+ *
+ * @return The time string as it appeared in the encoded object.
+ */
+ public String getTimeString()
+ {
+ return Strings.fromByteArray(time);
+ }
+
+ /**
+ * return the time - always in the form of
+ * YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm).
+ * <p>
+ * Normally in a certificate we would expect "Z" rather than "GMT",
+ * however adding the "GMT" means we can just use:
+ * <pre>
+ * dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
+ * </pre>
+ * To read in the time and get a date which is compatible with our local
+ * time zone.
+ * @return a String representation of the time.
+ */
+ public String getTime()
+ {
+ String stime = Strings.fromByteArray(time);
+
+ //
+ // standardise the format.
+ //
+ if (stime.charAt(stime.length() - 1) == 'Z')
+ {
+ return stime.substring(0, stime.length() - 1) + "GMT+00:00";
+ }
+ else
+ {
+ int signPos = stime.length() - 6;
+ char sign = stime.charAt(signPos);
+ if ((sign == '-' || sign == '+') && stime.indexOf("GMT") == signPos - 3)
+ {
+ // already a GMT string!
+ return stime;
+ }
+
+ signPos = stime.length() - 5;
+ sign = stime.charAt(signPos);
+ if (sign == '-' || sign == '+')
+ {
+ return stime.substring(0, signPos)
+ + "GMT"
+ + stime.substring(signPos, signPos + 3)
+ + ":"
+ + stime.substring(signPos + 3);
+ }
+
+ signPos = stime.length() - 3;
+ sign = stime.charAt(signPos);
+ if (sign == '-' || sign == '+')
+ {
+ return stime.substring(0, signPos)
+ + "GMT"
+ + stime.substring(signPos)
+ + ":00";
+ }
+ }
+ return stime + calculateGMTOffset(stime);
+ }
+
+ private String calculateGMTOffset(String stime)
+ {
+ String sign = "+";
+ TimeZone timeZone = TimeZone.getDefault();
+ int offset = timeZone.getRawOffset();
+ if (offset < 0)
+ {
+ sign = "-";
+ offset = -offset;
+ }
+ int hours = offset / (60 * 60 * 1000);
+ int minutes = (offset - (hours * 60 * 60 * 1000)) / (60 * 1000);
+
+ try
+ {
+ if (timeZone.useDaylightTime())
+ {
+ if (hasFractionalSeconds())
+ {
+ stime = pruneFractionalSeconds(stime);
+ }
+ SimpleDateFormat dateF = calculateGMTDateFormat();
+ if (timeZone.inDaylightTime(
+ dateF.parse(stime + "GMT" + sign + convert(hours) + ":" + convert(minutes))))
+ {
+ hours += sign.equals("+") ? 1 : -1;
+ }
+ }
+ }
+ catch (ParseException e)
+ {
+ // we'll do our best and ignore daylight savings
+ }
+
+ return "GMT" + sign + convert(hours) + ":" + convert(minutes);
+ }
+
+ private SimpleDateFormat calculateGMTDateFormat()
+ {
+ SimpleDateFormat dateF;
+
+ if (hasFractionalSeconds())
+ {
+ dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz");
+ }
+ else if (hasSeconds())
+ {
+ dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
+ }
+ else if (hasMinutes())
+ {
+ dateF = new SimpleDateFormat("yyyyMMddHHmmz");
+ }
+ else
+ {
+ dateF = new SimpleDateFormat("yyyyMMddHHz");
+ }
+
+ dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
+ return dateF;
+ }
+
+ private String pruneFractionalSeconds(String origTime)
+ {
+ // java misinterprets extra digits as being milliseconds...
+ String frac = origTime.substring(14);
+ int index;
+ for (index = 1; index < frac.length(); index++)
+ {
+ char ch = frac.charAt(index);
+ if (!('0' <= ch && ch <= '9'))
+ {
+ break;
+ }
+ }
+
+ if (index - 1 > 3)
+ {
+ frac = frac.substring(0, 4) + frac.substring(index);
+ origTime = origTime.substring(0, 14) + frac;
+ }
+ else if (index - 1 == 1)
+ {
+ frac = frac.substring(0, index) + "00" + frac.substring(index);
+ origTime = origTime.substring(0, 14) + frac;
+ }
+ else if (index - 1 == 2)
+ {
+ frac = frac.substring(0, index) + "0" + frac.substring(index);
+ origTime = origTime.substring(0, 14) + frac;
+ }
+
+ return origTime;
+ }
+
+ private String convert(int time)
+ {
+ if (time < 10)
+ {
+ return "0" + time;
+ }
+
+ return Integer.toString(time);
+ }
+
+ public Date getDate()
+ throws ParseException
+ {
+ SimpleDateFormat dateF;
+ String stime = Strings.fromByteArray(time);
+ String d = stime;
+
+ if (stime.endsWith("Z"))
+ {
+ if (hasFractionalSeconds())
+ {
+ // Android-changed: Use localized version
+ // dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'");
+ dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'", Locale.US);
+ }
+ else if (hasSeconds())
+ {
+ // Android-changed: Use localized version
+ // dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
+ dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'", Locale.US);
+ }
+ else if (hasMinutes())
+ {
+ // Android-changed: Use localized version
+ // dateF = new SimpleDateFormat("yyyyMMddHHmm'Z'");
+ dateF = new SimpleDateFormat("yyyyMMddHHmm'Z'", Locale.US);
+ }
+ else
+ {
+ // Android-changed: Use localized version
+ // dateF = new SimpleDateFormat("yyyyMMddHH'Z'");
+ dateF = new SimpleDateFormat("yyyyMMddHH'Z'", Locale.US);
+ }
+
+ dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
+ }
+ else if (stime.indexOf('-') > 0 || stime.indexOf('+') > 0)
+ {
+ d = this.getTime();
+ dateF = calculateGMTDateFormat();
+ }
+ else
+ {
+ if (hasFractionalSeconds())
+ {
+ // Android-changed: Use localized version
+ // dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
+ dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS", Locale.US);
+ }
+ else if (hasSeconds())
+ {
+ // Android-changed: Use localized version
+ // dateF = new SimpleDateFormat("yyyyMMddHHmmss");
+ dateF = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
+ }
+ else if (hasMinutes())
+ {
+ // Android-changed: Use localized version
+ // dateF = new SimpleDateFormat("yyyyMMddHHmm");
+ dateF = new SimpleDateFormat("yyyyMMddHHmm", Locale.US);
+ }
+ else
+ {
+ // Android-changed: Use localized version
+ // dateF = new SimpleDateFormat("yyyyMMddHH");
+ dateF = new SimpleDateFormat("yyyyMMddHH", Locale.US);
+ }
+
+ dateF.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID()));
+ }
+
+ if (hasFractionalSeconds())
+ {
+ d = pruneFractionalSeconds(d);
+ }
+
+ return DateUtil.epochAdjust(dateF.parse(d));
+ }
+
+ protected boolean hasFractionalSeconds()
+ {
+ for (int i = 0; i != time.length; i++)
+ {
+ if (time[i] == '.')
+ {
+ if (i == 14)
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ protected boolean hasSeconds()
+ {
+ return isDigit(12) && isDigit(13);
+ }
+
+ protected boolean hasMinutes()
+ {
+ return isDigit(10) && isDigit(11);
+ }
+
+ private boolean isDigit(int pos)
+ {
+ return time.length > pos && time[pos] >= '0' && time[pos] <= '9';
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ int length = time.length;
+
+ return 1 + StreamUtil.calculateBodyLength(length) + length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.GENERALIZED_TIME, time);
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return new DERGeneralizedTime(time);
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return new DERGeneralizedTime(time);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof ASN1GeneralizedTime))
+ {
+ return false;
+ }
+
+ return Arrays.areEqual(time, ((ASN1GeneralizedTime)o).time);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(time);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Generator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Generator.java
new file mode 100644
index 00000000..29c5bc4a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Generator.java
@@ -0,0 +1,32 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.OutputStream;
+
+/**
+ * Basic class for streaming generators.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1Generator
+{
+ // TODO This is problematic if we want an isolating buffer for all ASN.1 writes
+ protected OutputStream _out;
+
+ /**
+ * Base constructor.
+ *
+ * @param out
+ * the end output stream that object encodings are written to.
+ */
+ public ASN1Generator(OutputStream out)
+ {
+ _out = out;
+ }
+
+ /**
+ * Return the actual stream object encodings are written to.
+ *
+ * @return the stream that is directly encoded to.
+ */
+ public abstract OutputStream getRawOutputStream();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1InputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1InputStream.java
new file mode 100644
index 00000000..482fcff9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1InputStream.java
@@ -0,0 +1,508 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.android.internal.org.bouncycastle.util.io.Streams;
+
+/**
+ * A general purpose ASN.1 decoder - note: this class differs from the
+ * others in that it returns null after it has read the last object in
+ * the stream. If an ASN.1 NULL is encountered a DER/BER Null object is
+ * returned.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1InputStream
+ extends FilterInputStream
+ implements BERTags
+{
+ private final int limit;
+ private final boolean lazyEvaluate;
+
+ private final byte[][] tmpBuffers;
+
+ public ASN1InputStream(
+ InputStream is)
+ {
+ this(is, StreamUtil.findLimit(is));
+ }
+
+ /**
+ * Create an ASN1InputStream based on the input byte array. The length of DER objects in
+ * the stream is automatically limited to the length of the input array.
+ *
+ * @param input array containing ASN.1 encoded data.
+ */
+ public ASN1InputStream(
+ byte[] input)
+ {
+ this(new ByteArrayInputStream(input), input.length);
+ }
+
+ /**
+ * Create an ASN1InputStream based on the input byte array. The length of DER objects in
+ * the stream is automatically limited to the length of the input array.
+ *
+ * @param input array containing ASN.1 encoded data.
+ * @param lazyEvaluate true if parsing inside constructed objects can be delayed.
+ */
+ public ASN1InputStream(
+ byte[] input,
+ boolean lazyEvaluate)
+ {
+ this(new ByteArrayInputStream(input), input.length, lazyEvaluate);
+ }
+
+ /**
+ * Create an ASN1InputStream where no DER object will be longer than limit.
+ *
+ * @param input stream containing ASN.1 encoded data.
+ * @param limit maximum size of a DER encoded object.
+ */
+ public ASN1InputStream(
+ InputStream input,
+ int limit)
+ {
+ this(input, limit, false);
+ }
+
+ /**
+ * Create an ASN1InputStream where no DER object will be longer than limit, and constructed
+ * objects such as sequences will be parsed lazily.
+ *
+ * @param input stream containing ASN.1 encoded data.
+ * @param lazyEvaluate true if parsing inside constructed objects can be delayed.
+ */
+ public ASN1InputStream(
+ InputStream input,
+ boolean lazyEvaluate)
+ {
+ this(input, StreamUtil.findLimit(input), lazyEvaluate);
+ }
+
+ /**
+ * Create an ASN1InputStream where no DER object will be longer than limit, and constructed
+ * objects such as sequences will be parsed lazily.
+ *
+ * @param input stream containing ASN.1 encoded data.
+ * @param limit maximum size of a DER encoded object.
+ * @param lazyEvaluate true if parsing inside constructed objects can be delayed.
+ */
+ public ASN1InputStream(
+ InputStream input,
+ int limit,
+ boolean lazyEvaluate)
+ {
+ super(input);
+ this.limit = limit;
+ this.lazyEvaluate = lazyEvaluate;
+ this.tmpBuffers = new byte[11][];
+ }
+
+ int getLimit()
+ {
+ return limit;
+ }
+
+ protected int readLength()
+ throws IOException
+ {
+ return readLength(this, limit, false);
+ }
+
+ protected void readFully(
+ byte[] bytes)
+ throws IOException
+ {
+ if (Streams.readFully(this, bytes) != bytes.length)
+ {
+ throw new EOFException("EOF encountered in middle of object");
+ }
+ }
+
+ /**
+ * build an object given its tag and the number of bytes to construct it from.
+ *
+ * @param tag the full tag details.
+ * @param tagNo the tagNo defined.
+ * @param length the length of the object.
+ * @return the resulting primitive.
+ * @throws java.io.IOException on processing exception.
+ */
+ protected ASN1Primitive buildObject(
+ int tag,
+ int tagNo,
+ int length)
+ throws IOException
+ {
+ boolean isConstructed = (tag & CONSTRUCTED) != 0;
+
+ DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length, limit);
+
+ if ((tag & APPLICATION) != 0)
+ {
+ return new DLApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
+ }
+
+ if ((tag & TAGGED) != 0)
+ {
+ return new ASN1StreamParser(defIn).readTaggedObject(isConstructed, tagNo);
+ }
+
+ if (isConstructed)
+ {
+ // TODO There are other tags that may be constructed (e.g. BIT_STRING)
+ switch (tagNo)
+ {
+ case OCTET_STRING:
+ //
+ // yes, people actually do this...
+ //
+ ASN1EncodableVector v = readVector(defIn);
+ ASN1OctetString[] strings = new ASN1OctetString[v.size()];
+
+ for (int i = 0; i != strings.length; i++)
+ {
+ ASN1Encodable asn1Obj = v.get(i);
+ if (asn1Obj instanceof ASN1OctetString)
+ {
+ strings[i] = (ASN1OctetString)asn1Obj;
+ }
+ else
+ {
+ throw new ASN1Exception("unknown object encountered in constructed OCTET STRING: " + asn1Obj.getClass());
+ }
+ }
+
+ return new BEROctetString(strings);
+ case SEQUENCE:
+ if (lazyEvaluate)
+ {
+ return new LazyEncodedSequence(defIn.toByteArray());
+ }
+ else
+ {
+ return DLFactory.createSequence(readVector(defIn));
+ }
+ case SET:
+ return DLFactory.createSet(readVector(defIn));
+ case EXTERNAL:
+ return new DLExternal(readVector(defIn));
+ default:
+ throw new IOException("unknown tag " + tagNo + " encountered");
+ }
+ }
+
+ return createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
+ }
+
+ ASN1EncodableVector readVector(DefiniteLengthInputStream dIn) throws IOException
+ {
+ if (dIn.getRemaining() < 1)
+ {
+ return new ASN1EncodableVector(0);
+ }
+
+ ASN1InputStream subStream = new ASN1InputStream(dIn);
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1Primitive p;
+ while ((p = subStream.readObject()) != null)
+ {
+ v.add(p);
+ }
+ return v;
+ }
+
+ public ASN1Primitive readObject()
+ throws IOException
+ {
+ int tag = read();
+ if (tag <= 0)
+ {
+ if (tag == 0)
+ {
+ throw new IOException("unexpected end-of-contents marker");
+ }
+
+ return null;
+ }
+
+ //
+ // calculate tag number
+ //
+ int tagNo = readTagNumber(this, tag);
+
+ boolean isConstructed = (tag & CONSTRUCTED) != 0;
+
+ //
+ // calculate length
+ //
+ int length = readLength();
+
+ if (length < 0) // indefinite-length method
+ {
+ if (!isConstructed)
+ {
+ throw new IOException("indefinite-length primitive encoding encountered");
+ }
+
+ IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit);
+ ASN1StreamParser sp = new ASN1StreamParser(indIn, limit);
+
+ if ((tag & APPLICATION) != 0)
+ {
+ return new BERApplicationSpecificParser(tagNo, sp).getLoadedObject();
+ }
+
+ if ((tag & TAGGED) != 0)
+ {
+ return new BERTaggedObjectParser(true, tagNo, sp).getLoadedObject();
+ }
+
+ // TODO There are other tags that may be constructed (e.g. BIT_STRING)
+ switch (tagNo)
+ {
+ case OCTET_STRING:
+ return new BEROctetStringParser(sp).getLoadedObject();
+ case SEQUENCE:
+ return new BERSequenceParser(sp).getLoadedObject();
+ case SET:
+ return new BERSetParser(sp).getLoadedObject();
+ case EXTERNAL:
+ return new DERExternalParser(sp).getLoadedObject();
+ default:
+ throw new IOException("unknown BER object encountered");
+ }
+ }
+ else
+ {
+ try
+ {
+ return buildObject(tag, tagNo, length);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ASN1Exception("corrupted stream detected", e);
+ }
+ }
+ }
+
+ static int readTagNumber(InputStream s, int tag)
+ throws IOException
+ {
+ int tagNo = tag & 0x1f;
+
+ //
+ // with tagged object tag number is bottom 5 bits, or stored at the start of the content
+ //
+ if (tagNo == 0x1f)
+ {
+ tagNo = 0;
+
+ int b = s.read();
+
+ // X.690-0207 8.1.2.4.2
+ // "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
+ if ((b & 0x7f) == 0) // Note: -1 will pass
+ {
+ throw new IOException("corrupted stream - invalid high tag number found");
+ }
+
+ while ((b >= 0) && ((b & 0x80) != 0))
+ {
+ tagNo |= (b & 0x7f);
+ tagNo <<= 7;
+ b = s.read();
+ }
+
+ if (b < 0)
+ {
+ throw new EOFException("EOF found inside tag value.");
+ }
+
+ tagNo |= (b & 0x7f);
+ }
+
+ return tagNo;
+ }
+
+ static int readLength(InputStream s, int limit, boolean isParsing)
+ throws IOException
+ {
+ int length = s.read();
+ if (length < 0)
+ {
+ throw new EOFException("EOF found when length expected");
+ }
+
+ if (length == 0x80)
+ {
+ return -1; // indefinite-length encoding
+ }
+
+ if (length > 127)
+ {
+ int size = length & 0x7f;
+
+ // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
+ if (size > 4)
+ {
+ throw new IOException("DER length more than 4 bytes: " + size);
+ }
+
+ length = 0;
+ for (int i = 0; i < size; i++)
+ {
+ int next = s.read();
+
+ if (next < 0)
+ {
+ throw new EOFException("EOF found reading length");
+ }
+
+ length = (length << 8) + next;
+ }
+
+ if (length < 0)
+ {
+ throw new IOException("corrupted stream - negative length found");
+ }
+
+ if (length >= limit && !isParsing) // after all we must have read at least 1 byte
+ {
+ throw new IOException("corrupted stream - out of bounds length found: " + length + " >= " + limit);
+ }
+ }
+
+ return length;
+ }
+
+ private static byte[] getBuffer(DefiniteLengthInputStream defIn, byte[][] tmpBuffers)
+ throws IOException
+ {
+ int len = defIn.getRemaining();
+ if (len >= tmpBuffers.length)
+ {
+ return defIn.toByteArray();
+ }
+
+ byte[] buf = tmpBuffers[len];
+ if (buf == null)
+ {
+ buf = tmpBuffers[len] = new byte[len];
+ }
+
+ defIn.readAllIntoByteArray(buf);
+
+ return buf;
+ }
+
+ private static char[] getBMPCharBuffer(DefiniteLengthInputStream defIn)
+ throws IOException
+ {
+ int remainingBytes = defIn.getRemaining();
+ if (0 != (remainingBytes & 1))
+ {
+ throw new IOException("malformed BMPString encoding encountered");
+ }
+
+ char[] string = new char[remainingBytes / 2];
+ int stringPos = 0;
+
+ byte[] buf = new byte[8];
+ while (remainingBytes >= 8)
+ {
+ if (Streams.readFully(defIn, buf, 0, 8) != 8)
+ {
+ throw new EOFException("EOF encountered in middle of BMPString");
+ }
+
+ string[stringPos ] = (char)((buf[0] << 8) | (buf[1] & 0xFF));
+ string[stringPos + 1] = (char)((buf[2] << 8) | (buf[3] & 0xFF));
+ string[stringPos + 2] = (char)((buf[4] << 8) | (buf[5] & 0xFF));
+ string[stringPos + 3] = (char)((buf[6] << 8) | (buf[7] & 0xFF));
+ stringPos += 4;
+ remainingBytes -= 8;
+ }
+ if (remainingBytes > 0)
+ {
+ if (Streams.readFully(defIn, buf, 0, remainingBytes) != remainingBytes)
+ {
+ throw new EOFException("EOF encountered in middle of BMPString");
+ }
+
+ int bufPos = 0;
+ do
+ {
+ int b1 = buf[bufPos++] << 8;
+ int b2 = buf[bufPos++] & 0xFF;
+ string[stringPos++] = (char)(b1 | b2);
+ }
+ while (bufPos < remainingBytes);
+ }
+
+ if (0 != defIn.getRemaining() || string.length != stringPos)
+ {
+ throw new IllegalStateException();
+ }
+
+ return string;
+ }
+
+ static ASN1Primitive createPrimitiveDERObject(
+ int tagNo,
+ DefiniteLengthInputStream defIn,
+ byte[][] tmpBuffers)
+ throws IOException
+ {
+ switch (tagNo)
+ {
+ case BIT_STRING:
+ return ASN1BitString.fromInputStream(defIn.getRemaining(), defIn);
+ case BMP_STRING:
+ return new DERBMPString(getBMPCharBuffer(defIn));
+ case BOOLEAN:
+ return ASN1Boolean.fromOctetString(getBuffer(defIn, tmpBuffers));
+ case ENUMERATED:
+ return ASN1Enumerated.fromOctetString(getBuffer(defIn, tmpBuffers));
+ case GENERALIZED_TIME:
+ return new ASN1GeneralizedTime(defIn.toByteArray());
+ case GENERAL_STRING:
+ return new DERGeneralString(defIn.toByteArray());
+ case IA5_STRING:
+ return new DERIA5String(defIn.toByteArray());
+ case INTEGER:
+ return new ASN1Integer(defIn.toByteArray(), false);
+ case NULL:
+ return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?)
+ case NUMERIC_STRING:
+ return new DERNumericString(defIn.toByteArray());
+ case OBJECT_IDENTIFIER:
+ return ASN1ObjectIdentifier.fromOctetString(getBuffer(defIn, tmpBuffers));
+ case OCTET_STRING:
+ return new DEROctetString(defIn.toByteArray());
+ case PRINTABLE_STRING:
+ return new DERPrintableString(defIn.toByteArray());
+ case T61_STRING:
+ return new DERT61String(defIn.toByteArray());
+ case UNIVERSAL_STRING:
+ return new DERUniversalString(defIn.toByteArray());
+ case UTC_TIME:
+ return new ASN1UTCTime(defIn.toByteArray());
+ case UTF8_STRING:
+ return new DERUTF8String(defIn.toByteArray());
+ case VISIBLE_STRING:
+ return new DERVisibleString(defIn.toByteArray());
+ case GRAPHIC_STRING:
+ return new DERGraphicString(defIn.toByteArray());
+ case VIDEOTEX_STRING:
+ return new DERVideotexString(defIn.toByteArray());
+ default:
+ throw new IOException("unknown tag " + tagNo + " encountered");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Integer.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Integer.java
new file mode 100644
index 00000000..d09e3436
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Integer.java
@@ -0,0 +1,290 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Properties;
+
+/**
+ * Class representing the ASN.1 INTEGER type.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1Integer
+ extends ASN1Primitive
+{
+ static final int SIGN_EXT_SIGNED = 0xFFFFFFFF;
+ static final int SIGN_EXT_UNSIGNED = 0xFF;
+
+ private final byte[] bytes;
+ private final int start;
+
+ /**
+ * Return an integer from the passed in object.
+ *
+ * @param obj an ASN1Integer or an object that can be converted into one.
+ * @return an ASN1Integer instance.
+ * @throws IllegalArgumentException if the object cannot be converted.
+ */
+ public static ASN1Integer getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1Integer)
+ {
+ return (ASN1Integer)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1Integer)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return an Integer from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @return an ASN1Integer instance.
+ * @throws IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static ASN1Integer getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof ASN1Integer)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new ASN1Integer(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ /**
+ * Construct an INTEGER from the passed in long value.
+ *
+ * @param value the long representing the value desired.
+ */
+ public ASN1Integer(long value)
+ {
+ this.bytes = BigInteger.valueOf(value).toByteArray();
+ this.start = 0;
+ }
+
+ /**
+ * Construct an INTEGER from the passed in BigInteger value.
+ *
+ * @param value the BigInteger representing the value desired.
+ */
+ public ASN1Integer(BigInteger value)
+ {
+ this.bytes = value.toByteArray();
+ this.start = 0;
+ }
+
+ /**
+ * Construct an INTEGER from the passed in byte array.
+ *
+ * <p>
+ * <b>NB: Strict Validation applied by default.</b>
+ * </p>
+ * <p>
+ * It has turned out that there are still a few applications that struggle with
+ * the ASN.1 BER encoding rules for an INTEGER as described in:
+ *
+ * https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
+ * Section 8.3.2.
+ * </p>
+ * <p>
+ * Users can set the 'org.bouncycastle.asn1.allow_unsafe_integer' to 'true'
+ * and a looser validation will be applied. Users must recognise that this is
+ * not ideal and may pave the way for an exploit based around a faulty encoding
+ * in the future.
+ * </p>
+ *
+ * @param bytes the byte array representing a 2's complement encoding of a BigInteger.
+ */
+ public ASN1Integer(byte[] bytes)
+ {
+ this(bytes, true);
+ }
+
+ ASN1Integer(byte[] bytes, boolean clone)
+ {
+ if (isMalformed(bytes))
+ {
+ throw new IllegalArgumentException("malformed integer");
+ }
+
+ this.bytes = clone ? Arrays.clone(bytes) : bytes;
+ this.start = signBytesToSkip(bytes);
+ }
+
+ /**
+ * in some cases positive values get crammed into a space,
+ * that's not quite big enough...
+ *
+ * @return the BigInteger that results from treating this ASN.1 INTEGER as unsigned.
+ */
+ public BigInteger getPositiveValue()
+ {
+ return new BigInteger(1, bytes);
+ }
+
+ public BigInteger getValue()
+ {
+ return new BigInteger(bytes);
+ }
+
+ public boolean hasValue(BigInteger x)
+ {
+ return null != x
+ // Fast check to avoid allocation
+ && intValue(bytes, start, SIGN_EXT_SIGNED) == x.intValue()
+ && getValue().equals(x);
+ }
+
+ public int intPositiveValueExact()
+ {
+ int count = bytes.length - start;
+ if (count > 4 || (count == 4 && 0 != (bytes[start] & 0x80)))
+ {
+ throw new ArithmeticException("ASN.1 Integer out of positive int range");
+ }
+
+ return intValue(bytes, start, SIGN_EXT_UNSIGNED);
+ }
+
+ public int intValueExact()
+ {
+ int count = bytes.length - start;
+ if (count > 4)
+ {
+ throw new ArithmeticException("ASN.1 Integer out of int range");
+ }
+
+ return intValue(bytes, start, SIGN_EXT_SIGNED);
+ }
+
+ public long longValueExact()
+ {
+ int count = bytes.length - start;
+ if (count > 8)
+ {
+ throw new ArithmeticException("ASN.1 Integer out of long range");
+ }
+
+ return longValue(bytes, start, SIGN_EXT_SIGNED);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.INTEGER, bytes);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(bytes);
+ }
+
+ boolean asn1Equals(ASN1Primitive o)
+ {
+ if (!(o instanceof ASN1Integer))
+ {
+ return false;
+ }
+
+ ASN1Integer other = (ASN1Integer)o;
+
+ return Arrays.areEqual(this.bytes, other.bytes);
+ }
+
+ public String toString()
+ {
+ return getValue().toString();
+ }
+
+ static int intValue(byte[] bytes, int start, int signExt)
+ {
+ int length = bytes.length;
+ int pos = Math.max(start, length - 4);
+
+ int val = bytes[pos] & signExt;
+ while (++pos < length)
+ {
+ val = (val << 8) | (bytes[pos] & SIGN_EXT_UNSIGNED);
+ }
+ return val;
+ }
+
+ static long longValue(byte[] bytes, int start, int signExt)
+ {
+ int length = bytes.length;
+ int pos = Math.max(start, length - 8);
+
+ long val = bytes[pos] & signExt;
+ while (++pos < length)
+ {
+ val = (val << 8) | (bytes[pos] & SIGN_EXT_UNSIGNED);
+ }
+ return val;
+ }
+
+ /**
+ * Apply the correct validation for an INTEGER primitive following the BER rules.
+ *
+ * @param bytes The raw encoding of the integer.
+ * @return true if the (in)put fails this validation.
+ */
+ static boolean isMalformed(byte[] bytes)
+ {
+ switch (bytes.length)
+ {
+ case 0:
+ return true;
+ case 1:
+ return false;
+ default:
+ return bytes[0] == (bytes[1] >> 7)
+ // Apply loose validation, see note in public constructor ASN1Integer(byte[])
+ && !Properties.isOverrideSet("com.android.internal.org.bouncycastle.asn1.allow_unsafe_integer");
+ }
+ }
+
+ static int signBytesToSkip(byte[] bytes)
+ {
+ int pos = 0, last = bytes.length - 1;
+ while (pos < last
+ && bytes[pos] == (bytes[pos + 1] >> 7))
+ {
+ ++pos;
+ }
+ return pos;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Null.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Null.java
new file mode 100644
index 00000000..d47488ee
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Null.java
@@ -0,0 +1,84 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/***************************************************************/
+/****** DO NOT EDIT THIS CLASS bc-java SOURCE FILE ******/
+/***************************************************************/
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * A NULL object - use DERNull.INSTANCE for populating structures.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1Null
+ extends ASN1Primitive
+{
+ ASN1Null()
+ {
+
+ }
+
+ /**
+ * Return an instance of ASN.1 NULL from the passed in object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link ASN1Null} object
+ * <li> a byte[] containing ASN.1 NULL object
+ * </ul>
+ * </p>
+ *
+ * @param o object to be converted.
+ * @return an instance of ASN1Null, or null.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static ASN1Null getInstance(Object o)
+ {
+ if (o instanceof ASN1Null)
+ {
+ return (ASN1Null)o;
+ }
+
+ if (o != null)
+ {
+ try
+ {
+ return ASN1Null.getInstance(ASN1Primitive.fromByteArray((byte[])o));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct NULL from byte[]: " + e.getMessage());
+ }
+ catch (ClassCastException e)
+ {
+ throw new IllegalArgumentException("unknown object in getInstance(): " + o.getClass().getName());
+ }
+ }
+
+ return null;
+ }
+
+ public int hashCode()
+ {
+ return -1;
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof ASN1Null))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
+
+ public String toString()
+ {
+ return "NULL";
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Object.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Object.java
new file mode 100644
index 00000000..adcd257a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Object.java
@@ -0,0 +1,106 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.util.Encodable;
+
+/**
+ * Base class for defining an ASN.1 object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1Object
+ implements ASN1Encodable, Encodable
+{
+ public void encodeTo(OutputStream output) throws IOException
+ {
+ ASN1OutputStream.create(output).writeObject(this);
+ }
+
+ public void encodeTo(OutputStream output, String encoding) throws IOException
+ {
+ ASN1OutputStream.create(output, encoding).writeObject(this);
+ }
+
+ /**
+ * Return the default BER or DER encoding for this object.
+ *
+ * @return BER/DER byte encoded object.
+ * @throws java.io.IOException on encoding error.
+ */
+ public byte[] getEncoded() throws IOException
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ encodeTo(bOut);
+ return bOut.toByteArray();
+ }
+
+ /**
+ * Return either the default for "BER" or a DER encoding if "DER" is specified.
+ *
+ * @param encoding name of encoding to use.
+ * @return byte encoded object.
+ * @throws IOException on encoding error.
+ */
+ public byte[] getEncoded(String encoding) throws IOException
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ encodeTo(bOut, encoding);
+ return bOut.toByteArray();
+ }
+
+ public int hashCode()
+ {
+ return this.toASN1Primitive().hashCode();
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+
+ if (!(o instanceof ASN1Encodable))
+ {
+ return false;
+ }
+
+ ASN1Encodable other = (ASN1Encodable)o;
+
+ return this.toASN1Primitive().equals(other.toASN1Primitive());
+ }
+
+ // BEGIN Android-changed: Was removed in upstream.
+ // Used by https://source.corp.google.com/android/cts/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
+ /**
+ * @deprecated use toASN1Primitive()
+ * @return the underlying primitive type.
+ */
+ public ASN1Primitive toASN1Object()
+ {
+ return this.toASN1Primitive();
+ }
+ // END Android-changed
+
+ /**
+ * Return true if obj is a byte array and represents an object with the given tag value.
+ *
+ * @param obj object of interest.
+ * @param tagValue tag value to check for.
+ * @return true if obj is a byte encoding starting with the given tag value, false otherwise.
+ */
+ protected static boolean hasEncodedTagValue(Object obj, int tagValue)
+ {
+ return (obj instanceof byte[]) && ((byte[])obj)[0] == tagValue;
+ }
+
+ /**
+ * Method providing a primitive representation of this object suitable for encoding.
+ * @return a primitive representation of this object.
+ */
+ public abstract ASN1Primitive toASN1Primitive();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectIdentifier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
new file mode 100644
index 00000000..0a0eac7a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
@@ -0,0 +1,485 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Class representing the ASN.1 OBJECT IDENTIFIER type.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1ObjectIdentifier
+ extends ASN1Primitive
+{
+ private final String identifier;
+
+ private byte[] body;
+
+ /**
+ * Return an OID from the passed in object
+ *
+ * @param obj an ASN1ObjectIdentifier or an object that can be converted into one.
+ * @return an ASN1ObjectIdentifier instance, or null.
+ * @throws IllegalArgumentException if the object cannot be converted.
+ */
+ public static ASN1ObjectIdentifier getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1ObjectIdentifier)
+ {
+ return (ASN1ObjectIdentifier)obj;
+ }
+
+ if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+
+ if (primitive instanceof ASN1ObjectIdentifier)
+ {
+ return (ASN1ObjectIdentifier)primitive;
+ }
+ }
+
+ if (obj instanceof byte[])
+ {
+ byte[] enc = (byte[])obj;
+ try
+ {
+ return (ASN1ObjectIdentifier)fromByteArray(enc);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct object identifier from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return an OBJECT IDENTIFIER from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @return an ASN1ObjectIdentifier instance, or null.
+ * @throws IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static ASN1ObjectIdentifier getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof ASN1ObjectIdentifier)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return ASN1ObjectIdentifier.fromOctetString(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7f;
+
+ ASN1ObjectIdentifier(
+ byte[] bytes)
+ {
+ StringBuffer objId = new StringBuffer();
+ long value = 0;
+ BigInteger bigValue = null;
+ boolean first = true;
+
+ for (int i = 0; i != bytes.length; i++)
+ {
+ int b = bytes[i] & 0xff;
+
+ if (value <= LONG_LIMIT)
+ {
+ value += (b & 0x7f);
+ if ((b & 0x80) == 0) // end of number reached
+ {
+ if (first)
+ {
+ if (value < 40)
+ {
+ objId.append('0');
+ }
+ else if (value < 80)
+ {
+ objId.append('1');
+ value -= 40;
+ }
+ else
+ {
+ objId.append('2');
+ value -= 80;
+ }
+ first = false;
+ }
+
+ objId.append('.');
+ objId.append(value);
+ value = 0;
+ }
+ else
+ {
+ value <<= 7;
+ }
+ }
+ else
+ {
+ if (bigValue == null)
+ {
+ bigValue = BigInteger.valueOf(value);
+ }
+ bigValue = bigValue.or(BigInteger.valueOf(b & 0x7f));
+ if ((b & 0x80) == 0)
+ {
+ if (first)
+ {
+ objId.append('2');
+ bigValue = bigValue.subtract(BigInteger.valueOf(80));
+ first = false;
+ }
+
+ objId.append('.');
+ objId.append(bigValue);
+ bigValue = null;
+ value = 0;
+ }
+ else
+ {
+ bigValue = bigValue.shiftLeft(7);
+ }
+ }
+ }
+
+ // Android-changed: Intern the identifier so there aren't hundreds of duplicates in practice.
+ this.identifier = objId.toString().intern();
+ this.body = Arrays.clone(bytes);
+ }
+
+ /**
+ * Create an OID based on the passed in String.
+ *
+ * @param identifier a string representation of an OID.
+ */
+ public ASN1ObjectIdentifier(
+ String identifier)
+ {
+ if (identifier == null)
+ {
+ throw new NullPointerException("'identifier' cannot be null");
+ }
+ if (!isValidIdentifier(identifier))
+ {
+ throw new IllegalArgumentException("string " + identifier + " not an OID");
+ }
+
+ // Android-changed: Intern the identifier so there aren't hundreds of duplicates in practice.
+ this.identifier = identifier.intern();
+ }
+
+ /**
+ * Create an OID that creates a branch under the current one.
+ *
+ * @param branchID node numbers for the new branch.
+ * @return the OID for the new created branch.
+ */
+ ASN1ObjectIdentifier(ASN1ObjectIdentifier oid, String branchID)
+ {
+ if (!isValidBranchID(branchID, 0))
+ {
+ throw new IllegalArgumentException("string " + branchID + " not a valid OID branch");
+ }
+
+ this.identifier = oid.getId() + "." + branchID;
+ }
+
+ /**
+ * Return the OID as a string.
+ *
+ * @return the string representation of the OID carried by this object.
+ */
+ public String getId()
+ {
+ return identifier;
+ }
+
+ /**
+ * Return an OID that creates a branch under the current one.
+ *
+ * @param branchID node numbers for the new branch.
+ * @return the OID for the new created branch.
+ */
+ public ASN1ObjectIdentifier branch(String branchID)
+ {
+ return new ASN1ObjectIdentifier(this, branchID);
+ }
+
+ /**
+ * Return true if this oid is an extension of the passed in branch - stem.
+ *
+ * @param stem the arc or branch that is a possible parent.
+ * @return true if the branch is on the passed in stem, false otherwise.
+ */
+ public boolean on(ASN1ObjectIdentifier stem)
+ {
+ String id = getId(), stemId = stem.getId();
+ return id.length() > stemId.length() && id.charAt(stemId.length()) == '.' && id.startsWith(stemId);
+ }
+
+ private void writeField(
+ ByteArrayOutputStream out,
+ long fieldValue)
+ {
+ byte[] result = new byte[9];
+ int pos = 8;
+ result[pos] = (byte)((int)fieldValue & 0x7f);
+ while (fieldValue >= (1L << 7))
+ {
+ fieldValue >>= 7;
+ result[--pos] = (byte)((int)fieldValue & 0x7f | 0x80);
+ }
+ out.write(result, pos, 9 - pos);
+ }
+
+ private void writeField(
+ ByteArrayOutputStream out,
+ BigInteger fieldValue)
+ {
+ int byteCount = (fieldValue.bitLength() + 6) / 7;
+ if (byteCount == 0)
+ {
+ out.write(0);
+ }
+ else
+ {
+ BigInteger tmpValue = fieldValue;
+ byte[] tmp = new byte[byteCount];
+ for (int i = byteCount - 1; i >= 0; i--)
+ {
+ tmp[i] = (byte)((tmpValue.intValue() & 0x7f) | 0x80);
+ tmpValue = tmpValue.shiftRight(7);
+ }
+ tmp[byteCount - 1] &= 0x7f;
+ out.write(tmp, 0, tmp.length);
+ }
+ }
+
+ private void doOutput(ByteArrayOutputStream aOut)
+ {
+ OIDTokenizer tok = new OIDTokenizer(identifier);
+ int first = Integer.parseInt(tok.nextToken()) * 40;
+
+ String secondToken = tok.nextToken();
+ if (secondToken.length() <= 18)
+ {
+ writeField(aOut, first + Long.parseLong(secondToken));
+ }
+ else
+ {
+ writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first)));
+ }
+
+ while (tok.hasMoreTokens())
+ {
+ String token = tok.nextToken();
+ if (token.length() <= 18)
+ {
+ writeField(aOut, Long.parseLong(token));
+ }
+ else
+ {
+ writeField(aOut, new BigInteger(token));
+ }
+ }
+ }
+
+ private synchronized byte[] getBody()
+ {
+ if (body == null)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ doOutput(bOut);
+
+ body = bOut.toByteArray();
+ }
+
+ return body;
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ throws IOException
+ {
+ int length = getBody().length;
+
+ return 1 + StreamUtil.calculateBodyLength(length) + length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.OBJECT_IDENTIFIER, getBody());
+ }
+
+ public int hashCode()
+ {
+ return identifier.hashCode();
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (!(o instanceof ASN1ObjectIdentifier))
+ {
+ return false;
+ }
+
+ return identifier.equals(((ASN1ObjectIdentifier)o).identifier);
+ }
+
+ public String toString()
+ {
+ return getId();
+ }
+
+ private static boolean isValidBranchID(
+ String branchID, int start)
+ {
+ int digitCount = 0;
+
+ int pos = branchID.length();
+ while (--pos >= start)
+ {
+ char ch = branchID.charAt(pos);
+
+ if (ch == '.')
+ {
+ if (0 == digitCount
+ || (digitCount > 1 && branchID.charAt(pos + 1) == '0'))
+ {
+ return false;
+ }
+
+ digitCount = 0;
+ }
+ else if ('0' <= ch && ch <= '9')
+ {
+ ++digitCount;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (0 == digitCount
+ || (digitCount > 1 && branchID.charAt(pos + 1) == '0'))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ private static boolean isValidIdentifier(
+ String identifier)
+ {
+ if (identifier.length() < 3 || identifier.charAt(1) != '.')
+ {
+ return false;
+ }
+
+ char first = identifier.charAt(0);
+ if (first < '0' || first > '2')
+ {
+ return false;
+ }
+
+ return isValidBranchID(identifier, 2);
+ }
+
+ /**
+ * Intern will return a reference to a pooled version of this object, unless it
+ * is not present in which case intern will add it.
+ * <p>
+ * The pool is also used by the ASN.1 parsers to limit the number of duplicated OID
+ * objects in circulation.
+ * </p>
+ *
+ * @return a reference to the identifier in the pool.
+ */
+ public ASN1ObjectIdentifier intern()
+ {
+ final OidHandle hdl = new OidHandle(getBody());
+ ASN1ObjectIdentifier oid = pool.get(hdl);
+ if (oid == null)
+ {
+ oid = pool.putIfAbsent(hdl, this);
+ if (oid == null)
+ {
+ oid = this;
+ }
+ }
+ return oid;
+ }
+
+ private static final ConcurrentMap<OidHandle, ASN1ObjectIdentifier> pool = new ConcurrentHashMap<OidHandle, ASN1ObjectIdentifier>();
+
+ private static class OidHandle
+ {
+ private final int key;
+ private final byte[] enc;
+
+ OidHandle(byte[] enc)
+ {
+ this.key = Arrays.hashCode(enc);
+ this.enc = enc;
+ }
+
+ public int hashCode()
+ {
+ return key;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o instanceof OidHandle)
+ {
+ return Arrays.areEqual(enc, ((OidHandle)o).enc);
+ }
+
+ return false;
+ }
+ }
+
+ static ASN1ObjectIdentifier fromOctetString(byte[] enc)
+ {
+ final OidHandle hdl = new OidHandle(enc);
+ ASN1ObjectIdentifier oid = pool.get(hdl);
+ if (oid == null)
+ {
+ return new ASN1ObjectIdentifier(enc);
+ }
+ return oid;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetString.java
new file mode 100644
index 00000000..f7b9617a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetString.java
@@ -0,0 +1,303 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * Abstract base for the ASN.1 OCTET STRING data type
+ * <p>
+ * This supports BER, and DER forms of the data.
+ * </p><p>
+ * DER form is always primitive single OCTET STRING, while
+ * BER support includes the constructed forms.
+ * </p>
+ * <p><b>X.690</b></p>
+ * <p><b>8: Basic encoding rules</b></p>
+ * <p><b>8.7 Encoding of an octetstring value</b></p>
+ * <p>
+ * <b>8.7.1</b> The encoding of an octetstring value shall be
+ * either primitive or constructed at the option of the sender.
+ * <blockquote>
+ * NOTE &mdash; Where it is necessary to transfer part of an octet string
+ * before the entire OCTET STRING is available, the constructed encoding
+ * is used.
+ * </blockquote>
+ * <p>
+ * <b>8.7.2</b> The primitive encoding contains zero,
+ * one or more contents octets equal in value to the octets
+ * in the data value, in the order they appear in the data value,
+ * and with the most significant bit of an octet of the data value
+ * aligned with the most significant bit of an octet of the contents octets.
+ * </p>
+ * <p>
+ * <b>8.7.3</b> The contents octets for the constructed encoding shall consist
+ * of zero, one, or more encodings.
+ * </p>
+ * <blockquote>
+ * NOTE &mdash; Each such encoding includes identifier, length, and contents octets,
+ * and may include end-of-contents octets if it is constructed.
+ * </blockquote>
+ * <p>
+ * <b>8.7.3.1</b> To encode an octetstring value in this way,
+ * it is segmented. Each segment shall consist of a series of
+ * consecutive octets of the value. There shall be no significance
+ * placed on the segment boundaries.</p>
+ * <blockquote>
+ * NOTE &mdash; A segment may be of size zero, i.e. contain no octets.
+ * </blockquote>
+ * <p>
+ * <b>8.7.3.2</b> Each encoding in the contents octets shall represent
+ * a segment of the overall octetstring, the encoding arising from
+ * a recursive application of this subclause.
+ * In this recursive application, each segment is treated as if it were
+ * a octetstring value. The encodings of the segments shall appear in the contents
+ * octets in the order in which their octets appear in the overall value.
+ * </p>
+ * <blockquote>
+ * NOTE 1 &mdash; As a consequence of this recursion,
+ * each encoding in the contents octets may itself
+ * be primitive or constructed.
+ * However, such encodings will usually be primitive.
+ * </blockquote>
+ * <blockquote>
+ * NOTE 2 &mdash; In particular, the tags in the contents octets are always universal class, number 4.
+ * </blockquote>
+ * <p><b>9: Canonical encoding rules</b></p>
+ * <p><b>9.1 Length forms</b></p>
+ * <p>
+ * If the encoding is constructed, it shall employ the indefinite-length form.
+ * If the encoding is primitive, it shall include the fewest length octets necessary.
+ * [Contrast with 8.1.3.2 b).]
+ * </p>
+ * <p><b>9.2 String encoding forms</b></p>
+ * <p>
+ * BIT STRING, OCTET STRING,and restricted character string
+ * values shall be encoded with a primitive encoding if they would
+ * require no more than 1000 contents octets, and as a constructed
+ * encoding otherwise. The string fragments contained in
+ * the constructed encoding shall be encoded with a primitive encoding.
+ * The encoding of each fragment, except possibly
+ * the last, shall have 1000 contents octets. (Contrast with 8.21.6.)
+ * </p><p>
+ * <b>10: Distinguished encoding rules</b>
+ * </p><p>
+ * <b>10.1 Length forms</b>
+ * The definite form of length encoding shall be used,
+ * encoded in the minimum number of octets.
+ * [Contrast with 8.1.3.2 b).]
+ * </p><p>
+ * <b>10.2 String encoding forms</b>
+ * For BIT STRING, OCTET STRING and restricted character string types,
+ * the constructed form of encoding shall not be used.
+ * (Contrast with 8.21.6.)
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1OctetString
+ extends ASN1Primitive
+ implements ASN1OctetStringParser
+{
+ byte[] string;
+
+ /**
+ * return an Octet String from a tagged object.
+ *
+ * @param taggedObject the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static ASN1OctetString getInstance(
+ ASN1TaggedObject taggedObject,
+ boolean explicit)
+ {
+ if (explicit)
+ {
+ if (!taggedObject.isExplicit())
+ {
+ throw new IllegalArgumentException("object implicit - explicit expected.");
+ }
+
+ return getInstance(taggedObject.getObject());
+ }
+
+ ASN1Primitive o = taggedObject.getObject();
+
+ /*
+ * constructed object which appears to be explicitly tagged and it's really implicit means
+ * we have to add the surrounding octet string.
+ */
+ if (taggedObject.isExplicit())
+ {
+ ASN1OctetString singleSegment = getInstance(o);
+
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return new BEROctetString(new ASN1OctetString[]{ singleSegment });
+ }
+
+ // TODO Should really be similar to the BERTaggedObject case above:
+// return new DLOctetString(new ASN1OctetString[]{ singleSegment });
+ return (ASN1OctetString)new BEROctetString(new ASN1OctetString[]{ singleSegment }).toDLObject();
+ }
+
+ if (o instanceof ASN1OctetString)
+ {
+ ASN1OctetString s = (ASN1OctetString)o;
+
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return s;
+ }
+
+ return (ASN1OctetString)s.toDLObject();
+ }
+
+ /*
+ * in this case the parser returns a sequence, convert it into an octet string.
+ */
+ if (o instanceof ASN1Sequence)
+ {
+ ASN1Sequence s = (ASN1Sequence)o;
+
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return BEROctetString.fromSequence(s);
+ }
+
+ // TODO Should really be similar to the BERTaggedObject case above:
+// return DLOctetString.fromSequence(s);
+ return (ASN1OctetString)BEROctetString.fromSequence(s).toDLObject();
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
+ }
+
+ /**
+ * return an Octet String from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static ASN1OctetString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1OctetString)
+ {
+ return (ASN1OctetString)obj;
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return getInstance(fromByteArray((byte[])obj));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct OCTET STRING from byte[]: " + e.getMessage());
+ }
+ }
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+
+ if (primitive instanceof ASN1OctetString)
+ {
+ return (ASN1OctetString)primitive;
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param string the octets making up the octet string.
+ */
+ public ASN1OctetString(
+ byte[] string)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+ this.string = string;
+ }
+
+ /**
+ * Return the content of the OCTET STRING as an InputStream.
+ *
+ * @return an InputStream representing the OCTET STRING's content.
+ */
+ public InputStream getOctetStream()
+ {
+ return new ByteArrayInputStream(string);
+ }
+
+ /**
+ * Return the parser associated with this object.
+ *
+ * @return a parser based on this OCTET STRING
+ */
+ public ASN1OctetStringParser parser()
+ {
+ return this;
+ }
+
+ /**
+ * Return the content of the OCTET STRING as a byte array.
+ *
+ * @return the byte[] representing the OCTET STRING's content.
+ */
+ public byte[] getOctets()
+ {
+ return string;
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(this.getOctets());
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof ASN1OctetString))
+ {
+ return false;
+ }
+
+ ASN1OctetString other = (ASN1OctetString)o;
+
+ return Arrays.areEqual(string, other.string);
+ }
+
+ public ASN1Primitive getLoadedObject()
+ {
+ return this.toASN1Primitive();
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return new DEROctetString(string);
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return new DEROctetString(string);
+ }
+
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
+
+ public String toString()
+ {
+ return "#" + Strings.fromByteArray(Hex.encode(string));
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetStringParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetStringParser.java
new file mode 100644
index 00000000..96202a15
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetStringParser.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.InputStream;
+
+/**
+ * A basic parser for an OCTET STRING object
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ASN1OctetStringParser
+ extends ASN1Encodable, InMemoryRepresentable
+{
+ /**
+ * Return the content of the OCTET STRING as an InputStream.
+ *
+ * @return an InputStream representing the OCTET STRING's content.
+ */
+ public InputStream getOctetStream();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OutputStream.java
new file mode 100644
index 00000000..7447d3b3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OutputStream.java
@@ -0,0 +1,323 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Enumeration;
+
+/**
+ * Stream that produces output based on the default encoding for the passed in objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1OutputStream
+{
+ public static ASN1OutputStream create(OutputStream out)
+ {
+ return new ASN1OutputStream(out);
+ }
+
+ public static ASN1OutputStream create(OutputStream out, String encoding)
+ {
+ if (encoding.equals(ASN1Encoding.DER))
+ {
+ return new DEROutputStream(out);
+ }
+ else if (encoding.equals(ASN1Encoding.DL))
+ {
+ return new DLOutputStream(out);
+ }
+ else
+ {
+ return new ASN1OutputStream(out);
+ }
+ }
+
+ private OutputStream os;
+
+ /**
+ * @deprecated Use {@link ASN1OutputStream#create(OutputStream)} instead.
+ */
+ public ASN1OutputStream(OutputStream os)
+ {
+ this.os = os;
+ }
+
+ final void writeLength(
+ int length)
+ throws IOException
+ {
+ if (length > 127)
+ {
+ int size = 1;
+ int val = length;
+
+ while ((val >>>= 8) != 0)
+ {
+ size++;
+ }
+
+ write((byte)(size | 0x80));
+
+ for (int i = (size - 1) * 8; i >= 0; i -= 8)
+ {
+ write((byte)(length >> i));
+ }
+ }
+ else
+ {
+ write((byte)length);
+ }
+ }
+
+ final void write(int b)
+ throws IOException
+ {
+ os.write(b);
+ }
+
+ final void write(byte[] bytes, int off, int len)
+ throws IOException
+ {
+ os.write(bytes, off, len);
+ }
+
+ final void writeElements(ASN1Encodable[] elements)
+ throws IOException
+ {
+ int count = elements.length;
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive primitive = elements[i].toASN1Primitive();
+
+ writePrimitive(primitive, true);
+ }
+ }
+
+ final void writeElements(Enumeration elements)
+ throws IOException
+ {
+ while (elements.hasMoreElements())
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)elements.nextElement()).toASN1Primitive();
+
+ writePrimitive(primitive, true);
+ }
+ }
+
+ final void writeEncoded(
+ boolean withTag,
+ int tag,
+ byte contents)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(1);
+ write(contents);
+ }
+
+ final void writeEncoded(
+ boolean withTag,
+ int tag,
+ byte[] contents)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(contents.length);
+ write(contents, 0, contents.length);
+ }
+
+ final void writeEncoded(
+ boolean withTag,
+ int tag,
+ byte[] contents,
+ int contentsOff,
+ int contentsLen)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(contentsLen);
+ write(contents, contentsOff, contentsLen);
+ }
+
+ final void writeEncoded(
+ boolean withTag,
+ int tag,
+ byte headByte,
+ byte[] tailBytes)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(1 + tailBytes.length);
+ write(headByte);
+ write(tailBytes, 0, tailBytes.length);
+ }
+
+ final void writeEncoded(
+ boolean withTag,
+ int tag,
+ byte headByte,
+ byte[] body,
+ int bodyOff,
+ int bodyLen,
+ byte tailByte)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ writeLength(2 + bodyLen);
+ write(headByte);
+ write(body, bodyOff, bodyLen);
+ write(tailByte);
+ }
+
+ final void writeEncoded(boolean withTag, int flags, int tagNo, byte[] contents)
+ throws IOException
+ {
+ writeTag(withTag, flags, tagNo);
+ writeLength(contents.length);
+ write(contents, 0, contents.length);
+ }
+
+ final void writeEncodedIndef(boolean withTag, int flags, int tagNo, byte[] contents)
+ throws IOException
+ {
+ writeTag(withTag, flags, tagNo);
+ write(0x80);
+ write(contents, 0, contents.length);
+ write(0x00);
+ write(0x00);
+ }
+
+ final void writeEncodedIndef(boolean withTag, int tag, ASN1Encodable[] elements)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ write(0x80);
+ writeElements(elements);
+ write(0x00);
+ write(0x00);
+ }
+
+ final void writeEncodedIndef(boolean withTag, int tag, Enumeration elements)
+ throws IOException
+ {
+ if (withTag)
+ {
+ write(tag);
+ }
+ write(0x80);
+ writeElements(elements);
+ write(0x00);
+ write(0x00);
+ }
+
+ final void writeTag(boolean withTag, int flags, int tagNo)
+ throws IOException
+ {
+ if (!withTag)
+ {
+ return;
+ }
+
+ if (tagNo < 31)
+ {
+ write(flags | tagNo);
+ }
+ else
+ {
+ write(flags | 0x1f);
+ if (tagNo < 128)
+ {
+ write(tagNo);
+ }
+ else
+ {
+ byte[] stack = new byte[5];
+ int pos = stack.length;
+
+ stack[--pos] = (byte)(tagNo & 0x7F);
+
+ do
+ {
+ tagNo >>= 7;
+ stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
+ }
+ while (tagNo > 127);
+
+ write(stack, pos, stack.length - pos);
+ }
+ }
+ }
+
+ public void writeObject(ASN1Encodable obj) throws IOException
+ {
+ if (null == obj)
+ {
+ throw new IOException("null object detected");
+ }
+
+ writePrimitive(obj.toASN1Primitive(), true);
+ flushInternal();
+ }
+
+ public void writeObject(ASN1Primitive primitive) throws IOException
+ {
+ if (null == primitive)
+ {
+ throw new IOException("null object detected");
+ }
+
+ writePrimitive(primitive, true);
+ flushInternal();
+ }
+
+ void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
+ {
+ primitive.encode(this, withTag);
+ }
+
+ public void close()
+ throws IOException
+ {
+ os.close();
+ }
+
+ public void flush()
+ throws IOException
+ {
+ os.flush();
+ }
+
+ void flushInternal()
+ throws IOException
+ {
+ // Placeholder to support future internal buffering
+ }
+
+ DEROutputStream getDERSubStream()
+ {
+ return new DEROutputStream(os);
+ }
+
+ ASN1OutputStream getDLSubStream()
+ {
+ return new DLOutputStream(os);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ParsingException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ParsingException.java
new file mode 100644
index 00000000..38cce7bd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ParsingException.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+/**
+ * Exception thrown when correctly encoded, but unexpected data is found in a stream while building an object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1ParsingException
+ extends IllegalStateException
+{
+ private Throwable cause;
+
+ /**
+ * Base constructor
+ *
+ * @param message a message concerning the exception.
+ */
+ public ASN1ParsingException(String message)
+ {
+ super(message);
+ }
+
+ /**
+ * Constructor when this exception is due to another one.
+ *
+ * @param message a message concerning the exception.
+ * @param cause the exception that caused this exception to be thrown.
+ */
+ public ASN1ParsingException(String message, Throwable cause)
+ {
+ super(message);
+ this.cause = cause;
+ }
+
+ /**
+ * Return the underlying cause of this exception, if any.
+ *
+ * @return the exception causing this one, null if there isn't one.
+ */
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Primitive.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Primitive.java
new file mode 100644
index 00000000..f8dafff4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Primitive.java
@@ -0,0 +1,123 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Base class for ASN.1 primitive objects. These are the actual objects used to generate byte encodings.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1Primitive
+ extends ASN1Object
+{
+ ASN1Primitive()
+ {
+ }
+
+ public void encodeTo(OutputStream output) throws IOException
+ {
+ ASN1OutputStream.create(output).writeObject(this);
+ }
+
+ public void encodeTo(OutputStream output, String encoding) throws IOException
+ {
+ ASN1OutputStream.create(output, encoding).writeObject(this);
+ }
+
+ /**
+ * Create a base ASN.1 object from a byte stream.
+ *
+ * @param data the byte stream to parse.
+ * @return the base ASN.1 object represented by the byte stream.
+ * @exception IOException if there is a problem parsing the data, or parsing the stream did not exhaust the available data.
+ */
+ public static ASN1Primitive fromByteArray(byte[] data)
+ throws IOException
+ {
+ ASN1InputStream aIn = new ASN1InputStream(data);
+
+ try
+ {
+ ASN1Primitive o = aIn.readObject();
+
+ if (aIn.available() != 0)
+ {
+ throw new IOException("Extra data detected in stream");
+ }
+
+ return o;
+ }
+ catch (ClassCastException e)
+ {
+ throw new IOException("cannot recognise object in stream");
+ }
+ }
+
+ public final boolean equals(Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+
+ return (o instanceof ASN1Encodable) && asn1Equals(((ASN1Encodable)o).toASN1Primitive());
+ }
+
+ public final boolean equals(ASN1Encodable other)
+ {
+ return this == other || (null != other && asn1Equals(other.toASN1Primitive()));
+ }
+
+ public final boolean equals(ASN1Primitive other)
+ {
+ return this == other || asn1Equals(other);
+ }
+
+ public final ASN1Primitive toASN1Primitive()
+ {
+ return this;
+ }
+
+ /**
+ * Return the current object as one which encodes using Distinguished Encoding Rules.
+ *
+ * @return a DER version of this.
+ */
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ /**
+ * Return the current object as one which encodes using Definite Length encoding.
+ *
+ * @return a DL version of this.
+ */
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
+ public abstract int hashCode();
+
+ /**
+ * Return true if this objected is a CONSTRUCTED one, false otherwise.
+ * @return true if CONSTRUCTED bit set on object's tag, false otherwise.
+ */
+ abstract boolean isConstructed();
+
+ /**
+ * Return the length of the encoding this object will produce.
+ * @return the length of the object's encoding.
+ * @throws IOException if the encoding length cannot be calculated.
+ */
+ abstract int encodedLength() throws IOException;
+
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
+
+ /**
+ * Equality (similarity) comparison for two ASN1Primitive objects.
+ */
+ abstract boolean asn1Equals(ASN1Primitive o);
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Sequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Sequence.java
new file mode 100644
index 00000000..afbb74f7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Sequence.java
@@ -0,0 +1,418 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * ASN.1 <code>SEQUENCE</code> and <code>SEQUENCE OF</code> constructs.
+ * <p>
+ * DER form is always definite form length fields, while
+ * BER support uses indefinite form.
+ * <hr>
+ * <p><b>X.690</b></p>
+ * <p><b>8: Basic encoding rules</b></p>
+ * <p><b>8.9 Encoding of a sequence value </b></p>
+ * 8.9.1 The encoding of a sequence value shall be constructed.
+ * <p>
+ * <b>8.9.2</b> The contents octets shall consist of the complete
+ * encoding of one data value from each of the types listed in
+ * the ASN.1 definition of the sequence type, in the order of
+ * their appearance in the definition, unless the type was referenced
+ * with the keyword <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
+ * </p><p>
+ * <b>8.9.3</b> The encoding of a data value may, but need not,
+ * be present for a type which was referenced with the keyword
+ * <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
+ * If present, it shall appear in the encoding at the point
+ * corresponding to the appearance of the type in the ASN.1 definition.
+ * </p><p>
+ * <b>8.10 Encoding of a sequence-of value </b>
+ * </p><p>
+ * <b>8.10.1</b> The encoding of a sequence-of value shall be constructed.
+ * <p>
+ * <b>8.10.2</b> The contents octets shall consist of zero,
+ * one or more complete encodings of data values from the type listed in
+ * the ASN.1 definition.
+ * <p>
+ * <b>8.10.3</b> The order of the encodings of the data values shall be
+ * the same as the order of the data values in the sequence-of value to
+ * be encoded.
+ * </p>
+ * <p><b>9: Canonical encoding rules</b></p>
+ * <p><b>9.1 Length forms</b></p>
+ * If the encoding is constructed, it shall employ the indefinite-length form.
+ * If the encoding is primitive, it shall include the fewest length octets necessary.
+ * [Contrast with 8.1.3.2 b).]
+ *
+ * <p><b>11: Restrictions on BER employed by both CER and DER</b></p>
+ * <p><b>11.5 Set and sequence components with default value</b></p>
+ * <p>
+ * The encoding of a set value or sequence value shall not include
+ * an encoding for any component value which is equal to
+ * its default value.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1Sequence
+ extends ASN1Primitive
+ implements com.android.internal.org.bouncycastle.util.Iterable<ASN1Encodable>
+{
+ // NOTE: Only non-final to support LazyEncodedSequence
+ ASN1Encodable[] elements;
+
+ /**
+ * Return an ASN1Sequence from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1Sequence instance, or null.
+ */
+ public static ASN1Sequence getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1Sequence)
+ {
+ return (ASN1Sequence)obj;
+ }
+ else if (obj instanceof ASN1SequenceParser)
+ {
+ return ASN1Sequence.getInstance(((ASN1SequenceParser)obj).toASN1Primitive());
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return ASN1Sequence.getInstance(fromByteArray((byte[])obj));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct sequence from byte[]: " + e.getMessage());
+ }
+ }
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+
+ if (primitive instanceof ASN1Sequence)
+ {
+ return (ASN1Sequence)primitive;
+ }
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return an ASN1 SEQUENCE from a tagged object. There is a special
+ * case here, if an object appears to have been explicitly tagged on
+ * reading but we were expecting it to be implicitly tagged in the
+ * normal course of events it indicates that we lost the surrounding
+ * sequence - so we need to add it back (this will happen if the tagged
+ * object is a sequence that contains other sequences). If you are
+ * dealing with implicitly tagged sequences you really <b>should</b>
+ * be using this method.
+ *
+ * @param taggedObject the tagged object.
+ * @param explicit true if the object is meant to be explicitly tagged,
+ * false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1Sequence instance.
+ */
+ public static ASN1Sequence getInstance(
+ ASN1TaggedObject taggedObject,
+ boolean explicit)
+ {
+ if (explicit)
+ {
+ if (!taggedObject.isExplicit())
+ {
+ throw new IllegalArgumentException("object implicit - explicit expected.");
+ }
+
+ return getInstance(taggedObject.getObject());
+ }
+
+ ASN1Primitive o = taggedObject.getObject();
+
+ /*
+ * constructed object which appears to be explicitly tagged when it should be implicit means
+ * we have to add the surrounding sequence.
+ */
+ if (taggedObject.isExplicit())
+ {
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return new BERSequence(o);
+ }
+
+ return new DLSequence(o);
+ }
+
+ if (o instanceof ASN1Sequence)
+ {
+ ASN1Sequence s = (ASN1Sequence)o;
+
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return s;
+ }
+
+ return (ASN1Sequence)s.toDLObject();
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
+ }
+
+ /**
+ * Create an empty SEQUENCE
+ */
+ protected ASN1Sequence()
+ {
+ this.elements = ASN1EncodableVector.EMPTY_ELEMENTS;
+ }
+
+ /**
+ * Create a SEQUENCE containing one object.
+ * @param element the object to be put in the SEQUENCE.
+ */
+ protected ASN1Sequence(ASN1Encodable element)
+ {
+ if (null == element)
+ {
+ throw new NullPointerException("'element' cannot be null");
+ }
+
+ this.elements = new ASN1Encodable[]{ element };
+ }
+
+ /**
+ * Create a SEQUENCE containing a vector of objects.
+ * @param elementVector the vector of objects to be put in the SEQUENCE.
+ */
+ protected ASN1Sequence(ASN1EncodableVector elementVector)
+ {
+ if (null == elementVector)
+ {
+ throw new NullPointerException("'elementVector' cannot be null");
+ }
+
+ this.elements = elementVector.takeElements();
+ }
+
+ /**
+ * Create a SEQUENCE containing an array of objects.
+ * @param elements the array of objects to be put in the SEQUENCE.
+ */
+ protected ASN1Sequence(ASN1Encodable[] elements)
+ {
+ if (Arrays.isNullOrContainsNull(elements))
+ {
+ throw new NullPointerException("'elements' cannot be null, or contain null");
+ }
+
+ this.elements = ASN1EncodableVector.cloneElements(elements);
+ }
+
+ ASN1Sequence(ASN1Encodable[] elements, boolean clone)
+ {
+ this.elements = clone ? ASN1EncodableVector.cloneElements(elements) : elements;
+ }
+
+ public ASN1Encodable[] toArray()
+ {
+ return ASN1EncodableVector.cloneElements(elements);
+ }
+
+ ASN1Encodable[] toArrayInternal()
+ {
+ return elements;
+ }
+
+ public Enumeration getObjects()
+ {
+ return new Enumeration()
+ {
+ private int pos = 0;
+
+ public boolean hasMoreElements()
+ {
+ return pos < elements.length;
+ }
+
+ public Object nextElement()
+ {
+ if (pos < elements.length)
+ {
+ return elements[pos++];
+ }
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
+ public ASN1SequenceParser parser()
+ {
+ // NOTE: Call size() here to 'force' a LazyEncodedSequence
+ final int count = size();
+
+ return new ASN1SequenceParser()
+ {
+ private int pos = 0;
+
+ public ASN1Encodable readObject() throws IOException
+ {
+ if (count == pos)
+ {
+ return null;
+ }
+
+ ASN1Encodable obj = elements[pos++];
+ if (obj instanceof ASN1Sequence)
+ {
+ return ((ASN1Sequence)obj).parser();
+ }
+ if (obj instanceof ASN1Set)
+ {
+ return ((ASN1Set)obj).parser();
+ }
+
+ return obj;
+ }
+
+ public ASN1Primitive getLoadedObject()
+ {
+ return ASN1Sequence.this;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return ASN1Sequence.this;
+ }
+ };
+ }
+
+ /**
+ * Return the object at the sequence position indicated by index.
+ *
+ * @param index the sequence number (starting at zero) of the object
+ * @return the object at the sequence position indicated by index.
+ */
+ public ASN1Encodable getObjectAt(int index)
+ {
+ return elements[index];
+ }
+
+ /**
+ * Return the number of objects in this sequence.
+ *
+ * @return the number of objects in this sequence.
+ */
+ public int size()
+ {
+ return elements.length;
+ }
+
+ public int hashCode()
+ {
+// return Arrays.hashCode(elements);
+ int i = elements.length;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ hc *= 257;
+ hc ^= elements[i].toASN1Primitive().hashCode();
+ }
+
+ return hc;
+ }
+
+ boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1Sequence))
+ {
+ return false;
+ }
+
+ ASN1Sequence that = (ASN1Sequence)other;
+
+ int count = this.size();
+ if (that.size() != count)
+ {
+ return false;
+ }
+
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive p1 = this.elements[i].toASN1Primitive();
+ ASN1Primitive p2 = that.elements[i].toASN1Primitive();
+
+ if (p1 != p2 && !p1.asn1Equals(p2))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Change current SEQUENCE object to be encoded as {@link DERSequence}.
+ * This is part of Distinguished Encoding Rules form serialization.
+ */
+ ASN1Primitive toDERObject()
+ {
+ return new DERSequence(elements, false);
+ }
+
+ /**
+ * Change current SEQUENCE object to be encoded as {@link DLSequence}.
+ * This is part of Direct Length form serialization.
+ */
+ ASN1Primitive toDLObject()
+ {
+ return new DLSequence(elements, false);
+ }
+
+ boolean isConstructed()
+ {
+ return true;
+ }
+
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
+
+ public String toString()
+ {
+ // NOTE: Call size() here to 'force' a LazyEncodedSequence
+ int count = size();
+ if (0 == count)
+ {
+ return "[]";
+ }
+
+ StringBuffer sb = new StringBuffer();
+ sb.append('[');
+ for (int i = 0;;)
+ {
+ sb.append(elements[i]);
+ if (++i >= count)
+ {
+ break;
+ }
+ sb.append(", ");
+ }
+ sb.append(']');
+ return sb.toString();
+ }
+
+ public Iterator<ASN1Encodable> iterator()
+ {
+ return new Arrays.Iterator<ASN1Encodable>(elements);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1SequenceParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1SequenceParser.java
new file mode 100644
index 00000000..6d966a67
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1SequenceParser.java
@@ -0,0 +1,21 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * A basic parser for a SEQUENCE object
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ASN1SequenceParser
+ extends ASN1Encodable, InMemoryRepresentable
+{
+ /**
+ * Read the next object from the underlying object representing a SEQUENCE.
+ *
+ * @throws IOException for bad input stream.
+ * @return the next object, null if we are at the end.
+ */
+ ASN1Encodable readObject()
+ throws IOException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Set.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Set.java
new file mode 100644
index 00000000..110d200b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Set.java
@@ -0,0 +1,609 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * ASN.1 <code>SET</code> and <code>SET OF</code> constructs.
+ * <p>
+ * Note: This does not know which syntax the set is!
+ * (The difference: ordering of SET elements or not ordering.)
+ * </p><p>
+ * DER form is always definite form length fields, while
+ * BER support uses indefinite form.
+ * </p><p>
+ * The CER form support does not exist.
+ * </p><p>
+ * <h2>X.690</h2>
+ * <h3>8: Basic encoding rules</h3>
+ * <h4>8.11 Encoding of a set value </h4>
+ * <b>8.11.1</b> The encoding of a set value shall be constructed
+ * <p>
+ * <b>8.11.2</b> The contents octets shall consist of the complete
+ * encoding of a data value from each of the types listed in the
+ * ASN.1 definition of the set type, in an order chosen by the sender,
+ * unless the type was referenced with the keyword
+ * <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
+ * </p><p>
+ * <b>8.11.3</b> The encoding of a data value may, but need not,
+ * be present for a type which was referenced with the keyword
+ * <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
+ * <blockquote>
+ * NOTE &mdash; The order of data values in a set value is not significant,
+ * and places no constraints on the order during transfer
+ * </blockquote>
+ * <h4>8.12 Encoding of a set-of value</h4>
+ * <p>
+ * <b>8.12.1</b> The encoding of a set-of value shall be constructed.
+ * </p><p>
+ * <b>8.12.2</b> The text of 8.10.2 applies:
+ * <i>The contents octets shall consist of zero,
+ * one or more complete encodings of data values from the type listed in
+ * the ASN.1 definition.</i>
+ * </p><p>
+ * <b>8.12.3</b> The order of data values need not be preserved by
+ * the encoding and subsequent decoding.
+ *
+ * <h3>9: Canonical encoding rules</h3>
+ * <h4>9.1 Length forms</h4>
+ * If the encoding is constructed, it shall employ the indefinite-length form.
+ * If the encoding is primitive, it shall include the fewest length octets necessary.
+ * [Contrast with 8.1.3.2 b).]
+ * <h4>9.3 Set components</h4>
+ * The encodings of the component values of a set value shall
+ * appear in an order determined by their tags as specified
+ * in 8.6 of ITU-T Rec. X.680 | ISO/IEC 8824-1.
+ * Additionally, for the purposes of determining the order in which
+ * components are encoded when one or more component is an untagged
+ * choice type, each untagged choice type is ordered as though it
+ * has a tag equal to that of the smallest tag in that choice type
+ * or any untagged choice types nested within.
+ *
+ * <h3>10: Distinguished encoding rules</h3>
+ * <h4>10.1 Length forms</h4>
+ * The definite form of length encoding shall be used,
+ * encoded in the minimum number of octets.
+ * [Contrast with 8.1.3.2 b).]
+ * <h4>10.3 Set components</h4>
+ * The encodings of the component values of a set value shall appear
+ * in an order determined by their tags as specified
+ * in 8.6 of ITU-T Rec. X.680 | ISO/IEC 8824-1.
+ * <blockquote>
+ * NOTE &mdash; Where a component of the set is an untagged choice type,
+ * the location of that component in the ordering will depend on
+ * the tag of the choice component being encoded.
+ * </blockquote>
+ *
+ * <h3>11: Restrictions on BER employed by both CER and DER</h3>
+ * <h4>11.5 Set and sequence components with default value </h4>
+ * The encoding of a set value or sequence value shall not include
+ * an encoding for any component value which is equal to
+ * its default value.
+ * <h4>11.6 Set-of components </h4>
+ * <p>
+ * The encodings of the component values of a set-of value
+ * shall appear in ascending order, the encodings being compared
+ * as octet strings with the shorter components being padded at
+ * their trailing end with 0-octets.
+ * <blockquote>
+ * NOTE &mdash; The padding octets are for comparison purposes only
+ * and do not appear in the encodings.
+ * </blockquote>
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1Set
+ extends ASN1Primitive
+ implements com.android.internal.org.bouncycastle.util.Iterable<ASN1Encodable>
+{
+ protected final ASN1Encodable[] elements;
+ protected final boolean isSorted;
+
+ /**
+ * return an ASN1Set from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1Set instance, or null.
+ */
+ public static ASN1Set getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1Set)
+ {
+ return (ASN1Set)obj;
+ }
+ else if (obj instanceof ASN1SetParser)
+ {
+ return ASN1Set.getInstance(((ASN1SetParser)obj).toASN1Primitive());
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return ASN1Set.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct set from byte[]: " + e.getMessage());
+ }
+ }
+ else if (obj instanceof ASN1Encodable)
+ {
+ ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
+
+ if (primitive instanceof ASN1Set)
+ {
+ return (ASN1Set)primitive;
+ }
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return an ASN1 set from a tagged object. There is a special
+ * case here, if an object appears to have been explicitly tagged on
+ * reading but we were expecting it to be implicitly tagged in the
+ * normal course of events it indicates that we lost the surrounding
+ * set - so we need to add it back (this will happen if the tagged
+ * object is a sequence that contains other sequences). If you are
+ * dealing with implicitly tagged sets you really <b>should</b>
+ * be using this method.
+ *
+ * @param taggedObject the tagged object.
+ * @param explicit true if the object is meant to be explicitly tagged
+ * false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1Set instance.
+ */
+ public static ASN1Set getInstance(
+ ASN1TaggedObject taggedObject,
+ boolean explicit)
+ {
+ if (explicit)
+ {
+ if (!taggedObject.isExplicit())
+ {
+ throw new IllegalArgumentException("object implicit - explicit expected.");
+ }
+
+ return getInstance(taggedObject.getObject());
+ }
+
+ ASN1Primitive o = taggedObject.getObject();
+
+ /*
+ * constructed object which appears to be explicitly tagged and it's really implicit means
+ * we have to add the surrounding set.
+ */
+ if (taggedObject.isExplicit())
+ {
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return new BERSet(o);
+ }
+
+ return new DLSet(o);
+ }
+
+ if (o instanceof ASN1Set)
+ {
+ ASN1Set s = (ASN1Set)o;
+
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return s;
+ }
+
+ return (ASN1Set)s.toDLObject();
+ }
+
+ /*
+ * in this case the parser returns a sequence, convert it into a set.
+ */
+ if (o instanceof ASN1Sequence)
+ {
+ ASN1Sequence s = (ASN1Sequence)o;
+
+ // NOTE: Will force() a LazyEncodedSequence
+ ASN1Encodable[] elements = s.toArrayInternal();
+
+ if (taggedObject instanceof BERTaggedObject)
+ {
+ return new BERSet(false, elements);
+ }
+
+ return new DLSet(false, elements);
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
+ }
+
+ protected ASN1Set()
+ {
+ this.elements = ASN1EncodableVector.EMPTY_ELEMENTS;
+ this.isSorted = true;
+ }
+
+ /**
+ * Create a SET containing one object
+ * @param element object to be added to the SET.
+ */
+ protected ASN1Set(ASN1Encodable element)
+ {
+ if (null == element)
+ {
+ throw new NullPointerException("'element' cannot be null");
+ }
+
+ this.elements = new ASN1Encodable[]{ element };
+ this.isSorted = true;
+ }
+
+ /**
+ * Create a SET containing a vector of objects.
+ * @param elementVector a vector of objects to make up the SET.
+ * @param doSort true if should be sorted DER style, false otherwise.
+ */
+ protected ASN1Set(ASN1EncodableVector elementVector, boolean doSort)
+ {
+ if (null == elementVector)
+ {
+ throw new NullPointerException("'elementVector' cannot be null");
+ }
+
+ ASN1Encodable[] tmp;
+ if (doSort && elementVector.size() >= 2)
+ {
+ tmp = elementVector.copyElements();
+ sort(tmp);
+ }
+ else
+ {
+ tmp = elementVector.takeElements();
+ }
+
+ this.elements = tmp;
+ this.isSorted = doSort || tmp.length < 2;
+ }
+
+ /**
+ * Create a SET containing an array of objects.
+ * @param elements an array of objects to make up the SET.
+ * @param doSort true if should be sorted DER style, false otherwise.
+ */
+ protected ASN1Set(ASN1Encodable[] elements, boolean doSort)
+ {
+ if (Arrays.isNullOrContainsNull(elements))
+ {
+ throw new NullPointerException("'elements' cannot be null, or contain null");
+ }
+
+ ASN1Encodable[] tmp = ASN1EncodableVector.cloneElements(elements);
+ if (doSort && tmp.length >= 2)
+ {
+ sort(tmp);
+ }
+
+ this.elements = tmp;
+ this.isSorted = doSort || tmp.length < 2;
+ }
+
+ ASN1Set(boolean isSorted, ASN1Encodable[] elements)
+ {
+ this.elements = elements;
+ this.isSorted = isSorted || elements.length < 2;
+ }
+
+ public Enumeration getObjects()
+ {
+ return new Enumeration()
+ {
+ private int pos = 0;
+
+ public boolean hasMoreElements()
+ {
+ return pos < elements.length;
+ }
+
+ public Object nextElement()
+ {
+ if (pos < elements.length)
+ {
+ return elements[pos++];
+ }
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
+ /**
+ * return the object at the set position indicated by index.
+ *
+ * @param index the set number (starting at zero) of the object
+ * @return the object at the set position indicated by index.
+ */
+ public ASN1Encodable getObjectAt(int index)
+ {
+ return elements[index];
+ }
+
+ /**
+ * return the number of objects in this set.
+ *
+ * @return the number of objects in this set.
+ */
+ public int size()
+ {
+ return elements.length;
+ }
+
+ public ASN1Encodable[] toArray()
+ {
+ return ASN1EncodableVector.cloneElements(elements);
+ }
+
+ public ASN1SetParser parser()
+ {
+ final int count = size();
+
+ return new ASN1SetParser()
+ {
+ private int pos = 0;
+
+ public ASN1Encodable readObject() throws IOException
+ {
+ if (count == pos)
+ {
+ return null;
+ }
+
+ ASN1Encodable obj = elements[pos++];
+ if (obj instanceof ASN1Sequence)
+ {
+ return ((ASN1Sequence)obj).parser();
+ }
+ if (obj instanceof ASN1Set)
+ {
+ return ((ASN1Set)obj).parser();
+ }
+
+ return obj;
+ }
+
+ public ASN1Primitive getLoadedObject()
+ {
+ return ASN1Set.this;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return ASN1Set.this;
+ }
+ };
+ }
+
+ public int hashCode()
+ {
+// return Arrays.hashCode(elements);
+ int i = elements.length;
+ int hc = i + 1;
+
+ // NOTE: Order-independent contribution of elements to avoid sorting
+ while (--i >= 0)
+ {
+ hc += elements[i].toASN1Primitive().hashCode();
+ }
+
+ return hc;
+ }
+
+ /**
+ * Change current SET object to be encoded as {@link DERSet}.
+ * This is part of Distinguished Encoding Rules form serialization.
+ */
+ ASN1Primitive toDERObject()
+ {
+ ASN1Encodable[] tmp;
+ if (isSorted)
+ {
+ tmp = elements;
+ }
+ else
+ {
+ tmp = (ASN1Encodable[])elements.clone();
+ sort(tmp);
+ }
+
+ return new DERSet(true, tmp);
+ }
+
+ /**
+ * Change current SET object to be encoded as {@link DLSet}.
+ * This is part of Direct Length form serialization.
+ */
+ ASN1Primitive toDLObject()
+ {
+ return new DLSet(isSorted, elements);
+ }
+
+ boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1Set))
+ {
+ return false;
+ }
+
+ ASN1Set that = (ASN1Set)other;
+
+ int count = this.size();
+ if (that.size() != count)
+ {
+ return false;
+ }
+
+ DERSet dis = (DERSet)this.toDERObject();
+ DERSet dat = (DERSet)that.toDERObject();
+
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive p1 = dis.elements[i].toASN1Primitive();
+ ASN1Primitive p2 = dat.elements[i].toASN1Primitive();
+
+ if (p1 != p2 && !p1.asn1Equals(p2))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ boolean isConstructed()
+ {
+ return true;
+ }
+
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
+
+ public String toString()
+ {
+ int count = size();
+ if (0 == count)
+ {
+ return "[]";
+ }
+
+ StringBuffer sb = new StringBuffer();
+ sb.append('[');
+ for (int i = 0;;)
+ {
+ sb.append(elements[i]);
+ if (++i >= count)
+ {
+ break;
+ }
+ sb.append(", ");
+ }
+ sb.append(']');
+ return sb.toString();
+ }
+
+ public Iterator<ASN1Encodable> iterator()
+ {
+ return new Arrays.Iterator<ASN1Encodable>(toArray());
+ }
+
+ private static byte[] getDEREncoded(ASN1Encodable obj)
+ {
+ try
+ {
+ return obj.toASN1Primitive().getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("cannot encode object added to SET");
+ }
+ }
+
+ /**
+ * return true if a <= b (arrays are assumed padded with zeros).
+ */
+ private static boolean lessThanOrEqual(byte[] a, byte[] b)
+ {
+// assert a.length >= 2 && b.length >= 2;
+
+ /*
+ * NOTE: Set elements in DER encodings are ordered first according to their tags (class and
+ * number); the CONSTRUCTED bit is not part of the tag.
+ *
+ * For SET-OF, this is unimportant. All elements have the same tag and DER requires them to
+ * either all be in constructed form or all in primitive form, according to that tag. The
+ * elements are effectively ordered according to their content octets.
+ *
+ * For SET, the elements will have distinct tags, and each will be in constructed or
+ * primitive form accordingly. Failing to ignore the CONSTRUCTED bit could therefore lead to
+ * ordering inversions.
+ */
+ int a0 = a[0] & ~BERTags.CONSTRUCTED;
+ int b0 = b[0] & ~BERTags.CONSTRUCTED;
+ if (a0 != b0)
+ {
+ return a0 < b0;
+ }
+
+ int last = Math.min(a.length, b.length) - 1;
+ for (int i = 1; i < last; ++i)
+ {
+ if (a[i] != b[i])
+ {
+ return (a[i] & 0xFF) < (b[i] & 0xFF);
+ }
+ }
+ return (a[last] & 0xFF) <= (b[last] & 0xFF);
+ }
+
+ private static void sort(ASN1Encodable[] t)
+ {
+ int count = t.length;
+ if (count < 2)
+ {
+ return;
+ }
+
+ ASN1Encodable eh = t[0], ei = t[1];
+ byte[] bh = getDEREncoded(eh), bi = getDEREncoded(ei);;
+
+ if (lessThanOrEqual(bi, bh))
+ {
+ ASN1Encodable et = ei; ei = eh; eh = et;
+ byte[] bt = bi; bi = bh; bh = bt;
+ }
+
+ for (int i = 2; i < count; ++i)
+ {
+ ASN1Encodable e2 = t[i];
+ byte[] b2 = getDEREncoded(e2);
+
+ if (lessThanOrEqual(bi, b2))
+ {
+ t[i - 2] = eh;
+ eh = ei; bh = bi;
+ ei = e2; bi = b2;
+ continue;
+ }
+
+ if (lessThanOrEqual(bh, b2))
+ {
+ t[i - 2] = eh;
+ eh = e2; bh = b2;
+ continue;
+ }
+
+ int j = i - 1;
+ while (--j > 0)
+ {
+ ASN1Encodable e1 = t[j - 1];
+ byte[] b1 = getDEREncoded(e1);
+
+ if (lessThanOrEqual(b1, b2))
+ {
+ break;
+ }
+
+ t[j] = e1;
+ }
+
+ t[j] = e2;
+ }
+
+ t[count - 2] = eh;
+ t[count - 1] = ei;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1SetParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1SetParser.java
new file mode 100644
index 00000000..a46c0dd4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1SetParser.java
@@ -0,0 +1,21 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * A basic parser for a SET object
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ASN1SetParser
+ extends ASN1Encodable, InMemoryRepresentable
+{
+ /**
+ * Read the next object from the underlying object representing a SET.
+ *
+ * @throws IOException for bad input stream.
+ * @return the next object, null if we are at the end.
+ */
+ public ASN1Encodable readObject()
+ throws IOException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1StreamParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1StreamParser.java
new file mode 100644
index 00000000..888a2f66
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1StreamParser.java
@@ -0,0 +1,256 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A parser for ASN.1 streams which also returns, where possible, parsers for the objects it encounters.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1StreamParser
+{
+ private final InputStream _in;
+ private final int _limit;
+ private final byte[][] tmpBuffers;
+
+ public ASN1StreamParser(
+ InputStream in)
+ {
+ this(in, StreamUtil.findLimit(in));
+ }
+
+ public ASN1StreamParser(
+ InputStream in,
+ int limit)
+ {
+ this._in = in;
+ this._limit = limit;
+
+ this.tmpBuffers = new byte[11][];
+ }
+
+ public ASN1StreamParser(
+ byte[] encoding)
+ {
+ this(new ByteArrayInputStream(encoding), encoding.length);
+ }
+
+ ASN1Encodable readIndef(int tagValue) throws IOException
+ {
+ // Note: INDEF => CONSTRUCTED
+
+ // TODO There are other tags that may be constructed (e.g. BIT_STRING)
+ switch (tagValue)
+ {
+ case BERTags.EXTERNAL:
+ return new DERExternalParser(this);
+ case BERTags.OCTET_STRING:
+ return new BEROctetStringParser(this);
+ case BERTags.SEQUENCE:
+ return new BERSequenceParser(this);
+ case BERTags.SET:
+ return new BERSetParser(this);
+ default:
+ throw new ASN1Exception("unknown BER object encountered: 0x" + Integer.toHexString(tagValue));
+ }
+ }
+
+ ASN1Encodable readImplicit(boolean constructed, int tag) throws IOException
+ {
+ if (_in instanceof IndefiniteLengthInputStream)
+ {
+ if (!constructed)
+ {
+ throw new IOException("indefinite-length primitive encoding encountered");
+ }
+
+ return readIndef(tag);
+ }
+
+ if (constructed)
+ {
+ switch (tag)
+ {
+ case BERTags.SET:
+ return new DLSetParser(this);
+ case BERTags.SEQUENCE:
+ return new DLSequenceParser(this);
+ case BERTags.OCTET_STRING:
+ return new BEROctetStringParser(this);
+ }
+ }
+ else
+ {
+ switch (tag)
+ {
+ case BERTags.SET:
+ throw new ASN1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)");
+ case BERTags.SEQUENCE:
+ throw new ASN1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)");
+ case BERTags.OCTET_STRING:
+ return new DEROctetStringParser((DefiniteLengthInputStream)_in);
+ }
+ }
+
+ throw new ASN1Exception("implicit tagging not implemented");
+ }
+
+ ASN1Primitive readTaggedObject(boolean constructed, int tag) throws IOException
+ {
+ if (!constructed)
+ {
+ // Note: !CONSTRUCTED => IMPLICIT
+ DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in;
+ return new DLTaggedObject(false, tag, new DEROctetString(defIn.toByteArray()));
+ }
+
+ ASN1EncodableVector v = readVector();
+
+ if (_in instanceof IndefiniteLengthInputStream)
+ {
+ return v.size() == 1
+ ? new BERTaggedObject(true, tag, v.get(0))
+ : new BERTaggedObject(false, tag, BERFactory.createSequence(v));
+ }
+
+ return v.size() == 1
+ ? new DLTaggedObject(true, tag, v.get(0))
+ : new DLTaggedObject(false, tag, DLFactory.createSequence(v));
+ }
+
+ public ASN1Encodable readObject()
+ throws IOException
+ {
+ int tag = _in.read();
+ if (tag == -1)
+ {
+ return null;
+ }
+
+ //
+ // turn of looking for "00" while we resolve the tag
+ //
+ set00Check(false);
+
+ //
+ // calculate tag number
+ //
+ int tagNo = ASN1InputStream.readTagNumber(_in, tag);
+
+ boolean isConstructed = (tag & BERTags.CONSTRUCTED) != 0;
+
+ //
+ // calculate length
+ //
+ int length = ASN1InputStream.readLength(_in, _limit,
+ tagNo == BERTags.OCTET_STRING || tagNo == BERTags.SEQUENCE || tagNo == BERTags.SET || tagNo == BERTags.EXTERNAL);
+
+ if (length < 0) // indefinite-length method
+ {
+ if (!isConstructed)
+ {
+ throw new IOException("indefinite-length primitive encoding encountered");
+ }
+
+ IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit);
+ ASN1StreamParser sp = new ASN1StreamParser(indIn, _limit);
+
+ if ((tag & BERTags.APPLICATION) != 0)
+ {
+ return new BERApplicationSpecificParser(tagNo, sp);
+ }
+
+ if ((tag & BERTags.TAGGED) != 0)
+ {
+ return new BERTaggedObjectParser(true, tagNo, sp);
+ }
+
+ return sp.readIndef(tagNo);
+ }
+ else
+ {
+ DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length, _limit);
+
+ if ((tag & BERTags.APPLICATION) != 0)
+ {
+ return new DLApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
+ }
+
+ if ((tag & BERTags.TAGGED) != 0)
+ {
+ return new BERTaggedObjectParser(isConstructed, tagNo, new ASN1StreamParser(defIn));
+ }
+
+ if (isConstructed)
+ {
+ // TODO There are other tags that may be constructed (e.g. BIT_STRING)
+ switch (tagNo)
+ {
+ case BERTags.OCTET_STRING:
+ //
+ // yes, people actually do this...
+ //
+ return new BEROctetStringParser(new ASN1StreamParser(defIn));
+ case BERTags.SEQUENCE:
+ return new DLSequenceParser(new ASN1StreamParser(defIn));
+ case BERTags.SET:
+ return new DLSetParser(new ASN1StreamParser(defIn));
+ case BERTags.EXTERNAL:
+ return new DERExternalParser(new ASN1StreamParser(defIn));
+ default:
+ throw new IOException("unknown tag " + tagNo + " encountered");
+ }
+ }
+
+ // Some primitive encodings can be handled by parsers too...
+ switch (tagNo)
+ {
+ case BERTags.OCTET_STRING:
+ return new DEROctetStringParser(defIn);
+ }
+
+ try
+ {
+ return ASN1InputStream.createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ASN1Exception("corrupted stream detected", e);
+ }
+ }
+ }
+
+ private void set00Check(boolean enabled)
+ {
+ if (_in instanceof IndefiniteLengthInputStream)
+ {
+ ((IndefiniteLengthInputStream)_in).setEofOn00(enabled);
+ }
+ }
+
+ ASN1EncodableVector readVector() throws IOException
+ {
+ ASN1Encodable obj = readObject();
+ if (null == obj)
+ {
+ return new ASN1EncodableVector(0);
+ }
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ do
+ {
+ if (obj instanceof InMemoryRepresentable)
+ {
+ v.add(((InMemoryRepresentable)obj).getLoadedObject());
+ }
+ else
+ {
+ v.add(obj.toASN1Primitive());
+ }
+ }
+ while ((obj = readObject()) != null);
+ return v;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1String.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1String.java
new file mode 100644
index 00000000..030b7aad
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1String.java
@@ -0,0 +1,15 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+/**
+ * General interface implemented by ASN.1 STRING objects for extracting the content String.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ASN1String
+{
+ /**
+ * Return a Java String representation of this STRING type's content.
+ * @return a Java String representation of this STRING.
+ */
+ public String getString();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObject.java
new file mode 100644
index 00000000..c0f96273
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObject.java
@@ -0,0 +1,189 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * ASN.1 TaggedObject - in ASN.1 notation this is any object preceded by
+ * a [n] where n is some number - these are assumed to follow the construction
+ * rules (as with sequences).
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ASN1TaggedObject
+ extends ASN1Primitive
+ implements ASN1TaggedObjectParser
+{
+ final int tagNo;
+ final boolean explicit;
+ final ASN1Encodable obj;
+
+ static public ASN1TaggedObject getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ if (explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+ throw new IllegalArgumentException("implicitly tagged tagged object");
+ }
+
+ static public ASN1TaggedObject getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1TaggedObject)
+ {
+ return (ASN1TaggedObject)obj;
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return ASN1TaggedObject.getInstance(fromByteArray((byte[])obj));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("failed to construct tagged object from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Create a tagged object with the style given by the value of explicit.
+ * <p>
+ * If the object implements ASN1Choice the tag style will always be changed
+ * to explicit in accordance with the ASN.1 encoding rules.
+ * </p>
+ * @param explicit true if the object is explicitly tagged.
+ * @param tagNo the tag number for this object.
+ * @param obj the tagged object.
+ */
+ public ASN1TaggedObject(
+ boolean explicit,
+ int tagNo,
+ ASN1Encodable obj)
+ {
+ if (null == obj)
+ {
+ throw new NullPointerException("'obj' cannot be null");
+ }
+
+ this.tagNo = tagNo;
+ this.explicit = explicit || (obj instanceof ASN1Choice);
+ this.obj = obj;
+ }
+
+ boolean asn1Equals(ASN1Primitive other)
+ {
+ if (!(other instanceof ASN1TaggedObject))
+ {
+ return false;
+ }
+
+ ASN1TaggedObject that = (ASN1TaggedObject)other;
+
+ if (this.tagNo != that.tagNo || this.explicit != that.explicit)
+ {
+ return false;
+ }
+
+ ASN1Primitive p1 = this.obj.toASN1Primitive();
+ ASN1Primitive p2 = that.obj.toASN1Primitive();
+
+ return p1 == p2 || p1.asn1Equals(p2);
+ }
+
+ public int hashCode()
+ {
+ return tagNo ^ (explicit ? 0x0F : 0xF0) ^ obj.toASN1Primitive().hashCode();
+ }
+
+ /**
+ * Return the tag number associated with this object.
+ *
+ * @return the tag number.
+ */
+ public int getTagNo()
+ {
+ return tagNo;
+ }
+
+ /**
+ * return whether or not the object may be explicitly tagged.
+ * <p>
+ * Note: if the object has been read from an input stream, the only
+ * time you can be sure if isExplicit is returning the true state of
+ * affairs is if it returns false. An implicitly tagged object may appear
+ * to be explicitly tagged, so you need to understand the context under
+ * which the reading was done as well, see getObject below.
+ */
+ public boolean isExplicit()
+ {
+ return explicit;
+ }
+
+ /**
+ * Return whatever was following the tag.
+ * <p>
+ * Note: tagged objects are generally context dependent if you're
+ * trying to extract a tagged object you should be going via the
+ * appropriate getInstance method.
+ */
+ public ASN1Primitive getObject()
+ {
+ return obj.toASN1Primitive();
+ }
+
+ /**
+ * Return the object held in this tagged object as a parser assuming it has
+ * the type of the passed in tag. If the object doesn't have a parser
+ * associated with it, the base object is returned.
+ */
+ public ASN1Encodable getObjectParser(
+ int tag,
+ boolean isExplicit)
+ throws IOException
+ {
+ switch (tag)
+ {
+ case BERTags.SET:
+ return ASN1Set.getInstance(this, isExplicit).parser();
+ case BERTags.SEQUENCE:
+ return ASN1Sequence.getInstance(this, isExplicit).parser();
+ case BERTags.OCTET_STRING:
+ return ASN1OctetString.getInstance(this, isExplicit).parser();
+ }
+
+ if (isExplicit)
+ {
+ return getObject();
+ }
+
+ throw new ASN1Exception("implicit tagging not implemented for tag: " + tag);
+ }
+
+ public ASN1Primitive getLoadedObject()
+ {
+ return this.toASN1Primitive();
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return new DERTaggedObject(explicit, tagNo, obj);
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return new DLTaggedObject(explicit, tagNo, obj);
+ }
+
+ abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
+
+ public String toString()
+ {
+ return "[" + tagNo + "]" + obj;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObjectParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObjectParser.java
new file mode 100644
index 00000000..41fcf426
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObjectParser.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Interface for the parsing of a generic tagged ASN.1 object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ASN1TaggedObjectParser
+ extends ASN1Encodable, InMemoryRepresentable
+{
+ /**
+ * Return the tag number associated with the underlying tagged object.
+ * @return the object's tag number.
+ */
+ int getTagNo();
+
+ /**
+ * Return a parser for the actual object tagged.
+ *
+ * @param tag the primitive tag value for the object tagged originally.
+ * @param isExplicit true if the tagging was done explicitly.
+ * @return a parser for the tagged object.
+ * @throws IOException if a parser cannot be constructed.
+ */
+ ASN1Encodable getObjectParser(int tag, boolean isExplicit)
+ throws IOException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTCTime.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTCTime.java
new file mode 100644
index 00000000..7bd92981
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTCTime.java
@@ -0,0 +1,330 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+// Android-added: Localization support
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.SimpleTimeZone;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+- * UTC time object.
+ * Internal facade of {@link ASN1UTCTime}.
+ * <p>
+ * This datatype is valid only from 1950-01-01 00:00:00 UTC until 2049-12-31 23:59:59 UTC.
+ * </p>
+ * <hr>
+ * <p><b>X.690</b></p>
+ * <p><b>11: Restrictions on BER employed by both CER and DER</b></p>
+ * <p><b>11.8 UTCTime </b></p>
+ * <b>11.8.1</b> The encoding shall terminate with "Z",
+ * as described in the ITU-T X.680 | ISO/IEC 8824-1 clause on UTCTime.
+ * <p>
+ * <b>11.8.2</b> The seconds element shall always be present.
+ * <p>
+ * <b>11.8.3</b> Midnight (GMT) shall be represented in the form:
+ * <blockquote>
+ * "YYMMDD000000Z"
+ * </blockquote>
+ * where "YYMMDD" represents the day following the midnight in question.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1UTCTime
+ extends ASN1Primitive
+{
+ private byte[] time;
+
+ /**
+ * Return an UTC Time from the passed in object.
+ *
+ * @param obj an ASN1UTCTime or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1UTCTime instance, or null.
+ */
+ public static ASN1UTCTime getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1UTCTime)
+ {
+ return (ASN1UTCTime)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1UTCTime)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return an UTC Time from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1UTCTime instance, or null.
+ */
+ public static ASN1UTCTime getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Object o = obj.getObject();
+
+ if (explicit || o instanceof ASN1UTCTime)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new ASN1UTCTime(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ /**
+ * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
+ * never encoded. When you're creating one of these objects from scratch, that's
+ * what you want to use, otherwise we'll try to deal with whatever gets read from
+ * the input stream... (this is why the input format is different from the getTime()
+ * method output).
+ * <p>
+ *
+ * @param time the time string.
+ */
+ public ASN1UTCTime(
+ String time)
+ {
+ this.time = Strings.toByteArray(time);
+ try
+ {
+ this.getDate();
+ }
+ catch (ParseException e)
+ {
+ throw new IllegalArgumentException("invalid date string: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Base constructor from a java.util.date object
+ * @param time the Date to build the time from.
+ */
+ public ASN1UTCTime(
+ Date time)
+ {
+ // Android-changed: Use localized version
+ // SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'", DateUtil.EN_Locale);
+ SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'", Locale.US);
+
+ dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
+
+ this.time = Strings.toByteArray(dateF.format(time));
+ }
+
+ /**
+ * Base constructor from a java.util.date and Locale - you may need to use this if the default locale
+ * doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations.
+ *
+ * @param time a date object representing the time of interest.
+ * @param locale an appropriate Locale for producing an ASN.1 UTCTime value.
+ */
+ public ASN1UTCTime(
+ Date time,
+ Locale locale)
+ {
+ // BEGIN Android-changed: Use localized version
+ // SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'", locale);
+ SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'", Locale.US);
+ dateF.setCalendar(Calendar.getInstance(locale));
+ // END Android-changed: Use localized version
+
+ dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
+
+ this.time = Strings.toByteArray(dateF.format(time));
+ }
+
+ ASN1UTCTime(
+ byte[] time)
+ {
+ if (time.length < 2)
+ {
+ throw new IllegalArgumentException("UTCTime string too short");
+ }
+ this.time = time;
+ if (!(isDigit(0) && isDigit(1)))
+ {
+ throw new IllegalArgumentException("illegal characters in UTCTime string");
+ }
+ }
+
+ /**
+ * Return the time as a date based on whatever a 2 digit year will return. For
+ * standardised processing use getAdjustedDate().
+ *
+ * @return the resulting date
+ * @exception ParseException if the date string cannot be parsed.
+ */
+ public Date getDate()
+ throws ParseException
+ {
+ // Android-changed: Use localized version
+ // SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz");
+ SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz", Locale.US);
+
+ return DateUtil.epochAdjust(dateF.parse(getTime()));
+ }
+
+ /**
+ * Return the time as an adjusted date
+ * in the range of 1950 - 2049.
+ *
+ * @return a date in the range of 1950 to 2049.
+ * @exception ParseException if the date string cannot be parsed.
+ */
+ public Date getAdjustedDate()
+ throws ParseException
+ {
+ // Android-changed: Use localized version
+ // SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
+ SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz", Locale.US);
+
+ dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
+
+ return DateUtil.epochAdjust(dateF.parse(getAdjustedTime()));
+ }
+
+ /**
+ * Return the time - always in the form of
+ * YYMMDDhhmmssGMT(+hh:mm|-hh:mm).
+ * <p>
+ * Normally in a certificate we would expect "Z" rather than "GMT",
+ * however adding the "GMT" means we can just use:
+ * <pre>
+ * dateF = new SimpleDateFormat("yyMMddHHmmssz");
+ * </pre>
+ * To read in the time and get a date which is compatible with our local
+ * time zone.
+ * <p>
+ * <b>Note:</b> In some cases, due to the local date processing, this
+ * may lead to unexpected results. If you want to stick the normal
+ * convention of 1950 to 2049 use the getAdjustedTime() method.
+ */
+ public String getTime()
+ {
+ String stime = Strings.fromByteArray(time);
+
+ //
+ // standardise the format.
+ //
+ if (stime.indexOf('-') < 0 && stime.indexOf('+') < 0)
+ {
+ if (stime.length() == 11)
+ {
+ return stime.substring(0, 10) + "00GMT+00:00";
+ }
+ else
+ {
+ return stime.substring(0, 12) + "GMT+00:00";
+ }
+ }
+ else
+ {
+ int index = stime.indexOf('-');
+ if (index < 0)
+ {
+ index = stime.indexOf('+');
+ }
+ String d = stime;
+
+ if (index == stime.length() - 3)
+ {
+ d += "00";
+ }
+
+ if (index == 10)
+ {
+ return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15);
+ }
+ else
+ {
+ return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" + d.substring(15, 17);
+ }
+ }
+ }
+
+ /**
+ * Return a time string as an adjusted date with a 4 digit year. This goes
+ * in the range of 1950 - 2049.
+ */
+ public String getAdjustedTime()
+ {
+ String d = this.getTime();
+
+ if (d.charAt(0) < '5')
+ {
+ return "20" + d;
+ }
+ else
+ {
+ return "19" + d;
+ }
+ }
+
+ private boolean isDigit(int pos)
+ {
+ return time.length > pos && time[pos] >= '0' && time[pos] <= '9';
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ int length = time.length;
+
+ return 1 + StreamUtil.calculateBodyLength(length) + length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.UTC_TIME, time);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof ASN1UTCTime))
+ {
+ return false;
+ }
+
+ return Arrays.areEqual(time, ((ASN1UTCTime)o).time);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(time);
+ }
+
+ public String toString()
+ {
+ return Strings.fromByteArray(time);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecific.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecific.java
new file mode 100644
index 00000000..cb5023a7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecific.java
@@ -0,0 +1,112 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * An indefinite-length encoding version of an ASN.1 ApplicationSpecific object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BERApplicationSpecific
+ extends ASN1ApplicationSpecific
+{
+ BERApplicationSpecific(
+ boolean isConstructed,
+ int tag,
+ byte[] octets)
+ {
+ super(isConstructed, tag, octets);
+ }
+
+ /**
+ * Create an application specific object with a tagging of explicit/constructed.
+ *
+ * @param tag the tag number for this object.
+ * @param object the object to be contained.
+ */
+ public BERApplicationSpecific(
+ int tag,
+ ASN1Encodable object)
+ throws IOException
+ {
+ this(true, tag, object);
+ }
+
+ /**
+ * Create an application specific object with the tagging style given by the value of constructed.
+ *
+ * @param constructed true if the object is constructed.
+ * @param tag the tag number for this object.
+ * @param object the object to be contained.
+ */
+ public BERApplicationSpecific(
+ boolean constructed,
+ int tag,
+ ASN1Encodable object)
+ throws IOException
+ {
+ super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
+ }
+
+ private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
+ throws IOException
+ {
+ byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.BER);
+
+ if (explicit)
+ {
+ return data;
+ }
+ else
+ {
+ int lenBytes = getLengthOfHeader(data);
+ byte[] tmp = new byte[data.length - lenBytes];
+ System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
+ return tmp;
+ }
+ }
+
+ /**
+ * Create an application specific object which is marked as constructed
+ *
+ * @param tagNo the tag number for this object.
+ * @param vec the objects making up the application specific object.
+ */
+ public BERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
+ {
+ super(true, tagNo, getEncodedVector(vec));
+ }
+
+ private static byte[] getEncodedVector(ASN1EncodableVector vec)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ for (int i = 0; i != vec.size(); i++)
+ {
+ try
+ {
+ bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.BER));
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("malformed object: " + e, e);
+ }
+ }
+ return bOut.toByteArray();
+ }
+
+ /* (non-Javadoc)
+ * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
+ */
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ int flags = BERTags.APPLICATION;
+ if (isConstructed)
+ {
+ flags |= BERTags.CONSTRUCTED;
+ }
+
+ out.writeEncodedIndef(withTag, flags, tag, octets);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecificParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecificParser.java
new file mode 100644
index 00000000..a1617b43
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecificParser.java
@@ -0,0 +1,61 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * A parser for indefinite-length ASN.1 ApplicationSpecific objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BERApplicationSpecificParser
+ implements ASN1ApplicationSpecificParser
+{
+ private final int tag;
+ private final ASN1StreamParser parser;
+
+ BERApplicationSpecificParser(int tag, ASN1StreamParser parser)
+ {
+ this.tag = tag;
+ this.parser = parser;
+ }
+
+ /**
+ * Return the object contained in this application specific object,
+ * @return the contained object.
+ * @throws IOException if the underlying stream cannot be read, or does not contain an ASN.1 encoding.
+ */
+ public ASN1Encodable readObject()
+ throws IOException
+ {
+ return parser.readObject();
+ }
+
+ /**
+ * Return an in-memory, encodable, representation of the application specific object.
+ *
+ * @return a BERApplicationSpecific.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return new BERApplicationSpecific(tag, parser.readVector());
+ }
+
+ /**
+ * Return a BERApplicationSpecific representing this parser and its contents.
+ *
+ * @return a BERApplicationSpecific
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException(e.getMessage(), e);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERConstructedOctetString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERConstructedOctetString.java
new file mode 100644
index 00000000..6a67881d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERConstructedOctetString.java
@@ -0,0 +1,146 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * @deprecated use BEROctetString
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BERConstructedOctetString
+ extends BEROctetString
+{
+ private static final int MAX_LENGTH = 1000;
+
+ /**
+ * convert a vector of octet strings into a single byte string
+ */
+ static private byte[] toBytes(
+ Vector octs)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ for (int i = 0; i != octs.size(); i++)
+ {
+ try
+ {
+ DEROctetString o = (DEROctetString)octs.elementAt(i);
+
+ bOut.write(o.getOctets());
+ }
+ catch (ClassCastException e)
+ {
+ throw new IllegalArgumentException(octs.elementAt(i).getClass().getName() + " found in input should only contain DEROctetString");
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("exception converting octets " + e.toString());
+ }
+ }
+
+ return bOut.toByteArray();
+ }
+
+ private Vector octs;
+
+ /**
+ * @param string the octets making up the octet string.
+ */
+ public BERConstructedOctetString(
+ byte[] string)
+ {
+ super(string);
+ }
+
+ public BERConstructedOctetString(
+ Vector octs)
+ {
+ super(toBytes(octs));
+
+ this.octs = octs;
+ }
+
+ public BERConstructedOctetString(
+ ASN1Primitive obj)
+ {
+ super(toByteArray(obj));
+ }
+
+ private static byte[] toByteArray(ASN1Primitive obj)
+ {
+ try
+ {
+ return obj.getEncoded();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("Unable to encode object");
+ }
+ }
+
+ public BERConstructedOctetString(
+ ASN1Encodable obj)
+ {
+ this(obj.toASN1Primitive());
+ }
+
+ public byte[] getOctets()
+ {
+ return string;
+ }
+
+ /**
+ * return the DER octets that make up this string.
+ */
+ public Enumeration getObjects()
+ {
+ if (octs == null)
+ {
+ return generateOcts().elements();
+ }
+
+ return octs.elements();
+ }
+
+ private Vector generateOcts()
+ {
+ Vector vec = new Vector();
+ for (int i = 0; i < string.length; i += MAX_LENGTH)
+ {
+ int end;
+
+ if (i + MAX_LENGTH > string.length)
+ {
+ end = string.length;
+ }
+ else
+ {
+ end = i + MAX_LENGTH;
+ }
+
+ byte[] nStr = new byte[end - i];
+
+ System.arraycopy(string, i, nStr, 0, nStr.length);
+
+ vec.addElement(new DEROctetString(nStr));
+ }
+
+ return vec;
+ }
+
+ public static BEROctetString fromSequence(ASN1Sequence seq)
+ {
+ Vector v = new Vector();
+ Enumeration e = seq.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ v.addElement(e.nextElement());
+ }
+
+ return new BERConstructedOctetString(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERFactory.java
new file mode 100644
index 00000000..5cc2da0c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERFactory.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+class BERFactory
+{
+ static final BERSequence EMPTY_SEQUENCE = new BERSequence();
+ static final BERSet EMPTY_SET = new BERSet();
+
+ static BERSequence createSequence(ASN1EncodableVector v)
+ {
+ if (v.size() < 1)
+ {
+ return EMPTY_SEQUENCE;
+ }
+
+ return new BERSequence(v);
+ }
+
+ static BERSet createSet(ASN1EncodableVector v)
+ {
+ if (v.size() < 1)
+ {
+ return EMPTY_SET;
+ }
+
+ return new BERSet(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERGenerator.java
new file mode 100644
index 00000000..fa9f0df7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERGenerator.java
@@ -0,0 +1,84 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Base class for generators for indefinite-length structures.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BERGenerator
+ extends ASN1Generator
+{
+ private boolean _tagged = false;
+ private boolean _isExplicit;
+ private int _tagNo;
+
+ protected BERGenerator(OutputStream out)
+ {
+ super(out);
+ }
+
+ protected BERGenerator(OutputStream out, int tagNo, boolean isExplicit)
+ {
+ super(out);
+
+ // TODO Check proper handling of implicit tagging
+ _tagged = true;
+ _isExplicit = isExplicit;
+ _tagNo = tagNo;
+ }
+
+ public OutputStream getRawOutputStream()
+ {
+ return _out;
+ }
+
+ private void writeHdr(int tag) throws IOException
+ {
+ _out.write(tag);
+ _out.write(0x80);
+ }
+
+ protected void writeBERHeader(int tag) throws IOException
+ {
+ if (_tagged)
+ {
+ int tagNum = _tagNo | BERTags.TAGGED;
+
+ if (_isExplicit)
+ {
+ writeHdr(tagNum | BERTags.CONSTRUCTED);
+ writeHdr(tag);
+ }
+ else
+ {
+ if ((tag & BERTags.CONSTRUCTED) != 0)
+ {
+ writeHdr(tagNum | BERTags.CONSTRUCTED);
+ }
+ else
+ {
+ writeHdr(tagNum);
+ }
+ }
+ }
+ else
+ {
+ writeHdr(tag);
+ }
+ }
+
+ protected void writeBEREnd() throws IOException
+ {
+ _out.write(0x00);
+ _out.write(0x00);
+
+ if (_tagged && _isExplicit) // write extra end for tag header
+ {
+ _out.write(0x00);
+ _out.write(0x00);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetString.java
new file mode 100644
index 00000000..8710d814
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetString.java
@@ -0,0 +1,195 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+/**
+ * ASN.1 OctetStrings, with indefinite length rules, and <i>constructed form</i> support.
+ * <p>
+ * The Basic Encoding Rules (BER) format allows encoding using so called "<i>constructed form</i>",
+ * which DER and CER formats forbid allowing only "primitive form".
+ * </p><p>
+ * This class <b>always</b> produces the constructed form with underlying segments
+ * in an indefinite length array. If the input wasn't the same, then this output
+ * is not faithful reproduction.
+ * </p>
+ * <p>
+ * See {@link ASN1OctetString} for X.690 encoding rules of OCTET-STRING objects.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BEROctetString
+ extends ASN1OctetString
+{
+ private static final int DEFAULT_CHUNK_SIZE = 1000;
+
+ private final int chunkSize;
+ private final ASN1OctetString[] octs;
+
+ /**
+ * Convert a vector of octet strings into a single byte string
+ */
+ static private byte[] toBytes(
+ ASN1OctetString[] octs)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ for (int i = 0; i != octs.length; i++)
+ {
+ try
+ {
+ bOut.write(octs[i].getOctets());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("exception converting octets " + e.toString());
+ }
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * Create an OCTET-STRING object from a byte[]
+ * @param string the octets making up the octet string.
+ */
+ public BEROctetString(
+ byte[] string)
+ {
+ this(string, DEFAULT_CHUNK_SIZE);
+ }
+
+ /**
+ * Multiple {@link ASN1OctetString} data blocks are input,
+ * the result is <i>constructed form</i>.
+ *
+ * @param octs an array of OCTET STRING to construct the BER OCTET STRING from.
+ */
+ public BEROctetString(
+ ASN1OctetString[] octs)
+ {
+ this(octs, DEFAULT_CHUNK_SIZE);
+ }
+
+ /**
+ * Create an OCTET-STRING object from a byte[]
+ * @param string the octets making up the octet string.
+ * @param chunkSize the number of octets stored in each DER encoded component OCTET STRING.
+ */
+ public BEROctetString(
+ byte[] string,
+ int chunkSize)
+ {
+ this(string, null, chunkSize);
+ }
+
+ /**
+ * Multiple {@link ASN1OctetString} data blocks are input,
+ * the result is <i>constructed form</i>.
+ *
+ * @param octs an array of OCTET STRING to construct the BER OCTET STRING from.
+ * @param chunkSize the number of octets stored in each DER encoded component OCTET STRING.
+ */
+ public BEROctetString(
+ ASN1OctetString[] octs,
+ int chunkSize)
+ {
+ this(toBytes(octs), octs, chunkSize);
+ }
+
+ private BEROctetString(byte[] string, ASN1OctetString[] octs, int chunkSize)
+ {
+ super(string);
+ this.octs = octs;
+ this.chunkSize = chunkSize;
+ }
+
+ /**
+ * Return the OCTET STRINGs that make up this string.
+ *
+ * @return an Enumeration of the component OCTET STRINGs.
+ */
+ public Enumeration getObjects()
+ {
+ if (octs == null)
+ {
+ return new Enumeration()
+ {
+ int pos = 0;
+
+ public boolean hasMoreElements()
+ {
+ return pos < string.length;
+ }
+
+ public Object nextElement()
+ {
+ if (pos < string.length)
+ {
+ int length = Math.min(string.length - pos, chunkSize);
+ byte[] chunk = new byte[length];
+ System.arraycopy(string, pos, chunk, 0, length);
+ pos += length;
+ return new DEROctetString(chunk);
+ }
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
+ return new Enumeration()
+ {
+ int counter = 0;
+
+ public boolean hasMoreElements()
+ {
+ return counter < octs.length;
+ }
+
+ public Object nextElement()
+ {
+ if (counter < octs.length)
+ {
+ return octs[counter++];
+ }
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
+ boolean isConstructed()
+ {
+ return true;
+ }
+
+ int encodedLength()
+ throws IOException
+ {
+ int length = 0;
+ for (Enumeration e = getObjects(); e.hasMoreElements();)
+ {
+ length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
+ }
+
+ return 2 + length + 2;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodedIndef(withTag, BERTags.CONSTRUCTED | BERTags.OCTET_STRING, getObjects());
+ }
+
+ static BEROctetString fromSequence(ASN1Sequence seq)
+ {
+ int count = seq.size();
+ ASN1OctetString[] v = new ASN1OctetString[count];
+ for (int i = 0; i < count; ++i)
+ {
+ v[i] = ASN1OctetString.getInstance(seq.getObjectAt(i));
+ }
+ return new BEROctetString(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringGenerator.java
new file mode 100644
index 00000000..877563d1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringGenerator.java
@@ -0,0 +1,133 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * A generator for indefinite-length OCTET STRINGs
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BEROctetStringGenerator
+ extends BERGenerator
+{
+ /**
+ * Use the passed in stream as the target for the generator, writing out the header tag
+ * for a constructed OCTET STRING.
+ *
+ * @param out target stream
+ * @throws IOException if the target stream cannot be written to.
+ */
+ public BEROctetStringGenerator(OutputStream out)
+ throws IOException
+ {
+ super(out);
+
+ writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
+ }
+
+ /**
+ * Use the passed in stream as the target for the generator, writing out the header tag
+ * for a tagged constructed OCTET STRING (possibly implicit).
+ *
+ * @param out target stream
+ * @param tagNo the tag number to introduce
+ * @param isExplicit true if this is an explicitly tagged object, false otherwise.
+ * @throws IOException if the target stream cannot be written to.
+ */
+ public BEROctetStringGenerator(
+ OutputStream out,
+ int tagNo,
+ boolean isExplicit)
+ throws IOException
+ {
+ super(out, tagNo, isExplicit);
+
+ writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
+ }
+
+ /**
+ * Return a stream representing the content target for this OCTET STRING
+ *
+ * @return an OutputStream which chunks data in blocks of 1000 (CER limit).
+ */
+ public OutputStream getOctetOutputStream()
+ {
+ return getOctetOutputStream(new byte[1000]); // limit for CER encoding.
+ }
+
+ /**
+ * Return a stream representing the content target for this OCTET STRING
+ *
+ * @param buf the buffer to use for chunking the data.
+ * @return an OutputStream which chunks data in blocks of buf length.
+ */
+ public OutputStream getOctetOutputStream(
+ byte[] buf)
+ {
+ return new BufferedBEROctetStream(buf);
+ }
+
+ private class BufferedBEROctetStream
+ extends OutputStream
+ {
+ private byte[] _buf;
+ private int _off;
+ private DEROutputStream _derOut;
+
+ BufferedBEROctetStream(
+ byte[] buf)
+ {
+ _buf = buf;
+ _off = 0;
+ _derOut = new DEROutputStream(_out);
+ }
+
+ public void write(
+ int b)
+ throws IOException
+ {
+ _buf[_off++] = (byte)b;
+
+ if (_off == _buf.length)
+ {
+ DEROctetString.encode(_derOut, true, _buf, 0, _buf.length);
+ _off = 0;
+ }
+ }
+
+ public void write(byte[] b, int off, int len) throws IOException
+ {
+ while (len > 0)
+ {
+ int numToCopy = Math.min(len, _buf.length - _off);
+ System.arraycopy(b, off, _buf, _off, numToCopy);
+
+ _off += numToCopy;
+ if (_off < _buf.length)
+ {
+ break;
+ }
+
+ DEROctetString.encode(_derOut, true, _buf, 0, _buf.length);
+ _off = 0;
+
+ off += numToCopy;
+ len -= numToCopy;
+ }
+ }
+
+ public void close()
+ throws IOException
+ {
+ if (_off != 0)
+ {
+ DEROctetString.encode(_derOut, true, _buf, 0, _off);
+ }
+
+ _derOut.flushInternal();
+
+ writeBEREnd();
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringParser.java
new file mode 100644
index 00000000..64ce07d5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringParser.java
@@ -0,0 +1,62 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.android.internal.org.bouncycastle.util.io.Streams;
+
+/**
+ * A parser for indefinite-length OCTET STRINGs.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BEROctetStringParser
+ implements ASN1OctetStringParser
+{
+ private ASN1StreamParser _parser;
+
+ BEROctetStringParser(
+ ASN1StreamParser parser)
+ {
+ _parser = parser;
+ }
+
+ /**
+ * Return an InputStream representing the contents of the OCTET STRING.
+ *
+ * @return an InputStream with its source as the OCTET STRING content.
+ */
+ public InputStream getOctetStream()
+ {
+ return new ConstructedOctetStream(_parser);
+ }
+
+ /**
+ * Return an in-memory, encodable, representation of the OCTET STRING.
+ *
+ * @return a BEROctetString.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return new BEROctetString(Streams.readAll(getOctetStream()));
+ }
+
+ /**
+ * Return an BEROctetString representing this parser and its contents.
+ *
+ * @return an BEROctetString
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROutputStream.java
new file mode 100644
index 00000000..eee12a12
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROutputStream.java
@@ -0,0 +1,23 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.OutputStream;
+
+/**
+ * A class which writes indefinite and definite length objects. Objects which specify DER will be
+ * encoded accordingly, but DL or BER objects will be encoded as defined.
+ */
+class BEROutputStream
+ extends ASN1OutputStream
+{
+ /**
+ * Base constructor.
+ *
+ * @param os
+ * target output stream.
+ */
+ BEROutputStream(OutputStream os)
+ {
+ super(os);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequence.java
new file mode 100644
index 00000000..e3770e48
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequence.java
@@ -0,0 +1,67 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Indefinite length SEQUENCE of objects.
+ * <p>
+ * Length field has value 0x80, and the sequence ends with two bytes of: 0x00, 0x00.
+ * </p><p>
+ * For X.690 syntax rules, see {@link ASN1Sequence}.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BERSequence
+ extends ASN1Sequence
+{
+ /**
+ * Create an empty sequence
+ */
+ public BERSequence()
+ {
+ }
+
+ /**
+ * Create a sequence containing one object
+ */
+ public BERSequence(ASN1Encodable element)
+ {
+ super(element);
+ }
+
+ /**
+ * Create a sequence containing a vector of objects.
+ */
+ public BERSequence(ASN1EncodableVector elementVector)
+ {
+ super(elementVector);
+ }
+
+ /**
+ * Create a sequence containing an array of objects.
+ */
+ public BERSequence(ASN1Encodable[] elements)
+ {
+ super(elements);
+ }
+
+ int encodedLength() throws IOException
+ {
+ int count = elements.length;
+ int totalLength = 0;
+
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive p = elements[i].toASN1Primitive();
+ totalLength += p.encodedLength();
+ }
+
+ return 2 + totalLength + 2;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodedIndef(withTag, BERTags.SEQUENCE | BERTags.CONSTRUCTED, elements);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequenceParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequenceParser.java
new file mode 100644
index 00000000..d2ce184c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequenceParser.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Parser for indefinite-length SEQUENCEs.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BERSequenceParser
+ implements ASN1SequenceParser
+{
+ private ASN1StreamParser _parser;
+
+ BERSequenceParser(ASN1StreamParser parser)
+ {
+ this._parser = parser;
+ }
+
+ /**
+ * Read the next object in the SEQUENCE.
+ *
+ * @return the next object in the SEQUENCE, null if there are no more.
+ * @throws IOException if there is an issue reading the underlying stream.
+ */
+ public ASN1Encodable readObject()
+ throws IOException
+ {
+ return _parser.readObject();
+ }
+
+ /**
+ * Return an in-memory, encodable, representation of the SEQUENCE.
+ *
+ * @return a BERSequence.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return new BERSequence(_parser.readVector());
+ }
+
+ /**
+ * Return an BERSequence representing this parser and its contents.
+ *
+ * @return an BERSequence
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException(e.getMessage());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSet.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSet.java
new file mode 100644
index 00000000..fbc6fd13
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSet.java
@@ -0,0 +1,82 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Indefinite length <code>SET</code> and <code>SET OF</code> constructs.
+ * <p>
+ * Note: This does not know which syntax the set is!
+ * </p><p>
+ * Length field has value 0x80, and the set ends with two bytes of: 0x00, 0x00.
+ * </p><p>
+ * For X.690 syntax rules, see {@link ASN1Set}.
+ * </p><p>
+ * In brief: Constructing this form does not sort the supplied elements,
+ * nor does the sorting happen before serialization. This is different
+ * from the way {@link DERSet} does things.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BERSet
+ extends ASN1Set
+{
+ /**
+ * Create an empty SET.
+ */
+ public BERSet()
+ {
+ }
+
+ /**
+ * Create a SET containing one object.
+ *
+ * @param element - a single object that makes up the set.
+ */
+ public BERSet(ASN1Encodable element)
+ {
+ super(element);
+ }
+
+ /**
+ * Create a SET containing multiple objects.
+ * @param elementVector a vector of objects making up the set.
+ */
+ public BERSet(ASN1EncodableVector elementVector)
+ {
+ super(elementVector, false);
+ }
+
+ /**
+ * Create a SET from an array of objects.
+ * @param elements an array of ASN.1 objects.
+ */
+ public BERSet(ASN1Encodable[] elements)
+ {
+ super(elements, false);
+ }
+
+ BERSet(boolean isSorted, ASN1Encodable[] elements)
+ {
+ super(isSorted, elements);
+ }
+
+ int encodedLength() throws IOException
+ {
+ int count = elements.length;
+ int totalLength = 0;
+
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive p = elements[i].toASN1Primitive();
+ totalLength += p.encodedLength();
+ }
+
+ return 2 + totalLength + 2;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncodedIndef(withTag, BERTags.SET | BERTags.CONSTRUCTED, elements);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSetParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSetParser.java
new file mode 100644
index 00000000..e66b756a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSetParser.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Parser for indefinite-length SETs.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BERSetParser
+ implements ASN1SetParser
+{
+ private ASN1StreamParser _parser;
+
+ BERSetParser(ASN1StreamParser parser)
+ {
+ this._parser = parser;
+ }
+
+ /**
+ * Read the next object in the SET.
+ *
+ * @return the next object in the SET, null if there are no more.
+ * @throws IOException if there is an issue reading the underlying stream.
+ */
+ public ASN1Encodable readObject()
+ throws IOException
+ {
+ return _parser.readObject();
+ }
+
+ /**
+ * Return an in-memory, encodable, representation of the SET.
+ *
+ * @return a BERSet.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return new BERSet(_parser.readVector());
+ }
+
+ /**
+ * Return an BERSet representing this parser and its contents.
+ *
+ * @return an BERSet
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException(e.getMessage(), e);
+ }
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObject.java
new file mode 100644
index 00000000..3c301b7e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObject.java
@@ -0,0 +1,140 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+/**
+ * BER TaggedObject - in ASN.1 notation this is any object preceded by
+ * a [n] where n is some number - these are assumed to follow the construction
+ * rules (as with sequences).
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BERTaggedObject
+ extends ASN1TaggedObject
+{
+ /**
+ * @param tagNo the tag number for this object.
+ * @param obj the tagged object.
+ */
+ public BERTaggedObject(
+ int tagNo,
+ ASN1Encodable obj)
+ {
+ super(true, tagNo, obj);
+ }
+
+ /**
+ * @param explicit true if an explicitly tagged object.
+ * @param tagNo the tag number for this object.
+ * @param obj the tagged object.
+ */
+ public BERTaggedObject(
+ boolean explicit,
+ int tagNo,
+ ASN1Encodable obj)
+ {
+ super(explicit, tagNo, obj);
+ }
+
+ /**
+ * create an implicitly tagged object that contains a zero
+ * length sequence.
+ */
+ public BERTaggedObject(
+ int tagNo)
+ {
+ super(false, tagNo, new BERSequence());
+ }
+
+ boolean isConstructed()
+ {
+ return explicit || obj.toASN1Primitive().isConstructed();
+ }
+
+ int encodedLength()
+ throws IOException
+ {
+ ASN1Primitive primitive = obj.toASN1Primitive();
+ int length = primitive.encodedLength();
+
+ if (explicit)
+ {
+ return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
+ }
+ else
+ {
+ // header length already in calculation
+ length = length - 1;
+
+ return StreamUtil.calculateTagLength(tagNo) + length;
+ }
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeTag(withTag, BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
+ out.write(0x80);
+
+ if (!explicit)
+ {
+ Enumeration e;
+ if (obj instanceof ASN1OctetString)
+ {
+ if (obj instanceof BEROctetString)
+ {
+ e = ((BEROctetString)obj).getObjects();
+ }
+ else
+ {
+ ASN1OctetString octs = (ASN1OctetString)obj;
+ BEROctetString berO = new BEROctetString(octs.getOctets());
+ e = berO.getObjects();
+ }
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ e = ((ASN1Sequence)obj).getObjects();
+ }
+ else if (obj instanceof ASN1Set)
+ {
+ e = ((ASN1Set)obj).getObjects();
+ }
+ else
+ {
+ throw new ASN1Exception("not implemented: " + obj.getClass().getName());
+ }
+
+ out.writeElements(e);
+ }
+ else
+ {
+ out.writePrimitive(obj.toASN1Primitive(), true);
+ }
+
+ out.write(0x00);
+ out.write(0x00);
+
+// ASN1Primitive primitive = obj.toASN1Primitive();
+//
+// int flags = BERTags.TAGGED;
+// if (explicit || primitive.isConstructed())
+// {
+// flags |= BERTags.CONSTRUCTED;
+// }
+//
+// out.writeTag(withTag, flags, tagNo);
+//
+// if (explicit)
+// {
+// out.write(0x80);
+// out.writePrimitive(obj.toASN1Primitive(), true);
+// out.write(0x00);
+// out.write(0x00);
+// }
+// else
+// {
+// out.writePrimitive(obj.toASN1Primitive(), false);
+// }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObjectParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObjectParser.java
new file mode 100644
index 00000000..0b8ddfd3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObjectParser.java
@@ -0,0 +1,100 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Parser for indefinite-length tagged objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BERTaggedObjectParser
+ implements ASN1TaggedObjectParser
+{
+ private boolean _constructed;
+ private int _tagNumber;
+ private ASN1StreamParser _parser;
+
+ BERTaggedObjectParser(
+ boolean constructed,
+ int tagNumber,
+ ASN1StreamParser parser)
+ {
+ _constructed = constructed;
+ _tagNumber = tagNumber;
+ _parser = parser;
+ }
+
+ /**
+ * Return true if this tagged object is marked as constructed.
+ *
+ * @return true if constructed, false otherwise.
+ */
+ public boolean isConstructed()
+ {
+ return _constructed;
+ }
+
+ /**
+ * Return the tag number associated with this object.
+ *
+ * @return the tag number.
+ */
+ public int getTagNo()
+ {
+ return _tagNumber;
+ }
+
+ /**
+ * Return an object parser for the contents of this tagged object.
+ *
+ * @param tag the actual tag number of the object (needed if implicit).
+ * @param isExplicit true if the contained object was explicitly tagged, false if implicit.
+ * @return an ASN.1 encodable object parser.
+ * @throws IOException if there is an issue building the object parser from the stream.
+ */
+ public ASN1Encodable getObjectParser(
+ int tag,
+ boolean isExplicit)
+ throws IOException
+ {
+ if (isExplicit)
+ {
+ if (!_constructed)
+ {
+ throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
+ }
+ return _parser.readObject();
+ }
+
+ return _parser.readImplicit(_constructed, tag);
+ }
+
+ /**
+ * Return an in-memory, encodable, representation of the tagged object.
+ *
+ * @return an ASN1TaggedObject.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return _parser.readTaggedObject(_constructed, _tagNumber);
+ }
+
+ /**
+ * Return an ASN1TaggedObject representing this parser and its contents.
+ *
+ * @return an ASN1TaggedObject
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return this.getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException(e.getMessage());
+ }
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTags.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTags.java
new file mode 100644
index 00000000..87649f6d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTags.java
@@ -0,0 +1,40 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface BERTags
+{
+ public static final int BOOLEAN = 0x01;
+ public static final int INTEGER = 0x02;
+ public static final int BIT_STRING = 0x03;
+ public static final int OCTET_STRING = 0x04;
+ public static final int NULL = 0x05;
+ public static final int OBJECT_IDENTIFIER = 0x06;
+ public static final int EXTERNAL = 0x08;
+ public static final int ENUMERATED = 0x0a; // decimal 10
+ public static final int SEQUENCE = 0x10; // decimal 16
+ public static final int SEQUENCE_OF = 0x10; // for completeness - used to model a SEQUENCE of the same type.
+ public static final int SET = 0x11; // decimal 17
+ public static final int SET_OF = 0x11; // for completeness - used to model a SET of the same type.
+
+
+ public static final int NUMERIC_STRING = 0x12; // decimal 18
+ public static final int PRINTABLE_STRING = 0x13; // decimal 19
+ public static final int T61_STRING = 0x14; // decimal 20
+ public static final int VIDEOTEX_STRING = 0x15; // decimal 21
+ public static final int IA5_STRING = 0x16; // decimal 22
+ public static final int UTC_TIME = 0x17; // decimal 23
+ public static final int GENERALIZED_TIME = 0x18; // decimal 24
+ public static final int GRAPHIC_STRING = 0x19; // decimal 25
+ public static final int VISIBLE_STRING = 0x1a; // decimal 26
+ public static final int GENERAL_STRING = 0x1b; // decimal 27
+ public static final int UNIVERSAL_STRING = 0x1c; // decimal 28
+ public static final int BMP_STRING = 0x1e; // decimal 30
+ public static final int UTF8_STRING = 0x0c; // decimal 12
+
+ public static final int CONSTRUCTED = 0x20; // decimal 32
+ public static final int APPLICATION = 0x40; // decimal 64
+ public static final int TAGGED = 0x80; // decimal 128
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ConstructedOctetStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ConstructedOctetStream.java
new file mode 100644
index 00000000..bde1f86f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ConstructedOctetStream.java
@@ -0,0 +1,124 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class ConstructedOctetStream
+ extends InputStream
+{
+ private final ASN1StreamParser _parser;
+
+ private boolean _first = true;
+ private InputStream _currentStream;
+
+ ConstructedOctetStream(
+ ASN1StreamParser parser)
+ {
+ _parser = parser;
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException
+ {
+ if (_currentStream == null)
+ {
+ if (!_first)
+ {
+ return -1;
+ }
+
+ ASN1OctetStringParser next = getNextParser();
+ if (next == null)
+ {
+ return -1;
+ }
+
+ _first = false;
+ _currentStream = next.getOctetStream();
+ }
+
+ int totalRead = 0;
+
+ for (;;)
+ {
+ int numRead = _currentStream.read(b, off + totalRead, len - totalRead);
+
+ if (numRead >= 0)
+ {
+ totalRead += numRead;
+
+ if (totalRead == len)
+ {
+ return totalRead;
+ }
+ }
+ else
+ {
+ ASN1OctetStringParser next = getNextParser();
+ if (next == null)
+ {
+ _currentStream = null;
+ return totalRead < 1 ? -1 : totalRead;
+ }
+
+ _currentStream = next.getOctetStream();
+ }
+ }
+ }
+
+ public int read()
+ throws IOException
+ {
+ if (_currentStream == null)
+ {
+ if (!_first)
+ {
+ return -1;
+ }
+
+ ASN1OctetStringParser next = getNextParser();
+ if (next == null)
+ {
+ return -1;
+ }
+
+ _first = false;
+ _currentStream = next.getOctetStream();
+ }
+
+ for (;;)
+ {
+ int b = _currentStream.read();
+
+ if (b >= 0)
+ {
+ return b;
+ }
+
+ ASN1OctetStringParser next = getNextParser();
+ if (next == null)
+ {
+ _currentStream = null;
+ return -1;
+ }
+
+ _currentStream = next.getOctetStream();
+ }
+ }
+
+ private ASN1OctetStringParser getNextParser() throws IOException
+ {
+ ASN1Encodable asn1Obj = _parser.readObject();
+ if (asn1Obj == null)
+ {
+ return null;
+ }
+
+ if (asn1Obj instanceof ASN1OctetStringParser)
+ {
+ return (ASN1OctetStringParser)asn1Obj;
+ }
+
+ throw new IOException("unknown object encountered: " + asn1Obj.getClass());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERApplicationSpecific.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERApplicationSpecific.java
new file mode 100644
index 00000000..f3e45898
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERApplicationSpecific.java
@@ -0,0 +1,126 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * A DER encoding version of an application specific object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERApplicationSpecific
+ extends ASN1ApplicationSpecific
+{
+ DERApplicationSpecific(
+ boolean isConstructed,
+ int tag,
+ byte[] octets)
+ {
+ super(isConstructed, tag, octets);
+ }
+
+ /**
+ * Create an application specific object from the passed in data. This will assume
+ * the data does not represent a constructed object.
+ *
+ * @param tag the tag number for this object.
+ * @param octets the encoding of the object's body.
+ */
+ public DERApplicationSpecific(
+ int tag,
+ byte[] octets)
+ {
+ this(false, tag, octets);
+ }
+
+ /**
+ * Create an application specific object with a tagging of explicit/constructed.
+ *
+ * @param tag the tag number for this object.
+ * @param object the object to be contained.
+ */
+ public DERApplicationSpecific(
+ int tag,
+ ASN1Encodable object)
+ throws IOException
+ {
+ this(true, tag, object);
+ }
+
+ /**
+ * Create an application specific object with the tagging style given by the value of constructed.
+ *
+ * @param constructed true if the object is constructed.
+ * @param tag the tag number for this object.
+ * @param object the object to be contained.
+ */
+ public DERApplicationSpecific(
+ boolean constructed,
+ int tag,
+ ASN1Encodable object)
+ throws IOException
+ {
+ super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
+ }
+
+ private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
+ throws IOException
+ {
+ byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.DER);
+
+ if (explicit)
+ {
+ return data;
+ }
+ else
+ {
+ int lenBytes = getLengthOfHeader(data);
+ byte[] tmp = new byte[data.length - lenBytes];
+ System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
+ return tmp;
+ }
+ }
+
+ /**
+ * Create an application specific object which is marked as constructed
+ *
+ * @param tagNo the tag number for this object.
+ * @param vec the objects making up the application specific object.
+ */
+ public DERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
+ {
+ super(true, tagNo, getEncodedVector(vec));
+ }
+
+ private static byte[] getEncodedVector(ASN1EncodableVector vec)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ for (int i = 0; i != vec.size(); i++)
+ {
+ try
+ {
+ bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.DER));
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("malformed object: " + e, e);
+ }
+ }
+ return bOut.toByteArray();
+ }
+
+ /* (non-Javadoc)
+ * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
+ */
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ int flags = BERTags.APPLICATION;
+ if (isConstructed)
+ {
+ flags |= BERTags.CONSTRUCTED;
+ }
+
+ out.writeEncoded(withTag, flags, tag, octets);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBMPString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBMPString.java
new file mode 100644
index 00000000..9ffb1bec
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBMPString.java
@@ -0,0 +1,217 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * DER BMPString object encodes BMP (<i>Basic Multilingual Plane</i>) subset
+ * (aka UCS-2) of UNICODE (ISO 10646) characters in codepoints 0 to 65535.
+ * <p>
+ * At ISO-10646:2011 the term "BMP" has been withdrawn, and replaced by
+ * term "UCS-2".
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERBMPString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private final char[] string;
+
+ /**
+ * Return a BMP String from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a DERBMPString instance, or null.
+ */
+ public static DERBMPString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERBMPString)
+ {
+ return (DERBMPString)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERBMPString)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return a BMP String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return a DERBMPString instance.
+ */
+ public static DERBMPString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DERBMPString)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new DERBMPString(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ /**
+ * Basic constructor - byte encoded string.
+ * @param string the encoded BMP STRING to wrap.
+ */
+ DERBMPString(
+ byte[] string)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
+ int byteLen = string.length;
+ if (0 != (byteLen & 1))
+ {
+ throw new IllegalArgumentException("malformed BMPString encoding encountered");
+ }
+
+ int charLen = byteLen / 2;
+ char[] cs = new char[charLen];
+
+ for (int i = 0; i != charLen; i++)
+ {
+ cs[i] = (char)((string[2 * i] << 8) | (string[2 * i + 1] & 0xff));
+ }
+
+ this.string = cs;
+ }
+
+ DERBMPString(char[] string)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
+ this.string = string;
+ }
+
+ /**
+ * Basic constructor
+ * @param string a String to wrap as a BMP STRING.
+ */
+ public DERBMPString(
+ String string)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+
+ this.string = string.toCharArray();
+ }
+
+ public String getString()
+ {
+ return new String(string);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+
+ protected boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof DERBMPString))
+ {
+ return false;
+ }
+
+ DERBMPString s = (DERBMPString)o;
+
+ return Arrays.areEqual(string, s.string);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(string.length * 2) + (string.length * 2);
+ }
+
+ void encode(
+ ASN1OutputStream out, boolean withTag)
+ throws IOException
+ {
+ int count = string.length;
+ if (withTag)
+ {
+ out.write(BERTags.BMP_STRING);
+ }
+ out.writeLength(count * 2);
+
+ byte[] buf = new byte[8];
+
+ int i = 0, limit = count & -4;
+ while (i < limit)
+ {
+ char c0 = string[i], c1 = string[i + 1], c2 = string[i + 2], c3 = string[i + 3];
+ i += 4;
+
+ buf[0] = (byte)(c0 >> 8);
+ buf[1] = (byte)c0;
+ buf[2] = (byte)(c1 >> 8);
+ buf[3] = (byte)c1;
+ buf[4] = (byte)(c2 >> 8);
+ buf[5] = (byte)c2;
+ buf[6] = (byte)(c3 >> 8);
+ buf[7] = (byte)c3;
+
+ out.write(buf, 0, 8);
+ }
+ if (i < count)
+ {
+ int bufPos = 0;
+ do
+ {
+ char c0 = string[i];
+ i += 1;
+
+ buf[bufPos++] = (byte)(c0 >> 8);
+ buf[bufPos++] = (byte)c0;
+ }
+ while (i < count);
+
+ out.write(buf, 0, bufPos);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBitString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBitString.java
new file mode 100644
index 00000000..40d010ac
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBitString.java
@@ -0,0 +1,160 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * A BIT STRING with DER encoding - the first byte contains the count of padding bits included in the byte array's last byte.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERBitString
+ extends ASN1BitString
+{
+ /**
+ * return a Bit String from the passed in object
+ *
+ * @param obj a DERBitString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a DERBitString instance, or null.
+ */
+ public static DERBitString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERBitString)
+ {
+ return (DERBitString)obj;
+ }
+ if (obj instanceof DLBitString)
+ {
+ return new DERBitString(((DLBitString)obj).data, ((DLBitString)obj).padBits);
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERBitString)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a Bit String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return a DERBitString instance, or null.
+ */
+ public static DERBitString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DERBitString)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ protected DERBitString(byte data, int padBits)
+ {
+ super(data, padBits);
+ }
+
+ /**
+ * @param data the octets making up the bit string.
+ * @param padBits the number of extra bits at the end of the string.
+ */
+ public DERBitString(
+ byte[] data,
+ int padBits)
+ {
+ super(data, padBits);
+ }
+
+ public DERBitString(
+ byte[] data)
+ {
+ this(data, 0);
+ }
+
+ public DERBitString(
+ int value)
+ {
+ super(getBytes(value), getPadBits(value));
+ }
+
+ public DERBitString(
+ ASN1Encodable obj)
+ throws IOException
+ {
+ super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ int len = data.length;
+ if (0 == len
+ || 0 == padBits
+ || (data[len - 1] == (byte)(data[len - 1] & (0xFF << padBits))))
+ {
+ out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
+ }
+ else
+ {
+ byte der = (byte)(data[len - 1] & (0xFF << padBits));
+ out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data, 0, len - 1, der);
+ }
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
+ static DERBitString fromOctetString(byte[] bytes)
+ {
+ if (bytes.length < 1)
+ {
+ throw new IllegalArgumentException("truncated BIT STRING detected");
+ }
+
+ int padBits = bytes[0];
+ byte[] data = new byte[bytes.length - 1];
+
+ if (data.length != 0)
+ {
+ System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
+ }
+
+ return new DERBitString(data, padBits);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEREncodableVector.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEREncodableVector.java
new file mode 100644
index 00000000..2c53b69a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEREncodableVector.java
@@ -0,0 +1,20 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+/**
+ * a general class for building up a vector of DER encodable objects -
+ * this will eventually be superseded by ASN1EncodableVector so you should
+ * use that class in preference.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DEREncodableVector
+ extends ASN1EncodableVector
+{
+ /**
+ * @deprecated use ASN1EncodableVector instead.
+ */
+ public DEREncodableVector()
+ {
+
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEREnumerated.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEREnumerated.java
new file mode 100644
index 00000000..6069d1ed
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEREnumerated.java
@@ -0,0 +1,39 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.math.BigInteger;
+
+/**
+ * @deprecated Use ASN1Enumerated instead of this.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DEREnumerated
+ extends ASN1Enumerated
+{
+ /**
+ * @param bytes the value of this enumerated as an encoded BigInteger (signed).
+ * @deprecated use ASN1Enumerated
+ */
+ DEREnumerated(byte[] bytes)
+ {
+ super(bytes);
+ }
+
+ /**
+ * @param value the value of this enumerated.
+ * @deprecated use ASN1Enumerated
+ */
+ public DEREnumerated(BigInteger value)
+ {
+ super(value);
+ }
+
+ /**
+ * @param value the value of this enumerated.
+ * @deprecated use ASN1Enumerated
+ */
+ public DEREnumerated(int value)
+ {
+ super(value);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternal.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternal.java
new file mode 100644
index 00000000..da29a777
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternal.java
@@ -0,0 +1,97 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * Class representing the DER-type External
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERExternal
+ extends ASN1External
+{
+ /**
+ * Construct a DER EXTERNAL object, the input encoding vector must have exactly two elements on it.
+ * <p>
+ * Acceptable input formats are:
+ * <ul>
+ * <li> {@link ASN1ObjectIdentifier} + data {@link DERTaggedObject} (direct reference form)</li>
+ * <li> {@link ASN1Integer} + data {@link DERTaggedObject} (indirect reference form)</li>
+ * <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
+ * </ul>
+ *
+ * @throws IllegalArgumentException if input size is wrong, or
+ */
+ public DERExternal(ASN1EncodableVector vector)
+ {
+ super(vector);
+ }
+
+ /**
+ * Creates a new instance of DERExternal
+ * See X.690 for more informations about the meaning of these parameters
+ * @param directReference The direct reference or <code>null</code> if not set.
+ * @param indirectReference The indirect reference or <code>null</code> if not set.
+ * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
+ * @param externalData The external data in its encoded form.
+ */
+ public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
+ {
+ this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
+ }
+
+ /**
+ * Creates a new instance of DERExternal.
+ * See X.690 for more informations about the meaning of these parameters
+ * @param directReference The direct reference or <code>null</code> if not set.
+ * @param indirectReference The indirect reference or <code>null</code> if not set.
+ * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
+ * @param encoding The encoding to be used for the external data
+ * @param externalData The external data
+ */
+ public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
+ {
+ super(directReference, indirectReference, dataValueDescriptor, encoding, externalData);
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
+ int encodedLength()
+ throws IOException
+ {
+ return this.getEncoded().length;
+ }
+
+ /* (non-Javadoc)
+ * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
+ */
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ if (directReference != null)
+ {
+ baos.write(directReference.getEncoded(ASN1Encoding.DER));
+ }
+ if (indirectReference != null)
+ {
+ baos.write(indirectReference.getEncoded(ASN1Encoding.DER));
+ }
+ if (dataValueDescriptor != null)
+ {
+ baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DER));
+ }
+ DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent);
+ baos.write(obj.getEncoded(ASN1Encoding.DER));
+
+ out.writeEncoded(withTag, BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternalParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternalParser.java
new file mode 100644
index 00000000..c400ab40
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternalParser.java
@@ -0,0 +1,70 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Parser DER EXTERNAL tagged objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERExternalParser
+ implements ASN1Encodable, InMemoryRepresentable
+{
+ private ASN1StreamParser _parser;
+
+ /**
+ * Base constructor.
+ *
+ * @param parser the underlying parser to read the DER EXTERNAL from.
+ */
+ public DERExternalParser(ASN1StreamParser parser)
+ {
+ this._parser = parser;
+ }
+
+ public ASN1Encodable readObject()
+ throws IOException
+ {
+ return _parser.readObject();
+ }
+
+ /**
+ * Return an in-memory, encodable, representation of the EXTERNAL object.
+ *
+ * @return a DERExternal.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ try
+ {
+ return new DLExternal(_parser.readVector());
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ASN1Exception(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Return an DERExternal representing this parser and its contents.
+ *
+ * @return an DERExternal
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException ioe)
+ {
+ throw new ASN1ParsingException("unable to get DER object", ioe);
+ }
+ catch (IllegalArgumentException ioe)
+ {
+ throw new ASN1ParsingException("unable to get DER object", ioe);
+ }
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERFactory.java
new file mode 100644
index 00000000..e4dc5f62
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERFactory.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+class DERFactory
+{
+ static final ASN1Sequence EMPTY_SEQUENCE = new DERSequence();
+ static final ASN1Set EMPTY_SET = new DERSet();
+
+ static ASN1Sequence createSequence(ASN1EncodableVector v)
+ {
+ if (v.size() < 1)
+ {
+ return EMPTY_SEQUENCE;
+ }
+
+ return new DERSequence(v);
+ }
+
+ static ASN1Set createSet(ASN1EncodableVector v)
+ {
+ if (v.size() < 1)
+ {
+ return EMPTY_SET;
+ }
+
+ return new DERSet(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralString.java
new file mode 100644
index 00000000..660923d5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralString.java
@@ -0,0 +1,150 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * ASN.1 GENERAL-STRING data type.
+ * <p>
+ * This is an 8-bit encoded ISO 646 (ASCII) character set
+ * with optional escapes to other character sets.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERGeneralString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private final byte[] string;
+
+ /**
+ * Return a GeneralString from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a DERBMPString instance, or null.
+ */
+ public static DERGeneralString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERGeneralString)
+ {
+ return (DERGeneralString) obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERGeneralString)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: "
+ + obj.getClass().getName());
+ }
+
+ /**
+ * Return a GeneralString from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return a DERGeneralString instance.
+ */
+ public static DERGeneralString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DERGeneralString)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new DERGeneralString(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ DERGeneralString(byte[] string)
+ {
+ this.string = string;
+ }
+
+ /**
+ * Construct a GeneralString from the passed in String.
+ *
+ * @param string the string to be contained in this object.
+ */
+ public DERGeneralString(String string)
+ {
+ this.string = Strings.toByteArray(string);
+ }
+
+ /**
+ * Return a Java String representation of our contained String.
+ *
+ * @return a Java String representing our contents.
+ */
+ public String getString()
+ {
+ return Strings.fromByteArray(string);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ /**
+ * Return a byte array representation of our contained String.
+ *
+ * @return a byte array representing our contents.
+ */
+ public byte[] getOctets()
+ {
+ return Arrays.clone(string);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.GENERAL_STRING, string);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+
+ boolean asn1Equals(ASN1Primitive o)
+ {
+ if (!(o instanceof DERGeneralString))
+ {
+ return false;
+ }
+ DERGeneralString s = (DERGeneralString)o;
+
+ return Arrays.areEqual(string, s.string);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralizedTime.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralizedTime.java
new file mode 100644
index 00000000..448f169f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralizedTime.java
@@ -0,0 +1,126 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.util.Date;
+
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * DER Generalized time object.
+ * <h3>11: Restrictions on BER employed by both CER and DER</h3>
+ * <h4>11.7 GeneralizedTime </h4>
+ * <p>
+ * <b>11.7.1</b> The encoding shall terminate with a "Z",
+ * as described in the ITU-T Rec. X.680 | ISO/IEC 8824-1 clause on
+ * GeneralizedTime.
+ * </p><p>
+ * <b>11.7.2</b> The seconds element shall always be present.
+ * </p>
+ * <p>
+ * <b>11.7.3</b> The fractional-seconds elements, if present,
+ * shall omit all trailing zeros; if the elements correspond to 0,
+ * they shall be wholly omitted, and the decimal point element also
+ * shall be omitted.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERGeneralizedTime
+ extends ASN1GeneralizedTime
+{
+ public DERGeneralizedTime(byte[] time)
+ {
+ super(time);
+ }
+
+ public DERGeneralizedTime(Date time)
+ {
+ super(time);
+ }
+
+ public DERGeneralizedTime(String time)
+ {
+ super(time);
+ }
+
+ private byte[] getDERTime()
+ {
+ if (time[time.length - 1] == 'Z')
+ {
+ if (!hasMinutes())
+ {
+ byte[] derTime = new byte[time.length + 4];
+
+ System.arraycopy(time, 0, derTime, 0, time.length - 1);
+ System.arraycopy(Strings.toByteArray("0000Z"), 0, derTime, time.length - 1, 5);
+
+ return derTime;
+ }
+ else if (!hasSeconds())
+ {
+ byte[] derTime = new byte[time.length + 2];
+
+ System.arraycopy(time, 0, derTime, 0, time.length - 1);
+ System.arraycopy(Strings.toByteArray("00Z"), 0, derTime, time.length - 1, 3);
+
+ return derTime;
+ }
+ else if (hasFractionalSeconds())
+ {
+ int ind = time.length - 2;
+ while (ind > 0 && time[ind] == '0')
+ {
+ ind--;
+ }
+
+ if (time[ind] == '.')
+ {
+ byte[] derTime = new byte[ind + 1];
+
+ System.arraycopy(time, 0, derTime, 0, ind);
+ derTime[ind] = (byte)'Z';
+
+ return derTime;
+ }
+ else
+ {
+ byte[] derTime = new byte[ind + 2];
+
+ System.arraycopy(time, 0, derTime, 0, ind + 1);
+ derTime[ind + 1] = (byte)'Z';
+
+ return derTime;
+ }
+ }
+ else
+ {
+ return time;
+ }
+ }
+ else
+ {
+ return time; // TODO: is there a better way?
+ }
+ }
+
+ int encodedLength()
+ {
+ int length = getDERTime().length;
+
+ return 1 + StreamUtil.calculateBodyLength(length) + length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.GENERALIZED_TIME, getDERTime());
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGraphicString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGraphicString.java
new file mode 100644
index 00000000..779c899b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGraphicString.java
@@ -0,0 +1,126 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERGraphicString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private final byte[] string;
+
+ /**
+ * return a Graphic String from the passed in object
+ *
+ * @param obj a DERGraphicString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a DERGraphicString instance, or null.
+ */
+ public static DERGraphicString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERGraphicString)
+ {
+ return (DERGraphicString)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERGraphicString)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a Graphic String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return a DERGraphicString instance, or null.
+ */
+ public static DERGraphicString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DERGraphicString)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new DERGraphicString(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ /**
+ * basic constructor - with bytes.
+ * @param string the byte encoding of the characters making up the string.
+ */
+ public DERGraphicString(
+ byte[] string)
+ {
+ this.string = Arrays.clone(string);
+ }
+
+ public byte[] getOctets()
+ {
+ return Arrays.clone(string);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.GRAPHIC_STRING, string);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof DERGraphicString))
+ {
+ return false;
+ }
+
+ DERGraphicString s = (DERGraphicString)o;
+
+ return Arrays.areEqual(string, s.string);
+ }
+
+ public String getString()
+ {
+ return Strings.fromByteArray(string);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERIA5String.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERIA5String.java
new file mode 100644
index 00000000..7cdb97b5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERIA5String.java
@@ -0,0 +1,192 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * DER IA5String object - this is a ISO 646 (ASCII) string encoding code points 0 to 127.
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERIA5String
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private final byte[] string;
+
+ /**
+ * Return an IA5 string from the passed in object
+ *
+ * @param obj a DERIA5String or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a DERIA5String instance, or null.
+ */
+ public static DERIA5String getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERIA5String)
+ {
+ return (DERIA5String)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERIA5String)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return an IA5 String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return a DERIA5String instance, or null.
+ */
+ public static DERIA5String getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DERIA5String)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new DERIA5String(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ /**
+ * Basic constructor - with bytes.
+ * @param string the byte encoding of the characters making up the string.
+ */
+ DERIA5String(
+ byte[] string)
+ {
+ this.string = string;
+ }
+
+ /**
+ * Basic constructor - without validation.
+ * @param string the base string to use..
+ */
+ public DERIA5String(
+ String string)
+ {
+ this(string, false);
+ }
+
+ /**
+ * Constructor with optional validation.
+ *
+ * @param string the base string to wrap.
+ * @param validate whether or not to check the string.
+ * @throws IllegalArgumentException if validate is true and the string
+ * contains characters that should not be in an IA5String.
+ */
+ public DERIA5String(
+ String string,
+ boolean validate)
+ {
+ if (string == null)
+ {
+ throw new NullPointerException("'string' cannot be null");
+ }
+ if (validate && !isIA5String(string))
+ {
+ throw new IllegalArgumentException("'string' contains illegal characters");
+ }
+
+ this.string = Strings.toByteArray(string);
+ }
+
+ public String getString()
+ {
+ return Strings.fromByteArray(string);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public byte[] getOctets()
+ {
+ return Arrays.clone(string);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.IA5_STRING, string);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof DERIA5String))
+ {
+ return false;
+ }
+
+ DERIA5String s = (DERIA5String)o;
+
+ return Arrays.areEqual(string, s.string);
+ }
+
+ /**
+ * return true if the passed in String can be represented without
+ * loss as an IA5String, false otherwise.
+ *
+ * @param str the string to check.
+ * @return true if character set in IA5String set, false otherwise.
+ */
+ public static boolean isIA5String(
+ String str)
+ {
+ for (int i = str.length() - 1; i >= 0; i--)
+ {
+ char ch = str.charAt(i);
+
+ if (ch > 0x007f)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERInteger.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERInteger.java
new file mode 100644
index 00000000..bc7d5487
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERInteger.java
@@ -0,0 +1,32 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.math.BigInteger;
+
+/**
+ * @deprecated Use ASN1Integer instead of this,
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERInteger
+ extends ASN1Integer
+{
+ /**
+ * Constructor from a byte array containing a signed representation of the number.
+ *
+ * @param bytes a byte array containing the signed number.A copy is made of the byte array.
+ */
+ public DERInteger(byte[] bytes)
+ {
+ super(bytes, true);
+ }
+
+ public DERInteger(BigInteger value)
+ {
+ super(value);
+ }
+
+ public DERInteger(long value)
+ {
+ super(value);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNull.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNull.java
new file mode 100644
index 00000000..e86c7838
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNull.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * An ASN.1 DER NULL object.
+ * <p>
+ * Preferably use the constant: DERNull.INSTANCE.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERNull
+ extends ASN1Null
+{
+ public static final DERNull INSTANCE = new DERNull();
+
+ private static final byte[] zeroBytes = new byte[0];
+
+ private DERNull()
+ {
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 2;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.NULL, zeroBytes);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNumericString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNumericString.java
new file mode 100644
index 00000000..a573f31f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNumericString.java
@@ -0,0 +1,196 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * DER NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }.
+ * ASN.1 NUMERIC-STRING object.
+ * <p>
+ * This is an ASCII string of characters {0,1,2,3,4,5,6,7,8,9} + space.
+ * <p>
+ * See X.680 section 37.2.
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERNumericString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private final byte[] string;
+
+ /**
+ * Return a Numeric string from the passed in object
+ *
+ * @param obj a DERNumericString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a DERNumericString instance, or null
+ */
+ public static DERNumericString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERNumericString)
+ {
+ return (DERNumericString)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERNumericString)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return an Numeric String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return a DERNumericString instance, or null.
+ */
+ public static DERNumericString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DERNumericString)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new DERNumericString(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ /**
+ * Basic constructor - with bytes.
+ */
+ DERNumericString(
+ byte[] string)
+ {
+ this.string = string;
+ }
+
+ /**
+ * Basic constructor - without validation..
+ */
+ public DERNumericString(
+ String string)
+ {
+ this(string, false);
+ }
+
+ /**
+ * Constructor with optional validation.
+ *
+ * @param string the base string to wrap.
+ * @param validate whether or not to check the string.
+ * @throws IllegalArgumentException if validate is true and the string
+ * contains characters that should not be in a NumericString.
+ */
+ public DERNumericString(
+ String string,
+ boolean validate)
+ {
+ if (validate && !isNumericString(string))
+ {
+ throw new IllegalArgumentException("string contains illegal characters");
+ }
+
+ this.string = Strings.toByteArray(string);
+ }
+
+ public String getString()
+ {
+ return Strings.fromByteArray(string);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public byte[] getOctets()
+ {
+ return Arrays.clone(string);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.NUMERIC_STRING, string);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof DERNumericString))
+ {
+ return false;
+ }
+
+ DERNumericString s = (DERNumericString)o;
+
+ return Arrays.areEqual(string, s.string);
+ }
+
+ /**
+ * Return true if the string can be represented as a NumericString ('0'..'9', ' ')
+ *
+ * @param str string to validate.
+ * @return true if numeric, fale otherwise.
+ */
+ public static boolean isNumericString(
+ String str)
+ {
+ for (int i = str.length() - 1; i >= 0; i--)
+ {
+ char ch = str.charAt(i);
+
+ if (ch > 0x007f)
+ {
+ return false;
+ }
+
+ if (('0' <= ch && ch <= '9') || ch == ' ')
+ {
+ continue;
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERObjectIdentifier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERObjectIdentifier.java
new file mode 100644
index 00000000..1f497c5b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERObjectIdentifier.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+/**
+ *
+ * @deprecated Use ASN1ObjectIdentifier instead of this,
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERObjectIdentifier
+ extends ASN1ObjectIdentifier
+{
+ public DERObjectIdentifier(String identifier)
+ {
+ super(identifier);
+ }
+
+ DERObjectIdentifier(byte[] bytes)
+ {
+ super(bytes);
+ }
+
+ DERObjectIdentifier(ASN1ObjectIdentifier oid, String branch)
+ {
+ super(oid, branch);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetString.java
new file mode 100644
index 00000000..7b2dc381
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetString.java
@@ -0,0 +1,65 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Carrier class for a DER encoding OCTET STRING
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DEROctetString
+ extends ASN1OctetString
+{
+ /**
+ * Base constructor.
+ *
+ * @param string the octets making up the octet string.
+ */
+ public DEROctetString(
+ byte[] string)
+ {
+ super(string);
+ }
+
+ /**
+ * Constructor from the encoding of an ASN.1 object.
+ *
+ * @param obj the object to be encoded.
+ */
+ public DEROctetString(
+ ASN1Encodable obj)
+ throws IOException
+ {
+ super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER));
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.OCTET_STRING, string);
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
+ static void encode(ASN1OutputStream derOut, boolean withTag, byte[] buf, int off, int len) throws IOException
+ {
+ derOut.writeEncoded(withTag, BERTags.OCTET_STRING, buf, off, len);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetStringParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetStringParser.java
new file mode 100644
index 00000000..db2da307
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetStringParser.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Parser for DER encoded OCTET STRINGS
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DEROctetStringParser
+ implements ASN1OctetStringParser
+{
+ private DefiniteLengthInputStream stream;
+
+ DEROctetStringParser(
+ DefiniteLengthInputStream stream)
+ {
+ this.stream = stream;
+ }
+
+ /**
+ * Return an InputStream representing the contents of the OCTET STRING.
+ *
+ * @return an InputStream with its source as the OCTET STRING content.
+ */
+ public InputStream getOctetStream()
+ {
+ return stream;
+ }
+
+ /**
+ * Return an in-memory, encodable, representation of the OCTET STRING.
+ *
+ * @return a DEROctetString.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return new DEROctetString(stream.toByteArray());
+ }
+
+ /**
+ * Return an DEROctetString representing this parser and its contents.
+ *
+ * @return an DEROctetString
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROutputStream.java
new file mode 100644
index 00000000..6e08148d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROutputStream.java
@@ -0,0 +1,35 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Stream that outputs encoding based on distinguished encoding rules.
+ * @hide This class is not part of the Android public SDK API
+ */
+// BEGIN Android-changed: Class is package-private in upstream.
+// Leaving as public as it's used by build/make/tools/signapk/src/com/android/signapk/SignApk.java
+public class DEROutputStream
+ extends ASN1OutputStream
+{
+ public DEROutputStream(OutputStream os)
+ {
+ super(os);
+ }
+
+ void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
+ {
+ primitive.toDERObject().encode(this, withTag);
+ }
+
+ DEROutputStream getDERSubStream()
+ {
+ return this;
+ }
+
+ ASN1OutputStream getDLSubStream()
+ {
+ return this;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERPrintableString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERPrintableString.java
new file mode 100644
index 00000000..e885eb7d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERPrintableString.java
@@ -0,0 +1,239 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * DER PrintableString object.
+ * <p>
+ * X.680 section 37.4 defines PrintableString character codes as ASCII subset of following characters:
+ * </p>
+ * <ul>
+ * <li>Latin capital letters: 'A' .. 'Z'</li>
+ * <li>Latin small letters: 'a' .. 'z'</li>
+ * <li>Digits: '0'..'9'</li>
+ * <li>Space</li>
+ * <li>Apostrophe: '\''</li>
+ * <li>Left parenthesis: '('</li>
+ * <li>Right parenthesis: ')'</li>
+ * <li>Plus sign: '+'</li>
+ * <li>Comma: ','</li>
+ * <li>Hyphen-minus: '-'</li>
+ * <li>Full stop: '.'</li>
+ * <li>Solidus: '/'</li>
+ * <li>Colon: ':'</li>
+ * <li>Equals sign: '='</li>
+ * <li>Question mark: '?'</li>
+ * </ul>
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERPrintableString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private final byte[] string;
+
+ /**
+ * Return a printable string from the passed in object.
+ *
+ * @param obj a DERPrintableString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a DERPrintableString instance, or null.
+ */
+ public static DERPrintableString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERPrintableString)
+ {
+ return (DERPrintableString)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERPrintableString)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return a Printable String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return a DERPrintableString instance, or null.
+ */
+ public static DERPrintableString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DERPrintableString)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new DERPrintableString(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ /**
+ * Basic constructor - byte encoded string.
+ */
+ DERPrintableString(
+ byte[] string)
+ {
+ this.string = string;
+ }
+
+ /**
+ * Basic constructor - this does not validate the string
+ */
+ public DERPrintableString(
+ String string)
+ {
+ this(string, false);
+ }
+
+ /**
+ * Constructor with optional validation.
+ *
+ * @param string the base string to wrap.
+ * @param validate whether or not to check the string.
+ * @throws IllegalArgumentException if validate is true and the string
+ * contains characters that should not be in a PrintableString.
+ */
+ public DERPrintableString(
+ String string,
+ boolean validate)
+ {
+ if (validate && !isPrintableString(string))
+ {
+ throw new IllegalArgumentException("string contains illegal characters");
+ }
+
+ this.string = Strings.toByteArray(string);
+ }
+
+ public String getString()
+ {
+ return Strings.fromByteArray(string);
+ }
+
+ public byte[] getOctets()
+ {
+ return Arrays.clone(string);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.PRINTABLE_STRING, string);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof DERPrintableString))
+ {
+ return false;
+ }
+
+ DERPrintableString s = (DERPrintableString)o;
+
+ return Arrays.areEqual(string, s.string);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ /**
+ * return true if the passed in String can be represented without
+ * loss as a PrintableString, false otherwise.
+ *
+ * @return true if in printable set, false otherwise.
+ */
+ public static boolean isPrintableString(
+ String str)
+ {
+ for (int i = str.length() - 1; i >= 0; i--)
+ {
+ char ch = str.charAt(i);
+
+ if (ch > 0x007f)
+ {
+ return false;
+ }
+
+ if ('a' <= ch && ch <= 'z')
+ {
+ continue;
+ }
+
+ if ('A' <= ch && ch <= 'Z')
+ {
+ continue;
+ }
+
+ if ('0' <= ch && ch <= '9')
+ {
+ continue;
+ }
+
+ switch (ch)
+ {
+ case ' ':
+ case '\'':
+ case '(':
+ case ')':
+ case '+':
+ case '-':
+ case '.':
+ case ':':
+ case '=':
+ case '?':
+ case '/':
+ case ',':
+ continue;
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequence.java
new file mode 100644
index 00000000..d1593ef8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequence.java
@@ -0,0 +1,147 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Definite length SEQUENCE, encoding tells explicit number of bytes
+ * that the content of this sequence occupies.
+ * <p>
+ * For X.690 syntax rules, see {@link ASN1Sequence}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERSequence
+ extends ASN1Sequence
+{
+ public static DERSequence convert(ASN1Sequence seq)
+ {
+ return (DERSequence)seq.toDERObject();
+ }
+
+ private int bodyLength = -1;
+
+ /**
+ * Create an empty sequence
+ */
+ public DERSequence()
+ {
+ }
+
+ /**
+ * Create a sequence containing one object
+ * @param element the object to go in the sequence.
+ */
+ public DERSequence(ASN1Encodable element)
+ {
+ super(element);
+ }
+
+ /**
+ * Create a sequence containing a vector of objects.
+ * @param elementVector the vector of objects to make up the sequence.
+ */
+ public DERSequence(ASN1EncodableVector elementVector)
+ {
+ super(elementVector);
+ }
+
+ /**
+ * Create a sequence containing an array of objects.
+ * @param elements the array of objects to make up the sequence.
+ */
+ public DERSequence(ASN1Encodable[] elements)
+ {
+ super(elements);
+ }
+
+ DERSequence(ASN1Encodable[] elements, boolean clone)
+ {
+ super(elements, clone);
+ }
+
+ private int getBodyLength() throws IOException
+ {
+ if (bodyLength < 0)
+ {
+ int count = elements.length;
+ int totalLength = 0;
+
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ totalLength += derObject.encodedLength();
+ }
+
+ this.bodyLength = totalLength;
+ }
+
+ return bodyLength;
+ }
+
+ int encodedLength() throws IOException
+ {
+ int length = getBodyLength();
+
+ return 1 + StreamUtil.calculateBodyLength(length) + length;
+ }
+
+ /*
+ * A note on the implementation:
+ * <p>
+ * As DER requires the constructed, definite-length model to
+ * be used for structured types, this varies slightly from the
+ * ASN.1 descriptions given. Rather than just outputting SEQUENCE,
+ * we also have to specify CONSTRUCTED, and the objects length.
+ */
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ if (withTag)
+ {
+ out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
+ }
+
+ DEROutputStream derOut = out.getDERSubStream();
+
+ int count = elements.length;
+ if (bodyLength >= 0 || count > 16)
+ {
+ out.writeLength(getBodyLength());
+
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ derObject.encode(derOut, true);
+ }
+ }
+ else
+ {
+ int totalLength = 0;
+
+ ASN1Primitive[] derObjects = new ASN1Primitive[count];
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ derObjects[i] = derObject;
+ totalLength += derObject.encodedLength();
+ }
+
+ this.bodyLength = totalLength;
+ out.writeLength(totalLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ derObjects[i].encode(derOut, true);
+ }
+ }
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequenceParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequenceParser.java
new file mode 100644
index 00000000..a0235928
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequenceParser.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * @deprecated Use DLSequenceParser instead
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERSequenceParser
+ implements ASN1SequenceParser
+{
+ private ASN1StreamParser _parser;
+
+ DERSequenceParser(ASN1StreamParser parser)
+ {
+ this._parser = parser;
+ }
+
+ /**
+ * Return the next object in the SEQUENCE.
+ *
+ * @return next object in SEQUENCE.
+ * @throws IOException if there is an issue loading the object.
+ */
+ public ASN1Encodable readObject()
+ throws IOException
+ {
+ return _parser.readObject();
+ }
+
+ /**
+ * Return an in memory, encodable, representation of the SEQUENCE.
+ *
+ * @return a DERSequence.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return new DLSequence(_parser.readVector());
+ }
+
+ /**
+ * Return a DERSequence representing this parser and its contents.
+ *
+ * @return a DERSequence.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException(e.getMessage());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSet.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSet.java
new file mode 100644
index 00000000..d6914adb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSet.java
@@ -0,0 +1,160 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * A DER encoded SET object
+ * <p>
+ * For X.690 syntax rules, see {@link ASN1Set}.
+ * </p><p>
+ * For short: Constructing this form does sort the supplied elements,
+ * and the sorting happens also before serialization (if necesssary).
+ * This is different from the way {@link BERSet},{@link DLSet} does things.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERSet
+ extends ASN1Set
+{
+ public static DERSet convert(ASN1Set set)
+ {
+ return (DERSet)set.toDERObject();
+ }
+
+ private int bodyLength = -1;
+
+ /**
+ * create an empty set
+ */
+ public DERSet()
+ {
+ }
+
+ /**
+ * create a set containing one object
+ * @param element the object to go in the set
+ */
+ public DERSet(ASN1Encodable element)
+ {
+ super(element);
+ }
+
+ /**
+ * create a set containing a vector of objects.
+ * @param elementVector the vector of objects to make up the set.
+ */
+ public DERSet(ASN1EncodableVector elementVector)
+ {
+ super(elementVector, true);
+ }
+
+ /**
+ * create a set containing an array of objects.
+ * @param elements the array of objects to make up the set.
+ */
+ public DERSet(ASN1Encodable[] elements)
+ {
+ super(elements, true);
+ }
+
+ DERSet(boolean isSorted, ASN1Encodable[] elements)
+ {
+ super(checkSorted(isSorted), elements);
+ }
+
+ private int getBodyLength() throws IOException
+ {
+ if (bodyLength < 0)
+ {
+ int count = elements.length;
+ int totalLength = 0;
+
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ totalLength += derObject.encodedLength();
+ }
+
+ this.bodyLength = totalLength;
+ }
+
+ return bodyLength;
+ }
+
+ int encodedLength() throws IOException
+ {
+ int length = getBodyLength();
+
+ return 1 + StreamUtil.calculateBodyLength(length) + length;
+ }
+
+ /*
+ * A note on the implementation:
+ * <p>
+ * As DER requires the constructed, definite-length model to
+ * be used for structured types, this varies slightly from the
+ * ASN.1 descriptions given. Rather than just outputting SET,
+ * we also have to specify CONSTRUCTED, and the objects length.
+ */
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ if (withTag)
+ {
+ out.write(BERTags.SET | BERTags.CONSTRUCTED);
+ }
+
+ DEROutputStream derOut = out.getDERSubStream();
+
+ int count = elements.length;
+ if (bodyLength >= 0 || count > 16)
+ {
+ out.writeLength(getBodyLength());
+
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ derObject.encode(derOut, true);
+ }
+ }
+ else
+ {
+ int totalLength = 0;
+
+ ASN1Primitive[] derObjects = new ASN1Primitive[count];
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
+ derObjects[i] = derObject;
+ totalLength += derObject.encodedLength();
+ }
+
+ this.bodyLength = totalLength;
+ out.writeLength(totalLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ derObjects[i].encode(derOut, true);
+ }
+ }
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return isSorted ? this : super.toDERObject();
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
+ private static boolean checkSorted(boolean isSorted)
+ {
+ if (!isSorted)
+ {
+ throw new IllegalStateException("DERSet elements should always be in sorted order");
+ }
+ return isSorted;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSetParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSetParser.java
new file mode 100644
index 00000000..f640c3c5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSetParser.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * @deprecated Use DLSetParser instead
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERSetParser
+ implements ASN1SetParser
+{
+ private ASN1StreamParser _parser;
+
+ DERSetParser(ASN1StreamParser parser)
+ {
+ this._parser = parser;
+ }
+
+ /**
+ * Return the next object in the SET.
+ *
+ * @return next object in SET.
+ * @throws IOException if there is an issue loading the object.
+ */
+ public ASN1Encodable readObject()
+ throws IOException
+ {
+ return _parser.readObject();
+ }
+
+ /**
+ * Return an in memory, encodable, representation of the SET.
+ *
+ * @return a DERSet.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return new DLSet(_parser.readVector());
+ }
+
+ /**
+ * Return a DERSet representing this parser and its contents.
+ *
+ * @return a DERSet
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException(e.getMessage(), e);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERT61String.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERT61String.java
new file mode 100644
index 00000000..2dad092f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERT61String.java
@@ -0,0 +1,151 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * DER T61String (also the teletex string), try not to use this if you don't need to. The standard support the encoding for
+ * this has been withdrawn.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERT61String
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private byte[] string;
+
+ /**
+ * Return a T61 string from the passed in object.
+ *
+ * @param obj a DERT61String or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a DERT61String instance, or null
+ */
+ public static DERT61String getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERT61String)
+ {
+ return (DERT61String)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERT61String)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return an T61 String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return a DERT61String instance, or null
+ */
+ public static DERT61String getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DERT61String)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new DERT61String(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ /**
+ * Basic constructor - string encoded as a sequence of bytes.
+ *
+ * @param string the byte encoding of the string to be wrapped.
+ */
+ public DERT61String(
+ byte[] string)
+ {
+ this.string = Arrays.clone(string);
+ }
+
+ /**
+ * Basic constructor - with string 8 bit assumed.
+ *
+ * @param string the string to be wrapped.
+ */
+ public DERT61String(
+ String string)
+ {
+ this.string = Strings.toByteArray(string);
+ }
+
+ /**
+ * Decode the encoded string and return it, 8 bit encoding assumed.
+ * @return the decoded String
+ */
+ public String getString()
+ {
+ return Strings.fromByteArray(string);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.T61_STRING, string);
+ }
+
+ /**
+ * Return the encoded string as a byte array.
+ * @return the actual bytes making up the encoded body of the T61 string.
+ */
+ public byte[] getOctets()
+ {
+ return Arrays.clone(string);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof DERT61String))
+ {
+ return false;
+ }
+
+ return Arrays.areEqual(string, ((DERT61String)o).string);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTaggedObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTaggedObject.java
new file mode 100644
index 00000000..201a7eda
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTaggedObject.java
@@ -0,0 +1,86 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * DER TaggedObject - in ASN.1 notation this is any object preceded by
+ * a [n] where n is some number - these are assumed to follow the construction
+ * rules (as with sequences).
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERTaggedObject
+ extends ASN1TaggedObject
+{
+ /**
+ * @param explicit true if an explicitly tagged object.
+ * @param tagNo the tag number for this object.
+ * @param obj the tagged object.
+ */
+ public DERTaggedObject(
+ boolean explicit,
+ int tagNo,
+ ASN1Encodable obj)
+ {
+ super(explicit, tagNo, obj);
+ }
+
+ public DERTaggedObject(int tagNo, ASN1Encodable encodable)
+ {
+ super(true, tagNo, encodable);
+ }
+
+ boolean isConstructed()
+ {
+ return explicit || obj.toASN1Primitive().toDERObject().isConstructed();
+ }
+
+ int encodedLength()
+ throws IOException
+ {
+ ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
+ int length = primitive.encodedLength();
+
+ if (explicit)
+ {
+ return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
+ }
+ else
+ {
+ // header length already in calculation
+ length = length - 1;
+
+ return StreamUtil.calculateTagLength(tagNo) + length;
+ }
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
+
+ int flags = BERTags.TAGGED;
+ if (explicit || primitive.isConstructed())
+ {
+ flags |= BERTags.CONSTRUCTED;
+ }
+
+ out.writeTag(withTag, flags, tagNo);
+
+ if (explicit)
+ {
+ out.writeLength(primitive.encodedLength());
+ }
+
+ primitive.encode(out.getDERSubStream(), explicit);
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return this;
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTags.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTags.java
new file mode 100644
index 00000000..fb68afe1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTags.java
@@ -0,0 +1,11 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+/**
+ * @deprecated use BERTags
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface DERTags
+ extends BERTags
+{
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTCTime.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTCTime.java
new file mode 100644
index 00000000..4e3c5f25
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTCTime.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.util.Date;
+
+/**
+ * DER UTC time object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERUTCTime
+ extends ASN1UTCTime
+{
+ DERUTCTime(byte[] bytes)
+ {
+ super(bytes);
+ }
+
+ public DERUTCTime(Date time)
+ {
+ super(time);
+ }
+
+ public DERUTCTime(String time)
+ {
+ super(time);
+ }
+
+ // TODO: create proper DER encoding.
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTF8String.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTF8String.java
new file mode 100644
index 00000000..d5f753a3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTF8String.java
@@ -0,0 +1,138 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * DER UTF8String object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERUTF8String
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private final byte[] string;
+
+ /**
+ * Return an UTF8 string from the passed in object.
+ *
+ * @param obj a DERUTF8String or an object that can be converted into one.
+ * @exception IllegalArgumentException
+ * if the object cannot be converted.
+ * @return a DERUTF8String instance, or null
+ */
+ public static DERUTF8String getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof DERUTF8String)
+ {
+ return (DERUTF8String)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERUTF8String)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: "
+ + obj.getClass().getName());
+ }
+
+ /**
+ * Return an UTF8 String from a tagged object.
+ *
+ * @param obj
+ * the tagged object holding the object we want
+ * @param explicit
+ * true if the object is meant to be explicitly tagged false
+ * otherwise.
+ * @exception IllegalArgumentException
+ * if the tagged object cannot be converted.
+ * @return a DERUTF8String instance, or null
+ */
+ public static DERUTF8String getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DERUTF8String)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new DERUTF8String(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ /*
+ * Basic constructor - byte encoded string.
+ */
+ DERUTF8String(byte[] string)
+ {
+ this.string = string;
+ }
+
+ /**
+ * Basic constructor
+ *
+ * @param string the string to be carried in the UTF8String object,
+ */
+ public DERUTF8String(String string)
+ {
+ this.string = Strings.toUTF8ByteArray(string);
+ }
+
+ public String getString()
+ {
+ return Strings.fromUTF8ByteArray(string);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+
+ boolean asn1Equals(ASN1Primitive o)
+ {
+ if (!(o instanceof DERUTF8String))
+ {
+ return false;
+ }
+
+ DERUTF8String s = (DERUTF8String)o;
+
+ return Arrays.areEqual(string, s.string);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ throws IOException
+ {
+ return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.UTF8_STRING, string);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUniversalString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUniversalString.java
new file mode 100644
index 00000000..b4c2a16e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUniversalString.java
@@ -0,0 +1,150 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * DER UniversalString object - encodes UNICODE (ISO 10646) characters using 32-bit format. In Java we
+ * have no way of representing this directly so we rely on byte arrays to carry these.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERUniversalString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ private final byte[] string;
+
+ /**
+ * Return a Universal String from the passed in object.
+ *
+ * @param obj a DERUniversalString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a DERUniversalString instance, or null
+ */
+ public static DERUniversalString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERUniversalString)
+ {
+ return (DERUniversalString)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERUniversalString)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return a Universal String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return a DERUniversalString instance, or null
+ */
+ public static DERUniversalString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DERUniversalString)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new DERUniversalString(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ /**
+ * Basic constructor - byte encoded string.
+ *
+ * @param string the byte encoding of the string to be carried in the UniversalString object,
+ */
+ public DERUniversalString(
+ byte[] string)
+ {
+ this.string = Arrays.clone(string);
+ }
+
+ public String getString()
+ {
+ StringBuffer buf = new StringBuffer("#");
+
+ byte[] string;
+ try
+ {
+ string = getEncoded();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("internal error encoding UniversalString");
+ }
+
+ for (int i = 0; i != string.length; i++)
+ {
+ buf.append(table[(string[i] >>> 4) & 0xf]);
+ buf.append(table[string[i] & 0xf]);
+ }
+
+ return buf.toString();
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public byte[] getOctets()
+ {
+ return Arrays.clone(string);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.UNIVERSAL_STRING, string);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof DERUniversalString))
+ {
+ return false;
+ }
+
+ return Arrays.areEqual(string, ((DERUniversalString)o).string);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVideotexString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVideotexString.java
new file mode 100644
index 00000000..155d5466
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVideotexString.java
@@ -0,0 +1,126 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERVideotexString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private final byte[] string;
+
+ /**
+ * return a Videotex String from the passed in object
+ *
+ * @param obj a DERVideotexString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a DERVideotexString instance, or null.
+ */
+ public static DERVideotexString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERVideotexString)
+ {
+ return (DERVideotexString)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERVideotexString)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a Videotex String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return a DERVideotexString instance, or null.
+ */
+ public static DERVideotexString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DERVideotexString)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new DERVideotexString(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ /**
+ * basic constructor - with bytes.
+ * @param string the byte encoding of the characters making up the string.
+ */
+ public DERVideotexString(
+ byte[] string)
+ {
+ this.string = Arrays.clone(string);
+ }
+
+ public byte[] getOctets()
+ {
+ return Arrays.clone(string);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.VIDEOTEX_STRING, string);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof DERVideotexString))
+ {
+ return false;
+ }
+
+ DERVideotexString s = (DERVideotexString)o;
+
+ return Arrays.areEqual(string, s.string);
+ }
+
+ public String getString()
+ {
+ return Strings.fromByteArray(string);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVisibleString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVisibleString.java
new file mode 100644
index 00000000..e402c13e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVisibleString.java
@@ -0,0 +1,143 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * DER VisibleString object encoding ISO 646 (ASCII) character code points 32 to 126.
+ * <p>
+ * Explicit character set escape sequences are not allowed.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DERVisibleString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private final byte[] string;
+
+ /**
+ * Return a Visible String from the passed in object.
+ *
+ * @param obj a DERVisibleString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a DERVisibleString instance, or null
+ */
+ public static DERVisibleString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERVisibleString)
+ {
+ return (DERVisibleString)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERVisibleString)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Return a Visible String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return a DERVisibleString instance, or null
+ */
+ public static DERVisibleString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DERVisibleString)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new DERVisibleString(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ /*
+ * Basic constructor - byte encoded string.
+ */
+ DERVisibleString(
+ byte[] string)
+ {
+ this.string = string;
+ }
+
+ /**
+ * Basic constructor
+ *
+ * @param string the string to be carried in the VisibleString object,
+ */
+ public DERVisibleString(
+ String string)
+ {
+ this.string = Strings.toByteArray(string);
+ }
+
+ public String getString()
+ {
+ return Strings.fromByteArray(string);
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public byte[] getOctets()
+ {
+ return Arrays.clone(string);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.VISIBLE_STRING, this.string);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof DERVisibleString))
+ {
+ return false;
+ }
+
+ return Arrays.areEqual(string, ((DERVisibleString)o).string);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLApplicationSpecific.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLApplicationSpecific.java
new file mode 100644
index 00000000..174ef829
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLApplicationSpecific.java
@@ -0,0 +1,126 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * A DER encoding version of an application specific object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DLApplicationSpecific
+ extends ASN1ApplicationSpecific
+{
+ DLApplicationSpecific(
+ boolean isConstructed,
+ int tag,
+ byte[] octets)
+ {
+ super(isConstructed, tag, octets);
+ }
+
+ /**
+ * Create an application specific object from the passed in data. This will assume
+ * the data does not represent a constructed object.
+ *
+ * @param tag the tag number for this object.
+ * @param octets the encoding of the object's body.
+ */
+ public DLApplicationSpecific(
+ int tag,
+ byte[] octets)
+ {
+ this(false, tag, octets);
+ }
+
+ /**
+ * Create an application specific object with a tagging of explicit/constructed.
+ *
+ * @param tag the tag number for this object.
+ * @param object the object to be contained.
+ */
+ public DLApplicationSpecific(
+ int tag,
+ ASN1Encodable object)
+ throws IOException
+ {
+ this(true, tag, object);
+ }
+
+ /**
+ * Create an application specific object with the tagging style given by the value of constructed.
+ *
+ * @param constructed true if the object is constructed.
+ * @param tag the tag number for this object.
+ * @param object the object to be contained.
+ */
+ public DLApplicationSpecific(
+ boolean constructed,
+ int tag,
+ ASN1Encodable object)
+ throws IOException
+ {
+ super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
+ }
+
+ private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
+ throws IOException
+ {
+ byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.DL);
+
+ if (explicit)
+ {
+ return data;
+ }
+ else
+ {
+ int lenBytes = getLengthOfHeader(data);
+ byte[] tmp = new byte[data.length - lenBytes];
+ System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
+ return tmp;
+ }
+ }
+
+ /**
+ * Create an application specific object which is marked as constructed
+ *
+ * @param tagNo the tag number for this object.
+ * @param vec the objects making up the application specific object.
+ */
+ public DLApplicationSpecific(int tagNo, ASN1EncodableVector vec)
+ {
+ super(true, tagNo, getEncodedVector(vec));
+ }
+
+ private static byte[] getEncodedVector(ASN1EncodableVector vec)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ for (int i = 0; i != vec.size(); i++)
+ {
+ try
+ {
+ bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.DL));
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("malformed object: " + e, e);
+ }
+ }
+ return bOut.toByteArray();
+ }
+
+ /* (non-Javadoc)
+ * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
+ */
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ int flags = BERTags.APPLICATION;
+ if (isConstructed)
+ {
+ flags |= BERTags.CONSTRUCTED;
+ }
+
+ out.writeEncoded(withTag, flags, tag, octets);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitString.java
new file mode 100644
index 00000000..cb72e952
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitString.java
@@ -0,0 +1,144 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * A Definite length BIT STRING
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DLBitString
+ extends ASN1BitString
+{
+ /**
+ * return a Bit String that can be definite-length encoded from the passed in object.
+ *
+ * @param obj a DL or DER BitString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1BitString instance, or null.
+ */
+ public static ASN1BitString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DLBitString)
+ {
+ return (DLBitString)obj;
+ }
+ if (obj instanceof DERBitString)
+ {
+ return (DERBitString)obj;
+ }
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1BitString)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a Bit String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1BitString instance, or null.
+ */
+ public static ASN1BitString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DLBitString)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
+ }
+ }
+
+ protected DLBitString(byte data, int padBits)
+ {
+ super(data, padBits);
+ }
+
+ /**
+ * @param data the octets making up the bit string.
+ * @param padBits the number of extra bits at the end of the string.
+ */
+ public DLBitString(
+ byte[] data,
+ int padBits)
+ {
+ super(data, padBits);
+ }
+
+ public DLBitString(
+ byte[] data)
+ {
+ this(data, 0);
+ }
+
+ public DLBitString(
+ int value)
+ {
+ super(getBytes(value), getPadBits(value));
+ }
+
+ public DLBitString(
+ ASN1Encodable obj)
+ throws IOException
+ {
+ super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
+ static DLBitString fromOctetString(byte[] bytes)
+ {
+ if (bytes.length < 1)
+ {
+ throw new IllegalArgumentException("truncated BIT STRING detected");
+ }
+
+ int padBits = bytes[0];
+ byte[] data = new byte[bytes.length - 1];
+
+ if (data.length != 0)
+ {
+ System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
+ }
+
+ return new DLBitString(data, padBits);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLExternal.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLExternal.java
new file mode 100644
index 00000000..5d8c6191
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLExternal.java
@@ -0,0 +1,92 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * Class representing the Definite-Length-type External
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DLExternal
+ extends ASN1External
+{
+ /**
+ * Construct a Definite-Length EXTERNAL object, the input encoding vector must have exactly two elements on it.
+ * <p>
+ * Acceptable input formats are:
+ * <ul>
+ * <li> {@link ASN1ObjectIdentifier} + data {@link DERTaggedObject} (direct reference form)</li>
+ * <li> {@link ASN1Integer} + data {@link DERTaggedObject} (indirect reference form)</li>
+ * <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
+ * </ul>
+ *
+ * @throws IllegalArgumentException if input size is wrong, or
+ */
+ public DLExternal(ASN1EncodableVector vector)
+ {
+ super(vector);
+ }
+
+ /**
+ * Creates a new instance of DERExternal
+ * See X.690 for more informations about the meaning of these parameters
+ * @param directReference The direct reference or <code>null</code> if not set.
+ * @param indirectReference The indirect reference or <code>null</code> if not set.
+ * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
+ * @param externalData The external data in its encoded form.
+ */
+ public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
+ {
+ this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
+ }
+
+ /**
+ * Creates a new instance of Definite-Length External.
+ * See X.690 for more informations about the meaning of these parameters
+ * @param directReference The direct reference or <code>null</code> if not set.
+ * @param indirectReference The indirect reference or <code>null</code> if not set.
+ * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
+ * @param encoding The encoding to be used for the external data
+ * @param externalData The external data
+ */
+ public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
+ {
+ super(directReference, indirectReference, dataValueDescriptor, encoding, externalData);
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+
+ int encodedLength()
+ throws IOException
+ {
+ return this.getEncoded().length;
+ }
+
+ /* (non-Javadoc)
+ * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
+ */
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ if (directReference != null)
+ {
+ baos.write(directReference.getEncoded(ASN1Encoding.DL));
+ }
+ if (indirectReference != null)
+ {
+ baos.write(indirectReference.getEncoded(ASN1Encoding.DL));
+ }
+ if (dataValueDescriptor != null)
+ {
+ baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DL));
+ }
+ ASN1TaggedObject obj = new DLTaggedObject(true, encoding, externalContent);
+ baos.write(obj.getEncoded(ASN1Encoding.DL));
+
+ out.writeEncoded(withTag, BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLFactory.java
new file mode 100644
index 00000000..5f8d5206
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLFactory.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+class DLFactory
+{
+ static final ASN1Sequence EMPTY_SEQUENCE = new DLSequence();
+ static final ASN1Set EMPTY_SET = new DLSet();
+
+ static ASN1Sequence createSequence(ASN1EncodableVector v)
+ {
+ if (v.size() < 1)
+ {
+ return EMPTY_SEQUENCE;
+ }
+
+ return new DLSequence(v);
+ }
+
+ static ASN1Set createSet(ASN1EncodableVector v)
+ {
+ if (v.size() < 1)
+ {
+ return EMPTY_SET;
+ }
+
+ return new DLSet(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLOutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLOutputStream.java
new file mode 100644
index 00000000..99a0abd4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLOutputStream.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Stream that outputs encoding based on definite length.
+ */
+class DLOutputStream
+ extends ASN1OutputStream
+{
+ DLOutputStream(OutputStream os)
+ {
+ super(os);
+ }
+
+ void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
+ {
+ primitive.toDLObject().encode(this, withTag);
+ }
+
+ ASN1OutputStream getDLSubStream()
+ {
+ return this;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequence.java
new file mode 100644
index 00000000..b4a770f8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequence.java
@@ -0,0 +1,133 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * The DLSequence encodes a SEQUENCE using definite length form.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DLSequence
+ extends ASN1Sequence
+{
+ private int bodyLength = -1;
+
+ /**
+ * Create an empty sequence
+ */
+ public DLSequence()
+ {
+ }
+
+ /**
+ * create a sequence containing one object
+ * @param element the object to go in the sequence.
+ */
+ public DLSequence(ASN1Encodable element)
+ {
+ super(element);
+ }
+
+ /**
+ * create a sequence containing a vector of objects.
+ * @param elementVector the vector of objects to make up the sequence.
+ */
+ public DLSequence(ASN1EncodableVector elementVector)
+ {
+ super(elementVector);
+ }
+
+ /**
+ * create a sequence containing an array of objects.
+ * @param elements the array of objects to make up the sequence.
+ */
+ public DLSequence(ASN1Encodable[] elements)
+ {
+ super(elements);
+ }
+
+ DLSequence(ASN1Encodable[] elements, boolean clone)
+ {
+ super(elements, clone);
+ }
+
+ private int getBodyLength() throws IOException
+ {
+ if (bodyLength < 0)
+ {
+ int count = elements.length;
+ int totalLength = 0;
+
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
+ totalLength += dlObject.encodedLength();
+ }
+
+ this.bodyLength = totalLength;
+ }
+
+ return bodyLength;
+ }
+
+ int encodedLength() throws IOException
+ {
+ int length = getBodyLength();
+
+ return 1 + StreamUtil.calculateBodyLength(length) + length;
+ }
+
+ /**
+ * A note on the implementation:
+ * <p>
+ * As DL requires the constructed, definite-length model to
+ * be used for structured types, this varies slightly from the
+ * ASN.1 descriptions given. Rather than just outputting SEQUENCE,
+ * we also have to specify CONSTRUCTED, and the objects length.
+ */
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ if (withTag)
+ {
+ out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
+ }
+
+ ASN1OutputStream dlOut = out.getDLSubStream();
+
+ int count = elements.length;
+ if (bodyLength >= 0 || count > 16)
+ {
+ out.writeLength(getBodyLength());
+
+ for (int i = 0; i < count; ++i)
+ {
+ dlOut.writePrimitive(elements[i].toASN1Primitive(), true);
+ }
+ }
+ else
+ {
+ int totalLength = 0;
+
+ ASN1Primitive[] dlObjects = new ASN1Primitive[count];
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
+ dlObjects[i] = dlObject;
+ totalLength += dlObject.encodedLength();
+ }
+
+ this.bodyLength = totalLength;
+ out.writeLength(totalLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ dlOut.writePrimitive(dlObjects[i], true);
+ }
+ }
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequenceParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequenceParser.java
new file mode 100644
index 00000000..62158d03
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequenceParser.java
@@ -0,0 +1,62 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Parser class for DL SEQUENCEs.
+ *
+ * TODO The class is only publicly visible to support 'instanceof' checks; provide an alternative
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DLSequenceParser
+ implements ASN1SequenceParser
+{
+ private ASN1StreamParser _parser;
+
+ DLSequenceParser(ASN1StreamParser parser)
+ {
+ this._parser = parser;
+ }
+
+ /**
+ * Return the next object in the SEQUENCE.
+ *
+ * @return next object in SEQUENCE.
+ * @throws IOException if there is an issue loading the object.
+ */
+ public ASN1Encodable readObject()
+ throws IOException
+ {
+ return _parser.readObject();
+ }
+
+ /**
+ * Return an in memory, encodable, representation of the SEQUENCE.
+ *
+ * @return a DLSequence.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return new DLSequence(_parser.readVector());
+ }
+
+ /**
+ * Return a DLSequence representing this parser and its contents.
+ *
+ * @return a DLSequence.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException(e.getMessage());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSet.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSet.java
new file mode 100644
index 00000000..543b4f92
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSet.java
@@ -0,0 +1,175 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * The DLSet encodes ASN.1 SET value without element ordering,
+ * and always using definite length form.
+ * <hr>
+ * <h2>X.690</h2>
+ * <h3>8: Basic encoding rules</h3>
+ * <h4>8.11 Encoding of a set value </h4>
+ * <b>8.11.1</b> The encoding of a set value shall be constructed
+ * <p>
+ * <b>8.11.2</b> The contents octets shall consist of the complete
+ * encoding of a data value from each of the types listed in the
+ * ASN.1 definition of the set type, in an order chosen by the sender,
+ * unless the type was referenced with the keyword
+ * <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
+ * <p>
+ * <b>8.11.3</b> The encoding of a data value may, but need not,
+ * be present for a type which was referenced with the keyword
+ * <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
+ * <blockquote>
+ * NOTE &mdash; The order of data values in a set value is not significant,
+ * and places no constraints on the order during transfer
+ * </blockquote>
+ * <h3>9: Canonical encoding rules</h3>
+ * <h4>9.3 Set components</h4>
+ * The encodings of the component values of a set value shall
+ * appear in an order determined by their tags as specified
+ * in 8.6 of ITU-T Rec. X.680 | ISO/IEC 8824-1.
+ * Additionally, for the purposes of determining the order in which
+ * components are encoded when one or more component is an untagged
+ * choice type, each untagged choice type is ordered as though it
+ * has a tag equal to that of the smallest tag in that choice type
+ * or any untagged choice types nested within.
+ * <h3>10: Distinguished encoding rules</h3>
+ * <h4>10.3 Set components</h4>
+ * The encodings of the component values of a set value shall appear
+ * in an order determined by their tags as specified
+ * in 8.6 of ITU-T Rec. X.680 | ISO/IEC 8824-1.
+ * <blockquote>
+ * NOTE &mdash; Where a component of the set is an untagged choice type,
+ * the location of that component in the ordering will depend on
+ * the tag of the choice component being encoded.
+ * </blockquote>
+ * <h3>11: Restrictions on BER employed by both CER and DER</h3>
+ * <h4>11.5 Set and sequence components with default value </h4>
+ * The encoding of a set value or sequence value shall not include
+ * an encoding for any component value which is equal to
+ * its default value.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DLSet
+ extends ASN1Set
+{
+ private int bodyLength = -1;
+
+ /**
+ * create an empty set
+ */
+ public DLSet()
+ {
+ }
+
+ /**
+ * @param element - a single object that makes up the set.
+ */
+ public DLSet(ASN1Encodable element)
+ {
+ super(element);
+ }
+
+ /**
+ * @param elementVector - a vector of objects making up the set.
+ */
+ public DLSet(ASN1EncodableVector elementVector)
+ {
+ super(elementVector, false);
+ }
+
+ /**
+ * create a set from an array of objects.
+ */
+ public DLSet(ASN1Encodable[] elements)
+ {
+ super(elements, false);
+ }
+
+ DLSet(boolean isSorted, ASN1Encodable[] elements)
+ {
+ super(isSorted, elements);
+ }
+
+ private int getBodyLength() throws IOException
+ {
+ if (bodyLength < 0)
+ {
+ int count = elements.length;
+ int totalLength = 0;
+
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
+ totalLength += dlObject.encodedLength();
+ }
+
+ this.bodyLength = totalLength;
+ }
+
+ return bodyLength;
+ }
+
+ int encodedLength() throws IOException
+ {
+ int length = getBodyLength();
+
+ return 1 + StreamUtil.calculateBodyLength(length) + length;
+ }
+
+ /**
+ * A note on the implementation:
+ * <p>
+ * As DL requires the constructed, definite-length model to
+ * be used for structured types, this varies slightly from the
+ * ASN.1 descriptions given. Rather than just outputting SET,
+ * we also have to specify CONSTRUCTED, and the objects length.
+ */
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ if (withTag)
+ {
+ out.write(BERTags.SET | BERTags.CONSTRUCTED);
+ }
+
+ ASN1OutputStream dlOut = out.getDLSubStream();
+
+ int count = elements.length;
+ if (bodyLength >= 0 || count > 16)
+ {
+ out.writeLength(getBodyLength());
+
+ for (int i = 0; i < count; ++i)
+ {
+ dlOut.writePrimitive(elements[i].toASN1Primitive(), true);
+ }
+ }
+ else
+ {
+ int totalLength = 0;
+
+ ASN1Primitive[] dlObjects = new ASN1Primitive[count];
+ for (int i = 0; i < count; ++i)
+ {
+ ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
+ dlObjects[i] = dlObject;
+ totalLength += dlObject.encodedLength();
+ }
+
+ this.bodyLength = totalLength;
+ out.writeLength(totalLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ dlOut.writePrimitive(dlObjects[i], true);
+ }
+ }
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSetParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSetParser.java
new file mode 100644
index 00000000..99d2ad9d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSetParser.java
@@ -0,0 +1,62 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Parser class for DL SETs.
+ *
+ * TODO The class is only publicly visible to support 'instanceof' checks; provide an alternative
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DLSetParser
+ implements ASN1SetParser
+{
+ private ASN1StreamParser _parser;
+
+ DLSetParser(ASN1StreamParser parser)
+ {
+ this._parser = parser;
+ }
+
+ /**
+ * Return the next object in the SET.
+ *
+ * @return next object in SET.
+ * @throws IOException if there is an issue loading the object.
+ */
+ public ASN1Encodable readObject()
+ throws IOException
+ {
+ return _parser.readObject();
+ }
+
+ /**
+ * Return an in memory, encodable, representation of the SET.
+ *
+ * @return a DLSet.
+ * @throws IOException if there is an issue loading the data.
+ */
+ public ASN1Primitive getLoadedObject()
+ throws IOException
+ {
+ return new DLSet(_parser.readVector());
+ }
+
+ /**
+ * Return a DLSet representing this parser and its contents.
+ *
+ * @return a DLSet
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ try
+ {
+ return getLoadedObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException(e.getMessage(), e);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLTaggedObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLTaggedObject.java
new file mode 100644
index 00000000..c6904a4b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLTaggedObject.java
@@ -0,0 +1,75 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Definite Length TaggedObject - in ASN.1 notation this is any object preceded by
+ * a [n] where n is some number - these are assumed to follow the construction
+ * rules (as with sequences).
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DLTaggedObject
+ extends ASN1TaggedObject
+{
+ /**
+ * @param explicit true if an explicitly tagged object.
+ * @param tagNo the tag number for this object.
+ * @param obj the tagged object.
+ */
+ public DLTaggedObject(
+ boolean explicit,
+ int tagNo,
+ ASN1Encodable obj)
+ {
+ super(explicit, tagNo, obj);
+ }
+
+ boolean isConstructed()
+ {
+ return explicit || obj.toASN1Primitive().toDLObject().isConstructed();
+ }
+
+ int encodedLength()
+ throws IOException
+ {
+ int length = obj.toASN1Primitive().toDLObject().encodedLength();
+
+ if (explicit)
+ {
+ return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
+ }
+ else
+ {
+ // header length already in calculation
+ length = length - 1;
+
+ return StreamUtil.calculateTagLength(tagNo) + length;
+ }
+ }
+
+ void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
+
+ int flags = BERTags.TAGGED;
+ if (explicit || primitive.isConstructed())
+ {
+ flags |= BERTags.CONSTRUCTED;
+ }
+
+ out.writeTag(withTag, flags, tagNo);
+
+ if (explicit)
+ {
+ out.writeLength(primitive.encodedLength());
+ }
+
+ out.getDLSubStream().writePrimitive(primitive, explicit);
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return this;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DateUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DateUtil.java
new file mode 100644
index 00000000..8cecd075
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DateUtil.java
@@ -0,0 +1,81 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+class DateUtil
+{
+ private static Long ZERO = longValueOf(0);
+
+ private static final Map localeCache = new HashMap();
+
+ static Locale EN_Locale = forEN();
+
+ private static Locale forEN()
+ {
+ if ("en".equalsIgnoreCase(Locale.getDefault().getLanguage()))
+ {
+ return Locale.getDefault();
+ }
+
+ Locale[] locales = Locale.getAvailableLocales();
+ for (int i = 0; i != locales.length; i++)
+ {
+ if ("en".equalsIgnoreCase(locales[i].getLanguage()))
+ {
+ return locales[i];
+ }
+ }
+
+ return Locale.getDefault();
+ }
+
+ static Date epochAdjust(Date date)
+ throws ParseException
+ {
+ Locale locale = Locale.getDefault();
+ if (locale == null)
+ {
+ return date;
+ }
+
+ synchronized (localeCache)
+ {
+ Long adj = (Long)localeCache.get(locale);
+
+ if (adj == null)
+ {
+ SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
+ long v = dateF.parse("19700101000000GMT+00:00").getTime();
+
+ if (v == 0)
+ {
+ adj = ZERO;
+ }
+ else
+ {
+ adj = longValueOf(v);
+ }
+
+ localeCache.put(locale, adj);
+ }
+
+ if (adj != ZERO)
+ {
+ return new Date(date.getTime() - adj.longValue());
+ }
+
+ return date;
+ }
+ }
+
+ private static Long longValueOf(long v)
+ {
+ return Long.valueOf(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DefiniteLengthInputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DefiniteLengthInputStream.java
new file mode 100644
index 00000000..f951b426
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DefiniteLengthInputStream.java
@@ -0,0 +1,145 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.android.internal.org.bouncycastle.util.io.Streams;
+
+/**
+ * Parse data stream of expected ASN.1 data expecting definite-length encoding..
+ */
+class DefiniteLengthInputStream
+ extends LimitedInputStream
+{
+ private static final byte[] EMPTY_BYTES = new byte[0];
+
+ private final int _originalLength;
+
+ private int _remaining;
+
+ DefiniteLengthInputStream(
+ InputStream in,
+ int length,
+ int limit)
+ {
+ super(in, limit);
+
+ if (length < 0)
+ {
+ throw new IllegalArgumentException("negative lengths not allowed");
+ }
+
+ this._originalLength = length;
+ this._remaining = length;
+
+ if (length == 0)
+ {
+ setParentEofDetect(true);
+ }
+ }
+
+ int getRemaining()
+ {
+ return _remaining;
+ }
+
+ public int read()
+ throws IOException
+ {
+ if (_remaining == 0)
+ {
+ return -1;
+ }
+
+ int b = _in.read();
+
+ if (b < 0)
+ {
+ throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
+ }
+
+ if (--_remaining == 0)
+ {
+ setParentEofDetect(true);
+ }
+
+ return b;
+ }
+
+ public int read(byte[] buf, int off, int len)
+ throws IOException
+ {
+ if (_remaining == 0)
+ {
+ return -1;
+ }
+
+ int toRead = Math.min(len, _remaining);
+ int numRead = _in.read(buf, off, toRead);
+
+ if (numRead < 0)
+ {
+ throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
+ }
+
+ if ((_remaining -= numRead) == 0)
+ {
+ setParentEofDetect(true);
+ }
+
+ return numRead;
+ }
+
+ void readAllIntoByteArray(byte[] buf)
+ throws IOException
+ {
+ if (_remaining != buf.length)
+ {
+ throw new IllegalArgumentException("buffer length not right for data");
+ }
+
+ if (_remaining == 0)
+ {
+ return;
+ }
+
+ // make sure it's safe to do this!
+ int limit = getLimit();
+ if (_remaining >= limit)
+ {
+ throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit);
+ }
+
+ if ((_remaining -= Streams.readFully(_in, buf)) != 0)
+ {
+ throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
+ }
+ setParentEofDetect(true);
+ }
+
+ byte[] toByteArray()
+ throws IOException
+ {
+ if (_remaining == 0)
+ {
+ return EMPTY_BYTES;
+ }
+
+ // make sure it's safe to do this!
+ int limit = getLimit();
+ if (_remaining >= limit)
+ {
+ throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit);
+ }
+
+ byte[] bytes = new byte[_remaining];
+ if ((_remaining -= Streams.readFully(_in, bytes)) != 0)
+ {
+ throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
+ }
+ setParentEofDetect(true);
+ return bytes;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/InMemoryRepresentable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/InMemoryRepresentable.java
new file mode 100644
index 00000000..96e16fed
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/InMemoryRepresentable.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * Interface implemented by objects that can be converted from streaming to in-memory objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface InMemoryRepresentable
+{
+ /**
+ * Get the in-memory representation of the ASN.1 object.
+ * @return an ASN1Primitive representing the loaded object.
+ * @throws IOException for bad input data.
+ */
+ ASN1Primitive getLoadedObject()
+ throws IOException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/IndefiniteLengthInputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/IndefiniteLengthInputStream.java
new file mode 100644
index 00000000..faf410de
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/IndefiniteLengthInputStream.java
@@ -0,0 +1,112 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+class IndefiniteLengthInputStream
+ extends LimitedInputStream
+{
+ private int _b1;
+ private int _b2;
+ private boolean _eofReached = false;
+ private boolean _eofOn00 = true;
+
+ IndefiniteLengthInputStream(
+ InputStream in,
+ int limit)
+ throws IOException
+ {
+ super(in, limit);
+
+ _b1 = in.read();
+ _b2 = in.read();
+
+ if (_b2 < 0)
+ {
+ // Corrupted stream
+ throw new EOFException();
+ }
+
+ checkForEof();
+ }
+
+ void setEofOn00(
+ boolean eofOn00)
+ {
+ _eofOn00 = eofOn00;
+ checkForEof();
+ }
+
+ private boolean checkForEof()
+ {
+ if (!_eofReached && _eofOn00 && (_b1 == 0x00 && _b2 == 0x00))
+ {
+ _eofReached = true;
+ setParentEofDetect(true);
+ }
+ return _eofReached;
+ }
+
+ public int read(byte[] b, int off, int len)
+ throws IOException
+ {
+ // Only use this optimisation if we aren't checking for 00
+ if (_eofOn00 || len < 3)
+ {
+ return super.read(b, off, len);
+ }
+
+ if (_eofReached)
+ {
+ return -1;
+ }
+
+ int numRead = _in.read(b, off + 2, len - 2);
+
+ if (numRead < 0)
+ {
+ // Corrupted stream
+ throw new EOFException();
+ }
+
+ b[off] = (byte)_b1;
+ b[off + 1] = (byte)_b2;
+
+ _b1 = _in.read();
+ _b2 = _in.read();
+
+ if (_b2 < 0)
+ {
+ // Corrupted stream
+ throw new EOFException();
+ }
+
+ return numRead + 2;
+ }
+
+ public int read()
+ throws IOException
+ {
+ if (checkForEof())
+ {
+ return -1;
+ }
+
+ int b = _in.read();
+
+ if (b < 0)
+ {
+ // Corrupted stream
+ throw new EOFException();
+ }
+
+ int v = _b1;
+
+ _b1 = _b2;
+ _b2 = b;
+
+ return v;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyConstructionEnumeration.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyConstructionEnumeration.java
new file mode 100644
index 00000000..31ba8971
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyConstructionEnumeration.java
@@ -0,0 +1,47 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+class LazyConstructionEnumeration
+ implements Enumeration
+{
+ private ASN1InputStream aIn;
+ private Object nextObj;
+
+ public LazyConstructionEnumeration(byte[] encoded)
+ {
+ aIn = new ASN1InputStream(encoded, true);
+ nextObj = readObject();
+ }
+
+ public boolean hasMoreElements()
+ {
+ return nextObj != null;
+ }
+
+ public Object nextElement()
+ {
+ if (nextObj != null)
+ {
+ Object o = nextObj;
+ nextObj = readObject();
+ return o;
+ }
+ throw new NoSuchElementException();
+ }
+
+ private Object readObject()
+ {
+ try
+ {
+ return aIn.readObject();
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("malformed DER construction: " + e, e);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyEncodedSequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyEncodedSequence.java
new file mode 100644
index 00000000..cd914ee7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyEncodedSequence.java
@@ -0,0 +1,129 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Iterator;
+
+/**
+ * Note: this class is for processing DER/DL encoded sequences only.
+ */
+class LazyEncodedSequence
+ extends ASN1Sequence
+{
+ private byte[] encoded;
+
+ LazyEncodedSequence(byte[] encoded) throws IOException
+ {
+ // NOTE: Initially, the actual 'elements' will be empty
+ super();
+
+ this.encoded = encoded;
+ }
+
+ public synchronized ASN1Encodable getObjectAt(int index)
+ {
+ force();
+
+ return super.getObjectAt(index);
+ }
+
+ public synchronized Enumeration getObjects()
+ {
+ if (null != encoded)
+ {
+ return new LazyConstructionEnumeration(encoded);
+ }
+
+ return super.getObjects();
+ }
+
+ public synchronized int hashCode()
+ {
+ force();
+
+ return super.hashCode();
+ }
+
+ public synchronized Iterator<ASN1Encodable> iterator()
+ {
+ force();
+
+ return super.iterator();
+ }
+
+ public synchronized int size()
+ {
+ force();
+
+ return super.size();
+ }
+
+ public synchronized ASN1Encodable[] toArray()
+ {
+ force();
+
+ return super.toArray();
+ }
+
+ ASN1Encodable[] toArrayInternal()
+ {
+ force();
+
+ return super.toArrayInternal();
+ }
+
+ synchronized int encodedLength()
+ throws IOException
+ {
+ if (null != encoded)
+ {
+ return 1 + StreamUtil.calculateBodyLength(encoded.length) + encoded.length;
+ }
+
+ return super.toDLObject().encodedLength();
+ }
+
+ synchronized void encode(ASN1OutputStream out, boolean withTag) throws IOException
+ {
+ if (null != encoded)
+ {
+ out.writeEncoded(withTag, BERTags.SEQUENCE | BERTags.CONSTRUCTED, encoded);
+ }
+ else
+ {
+ super.toDLObject().encode(out, withTag);
+ }
+ }
+
+ synchronized ASN1Primitive toDERObject()
+ {
+ force();
+
+ return super.toDERObject();
+ }
+
+ synchronized ASN1Primitive toDLObject()
+ {
+ force();
+
+ return super.toDLObject();
+ }
+
+ private void force()
+ {
+ if (null != encoded)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ Enumeration en = new LazyConstructionEnumeration(encoded);
+ while (en.hasMoreElements())
+ {
+ v.add((ASN1Primitive)en.nextElement());
+ }
+
+ this.elements = v.takeElements();
+ this.encoded = null;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LimitedInputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LimitedInputStream.java
new file mode 100644
index 00000000..a4b51950
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LimitedInputStream.java
@@ -0,0 +1,35 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.InputStream;
+
+/**
+ * Internal use stream that allows reading of a limited number of bytes from a wrapped stream.
+ */
+abstract class LimitedInputStream
+ extends InputStream
+{
+ protected final InputStream _in;
+ private int _limit;
+
+ LimitedInputStream(
+ InputStream in,
+ int limit)
+ {
+ this._in = in;
+ this._limit = limit;
+ }
+
+ int getLimit()
+ {
+ return _limit;
+ }
+
+ protected void setParentEofDetect(boolean on)
+ {
+ if (_in instanceof IndefiniteLengthInputStream)
+ {
+ ((IndefiniteLengthInputStream)_in).setEofOn00(on);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/OIDTokenizer.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/OIDTokenizer.java
new file mode 100644
index 00000000..2a1d8cdf
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/OIDTokenizer.java
@@ -0,0 +1,65 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+/**
+ * Class for breaking up an OID into it's component tokens, ala
+ * java.util.StringTokenizer. We need this class as some of the
+ * lightweight Java environment don't support classes like
+ * StringTokenizer.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OIDTokenizer
+{
+ private String oid;
+ private int index;
+
+ /**
+ * Base constructor.
+ *
+ * @param oid the string representation of the OID.
+ */
+ public OIDTokenizer(
+ String oid)
+ {
+ this.oid = oid;
+ this.index = 0;
+ }
+
+ /**
+ * Return whether or not there are more tokens in this tokenizer.
+ *
+ * @return true if there are more tokens, false otherwise.
+ */
+ public boolean hasMoreTokens()
+ {
+ return (index != -1);
+ }
+
+ /**
+ * Return the next token in the underlying String.
+ *
+ * @return the next token.
+ */
+ public String nextToken()
+ {
+ if (index == -1)
+ {
+ return null;
+ }
+
+ String token;
+ int end = oid.indexOf('.', index);
+
+ if (end == -1)
+ {
+ token = oid.substring(index);
+ index = -1;
+ return token;
+ }
+
+ token = oid.substring(index, end);
+
+ index = end + 1;
+ return token;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/StreamUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/StreamUtil.java
new file mode 100644
index 00000000..4795bbd9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/StreamUtil.java
@@ -0,0 +1,119 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.channels.FileChannel;
+
+class StreamUtil
+{
+ // Android-removed: Check max memory at runtime
+ // private static final long MAX_MEMORY = Runtime.getRuntime().maxMemory();
+
+ /**
+ * Find out possible longest length, capped by available memory.
+ *
+ * @param in input stream of interest
+ * @return length calculation or MAX_VALUE.
+ */
+ static int findLimit(InputStream in)
+ {
+ if (in instanceof LimitedInputStream)
+ {
+ return ((LimitedInputStream)in).getLimit();
+ }
+ else if (in instanceof ASN1InputStream)
+ {
+ return ((ASN1InputStream)in).getLimit();
+ }
+ else if (in instanceof ByteArrayInputStream)
+ {
+ return ((ByteArrayInputStream)in).available();
+ }
+ else if (in instanceof FileInputStream)
+ {
+ try
+ {
+ FileChannel channel = ((FileInputStream)in).getChannel();
+ long size = (channel != null) ? channel.size() : Integer.MAX_VALUE;
+
+ if (size < Integer.MAX_VALUE)
+ {
+ return (int)size;
+ }
+ }
+ catch (IOException e)
+ {
+ // ignore - they'll find out soon enough!
+ }
+ }
+
+ // BEGIN Android-changed: Check max memory at runtime
+ long maxMemory = Runtime.getRuntime().maxMemory();
+ if (maxMemory > Integer.MAX_VALUE)
+ {
+ return Integer.MAX_VALUE;
+ }
+
+ return (int) maxMemory;
+ // END Android-changed: Check max memory at runtime
+ }
+
+ static int calculateBodyLength(
+ int length)
+ {
+ int count = 1;
+
+ if (length > 127)
+ {
+ int size = 1;
+ int val = length;
+
+ while ((val >>>= 8) != 0)
+ {
+ size++;
+ }
+
+ for (int i = (size - 1) * 8; i >= 0; i -= 8)
+ {
+ count++;
+ }
+ }
+
+ return count;
+ }
+
+ static int calculateTagLength(int tagNo)
+ throws IOException
+ {
+ int length = 1;
+
+ if (tagNo >= 31)
+ {
+ if (tagNo < 128)
+ {
+ length++;
+ }
+ else
+ {
+ byte[] stack = new byte[5];
+ int pos = stack.length;
+
+ stack[--pos] = (byte)(tagNo & 0x7F);
+
+ do
+ {
+ tagNo >>= 7;
+ stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
+ }
+ while (tagNo > 127);
+
+ length += stack.length - pos;
+ }
+ }
+
+ return length;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
new file mode 100644
index 00000000..4310f102
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
@@ -0,0 +1,183 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.bc;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * Object Identifiers belonging to iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle (1.3.6.1.4.1.22554)
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface BCObjectIdentifiers
+{
+ /**
+ * iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle
+ *<p>
+ * 1.3.6.1.4.1.22554
+ */
+ public static final ASN1ObjectIdentifier bc = new ASN1ObjectIdentifier("1.3.6.1.4.1.22554");
+
+ /**
+ * pbe(1) algorithms
+ * <p>
+ * 1.3.6.1.4.1.22554.1
+ */
+ public static final ASN1ObjectIdentifier bc_pbe = bc.branch("1");
+
+ /**
+ * SHA-1(1)
+ * <p>
+ * 1.3.6.1.4.1.22554.1.1
+ */
+ public static final ASN1ObjectIdentifier bc_pbe_sha1 = bc_pbe.branch("1");
+
+ /** SHA-2.SHA-256; 1.3.6.1.4.1.22554.1.2.1 */
+ public static final ASN1ObjectIdentifier bc_pbe_sha256 = bc_pbe.branch("2.1");
+ /** SHA-2.SHA-384; 1.3.6.1.4.1.22554.1.2.2 */
+ public static final ASN1ObjectIdentifier bc_pbe_sha384 = bc_pbe.branch("2.2");
+ /** SHA-2.SHA-512; 1.3.6.1.4.1.22554.1.2.3 */
+ public static final ASN1ObjectIdentifier bc_pbe_sha512 = bc_pbe.branch("2.3");
+ /** SHA-2.SHA-224; 1.3.6.1.4.1.22554.1.2.4 */
+ public static final ASN1ObjectIdentifier bc_pbe_sha224 = bc_pbe.branch("2.4");
+
+ /**
+ * PKCS-5(1)|PKCS-12(2)
+ */
+ /** SHA-1.PKCS5; 1.3.6.1.4.1.22554.1.1.1 */
+ public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs5 = bc_pbe_sha1.branch("1");
+ /** SHA-1.PKCS12; 1.3.6.1.4.1.22554.1.1.2 */
+ public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12 = bc_pbe_sha1.branch("2");
+
+ /** SHA-256.PKCS12; 1.3.6.1.4.1.22554.1.2.1.1 */
+ public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs5 = bc_pbe_sha256.branch("1");
+ /** SHA-256.PKCS12; 1.3.6.1.4.1.22554.1.2.1.2 */
+ public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12 = bc_pbe_sha256.branch("2");
+
+ /**
+ * AES(1) . (CBC-128(2)|CBC-192(22)|CBC-256(42))
+ */
+ /** 1.3.6.1.4.1.22554.1.1.2.1.2 */
+ public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes128_cbc = bc_pbe_sha1_pkcs12.branch("1.2");
+ /** 1.3.6.1.4.1.22554.1.1.2.1.22 */
+ public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes192_cbc = bc_pbe_sha1_pkcs12.branch("1.22");
+ /** 1.3.6.1.4.1.22554.1.1.2.1.42 */
+ public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes256_cbc = bc_pbe_sha1_pkcs12.branch("1.42");
+
+ /** 1.3.6.1.4.1.22554.1.1.2.2.2 */
+ public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes128_cbc = bc_pbe_sha256_pkcs12.branch("1.2");
+ /** 1.3.6.1.4.1.22554.1.1.2.2.22 */
+ public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes192_cbc = bc_pbe_sha256_pkcs12.branch("1.22");
+ /** 1.3.6.1.4.1.22554.1.1.2.2.42 */
+ public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes256_cbc = bc_pbe_sha256_pkcs12.branch("1.42");
+
+ /**
+ * signature(2) algorithms
+ */
+ public static final ASN1ObjectIdentifier bc_sig = bc.branch("2");
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ /**
+ * Sphincs-256
+ *
+ public static final ASN1ObjectIdentifier sphincs256 = bc_sig.branch("1");
+ public static final ASN1ObjectIdentifier sphincs256_with_BLAKE512 = sphincs256.branch("1");
+ public static final ASN1ObjectIdentifier sphincs256_with_SHA512 = sphincs256.branch("2");
+ public static final ASN1ObjectIdentifier sphincs256_with_SHA3_512 = sphincs256.branch("3");
+
+ /**
+ * XMSS
+ */
+ public static final ASN1ObjectIdentifier xmss = bc_sig.branch("2");
+ public static final ASN1ObjectIdentifier xmss_SHA256ph = xmss.branch("1");
+ public static final ASN1ObjectIdentifier xmss_SHA512ph = xmss.branch("2");
+ public static final ASN1ObjectIdentifier xmss_SHAKE128ph = xmss.branch("3");
+ public static final ASN1ObjectIdentifier xmss_SHAKE256ph = xmss.branch("4");
+ public static final ASN1ObjectIdentifier xmss_SHA256 = xmss.branch("5");
+ public static final ASN1ObjectIdentifier xmss_SHA512 = xmss.branch("6");
+ public static final ASN1ObjectIdentifier xmss_SHAKE128 = xmss.branch("7");
+ public static final ASN1ObjectIdentifier xmss_SHAKE256 = xmss.branch("8");
+
+ /**
+ * XMSS^MT
+ */
+ public static final ASN1ObjectIdentifier xmss_mt = bc_sig.branch("3");
+ public static final ASN1ObjectIdentifier xmss_mt_SHA256ph = xmss_mt.branch("1");
+ public static final ASN1ObjectIdentifier xmss_mt_SHA512ph = xmss_mt.branch("2");
+ public static final ASN1ObjectIdentifier xmss_mt_SHAKE128ph = xmss_mt.branch("3");
+ public static final ASN1ObjectIdentifier xmss_mt_SHAKE256ph = xmss_mt.branch("4");
+ public static final ASN1ObjectIdentifier xmss_mt_SHA256 = xmss_mt.branch("5");
+ public static final ASN1ObjectIdentifier xmss_mt_SHA512 = xmss_mt.branch("6");
+ public static final ASN1ObjectIdentifier xmss_mt_SHAKE128 = xmss_mt.branch("7");
+ public static final ASN1ObjectIdentifier xmss_mt_SHAKE256 = xmss_mt.branch("8");
+
+ // old OIDs.
+ /**
+ * @deprecated use xmss_SHA256ph
+ */
+ public static final ASN1ObjectIdentifier xmss_with_SHA256 = xmss_SHA256ph;
+ /**
+ * @deprecated use xmss_SHA512ph
+ */
+ public static final ASN1ObjectIdentifier xmss_with_SHA512 = xmss_SHA512ph;
+ /**
+ * @deprecated use xmss_SHAKE128ph
+ */
+ public static final ASN1ObjectIdentifier xmss_with_SHAKE128 = xmss_SHAKE128ph;
+ /**
+ * @deprecated use xmss_SHAKE256ph
+ */
+ public static final ASN1ObjectIdentifier xmss_with_SHAKE256 = xmss_SHAKE256ph;
+
+ /**
+ * @deprecated use xmss_mt_SHA256ph
+ */
+ public static final ASN1ObjectIdentifier xmss_mt_with_SHA256 = xmss_mt_SHA256ph;
+ /**
+ * @deprecated use xmss_mt_SHA512ph
+ */
+ public static final ASN1ObjectIdentifier xmss_mt_with_SHA512 = xmss_mt_SHA512ph;
+ /**
+ * @deprecated use xmss_mt_SHAKE128ph
+ */
+ public static final ASN1ObjectIdentifier xmss_mt_with_SHAKE128 = xmss_mt_SHAKE128;
+ /**
+ * @deprecated use xmss_mt_SHAKE256ph
+ */
+ public static final ASN1ObjectIdentifier xmss_mt_with_SHAKE256 = xmss_mt_SHAKE256;
+
+ /**
+ * qTESLA
+ */
+ public static final ASN1ObjectIdentifier qTESLA = bc_sig.branch("4");
+
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_I = qTESLA.branch("1");
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_III_size = qTESLA.branch("2");
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_III_speed = qTESLA.branch("3");
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_p_I = qTESLA.branch("4");
+ public static final ASN1ObjectIdentifier qTESLA_Rnd1_p_III = qTESLA.branch("5");
+
+
+ public static final ASN1ObjectIdentifier qTESLA_p_I = qTESLA.branch("11");
+ public static final ASN1ObjectIdentifier qTESLA_p_III = qTESLA.branch("12");
+
+ /**
+ * key_exchange(3) algorithms
+ *
+ public static final ASN1ObjectIdentifier bc_exch = bc.branch("3");
+
+ /**
+ * NewHope
+ *
+ public static final ASN1ObjectIdentifier newHope = bc_exch.branch("1");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * X.509 extension(4) values
+ * <p>
+ * 1.3.6.1.4.1.22554.4
+ */
+ public static final ASN1ObjectIdentifier bc_ext = bc.branch("4");
+
+ public static final ASN1ObjectIdentifier linkedCertificate = bc_ext.branch("1");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Attribute.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Attribute.java
new file mode 100644
index 00000000..979108c8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Attribute.java
@@ -0,0 +1,112 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.cms;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <a href="https://tools.ietf.org/html/rfc5652#page-14">RFC 5652</a>:
+ * Attribute is a pair of OID (as type identifier) + set of values.
+ * <p>
+ * <pre>
+ * Attribute ::= SEQUENCE {
+ * attrType OBJECT IDENTIFIER,
+ * attrValues SET OF AttributeValue
+ * }
+ *
+ * AttributeValue ::= ANY
+ * </pre>
+ * <p>
+ * General rule on values is that same AttributeValue must not be included
+ * multiple times into the set. That is, if the value is a SET OF INTEGERs,
+ * then having same value repeated is wrong: (1, 1), but different values is OK: (1, 2).
+ * Normally the AttributeValue syntaxes are more complicated than that.
+ * <p>
+ * General rule of Attribute usage is that the {@link Attributes} containers
+ * must not have multiple Attribute:s with same attrType (OID) there.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Attribute
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier attrType;
+ private ASN1Set attrValues;
+
+ /**
+ * Return an Attribute object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link Attribute} object
+ * <li> {@link com.android.internal.org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with Attribute structure inside
+ * </ul>
+ *
+ * @param o the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static Attribute getInstance(
+ Object o)
+ {
+ if (o instanceof Attribute)
+ {
+ return (Attribute)o;
+ }
+
+ if (o != null)
+ {
+ return new Attribute(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ private Attribute(
+ ASN1Sequence seq)
+ {
+ attrType = (ASN1ObjectIdentifier)seq.getObjectAt(0);
+ attrValues = (ASN1Set)seq.getObjectAt(1);
+ }
+
+ public Attribute(
+ ASN1ObjectIdentifier attrType,
+ ASN1Set attrValues)
+ {
+ this.attrType = attrType;
+ this.attrValues = attrValues;
+ }
+
+ public ASN1ObjectIdentifier getAttrType()
+ {
+ return attrType;
+ }
+
+ public ASN1Set getAttrValues()
+ {
+ return attrValues;
+ }
+
+ public ASN1Encodable[] getAttributeValues()
+ {
+ return attrValues.toArray();
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(attrType);
+ v.add(attrValues);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/AttributeTable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/AttributeTable.java
new file mode 100644
index 00000000..e9cc12bd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/AttributeTable.java
@@ -0,0 +1,242 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.cms;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.DERSet;
+
+/**
+ * This is helper tool to construct {@link Attributes} sets.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AttributeTable
+{
+ private Hashtable attributes = new Hashtable();
+
+ public AttributeTable(
+ Hashtable attrs)
+ {
+ attributes = copyTable(attrs);
+ }
+
+ public AttributeTable(
+ ASN1EncodableVector v)
+ {
+ for (int i = 0; i != v.size(); i++)
+ {
+ Attribute a = Attribute.getInstance(v.get(i));
+
+ addAttribute(a.getAttrType(), a);
+ }
+ }
+
+ public AttributeTable(
+ ASN1Set s)
+ {
+ for (int i = 0; i != s.size(); i++)
+ {
+ Attribute a = Attribute.getInstance(s.getObjectAt(i));
+
+ addAttribute(a.getAttrType(), a);
+ }
+ }
+
+ public AttributeTable(
+ Attribute attr)
+ {
+ addAttribute(attr.getAttrType(), attr);
+ }
+
+ public AttributeTable(
+ Attributes attrs)
+ {
+ this(ASN1Set.getInstance(attrs.toASN1Primitive()));
+ }
+
+ private void addAttribute(
+ ASN1ObjectIdentifier oid,
+ Attribute a)
+ {
+ Object value = attributes.get(oid);
+
+ if (value == null)
+ {
+ attributes.put(oid, a);
+ }
+ else
+ {
+ Vector v;
+
+ if (value instanceof Attribute)
+ {
+ v = new Vector();
+
+ v.addElement(value);
+ v.addElement(a);
+ }
+ else
+ {
+ v = (Vector)value;
+
+ v.addElement(a);
+ }
+
+ attributes.put(oid, v);
+ }
+ }
+
+ /**
+ * Return the first attribute matching the OBJECT IDENTIFIER oid.
+ *
+ * @param oid type of attribute required.
+ * @return first attribute found of type oid.
+ */
+ public Attribute get(
+ ASN1ObjectIdentifier oid)
+ {
+ Object value = attributes.get(oid);
+
+ if (value instanceof Vector)
+ {
+ return (Attribute)((Vector)value).elementAt(0);
+ }
+
+ return (Attribute)value;
+ }
+
+ /**
+ * Return all the attributes matching the OBJECT IDENTIFIER oid. The vector will be
+ * empty if there are no attributes of the required type present.
+ *
+ * @param oid type of attribute required.
+ * @return a vector of all the attributes found of type oid.
+ */
+ public ASN1EncodableVector getAll(
+ ASN1ObjectIdentifier oid)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ Object value = attributes.get(oid);
+
+ if (value instanceof Vector)
+ {
+ Enumeration e = ((Vector)value).elements();
+
+ while (e.hasMoreElements())
+ {
+ v.add((Attribute)e.nextElement());
+ }
+ }
+ else if (value != null)
+ {
+ v.add((Attribute)value);
+ }
+
+ return v;
+ }
+
+ public int size()
+ {
+ int size = 0;
+
+ for (Enumeration en = attributes.elements(); en.hasMoreElements();)
+ {
+ Object o = en.nextElement();
+
+ if (o instanceof Vector)
+ {
+ size += ((Vector)o).size();
+ }
+ else
+ {
+ size++;
+ }
+ }
+
+ return size;
+ }
+
+ public Hashtable toHashtable()
+ {
+ return copyTable(attributes);
+ }
+
+ public ASN1EncodableVector toASN1EncodableVector()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ Enumeration e = attributes.elements();
+
+ while (e.hasMoreElements())
+ {
+ Object value = e.nextElement();
+
+ if (value instanceof Vector)
+ {
+ Enumeration en = ((Vector)value).elements();
+
+ while (en.hasMoreElements())
+ {
+ v.add(Attribute.getInstance(en.nextElement()));
+ }
+ }
+ else
+ {
+ v.add(Attribute.getInstance(value));
+ }
+ }
+
+ return v;
+ }
+
+ public Attributes toASN1Structure()
+ {
+ return new Attributes(this.toASN1EncodableVector());
+ }
+
+ private Hashtable copyTable(
+ Hashtable in)
+ {
+ Hashtable out = new Hashtable();
+ Enumeration e = in.keys();
+
+ while (e.hasMoreElements())
+ {
+ Object key = e.nextElement();
+
+ out.put(key, in.get(key));
+ }
+
+ return out;
+ }
+
+ /**
+ * Return a new table with the passed in attribute added.
+ *
+ * @param attrType the type of the attribute to add.
+ * @param attrValue the value corresponding to the attribute (will be wrapped in a SET).
+ * @return a new table with the extra attribute in it.
+ */
+ public AttributeTable add(ASN1ObjectIdentifier attrType, ASN1Encodable attrValue)
+ {
+ AttributeTable newTable = new AttributeTable(attributes);
+
+ newTable.addAttribute(attrType, new Attribute(attrType, new DERSet(attrValue)));
+
+ return newTable;
+ }
+
+ public AttributeTable remove(ASN1ObjectIdentifier attrType)
+ {
+ AttributeTable newTable = new AttributeTable(attributes);
+
+ newTable.attributes.remove(attrType);
+
+ return newTable;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Attributes.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Attributes.java
new file mode 100644
index 00000000..56edaf51
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Attributes.java
@@ -0,0 +1,95 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.cms;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DLSet;
+
+/**
+ * <a href="https://tools.ietf.org/html/rfc5652">RFC 5652</a> defines
+ * 5 "SET OF Attribute" entities with 5 different names.
+ * This is common implementation for them all:
+ * <pre>
+ * SignedAttributes ::= SET SIZE (1..MAX) OF Attribute
+ * UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute
+ * UnprotectedAttributes ::= SET SIZE (1..MAX) OF Attribute
+ * AuthAttributes ::= SET SIZE (1..MAX) OF Attribute
+ * UnauthAttributes ::= SET SIZE (1..MAX) OF Attribute
+ *
+ * Attributes ::=
+ * SET SIZE(1..MAX) OF Attribute
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Attributes
+ extends ASN1Object
+{
+ private ASN1Set attributes;
+
+ private Attributes(ASN1Set set)
+ {
+ attributes = set;
+ }
+
+ public Attributes(ASN1EncodableVector v)
+ {
+ attributes = new DLSet(v);
+ }
+
+ /**
+ * Return an Attribute set object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link Attributes} object
+ * <li> {@link com.android.internal.org.bouncycastle.asn1.ASN1Set#getInstance(java.lang.Object) ASN1Set} input formats with Attributes structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static Attributes getInstance(Object obj)
+ {
+ if (obj instanceof Attributes)
+ {
+ return (Attributes)obj;
+ }
+ else if (obj != null)
+ {
+ return new Attributes(ASN1Set.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static Attributes getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Set.getInstance(obj, explicit));
+ }
+
+ public Attribute[] getAttributes()
+ {
+ Attribute[] rv = new Attribute[attributes.size()];
+
+ for (int i = 0; i != rv.length; i++)
+ {
+ rv[i] = Attribute.getInstance(attributes.getObjectAt(i));
+ }
+
+ return rv;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return attributes;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java
new file mode 100644
index 00000000..9c6427b0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java
@@ -0,0 +1,138 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.cms;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * From RFC 6211
+ * <pre>
+ * CMSAlgorithmProtection ::= SEQUENCE {
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * signatureAlgorithm [1] SignatureAlgorithmIdentifier OPTIONAL,
+ * macAlgorithm [2] MessageAuthenticationCodeAlgorithm
+ * OPTIONAL
+ * }
+ * (WITH COMPONENTS { signatureAlgorithm PRESENT,
+ * macAlgorithm ABSENT } |
+ * WITH COMPONENTS { signatureAlgorithm ABSENT,
+ * macAlgorithm PRESENT })
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CMSAlgorithmProtection
+ extends ASN1Object
+{
+ public static final int SIGNATURE = 1;
+ public static final int MAC = 2;
+
+ private final AlgorithmIdentifier digestAlgorithm;
+ private final AlgorithmIdentifier signatureAlgorithm;
+ private final AlgorithmIdentifier macAlgorithm;
+
+ public CMSAlgorithmProtection(AlgorithmIdentifier digestAlgorithm, int type, AlgorithmIdentifier algorithmIdentifier)
+ {
+ if (digestAlgorithm == null || algorithmIdentifier == null)
+ {
+ throw new NullPointerException("AlgorithmIdentifiers cannot be null");
+ }
+
+ this.digestAlgorithm = digestAlgorithm;
+
+ if (type == 1)
+ {
+ this.signatureAlgorithm = algorithmIdentifier;
+ this.macAlgorithm = null;
+ }
+ else if (type == 2)
+ {
+ this.signatureAlgorithm = null;
+ this.macAlgorithm = algorithmIdentifier;
+ }
+ else
+ {
+ throw new IllegalArgumentException("Unknown type: " + type);
+ }
+ }
+
+ private CMSAlgorithmProtection(ASN1Sequence sequence)
+ {
+ if (sequence.size() != 2)
+ {
+ throw new IllegalArgumentException("Sequence wrong size: One of signatureAlgorithm or macAlgorithm must be present");
+ }
+
+ this.digestAlgorithm = AlgorithmIdentifier.getInstance(sequence.getObjectAt(0));
+
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(sequence.getObjectAt(1));
+ if (tagged.getTagNo() == 1)
+ {
+ this.signatureAlgorithm = AlgorithmIdentifier.getInstance(tagged, false);
+ this.macAlgorithm = null;
+ }
+ else if (tagged.getTagNo() == 2)
+ {
+ this.signatureAlgorithm = null;
+
+ this.macAlgorithm = AlgorithmIdentifier.getInstance(tagged, false);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Unknown tag found: " + tagged.getTagNo());
+ }
+ }
+
+ public static CMSAlgorithmProtection getInstance(
+ Object obj)
+ {
+ if (obj instanceof CMSAlgorithmProtection)
+ {
+ return (CMSAlgorithmProtection)obj;
+ }
+ else if (obj != null)
+ {
+ return new CMSAlgorithmProtection(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+
+ public AlgorithmIdentifier getDigestAlgorithm()
+ {
+ return digestAlgorithm;
+ }
+
+ public AlgorithmIdentifier getMacAlgorithm()
+ {
+ return macAlgorithm;
+ }
+
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return signatureAlgorithm;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(digestAlgorithm);
+ if (signatureAlgorithm != null)
+ {
+ v.add(new DERTaggedObject(false, 1, signatureAlgorithm));
+ }
+ if (macAlgorithm != null)
+ {
+ v.add(new DERTaggedObject(false, 2, macAlgorithm));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/CMSAttributes.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/CMSAttributes.java
new file mode 100644
index 00000000..2bc8e778
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/CMSAttributes.java
@@ -0,0 +1,38 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.cms;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+
+
+/**
+ * <a href="https://tools.ietf.org/html/rfc5652">RFC 5652</a> CMS attribute OID constants.
+ * and <a href="https://tools.ietf.org/html/rfc6211">RFC 6211</a> Algorithm Identifier Protection Attribute.
+ * <pre>
+ * contentType ::= 1.2.840.113549.1.9.3
+ * messageDigest ::= 1.2.840.113549.1.9.4
+ * signingTime ::= 1.2.840.113549.1.9.5
+ * counterSignature ::= 1.2.840.113549.1.9.6
+ *
+ * contentHint ::= 1.2.840.113549.1.9.16.2.4
+ * cmsAlgorithmProtect := 1.2.840.113549.1.9.52
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+
+public interface CMSAttributes
+{
+ /** PKCS#9: 1.2.840.113549.1.9.3 */
+ ASN1ObjectIdentifier contentType = PKCSObjectIdentifiers.pkcs_9_at_contentType;
+ /** PKCS#9: 1.2.840.113549.1.9.4 */
+ ASN1ObjectIdentifier messageDigest = PKCSObjectIdentifiers.pkcs_9_at_messageDigest;
+ /** PKCS#9: 1.2.840.113549.1.9.5 */
+ ASN1ObjectIdentifier signingTime = PKCSObjectIdentifiers.pkcs_9_at_signingTime;
+ /** PKCS#9: 1.2.840.113549.1.9.6 */
+ ASN1ObjectIdentifier counterSignature = PKCSObjectIdentifiers.pkcs_9_at_counterSignature;
+ /** PKCS#9: 1.2.840.113549.1.9.16.6.2.4 - See <a href="https://tools.ietf.org/html/rfc2634">RFC 2634</a> */
+ ASN1ObjectIdentifier contentHint = PKCSObjectIdentifiers.id_aa_contentHint;
+
+ ASN1ObjectIdentifier cmsAlgorithmProtect = PKCSObjectIdentifiers.id_aa_cmsAlgorithmProtect;
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/CMSObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/CMSObjectIdentifiers.java
new file mode 100644
index 00000000..38f5a552
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/CMSObjectIdentifiers.java
@@ -0,0 +1,47 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.cms;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CMSObjectIdentifiers
+{
+ /** PKCS#7: 1.2.840.113549.1.7.1 */
+ static final ASN1ObjectIdentifier data = PKCSObjectIdentifiers.data;
+ /** PKCS#7: 1.2.840.113549.1.7.2 */
+ static final ASN1ObjectIdentifier signedData = PKCSObjectIdentifiers.signedData;
+ /** PKCS#7: 1.2.840.113549.1.7.3 */
+ static final ASN1ObjectIdentifier envelopedData = PKCSObjectIdentifiers.envelopedData;
+ /** PKCS#7: 1.2.840.113549.1.7.4 */
+ static final ASN1ObjectIdentifier signedAndEnvelopedData = PKCSObjectIdentifiers.signedAndEnvelopedData;
+ /** PKCS#7: 1.2.840.113549.1.7.5 */
+ static final ASN1ObjectIdentifier digestedData = PKCSObjectIdentifiers.digestedData;
+ /** PKCS#7: 1.2.840.113549.1.7.6 */
+ static final ASN1ObjectIdentifier encryptedData = PKCSObjectIdentifiers.encryptedData;
+ /** PKCS#9: 1.2.840.113549.1.9.16.1.2 -- smime ct authData */
+ static final ASN1ObjectIdentifier authenticatedData = PKCSObjectIdentifiers.id_ct_authData;
+ /** PKCS#9: 1.2.840.113549.1.9.16.1.9 -- smime ct compressedData */
+ static final ASN1ObjectIdentifier compressedData = PKCSObjectIdentifiers.id_ct_compressedData;
+ /** PKCS#9: 1.2.840.113549.1.9.16.1.23 -- smime ct authEnvelopedData */
+ static final ASN1ObjectIdentifier authEnvelopedData = PKCSObjectIdentifiers.id_ct_authEnvelopedData;
+ /** PKCS#9: 1.2.840.113549.1.9.16.1.31 -- smime ct timestampedData*/
+ static final ASN1ObjectIdentifier timestampedData = PKCSObjectIdentifiers.id_ct_timestampedData;
+
+ /**
+ * The other Revocation Info arc
+ * <p>
+ * <pre>
+ * id-ri OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
+ * dod(6) internet(1) security(5) mechanisms(5) pkix(7) ri(16) }
+ * </pre>
+ */
+ static final ASN1ObjectIdentifier id_ri = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.16");
+
+ /** 1.3.6.1.5.5.7.16.2 */
+ static final ASN1ObjectIdentifier id_ri_ocsp_response = id_ri.branch("2");
+ /** 1.3.6.1.5.5.7.16.4 */
+ static final ASN1ObjectIdentifier id_ri_scvp = id_ri.branch("4");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/ContentInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/ContentInfo.java
new file mode 100644
index 00000000..51bbd3ea
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/ContentInfo.java
@@ -0,0 +1,132 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.cms;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.BERSequence;
+import com.android.internal.org.bouncycastle.asn1.BERTaggedObject;
+
+/**
+ * <a href="https://tools.ietf.org/html/rfc5652#section-3">RFC 5652</a> ContentInfo, and
+ * <a href="https://tools.ietf.org/html/rfc5652#section-5.2">RFC 5652</a> EncapsulatedContentInfo objects.
+ *
+ * <pre>
+ * ContentInfo ::= SEQUENCE {
+ * contentType ContentType,
+ * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL
+ * }
+ *
+ * EncapsulatedContentInfo ::= SEQUENCE {
+ * eContentType ContentType,
+ * eContent [0] EXPLICIT OCTET STRING OPTIONAL
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ContentInfo
+ extends ASN1Object
+ implements CMSObjectIdentifiers
+{
+ private ASN1ObjectIdentifier contentType;
+ private ASN1Encodable content;
+
+ /**
+ * Return an ContentInfo object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link ContentInfo} object
+ * <li> {@link com.android.internal.org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with ContentInfo structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static ContentInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof ContentInfo)
+ {
+ return (ContentInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new ContentInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static ContentInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * @deprecated use getInstance()
+ */
+ public ContentInfo(
+ ASN1Sequence seq)
+ {
+ if (seq.size() < 1 || seq.size() > 2)
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+
+ contentType = (ASN1ObjectIdentifier)seq.getObjectAt(0);
+
+ if (seq.size() > 1)
+ {
+ ASN1TaggedObject tagged = (ASN1TaggedObject)seq.getObjectAt(1);
+ if (!tagged.isExplicit() || tagged.getTagNo() != 0)
+ {
+ throw new IllegalArgumentException("Bad tag for 'content'");
+ }
+
+ content = tagged.getObject();
+ }
+ }
+
+ public ContentInfo(
+ ASN1ObjectIdentifier contentType,
+ ASN1Encodable content)
+ {
+ this.contentType = contentType;
+ this.content = content;
+ }
+
+ public ASN1ObjectIdentifier getContentType()
+ {
+ return contentType;
+ }
+
+ public ASN1Encodable getContent()
+ {
+ return content;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(contentType);
+
+ if (content != null)
+ {
+ v.add(new BERTaggedObject(0, content));
+ }
+
+ return new BERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/GCMParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/GCMParameters.java
new file mode 100644
index 00000000..e08c5a28
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/GCMParameters.java
@@ -0,0 +1,104 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.cms;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * <a href="https://tools.ietf.org/html/rfc5084">RFC 5084</a>: GCMParameters object.
+ * <p>
+ * <pre>
+ GCMParameters ::= SEQUENCE {
+ aes-nonce OCTET STRING, -- recommended size is 12 octets
+ aes-ICVlen AES-GCM-ICVlen DEFAULT 12 }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GCMParameters
+ extends ASN1Object
+{
+ private byte[] nonce;
+ private int icvLen;
+
+ /**
+ * Return an GCMParameters object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link com.android.internal.org.bouncycastle.asn1.cms.GCMParameters} object
+ * <li> {@link com.android.internal.org.bouncycastle.asn1.ASN1Sequence#getInstance(Object) ASN1Sequence} input formats with GCMParameters structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static GCMParameters getInstance(
+ Object obj)
+ {
+ if (obj instanceof GCMParameters)
+ {
+ return (GCMParameters)obj;
+ }
+ else if (obj != null)
+ {
+ return new GCMParameters(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private GCMParameters(
+ ASN1Sequence seq)
+ {
+ this.nonce = ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets();
+
+ if (seq.size() == 2)
+ {
+ this.icvLen = ASN1Integer.getInstance(seq.getObjectAt(1)).intValueExact();
+ }
+ else
+ {
+ this.icvLen = 12;
+ }
+ }
+
+ public GCMParameters(
+ byte[] nonce,
+ int icvLen)
+ {
+ this.nonce = Arrays.clone(nonce);
+ this.icvLen = icvLen;
+ }
+
+ public byte[] getNonce()
+ {
+ return Arrays.clone(nonce);
+ }
+
+ public int getIcvLen()
+ {
+ return icvLen;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(new DEROctetString(nonce));
+
+ if (icvLen != 12)
+ {
+ v.add(new ASN1Integer(icvLen));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java
new file mode 100644
index 00000000..6c15b2bc
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java
@@ -0,0 +1,140 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.cms;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.Certificate;
+import com.android.internal.org.bouncycastle.asn1.x509.X509CertificateStructure;
+import com.android.internal.org.bouncycastle.asn1.x509.X509Name;
+
+/**
+ * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.4">RFC 5652</a>: IssuerAndSerialNumber object.
+ * <p>
+ * <pre>
+ * IssuerAndSerialNumber ::= SEQUENCE {
+ * issuer Name,
+ * serialNumber CertificateSerialNumber
+ * }
+ *
+ * CertificateSerialNumber ::= INTEGER -- See RFC 5280
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class IssuerAndSerialNumber
+ extends ASN1Object
+{
+ private X500Name name;
+ private ASN1Integer serialNumber;
+
+ /**
+ * Return an IssuerAndSerialNumber object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link IssuerAndSerialNumber} object
+ * <li> {@link com.android.internal.org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with IssuerAndSerialNumber structure inside
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static IssuerAndSerialNumber getInstance(
+ Object obj)
+ {
+ if (obj instanceof IssuerAndSerialNumber)
+ {
+ return (IssuerAndSerialNumber)obj;
+ }
+ else if (obj != null)
+ {
+ return new IssuerAndSerialNumber(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * @deprecated use getInstance() method.
+ */
+ public IssuerAndSerialNumber(
+ ASN1Sequence seq)
+ {
+ this.name = X500Name.getInstance(seq.getObjectAt(0));
+ this.serialNumber = (ASN1Integer)seq.getObjectAt(1);
+ }
+
+ public IssuerAndSerialNumber(
+ Certificate certificate)
+ {
+ this.name = certificate.getIssuer();
+ this.serialNumber = certificate.getSerialNumber();
+ }
+
+ /**
+ * @deprecated use constructor taking Certificate
+ */
+ public IssuerAndSerialNumber(
+ X509CertificateStructure certificate)
+ {
+ this.name = certificate.getIssuer();
+ this.serialNumber = certificate.getSerialNumber();
+ }
+
+ public IssuerAndSerialNumber(
+ X500Name name,
+ BigInteger serialNumber)
+ {
+ this.name = name;
+ this.serialNumber = new ASN1Integer(serialNumber);
+ }
+
+ /**
+ * @deprecated use X500Name constructor
+ */
+ public IssuerAndSerialNumber(
+ X509Name name,
+ BigInteger serialNumber)
+ {
+ this.name = X500Name.getInstance(name);
+ this.serialNumber = new ASN1Integer(serialNumber);
+ }
+
+ /**
+ * @deprecated use X500Name constructor
+ */
+ public IssuerAndSerialNumber(
+ X509Name name,
+ ASN1Integer serialNumber)
+ {
+ this.name = X500Name.getInstance(name);
+ this.serialNumber = serialNumber;
+ }
+
+ public X500Name getName()
+ {
+ return name;
+ }
+
+ public ASN1Integer getSerialNumber()
+ {
+ return serialNumber;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(name);
+ v.add(serialNumber);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignedData.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignedData.java
new file mode 100644
index 00000000..dda5b4d4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignedData.java
@@ -0,0 +1,332 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.cms;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.BERSequence;
+import com.android.internal.org.bouncycastle.asn1.BERSet;
+import com.android.internal.org.bouncycastle.asn1.BERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">RFC 5652</a>:
+ * <p>
+ * A signed data object containing multitude of {@link SignerInfo}s.
+ * <pre>
+ * SignedData ::= SEQUENCE {
+ * version CMSVersion,
+ * digestAlgorithms DigestAlgorithmIdentifiers,
+ * encapContentInfo EncapsulatedContentInfo,
+ * certificates [0] IMPLICIT CertificateSet OPTIONAL,
+ * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+ * signerInfos SignerInfos
+ * }
+ *
+ * DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
+ *
+ * SignerInfos ::= SET OF SignerInfo
+ * </pre>
+ * <p>
+ * The version calculation uses following ruleset from RFC 5652 section 5.1:
+ * <pre>
+ * IF ((certificates is present) AND
+ * (any certificates with a type of other are present)) OR
+ * ((crls is present) AND
+ * (any crls with a type of other are present))
+ * THEN version MUST be 5
+ * ELSE
+ * IF (certificates is present) AND
+ * (any version 2 attribute certificates are present)
+ * THEN version MUST be 4
+ * ELSE
+ * IF ((certificates is present) AND
+ * (any version 1 attribute certificates are present)) OR
+ * (any SignerInfo structures are version 3) OR
+ * (encapContentInfo eContentType is other than id-data)
+ * THEN version MUST be 3
+ * ELSE version MUST be 1
+ * </pre>
+ * <p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignedData
+ extends ASN1Object
+{
+ private static final ASN1Integer VERSION_1 = new ASN1Integer(1);
+ private static final ASN1Integer VERSION_3 = new ASN1Integer(3);
+ private static final ASN1Integer VERSION_4 = new ASN1Integer(4);
+ private static final ASN1Integer VERSION_5 = new ASN1Integer(5);
+
+ private ASN1Integer version;
+ private ASN1Set digestAlgorithms;
+ private ContentInfo contentInfo;
+ private ASN1Set certificates;
+ private ASN1Set crls;
+ private ASN1Set signerInfos;
+ private boolean certsBer;
+ private boolean crlsBer;
+
+ /**
+ * Return a SignedData object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link SignedData} object
+ * <li> {@link com.android.internal.org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with SignedData structure inside
+ * </ul>
+ *
+ * @param o the object we want converted.
+ * @return a reference that can be assigned to SignedData (may be null)
+ * @throws IllegalArgumentException if the object cannot be converted.
+ */
+ public static SignedData getInstance(
+ Object o)
+ {
+ if (o instanceof SignedData)
+ {
+ return (SignedData)o;
+ }
+ else if (o != null)
+ {
+ return new SignedData(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public SignedData(
+ ASN1Set digestAlgorithms,
+ ContentInfo contentInfo,
+ ASN1Set certificates,
+ ASN1Set crls,
+ ASN1Set signerInfos)
+ {
+ this.version = calculateVersion(contentInfo.getContentType(), certificates, crls, signerInfos);
+ this.digestAlgorithms = digestAlgorithms;
+ this.contentInfo = contentInfo;
+ this.certificates = certificates;
+ this.crls = crls;
+ this.signerInfos = signerInfos;
+ this.crlsBer = crls instanceof BERSet;
+ this.certsBer = certificates instanceof BERSet;
+ }
+
+
+ private ASN1Integer calculateVersion(
+ ASN1ObjectIdentifier contentOid,
+ ASN1Set certs,
+ ASN1Set crls,
+ ASN1Set signerInfs)
+ {
+ boolean otherCert = false;
+ boolean otherCrl = false;
+ boolean attrCertV1Found = false;
+ boolean attrCertV2Found = false;
+
+ if (certs != null)
+ {
+ for (Enumeration en = certs.getObjects(); en.hasMoreElements();)
+ {
+ Object obj = en.nextElement();
+ if (obj instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(obj);
+
+ if (tagged.getTagNo() == 1)
+ {
+ attrCertV1Found = true;
+ }
+ else if (tagged.getTagNo() == 2)
+ {
+ attrCertV2Found = true;
+ }
+ else if (tagged.getTagNo() == 3)
+ {
+ otherCert = true;
+ }
+ }
+ }
+ }
+
+ if (otherCert)
+ {
+ return new ASN1Integer(5);
+ }
+
+ if (crls != null) // no need to check if otherCert is true
+ {
+ for (Enumeration en = crls.getObjects(); en.hasMoreElements();)
+ {
+ Object obj = en.nextElement();
+ if (obj instanceof ASN1TaggedObject)
+ {
+ otherCrl = true;
+ }
+ }
+ }
+
+ if (otherCrl)
+ {
+ return VERSION_5;
+ }
+
+ if (attrCertV2Found)
+ {
+ return VERSION_4;
+ }
+
+ if (attrCertV1Found)
+ {
+ return VERSION_3;
+ }
+
+ if (checkForVersion3(signerInfs))
+ {
+ return VERSION_3;
+ }
+
+ if (!CMSObjectIdentifiers.data.equals(contentOid))
+ {
+ return VERSION_3;
+ }
+
+ return VERSION_1;
+ }
+
+ private boolean checkForVersion3(ASN1Set signerInfs)
+ {
+ for (Enumeration e = signerInfs.getObjects(); e.hasMoreElements();)
+ {
+ SignerInfo s = SignerInfo.getInstance(e.nextElement());
+
+ if (s.getVersion().intValueExact() == 3)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private SignedData(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ version = ASN1Integer.getInstance(e.nextElement());
+ digestAlgorithms = ((ASN1Set)e.nextElement());
+ contentInfo = ContentInfo.getInstance(e.nextElement());
+
+ while (e.hasMoreElements())
+ {
+ ASN1Primitive o = (ASN1Primitive)e.nextElement();
+
+ //
+ // an interesting feature of SignedData is that there appear
+ // to be varying implementations...
+ // for the moment we ignore anything which doesn't fit.
+ //
+ if (o instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = (ASN1TaggedObject)o;
+
+ switch (tagged.getTagNo())
+ {
+ case 0:
+ certsBer = tagged instanceof BERTaggedObject;
+ certificates = ASN1Set.getInstance(tagged, false);
+ break;
+ case 1:
+ crlsBer = tagged instanceof BERTaggedObject;
+ crls = ASN1Set.getInstance(tagged, false);
+ break;
+ default:
+ throw new IllegalArgumentException("unknown tag value " + tagged.getTagNo());
+ }
+ }
+ else
+ {
+ signerInfos = (ASN1Set)o;
+ }
+ }
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public ASN1Set getDigestAlgorithms()
+ {
+ return digestAlgorithms;
+ }
+
+ public ContentInfo getEncapContentInfo()
+ {
+ return contentInfo;
+ }
+
+ public ASN1Set getCertificates()
+ {
+ return certificates;
+ }
+
+ public ASN1Set getCRLs()
+ {
+ return crls;
+ }
+
+ public ASN1Set getSignerInfos()
+ {
+ return signerInfos;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(6);
+
+ v.add(version);
+ v.add(digestAlgorithms);
+ v.add(contentInfo);
+
+ if (certificates != null)
+ {
+ if (certsBer)
+ {
+ v.add(new BERTaggedObject(false, 0, certificates));
+ }
+ else
+ {
+ v.add(new DERTaggedObject(false, 0, certificates));
+ }
+ }
+
+ if (crls != null)
+ {
+ if (crlsBer)
+ {
+ v.add(new BERTaggedObject(false, 1, crls));
+ }
+ else
+ {
+ v.add(new DERTaggedObject(false, 1, crls));
+ }
+ }
+
+ v.add(signerInfos);
+
+ return new BERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignerIdentifier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignerIdentifier.java
new file mode 100644
index 00000000..fdc2d9b8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignerIdentifier.java
@@ -0,0 +1,116 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.cms;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * <a href="https://tools.ietf.org/html/rfc5652#section-5.3">RFC 5652</a>:
+ * Identify who signed the containing {@link SignerInfo} object.
+ * <p>
+ * The certificates referred to by this are at containing {@link SignedData} structure.
+ * <p>
+ * <pre>
+ * SignerIdentifier ::= CHOICE {
+ * issuerAndSerialNumber IssuerAndSerialNumber,
+ * subjectKeyIdentifier [0] SubjectKeyIdentifier
+ * }
+ *
+ * SubjectKeyIdentifier ::= OCTET STRING
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignerIdentifier
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private ASN1Encodable id;
+
+ public SignerIdentifier(
+ IssuerAndSerialNumber id)
+ {
+ this.id = id;
+ }
+
+ public SignerIdentifier(
+ ASN1OctetString id)
+ {
+ this.id = new DERTaggedObject(false, 0, id);
+ }
+
+ public SignerIdentifier(
+ ASN1Primitive id)
+ {
+ this.id = id;
+ }
+
+ /**
+ * Return a SignerIdentifier object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link SignerIdentifier} object
+ * <li> {@link IssuerAndSerialNumber} object
+ * <li> {@link com.android.internal.org.bouncycastle.asn1.ASN1OctetString#getInstance(java.lang.Object) ASN1OctetString} input formats with SignerIdentifier structure inside
+ * <li> {@link com.android.internal.org.bouncycastle.asn1.ASN1Primitive ASN1Primitive} for SignerIdentifier constructor.
+ * </ul>
+ *
+ * @param o the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static SignerIdentifier getInstance(
+ Object o)
+ {
+ if (o == null || o instanceof SignerIdentifier)
+ {
+ return (SignerIdentifier)o;
+ }
+
+ if (o instanceof IssuerAndSerialNumber)
+ {
+ return new SignerIdentifier((IssuerAndSerialNumber)o);
+ }
+
+ if (o instanceof ASN1OctetString)
+ {
+ return new SignerIdentifier((ASN1OctetString)o);
+ }
+
+ if (o instanceof ASN1Primitive)
+ {
+ return new SignerIdentifier((ASN1Primitive)o);
+ }
+
+ throw new IllegalArgumentException(
+ "Illegal object in SignerIdentifier: " + o.getClass().getName());
+ }
+
+ public boolean isTagged()
+ {
+ return (id instanceof ASN1TaggedObject);
+ }
+
+ public ASN1Encodable getId()
+ {
+ if (id instanceof ASN1TaggedObject)
+ {
+ return ASN1OctetString.getInstance((ASN1TaggedObject)id, false);
+ }
+
+ return id;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return id.toASN1Primitive();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignerInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignerInfo.java
new file mode 100644
index 00000000..32fc718c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignerInfo.java
@@ -0,0 +1,284 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.cms;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * <a href="https://tools.ietf.org/html/rfc5652#section-5.3">RFC 5652</a>:
+ * Signature container per Signer, see {@link SignerIdentifier}.
+ * <pre>
+ * PKCS#7:
+ *
+ * SignerInfo ::= SEQUENCE {
+ * version Version,
+ * sid SignerIdentifier,
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
+ * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
+ * encryptedDigest EncryptedDigest,
+ * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
+ * }
+ *
+ * EncryptedDigest ::= OCTET STRING
+ *
+ * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * -----------------------------------------
+ *
+ * RFC 5652:
+ *
+ * SignerInfo ::= SEQUENCE {
+ * version CMSVersion,
+ * sid SignerIdentifier,
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
+ * signatureAlgorithm SignatureAlgorithmIdentifier,
+ * signature SignatureValue,
+ * unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL
+ * }
+ *
+ * -- {@link SignerIdentifier} referenced certificates are at containing
+ * -- {@link SignedData} certificates element.
+ *
+ * SignerIdentifier ::= CHOICE {
+ * issuerAndSerialNumber {@link IssuerAndSerialNumber},
+ * subjectKeyIdentifier [0] SubjectKeyIdentifier }
+ *
+ * -- See {@link Attributes} for generalized SET OF {@link Attribute}
+ *
+ * SignedAttributes ::= SET SIZE (1..MAX) OF Attribute
+ * UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute
+ *
+ * {@link Attribute} ::= SEQUENCE {
+ * attrType OBJECT IDENTIFIER,
+ * attrValues SET OF AttributeValue }
+ *
+ * AttributeValue ::= ANY
+ *
+ * SignatureValue ::= OCTET STRING
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignerInfo
+ extends ASN1Object
+{
+ private ASN1Integer version;
+ private SignerIdentifier sid;
+ private AlgorithmIdentifier digAlgorithm;
+ private ASN1Set authenticatedAttributes;
+ private AlgorithmIdentifier digEncryptionAlgorithm;
+ private ASN1OctetString encryptedDigest;
+ private ASN1Set unauthenticatedAttributes;
+
+ /**
+ * Return a SignerInfo object from the given input
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link SignerInfo} object
+ * <li> {@link com.android.internal.org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with SignerInfo structure inside
+ * </ul>
+ *
+ * @param o the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static SignerInfo getInstance(
+ Object o)
+ throws IllegalArgumentException
+ {
+ if (o instanceof SignerInfo)
+ {
+ return (SignerInfo)o;
+ }
+ else if (o != null)
+ {
+ return new SignerInfo(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ /**
+ *
+ * @param sid
+ * @param digAlgorithm CMS knows as 'digestAlgorithm'
+ * @param authenticatedAttributes CMS knows as 'signedAttrs'
+ * @param digEncryptionAlgorithm CMS knows as 'signatureAlgorithm'
+ * @param encryptedDigest CMS knows as 'signature'
+ * @param unauthenticatedAttributes CMS knows as 'unsignedAttrs'
+ */
+ public SignerInfo(
+ SignerIdentifier sid,
+ AlgorithmIdentifier digAlgorithm,
+ ASN1Set authenticatedAttributes,
+ AlgorithmIdentifier digEncryptionAlgorithm,
+ ASN1OctetString encryptedDigest,
+ ASN1Set unauthenticatedAttributes)
+ {
+ if (sid.isTagged())
+ {
+ this.version = new ASN1Integer(3);
+ }
+ else
+ {
+ this.version = new ASN1Integer(1);
+ }
+
+ this.sid = sid;
+ this.digAlgorithm = digAlgorithm;
+ this.authenticatedAttributes = authenticatedAttributes;
+ this.digEncryptionAlgorithm = digEncryptionAlgorithm;
+ this.encryptedDigest = encryptedDigest;
+ this.unauthenticatedAttributes = unauthenticatedAttributes;
+ }
+
+ /**
+ *
+ * @param sid
+ * @param digAlgorithm CMS knows as 'digestAlgorithm'
+ * @param authenticatedAttributes CMS knows as 'signedAttrs'
+ * @param digEncryptionAlgorithm CMS knows as 'signatureAlgorithm'
+ * @param encryptedDigest CMS knows as 'signature'
+ * @param unauthenticatedAttributes CMS knows as 'unsignedAttrs'
+ */
+ public SignerInfo(
+ SignerIdentifier sid,
+ AlgorithmIdentifier digAlgorithm,
+ Attributes authenticatedAttributes,
+ AlgorithmIdentifier digEncryptionAlgorithm,
+ ASN1OctetString encryptedDigest,
+ Attributes unauthenticatedAttributes)
+ {
+ if (sid.isTagged())
+ {
+ this.version = new ASN1Integer(3);
+ }
+ else
+ {
+ this.version = new ASN1Integer(1);
+ }
+
+ this.sid = sid;
+ this.digAlgorithm = digAlgorithm;
+ this.authenticatedAttributes = ASN1Set.getInstance(authenticatedAttributes);
+ this.digEncryptionAlgorithm = digEncryptionAlgorithm;
+ this.encryptedDigest = encryptedDigest;
+ this.unauthenticatedAttributes = ASN1Set.getInstance(unauthenticatedAttributes);
+ }
+
+ /**
+ * @deprecated use getInstance() method.
+ */
+ public SignerInfo(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ version = (ASN1Integer)e.nextElement();
+ sid = SignerIdentifier.getInstance(e.nextElement());
+ digAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement());
+
+ Object obj = e.nextElement();
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ authenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)obj, false);
+
+ digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement());
+ }
+ else
+ {
+ authenticatedAttributes = null;
+ digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(obj);
+ }
+
+ encryptedDigest = DEROctetString.getInstance(e.nextElement());
+
+ if (e.hasMoreElements())
+ {
+ unauthenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false);
+ }
+ else
+ {
+ unauthenticatedAttributes = null;
+ }
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public SignerIdentifier getSID()
+ {
+ return sid;
+ }
+
+ public ASN1Set getAuthenticatedAttributes()
+ {
+ return authenticatedAttributes;
+ }
+
+ public AlgorithmIdentifier getDigestAlgorithm()
+ {
+ return digAlgorithm;
+ }
+
+ public ASN1OctetString getEncryptedDigest()
+ {
+ return encryptedDigest;
+ }
+
+ public AlgorithmIdentifier getDigestEncryptionAlgorithm()
+ {
+ return digEncryptionAlgorithm;
+ }
+
+ public ASN1Set getUnauthenticatedAttributes()
+ {
+ return unauthenticatedAttributes;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(7);
+
+ v.add(version);
+ v.add(sid);
+ v.add(digAlgorithm);
+
+ if (authenticatedAttributes != null)
+ {
+ v.add(new DERTaggedObject(false, 0, authenticatedAttributes));
+ }
+
+ v.add(digEncryptionAlgorithm);
+ v.add(encryptedDigest);
+
+ if (unauthenticatedAttributes != null)
+ {
+ v.add(new DERTaggedObject(false, 1, unauthenticatedAttributes));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Time.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Time.java
new file mode 100644
index 00000000..ed1b3717
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Time.java
@@ -0,0 +1,208 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.cms;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+// Android-added: Localization support
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.SimpleTimeZone;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.ASN1UTCTime;
+import com.android.internal.org.bouncycastle.asn1.DERGeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.DERUTCTime;
+
+/**
+ * <a href="https://tools.ietf.org/html/rfc5652#section-11.3">RFC 5652</a>:
+ * Dual-mode timestamp format producing either UTCTIme or GeneralizedTime.
+ * <p>
+ * <pre>
+ * Time ::= CHOICE {
+ * utcTime UTCTime,
+ * generalTime GeneralizedTime }
+ * </pre>
+ * <p>
+ * This has a constructor using java.util.Date for input which generates
+ * a {@link com.android.internal.org.bouncycastle.asn1.DERUTCTime DERUTCTime} object if the
+ * supplied datetime is in range 1950-01-01-00:00:00 UTC until 2049-12-31-23:59:60 UTC.
+ * If the datetime value is outside that range, the generated object will be
+ * {@link com.android.internal.org.bouncycastle.asn1.DERGeneralizedTime DERGeneralizedTime}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Time
+ extends ASN1Object
+ implements ASN1Choice
+{
+ ASN1Primitive time;
+
+ public static Time getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+ /**
+ * @deprecated use getInstance()
+ */
+ public Time(
+ ASN1Primitive time)
+ {
+ if (!(time instanceof ASN1UTCTime)
+ && !(time instanceof ASN1GeneralizedTime))
+ {
+ throw new IllegalArgumentException("unknown object passed to Time");
+ }
+
+ this.time = time;
+ }
+
+ /**
+ * Creates a time object from a given date - if the date is between 1950
+ * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
+ * is used.
+ *
+ * @param time a date object representing the time of interest.
+ */
+ public Time(
+ Date time)
+ {
+ SimpleTimeZone tz = new SimpleTimeZone(0, "Z");
+ // Android-changed: Use localized version
+ // SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss");
+ SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
+
+ dateF.setTimeZone(tz);
+
+ String d = dateF.format(time) + "Z";
+ int year = Integer.parseInt(d.substring(0, 4));
+
+ if (year < 1950 || year > 2049)
+ {
+ this.time = new DERGeneralizedTime(d);
+ }
+ else
+ {
+ this.time = new DERUTCTime(d.substring(2));
+ }
+ }
+
+ /**
+ * Creates a time object from a given date and locale - if the date is between 1950
+ * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
+ * is used. You may need to use this constructor if the default locale
+ * doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations.
+ *
+ * @param time a date object representing the time of interest.
+ * @param locale an appropriate Locale for producing an ASN.1 GeneralizedTime value.
+ */
+ public Time(
+ Date time,
+ Locale locale)
+ {
+ SimpleTimeZone tz = new SimpleTimeZone(0, "Z");
+ // BEGIN Android-changed: Use localized version
+ // SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss", locale);
+ SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
+ dateF.setCalendar(Calendar.getInstance(locale));
+ // END Android-changed: Use localized version
+
+ dateF.setTimeZone(tz);
+
+ String d = dateF.format(time) + "Z";
+ int year = Integer.parseInt(d.substring(0, 4));
+
+ if (year < 1950 || year > 2049)
+ {
+ this.time = new DERGeneralizedTime(d);
+ }
+ else
+ {
+ this.time = new DERUTCTime(d.substring(2));
+ }
+ }
+
+ /**
+ * Return a Time object from the given object.
+ * <p>
+ * Accepted inputs:
+ * <ul>
+ * <li> null &rarr; null
+ * <li> {@link Time} object
+ * <li> {@link com.android.internal.org.bouncycastle.asn1.DERUTCTime DERUTCTime} object
+ * <li> {@link com.android.internal.org.bouncycastle.asn1.DERGeneralizedTime DERGeneralizedTime} object
+ * </ul>
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static Time getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof Time)
+ {
+ return (Time)obj;
+ }
+ else if (obj instanceof ASN1UTCTime)
+ {
+ return new Time((ASN1UTCTime)obj);
+ }
+ else if (obj instanceof ASN1GeneralizedTime)
+ {
+ return new Time((ASN1GeneralizedTime)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
+ }
+
+ /**
+ * Get the date+tine as a String in full form century format.
+ */
+ public String getTime()
+ {
+ if (time instanceof ASN1UTCTime)
+ {
+ return ((ASN1UTCTime)time).getAdjustedTime();
+ }
+ else
+ {
+ return ((ASN1GeneralizedTime)time).getTime();
+ }
+ }
+
+ /**
+ * Get java.util.Date version of date+time.
+ */
+ public Date getDate()
+ {
+ try
+ {
+ if (time instanceof ASN1UTCTime)
+ {
+ return ((ASN1UTCTime)time).getAdjustedDate();
+ }
+ else
+ {
+ return ((ASN1GeneralizedTime)time).getDate();
+ }
+ }
+ catch (ParseException e)
+ { // this should never happen
+ throw new IllegalStateException("invalid date string: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return time;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java
new file mode 100644
index 00000000..798f8a1a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java
@@ -0,0 +1,112 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.eac;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * German Federal Office for Information Security
+ * (Bundesamt f&uuml;r Sicherheit in der Informationstechnik)
+ * <a href="https://www.bsi.bund.de/">https://www.bsi.bund.de/</a>
+ * <p>
+ * <a href="https://www.bsi.bund.de/EN/Publications/TechnicalGuidelines/TR03110/BSITR03110.html">BSI TR-03110</a>
+ * Technical Guideline Advanced Security Mechanisms for Machine Readable Travel Documents
+ * <p>
+ * <a href="https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03110/TR-03110_v2.1_P3pdf.pdf">
+ * Technical Guideline TR-03110-3</a>
+ * Advanced Security Mechanisms for Machine Readable Travel Documents;
+ * Part 3: Common Specifications.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface EACObjectIdentifiers
+{
+ /**
+ * <pre>
+ * bsi-de OBJECT IDENTIFIER ::= {
+ * itu-t(0) identified-organization(4) etsi(0)
+ * reserved(127) etsi-identified-organization(0) 7
+ * }
+ * </pre>
+ * OID: 0.4.0.127.0.7
+ */
+ static final ASN1ObjectIdentifier bsi_de = new ASN1ObjectIdentifier("0.4.0.127.0.7");
+
+ /**
+ * <pre>
+ * id-PK OBJECT IDENTIFIER ::= {
+ * bsi-de protocols(2) smartcard(2) 1
+ * }
+ * </pre>
+ * OID: 0.4.0.127.0.7.2.2.1
+ */
+ static final ASN1ObjectIdentifier id_PK = bsi_de.branch("2.2.1");
+
+ /** OID: 0.4.0.127.0.7.2.2.1.1 */
+ static final ASN1ObjectIdentifier id_PK_DH = id_PK.branch("1");
+ /** OID: 0.4.0.127.0.7.2.2.1.2 */
+ static final ASN1ObjectIdentifier id_PK_ECDH = id_PK.branch("2");
+
+ /**
+ * <pre>
+ * id-CA OBJECT IDENTIFIER ::= {
+ * bsi-de protocols(2) smartcard(2) 3
+ * }
+ * </pre>
+ * OID: 0.4.0.127.0.7.2.2.3
+ */
+ static final ASN1ObjectIdentifier id_CA = bsi_de.branch("2.2.3");
+ /** OID: 0.4.0.127.0.7.2.2.3.1 */
+ static final ASN1ObjectIdentifier id_CA_DH = id_CA.branch("1");
+ /** OID: 0.4.0.127.0.7.2.2.3.1.1 */
+ static final ASN1ObjectIdentifier id_CA_DH_3DES_CBC_CBC = id_CA_DH.branch("1");
+ /** OID: 0.4.0.127.0.7.2.2.3.2 */
+ static final ASN1ObjectIdentifier id_CA_ECDH = id_CA.branch("2");
+ /** OID: 0.4.0.127.0.7.2.2.3.2.1 */
+ static final ASN1ObjectIdentifier id_CA_ECDH_3DES_CBC_CBC = id_CA_ECDH.branch("1");
+
+ /**
+ * <pre>
+ * id-TA OBJECT IDENTIFIER ::= {
+ * bsi-de protocols(2) smartcard(2) 2
+ * }
+ * </pre>
+ * OID: 0.4.0.127.0.7.2.2.2
+ */
+ static final ASN1ObjectIdentifier id_TA = bsi_de.branch("2.2.2");
+
+ /** OID: 0.4.0.127.0.7.2.2.2.1 */
+ static final ASN1ObjectIdentifier id_TA_RSA = id_TA.branch("1");
+ /** OID: 0.4.0.127.0.7.2.2.2.1.1 */
+ static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_1 = id_TA_RSA.branch("1");
+ /** OID: 0.4.0.127.0.7.2.2.2.1.2 */
+ static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_256 = id_TA_RSA.branch("2");
+ /** OID: 0.4.0.127.0.7.2.2.2.1.3 */
+ static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_1 = id_TA_RSA.branch("3");
+ /** OID: 0.4.0.127.0.7.2.2.2.1.4 */
+ static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_256 = id_TA_RSA.branch("4");
+ /** OID: 0.4.0.127.0.7.2.2.2.1.5 */
+ static final ASN1ObjectIdentifier id_TA_RSA_v1_5_SHA_512 = id_TA_RSA.branch("5");
+ /** OID: 0.4.0.127.0.7.2.2.2.1.6 */
+ static final ASN1ObjectIdentifier id_TA_RSA_PSS_SHA_512 = id_TA_RSA.branch("6");
+ /** OID: 0.4.0.127.0.7.2.2.2.2 */
+ static final ASN1ObjectIdentifier id_TA_ECDSA = id_TA.branch("2");
+ /** OID: 0.4.0.127.0.7.2.2.2.2.1 */
+ static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_1 = id_TA_ECDSA.branch("1");
+ /** OID: 0.4.0.127.0.7.2.2.2.2.2 */
+ static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_224 = id_TA_ECDSA.branch("2");
+ /** OID: 0.4.0.127.0.7.2.2.2.2.3 */
+ static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_256 = id_TA_ECDSA.branch("3");
+ /** OID: 0.4.0.127.0.7.2.2.2.2.4 */
+ static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_384 = id_TA_ECDSA.branch("4");
+ /** OID: 0.4.0.127.0.7.2.2.2.2.5 */
+ static final ASN1ObjectIdentifier id_TA_ECDSA_SHA_512 = id_TA_ECDSA.branch("5");
+
+ /**
+ * <pre>
+ * id-EAC-ePassport OBJECT IDENTIFIER ::= {
+ * bsi-de applications(3) mrtd(1) roles(2) 1
+ * }
+ * </pre>
+ * OID: 0.4.0.127.0.7.3.1.2.1
+ */
+ static final ASN1ObjectIdentifier id_EAC_ePassport = bsi_de.branch("3.1.2.1");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java
new file mode 100644
index 00000000..52ed008d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java
@@ -0,0 +1,88 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.gm;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface GMObjectIdentifiers
+{
+ ASN1ObjectIdentifier sm_scheme = new ASN1ObjectIdentifier("1.2.156.10197.1");
+
+ ASN1ObjectIdentifier sm6_ecb = sm_scheme.branch("101.1");
+ ASN1ObjectIdentifier sm6_cbc = sm_scheme.branch("101.2");
+ ASN1ObjectIdentifier sm6_ofb128 = sm_scheme.branch("101.3");
+ ASN1ObjectIdentifier sm6_cfb128 = sm_scheme.branch("101.4");
+
+ ASN1ObjectIdentifier sm1_ecb = sm_scheme.branch("102.1");
+ ASN1ObjectIdentifier sm1_cbc = sm_scheme.branch("102.2");
+ ASN1ObjectIdentifier sm1_ofb128 = sm_scheme.branch("102.3");
+ ASN1ObjectIdentifier sm1_cfb128 = sm_scheme.branch("102.4");
+ ASN1ObjectIdentifier sm1_cfb1 = sm_scheme.branch("102.5");
+ ASN1ObjectIdentifier sm1_cfb8 = sm_scheme.branch("102.6");
+
+ ASN1ObjectIdentifier ssf33_ecb = sm_scheme.branch("103.1");
+ ASN1ObjectIdentifier ssf33_cbc = sm_scheme.branch("103.2");
+ ASN1ObjectIdentifier ssf33_ofb128 = sm_scheme.branch("103.3");
+ ASN1ObjectIdentifier ssf33_cfb128 = sm_scheme.branch("103.4");
+ ASN1ObjectIdentifier ssf33_cfb1 = sm_scheme.branch("103.5");
+ ASN1ObjectIdentifier ssf33_cfb8 = sm_scheme.branch("103.6");
+
+ ASN1ObjectIdentifier sms4_ecb = sm_scheme.branch("104.1");
+ ASN1ObjectIdentifier sms4_cbc = sm_scheme.branch("104.2");
+ ASN1ObjectIdentifier sms4_ofb128 = sm_scheme.branch("104.3");
+ ASN1ObjectIdentifier sms4_cfb128 = sm_scheme.branch("104.4");
+ ASN1ObjectIdentifier sms4_cfb1 = sm_scheme.branch("104.5");
+ ASN1ObjectIdentifier sms4_cfb8 = sm_scheme.branch("104.6");
+ ASN1ObjectIdentifier sms4_ctr = sm_scheme.branch("104.7");
+ ASN1ObjectIdentifier sms4_gcm = sm_scheme.branch("104.8");
+ ASN1ObjectIdentifier sms4_ccm = sm_scheme.branch("104.9");
+ ASN1ObjectIdentifier sms4_xts = sm_scheme.branch("104.10");
+ ASN1ObjectIdentifier sms4_wrap = sm_scheme.branch("104.11");
+ ASN1ObjectIdentifier sms4_wrap_pad = sm_scheme.branch("104.12");
+ ASN1ObjectIdentifier sms4_ocb = sm_scheme.branch("104.100");
+
+ ASN1ObjectIdentifier sm5 = sm_scheme.branch("201");
+
+ ASN1ObjectIdentifier sm2p256v1 = sm_scheme.branch("301");
+ ASN1ObjectIdentifier sm2sign = sm_scheme.branch("301.1");
+ ASN1ObjectIdentifier sm2exchange = sm_scheme.branch("301.2");
+ ASN1ObjectIdentifier sm2encrypt = sm_scheme.branch("301.3");
+
+ ASN1ObjectIdentifier wapip192v1 = sm_scheme.branch("301.101");
+
+ ASN1ObjectIdentifier sm2encrypt_recommendedParameters = sm2encrypt.branch("1");
+ ASN1ObjectIdentifier sm2encrypt_specifiedParameters = sm2encrypt.branch("2");
+ ASN1ObjectIdentifier sm2encrypt_with_sm3 = sm2encrypt.branch("2.1");
+ ASN1ObjectIdentifier sm2encrypt_with_sha1 = sm2encrypt.branch("2.2");
+ ASN1ObjectIdentifier sm2encrypt_with_sha224 = sm2encrypt.branch("2.3");
+ ASN1ObjectIdentifier sm2encrypt_with_sha256 = sm2encrypt.branch("2.4");
+ ASN1ObjectIdentifier sm2encrypt_with_sha384 = sm2encrypt.branch("2.5");
+ ASN1ObjectIdentifier sm2encrypt_with_sha512 = sm2encrypt.branch("2.6");
+ ASN1ObjectIdentifier sm2encrypt_with_rmd160 = sm2encrypt.branch("2.7");
+ ASN1ObjectIdentifier sm2encrypt_with_whirlpool =sm2encrypt.branch("2.8");
+ ASN1ObjectIdentifier sm2encrypt_with_blake2b512 = sm2encrypt.branch("2.9");
+ ASN1ObjectIdentifier sm2encrypt_with_blake2s256 = sm2encrypt.branch("2.10");
+ ASN1ObjectIdentifier sm2encrypt_with_md5 = sm2encrypt.branch("2.11");
+
+ ASN1ObjectIdentifier id_sm9PublicKey = sm_scheme.branch("302");
+ ASN1ObjectIdentifier sm9sign = sm_scheme.branch("302.1");
+ ASN1ObjectIdentifier sm9keyagreement = sm_scheme.branch("302.2");
+ ASN1ObjectIdentifier sm9encrypt = sm_scheme.branch("302.3");
+
+ ASN1ObjectIdentifier sm3 = sm_scheme.branch("401");
+
+ ASN1ObjectIdentifier hmac_sm3 = sm3.branch("2");
+
+ ASN1ObjectIdentifier sm2sign_with_sm3 = sm_scheme.branch("501");
+ ASN1ObjectIdentifier sm2sign_with_sha1 = sm_scheme.branch("502");
+ ASN1ObjectIdentifier sm2sign_with_sha256 = sm_scheme.branch("503");
+ ASN1ObjectIdentifier sm2sign_with_sha512 = sm_scheme.branch("504");
+ ASN1ObjectIdentifier sm2sign_with_sha224 = sm_scheme.branch("505");
+ ASN1ObjectIdentifier sm2sign_with_sha384 = sm_scheme.branch("506");
+ ASN1ObjectIdentifier sm2sign_with_rmd160 = sm_scheme.branch("507");
+ ASN1ObjectIdentifier sm2sign_with_whirlpool = sm_scheme.branch("520");
+ ASN1ObjectIdentifier sm2sign_with_blake2b512 = sm_scheme.branch("521");
+ ASN1ObjectIdentifier sm2sign_with_blake2s256 = sm_scheme.branch("522");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/iana/IANAObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/iana/IANAObjectIdentifiers.java
new file mode 100644
index 00000000..13d7b2d8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/iana/IANAObjectIdentifiers.java
@@ -0,0 +1,62 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.iana;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * IANA:
+ * { iso(1) identifier-organization(3) dod(6) internet(1) } == IETF defined things
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface IANAObjectIdentifiers
+{
+
+ /** { iso(1) identifier-organization(3) dod(6) internet(1) } == IETF defined things */
+ static final ASN1ObjectIdentifier internet = new ASN1ObjectIdentifier("1.3.6.1");
+ /** 1.3.6.1.1: Internet directory: X.500 */
+ static final ASN1ObjectIdentifier directory = internet.branch("1");
+ /** 1.3.6.1.2: Internet management */
+ static final ASN1ObjectIdentifier mgmt = internet.branch("2");
+ /** 1.3.6.1.3: */
+ static final ASN1ObjectIdentifier experimental = internet.branch("3");
+ /** 1.3.6.1.4: */
+ static final ASN1ObjectIdentifier _private = internet.branch("4");
+ /** 1.3.6.1.5: Security services */
+ static final ASN1ObjectIdentifier security = internet.branch("5");
+ /** 1.3.6.1.6: SNMPv2 -- never really used */
+ static final ASN1ObjectIdentifier SNMPv2 = internet.branch("6");
+ /** 1.3.6.1.7: mail -- never really used */
+ static final ASN1ObjectIdentifier mail = internet.branch("7");
+
+
+ // id-SHA1 OBJECT IDENTIFIER ::=
+ // {iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) ipsec(8) isakmpOakley(1)}
+ //
+
+
+ /** IANA security mechanisms; 1.3.6.1.5.5 */
+ static final ASN1ObjectIdentifier security_mechanisms = security.branch("5");
+ /** IANA security nametypes; 1.3.6.1.5.6 */
+ static final ASN1ObjectIdentifier security_nametypes = security.branch("6");
+
+ /** PKIX base OID: 1.3.6.1.5.6.6 */
+ static final ASN1ObjectIdentifier pkix = security_mechanisms.branch("6");
+
+
+ /** IPSEC base OID: 1.3.6.1.5.5.8 */
+ static final ASN1ObjectIdentifier ipsec = security_mechanisms.branch("8");
+ /** IPSEC ISAKMP-Oakley OID: 1.3.6.1.5.5.8.1 */
+ static final ASN1ObjectIdentifier isakmpOakley = ipsec.branch("1");
+
+ /** IPSEC ISAKMP-Oakley hmacMD5 OID: 1.3.6.1.5.5.8.1.1 */
+ static final ASN1ObjectIdentifier hmacMD5 = isakmpOakley.branch("1");
+ /** IPSEC ISAKMP-Oakley hmacSHA1 OID: 1.3.6.1.5.5.8.1.2 */
+ static final ASN1ObjectIdentifier hmacSHA1 = isakmpOakley.branch("2");
+
+ /** IPSEC ISAKMP-Oakley hmacTIGER OID: 1.3.6.1.5.5.8.1.3 */
+ static final ASN1ObjectIdentifier hmacTIGER = isakmpOakley.branch("3");
+
+ /** IPSEC ISAKMP-Oakley hmacRIPEMD160 OID: 1.3.6.1.5.5.8.1.4 */
+ static final ASN1ObjectIdentifier hmacRIPEMD160 = isakmpOakley.branch("4");
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java
new file mode 100644
index 00000000..9bfcbfc8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java
@@ -0,0 +1,212 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.isismtt;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * ISISMT -- Industrial Signature Interoperability Specification
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ISISMTTObjectIdentifiers
+{
+
+ /** 1.3.36.8 */
+ static final ASN1ObjectIdentifier id_isismtt = new ASN1ObjectIdentifier("1.3.36.8");
+
+ /** 1.3.36.8.1 */
+ static final ASN1ObjectIdentifier id_isismtt_cp = id_isismtt.branch("1");
+
+ /**
+ * The id-isismtt-cp-accredited OID indicates that the certificate is a
+ * qualified certificate according to Directive 1999/93/EC of the European
+ * Parliament and of the Council of 13 December 1999 on a Community
+ * Framework for Electronic Signatures, which additionally conforms the
+ * special requirements of the SigG and has been issued by an accredited CA.
+ * <p>
+ * 1.3.36.8.1.1
+ */
+
+ static final ASN1ObjectIdentifier id_isismtt_cp_accredited = id_isismtt_cp.branch("1");
+
+ /** 1.3.36.8.3 */
+ static final ASN1ObjectIdentifier id_isismtt_at = id_isismtt.branch("3");
+
+ /**
+ * Certificate extensionDate of certificate generation
+ * <pre>
+ * DateOfCertGenSyntax ::= GeneralizedTime
+ * </pre>
+ * OID: 1.3.36.8.3.1
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_dateOfCertGen = id_isismtt_at.branch("1");
+
+ /**
+ * Attribute to indicate that the certificate holder may sign in the name of
+ * a third person. May also be used as extension in a certificate.
+ * <p>
+ * OID: 1.3.36.8.3.2
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_procuration = id_isismtt_at.branch("2");
+
+ /**
+ * Attribute to indicate admissions to certain professions. May be used as
+ * attribute in attribute certificate or as extension in a certificate
+ * <p>
+ * OID: 1.3.36.8.3.3
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_admission = id_isismtt_at.branch("3");
+
+ /**
+ * Monetary limit for transactions. The QcEuMonetaryLimit QC statement MUST
+ * be used in new certificates in place of the extension/attribute
+ * MonetaryLimit since January 1, 2004. For the sake of backward
+ * compatibility with certificates already in use, SigG conforming
+ * components MUST support MonetaryLimit (as well as QcEuLimitValue).
+ * <p>
+ * OID: 1.3.36.8.3.4
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_monetaryLimit = id_isismtt_at.branch("4");
+
+ /**
+ * A declaration of majority. May be used as attribute in attribute
+ * certificate or as extension in a certificate
+ * <p>
+ * OID: 1.3.36.8.3.5
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_declarationOfMajority = id_isismtt_at.branch("5");
+
+ /**
+ * Serial number of the smart card containing the corresponding private key
+ * <pre>
+ * ICCSNSyntax ::= OCTET STRING (SIZE(8..20))
+ * </pre>
+ * <p>
+ * OID: 1.3.36.8.3.6
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_iCCSN = id_isismtt_at.branch("6");
+
+ /**
+ * Reference for a file of a smartcard that stores the public key of this
+ * certificate and that is used as "security anchor".
+ * <pre>
+ * PKReferenceSyntax ::= OCTET STRING (SIZE(20))
+ * </pre>
+ * <p>
+ * OID: 1.3.36.8.3.7
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_PKReference = id_isismtt_at.branch("7");
+
+ /**
+ * Some other restriction regarding the usage of this certificate. May be
+ * used as attribute in attribute certificate or as extension in a
+ * certificate.
+ * <pre>
+ * RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
+ * </pre>
+ * <p>
+ * OID: 1.3.36.8.3.8
+ *
+ * @see com.android.internal.org.bouncycastle.asn1.isismtt.x509.Restriction
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_restriction = id_isismtt_at.branch("8");
+
+ /**
+ * (Single)Request extension: Clients may include this extension in a
+ * (single) Request to request the responder to send the certificate in the
+ * response message along with the status information. Besides the LDAP
+ * service, this extension provides another mechanism for the distribution
+ * of certificates, which MAY optionally be provided by certificate
+ * repositories.
+ * <pre>
+ * RetrieveIfAllowed ::= BOOLEAN
+ * </pre>
+ * <p>
+ * OID: 1.3.36.8.3.9
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_retrieveIfAllowed = id_isismtt_at.branch("9");
+
+ /**
+ * SingleOCSPResponse extension: The certificate requested by the client by
+ * inserting the RetrieveIfAllowed extension in the request, will be
+ * returned in this extension.
+ * <p>
+ * OID: 1.3.36.8.3.10
+ *
+ * @see com.android.internal.org.bouncycastle.asn1.isismtt.ocsp.RequestedCertificate
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_requestedCertificate = id_isismtt_at.branch("10");
+
+ /**
+ * Base ObjectIdentifier for naming authorities
+ * <p>
+ * OID: 1.3.36.8.3.11
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_namingAuthorities = id_isismtt_at.branch("11");
+
+ /**
+ * SingleOCSPResponse extension: Date, when certificate has been published
+ * in the directory and status information has become available. Currently,
+ * accrediting authorities enforce that SigG-conforming OCSP servers include
+ * this extension in the responses.
+ *
+ * <pre>
+ * CertInDirSince ::= GeneralizedTime
+ * </pre>
+ * <p>
+ * OID: 1.3.36.8.3.12
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_certInDirSince = id_isismtt_at.branch("12");
+
+ /**
+ * Hash of a certificate in OCSP.
+ * <p>
+ * OID: 1.3.36.8.3.13
+ *
+ * @see com.android.internal.org.bouncycastle.asn1.isismtt.ocsp.CertHash
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_certHash = id_isismtt_at.branch("13");
+
+ /**
+ * <pre>
+ * NameAtBirth ::= DirectoryString(SIZE(1..64)
+ * </pre>
+ *
+ * Used in
+ * {@link com.android.internal.org.bouncycastle.asn1.x509.SubjectDirectoryAttributes SubjectDirectoryAttributes}
+ * <p>
+ * OID: 1.3.36.8.3.14
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_nameAtBirth = id_isismtt_at.branch("14");
+
+ /**
+ * Some other information of non-restrictive nature regarding the usage of
+ * this certificate. May be used as attribute in atribute certificate or as
+ * extension in a certificate.
+ *
+ * <pre>
+ * AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
+ * </pre>
+ * <p>
+ * OID: 1.3.36.8.3.15
+ *
+ * @see com.android.internal.org.bouncycastle.asn1.isismtt.x509.AdditionalInformationSyntax
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_additionalInformation = id_isismtt_at.branch("15");
+
+ /**
+ * Indicates that an attribute certificate exists, which limits the
+ * usability of this public key certificate. Whenever verifying a signature
+ * with the help of this certificate, the content of the corresponding
+ * attribute certificate should be concerned. This extension MUST be
+ * included in a PKC, if a corresponding attribute certificate (having the
+ * PKC as base certificate) contains some attribute that restricts the
+ * usability of the PKC too. Attribute certificates with restricting content
+ * MUST always be included in the signed document.
+ * <pre>
+ * LiabilityLimitationFlagSyntax ::= BOOLEAN
+ * </pre>
+ * <p>
+ * OID: 0.2.262.1.10.12.0
+ */
+ static final ASN1ObjectIdentifier id_isismtt_at_liabilityLimitationFlag = new ASN1ObjectIdentifier("0.2.262.1.10.12.0");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java
new file mode 100644
index 00000000..3cca440c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.kisa;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * Korea Information Security Agency (KISA)
+ * ({iso(1) member-body(2) kr(410) kisa(200004)})
+ * <p>
+ * See <a href="https://tools.ietf.org/html/rfc4010">RFC 4010</a>
+ * Use of the SEED Encryption Algorithm
+ * in Cryptographic Message Syntax (CMS),
+ * and <a href="https://tools.ietf.org/html/rfc4269">RFC 4269</a>
+ * The SEED Encryption Algorithm
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface KISAObjectIdentifiers
+{
+ /** RFC 4010, 4269: id-seedCBC; OID 1.2.410.200004.1.4 */
+ static final ASN1ObjectIdentifier id_seedCBC = new ASN1ObjectIdentifier("1.2.410.200004.1.4");
+
+ /** RFC 4269: id-seedMAC; OID 1.2.410.200004.1.7 */
+ static final ASN1ObjectIdentifier id_seedMAC = new ASN1ObjectIdentifier("1.2.410.200004.1.7");
+
+ /** RFC 4269: pbeWithSHA1AndSEED-CBC; OID 1.2.410.200004.1.15 */
+ static final ASN1ObjectIdentifier pbeWithSHA1AndSEED_CBC = new ASN1ObjectIdentifier("1.2.410.200004.1.15");
+
+ /** RFC 4010: id-npki-app-cmsSeed-wrap; OID 1.2.410.200004.7.1.1.1 */
+ static final ASN1ObjectIdentifier id_npki_app_cmsSeed_wrap = new ASN1ObjectIdentifier("1.2.410.200004.7.1.1.1");
+
+ /** RFC 4010: SeedEncryptionAlgorithmInCMS; OID 1.2.840.113549.1.9.16.0.24 */
+ static final ASN1ObjectIdentifier id_mod_cms_seed = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.0.24");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
new file mode 100644
index 00000000..2f69ddea
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
@@ -0,0 +1,155 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.misc;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface MiscObjectIdentifiers
+{
+ //
+ // Netscape
+ // iso/itu(2) joint-assign(16) us(840) uscompany(1) netscape(113730) cert-extensions(1) }
+ //
+ /**
+ * Netscape cert extensions OID base: 2.16.840.1.113730.1
+ */
+ ASN1ObjectIdentifier netscape = new ASN1ObjectIdentifier("2.16.840.1.113730.1");
+ /**
+ * Netscape cert CertType OID: 2.16.840.1.113730.1.1
+ */
+ ASN1ObjectIdentifier netscapeCertType = netscape.branch("1");
+ /**
+ * Netscape cert BaseURL OID: 2.16.840.1.113730.1.2
+ */
+ ASN1ObjectIdentifier netscapeBaseURL = netscape.branch("2");
+ /**
+ * Netscape cert RevocationURL OID: 2.16.840.1.113730.1.3
+ */
+ ASN1ObjectIdentifier netscapeRevocationURL = netscape.branch("3");
+ /**
+ * Netscape cert CARevocationURL OID: 2.16.840.1.113730.1.4
+ */
+ ASN1ObjectIdentifier netscapeCARevocationURL = netscape.branch("4");
+ /**
+ * Netscape cert RenewalURL OID: 2.16.840.1.113730.1.7
+ */
+ ASN1ObjectIdentifier netscapeRenewalURL = netscape.branch("7");
+ /**
+ * Netscape cert CApolicyURL OID: 2.16.840.1.113730.1.8
+ */
+ ASN1ObjectIdentifier netscapeCApolicyURL = netscape.branch("8");
+ /**
+ * Netscape cert SSLServerName OID: 2.16.840.1.113730.1.12
+ */
+ ASN1ObjectIdentifier netscapeSSLServerName = netscape.branch("12");
+ /**
+ * Netscape cert CertComment OID: 2.16.840.1.113730.1.13
+ */
+ ASN1ObjectIdentifier netscapeCertComment = netscape.branch("13");
+
+ //
+ // Verisign
+ // iso/itu(2) joint-assign(16) us(840) uscompany(1) verisign(113733) cert-extensions(1) }
+ //
+ /**
+ * Verisign OID base: 2.16.840.1.113733.1
+ */
+ ASN1ObjectIdentifier verisign = new ASN1ObjectIdentifier("2.16.840.1.113733.1");
+
+ /**
+ * Verisign CZAG (Country,Zip,Age,Gender) Extension OID: 2.16.840.1.113733.1.6.3
+ */
+ ASN1ObjectIdentifier verisignCzagExtension = verisign.branch("6.3");
+
+ ASN1ObjectIdentifier verisignPrivate_6_9 = verisign.branch("6.9");
+ ASN1ObjectIdentifier verisignOnSiteJurisdictionHash = verisign.branch("6.11");
+ ASN1ObjectIdentifier verisignBitString_6_13 = verisign.branch("6.13");
+
+ /**
+ * Verisign D&amp;B D-U-N-S number Extension OID: 2.16.840.1.113733.1.6.15
+ */
+ ASN1ObjectIdentifier verisignDnbDunsNumber = verisign.branch("6.15");
+
+ ASN1ObjectIdentifier verisignIssStrongCrypto = verisign.branch("8.1");
+
+ //
+ // Novell
+ // iso/itu(2) country(16) us(840) organization(1) novell(113719)
+ //
+ /**
+ * Novell OID base: 2.16.840.1.113719
+ */
+ ASN1ObjectIdentifier novell = new ASN1ObjectIdentifier("2.16.840.1.113719");
+ /**
+ * Novell SecurityAttribs OID: 2.16.840.1.113719.1.9.4.1
+ */
+ ASN1ObjectIdentifier novellSecurityAttribs = novell.branch("1.9.4.1");
+
+ //
+ // Entrust
+ // iso(1) member-body(16) us(840) nortelnetworks(113533) entrust(7)
+ //
+ /**
+ * NortelNetworks Entrust OID base: 1.2.840.113533.7
+ */
+ ASN1ObjectIdentifier entrust = new ASN1ObjectIdentifier("1.2.840.113533.7");
+ /**
+ * NortelNetworks Entrust VersionExtension OID: 1.2.840.113533.7.65.0
+ */
+ ASN1ObjectIdentifier entrustVersionExtension = entrust.branch("65.0");
+
+ /**
+ * cast5CBC OBJECT IDENTIFIER ::= {iso(1) member-body(2) us(840) nt(113533) nsn(7) algorithms(66) 10} SEE RFC 2984
+ */
+ ASN1ObjectIdentifier cast5CBC = entrust.branch("66.10");
+
+ //
+ // HMAC-SHA1 hMAC-SHA1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
+ // dod(6) internet(1) security(5) mechanisms(5) 8 1 2 }
+ //
+ ASN1ObjectIdentifier hMAC_SHA1 = new ASN1ObjectIdentifier("1.3.6.1.5.5.8.1.2");
+
+ //
+ // Ascom
+ //
+ ASN1ObjectIdentifier as_sys_sec_alg_ideaCBC = new ASN1ObjectIdentifier("1.3.6.1.4.1.188.7.1.1.2");
+
+ //
+ // Peter Gutmann's Cryptlib
+ //
+ ASN1ObjectIdentifier cryptlib = new ASN1ObjectIdentifier("1.3.6.1.4.1.3029");
+
+ ASN1ObjectIdentifier cryptlib_algorithm = cryptlib.branch("1");
+ ASN1ObjectIdentifier cryptlib_algorithm_blowfish_ECB = cryptlib_algorithm.branch("1.1");
+ ASN1ObjectIdentifier cryptlib_algorithm_blowfish_CBC = cryptlib_algorithm.branch("1.2");
+ ASN1ObjectIdentifier cryptlib_algorithm_blowfish_CFB = cryptlib_algorithm.branch("1.3");
+ ASN1ObjectIdentifier cryptlib_algorithm_blowfish_OFB = cryptlib_algorithm.branch("1.4");
+
+ //
+ // Blake2b
+ //
+ ASN1ObjectIdentifier blake2 = new ASN1ObjectIdentifier("1.3.6.1.4.1.1722.12.2");
+
+ ASN1ObjectIdentifier id_blake2b160 = blake2.branch("1.5");
+ ASN1ObjectIdentifier id_blake2b256 = blake2.branch("1.8");
+ ASN1ObjectIdentifier id_blake2b384 = blake2.branch("1.12");
+ ASN1ObjectIdentifier id_blake2b512 = blake2.branch("1.16");
+
+ ASN1ObjectIdentifier id_blake2s128 = blake2.branch("2.4");
+ ASN1ObjectIdentifier id_blake2s160 = blake2.branch("2.5");
+ ASN1ObjectIdentifier id_blake2s224 = blake2.branch("2.7");
+ ASN1ObjectIdentifier id_blake2s256 = blake2.branch("2.8");
+
+ //
+ // Scrypt
+ ASN1ObjectIdentifier id_scrypt = new ASN1ObjectIdentifier("1.3.6.1.4.1.11591.4.11");
+
+ // Composite key/signature oid - prototyping
+ //
+ // id-alg-composite OBJECT IDENTIFIER ::= {
+ // iso(1) identified-organization(3) dod(6) internet(1) private(4)
+ // enterprise(1) OpenCA(18227) Algorithms(2) id-alg-composite(1) }
+ ASN1ObjectIdentifier id_alg_composite = new ASN1ObjectIdentifier("1.3.6.1.4.1.18227.2.1");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeCertType.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeCertType.java
new file mode 100644
index 00000000..2fdac519
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeCertType.java
@@ -0,0 +1,56 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.misc;
+
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+
+/**
+ * The NetscapeCertType object.
+ * <pre>
+ * NetscapeCertType ::= BIT STRING {
+ * SSLClient (0),
+ * SSLServer (1),
+ * S/MIME (2),
+ * Object Signing (3),
+ * Reserved (4),
+ * SSL CA (5),
+ * S/MIME CA (6),
+ * Object Signing CA (7) }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class NetscapeCertType
+ extends DERBitString
+{
+ public static final int sslClient = (1 << 7);
+ public static final int sslServer = (1 << 6);
+ public static final int smime = (1 << 5);
+ public static final int objectSigning = (1 << 4);
+ public static final int reserved = (1 << 3);
+ public static final int sslCA = (1 << 2);
+ public static final int smimeCA = (1 << 1);
+ public static final int objectSigningCA = (1 << 0);
+
+ /**
+ * Basic constructor.
+ *
+ * @param usage - the bitwise OR of the Key Usage flags giving the
+ * allowed uses for the key.
+ * e.g. (X509NetscapeCertType.sslCA | X509NetscapeCertType.smimeCA)
+ */
+ public NetscapeCertType(
+ int usage)
+ {
+ super(getBytes(usage), getPadBits(usage));
+ }
+
+ public NetscapeCertType(
+ DERBitString usage)
+ {
+ super(usage.getBytes(), usage.getPadBits());
+ }
+
+ public String toString()
+ {
+ return "NetscapeCertType: 0x" + Integer.toHexString(data[0] & 0xff);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java
new file mode 100644
index 00000000..ed0f5e28
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java
@@ -0,0 +1,22 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.misc;
+
+import com.android.internal.org.bouncycastle.asn1.DERIA5String;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class NetscapeRevocationURL
+ extends DERIA5String
+{
+ public NetscapeRevocationURL(
+ DERIA5String str)
+ {
+ super(str.getString());
+ }
+
+ public String toString()
+ {
+ return "NetscapeRevocationURL: " + this.getString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/VerisignCzagExtension.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/VerisignCzagExtension.java
new file mode 100644
index 00000000..a570d707
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/VerisignCzagExtension.java
@@ -0,0 +1,22 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.misc;
+
+import com.android.internal.org.bouncycastle.asn1.DERIA5String;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class VerisignCzagExtension
+ extends DERIA5String
+{
+ public VerisignCzagExtension(
+ DERIA5String str)
+ {
+ super(str.getString());
+ }
+
+ public String toString()
+ {
+ return "VerisignCzagExtension: " + this.getString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTNamedCurves.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTNamedCurves.java
new file mode 100644
index 00000000..fe9c18ba
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTNamedCurves.java
@@ -0,0 +1,101 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.nist;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.sec.SECNamedCurves;
+import com.android.internal.org.bouncycastle.asn1.sec.SECObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * Utility class for fetching curves using their NIST names as published in FIPS-PUB 186-3
+ * @hide This class is not part of the Android public SDK API
+ */
+public class NISTNamedCurves
+{
+ static final Hashtable objIds = new Hashtable();
+ static final Hashtable names = new Hashtable();
+
+ static void defineCurve(String name, ASN1ObjectIdentifier oid)
+ {
+ objIds.put(name, oid);
+ names.put(oid, name);
+ }
+
+ static
+ {
+ defineCurve("B-571", SECObjectIdentifiers.sect571r1);
+ defineCurve("B-409", SECObjectIdentifiers.sect409r1);
+ defineCurve("B-283", SECObjectIdentifiers.sect283r1);
+ defineCurve("B-233", SECObjectIdentifiers.sect233r1);
+ defineCurve("B-163", SECObjectIdentifiers.sect163r2);
+ defineCurve("K-571", SECObjectIdentifiers.sect571k1);
+ defineCurve("K-409", SECObjectIdentifiers.sect409k1);
+ defineCurve("K-283", SECObjectIdentifiers.sect283k1);
+ defineCurve("K-233", SECObjectIdentifiers.sect233k1);
+ defineCurve("K-163", SECObjectIdentifiers.sect163k1);
+ defineCurve("P-521", SECObjectIdentifiers.secp521r1);
+ defineCurve("P-384", SECObjectIdentifiers.secp384r1);
+ defineCurve("P-256", SECObjectIdentifiers.secp256r1);
+ defineCurve("P-224", SECObjectIdentifiers.secp224r1);
+ defineCurve("P-192", SECObjectIdentifiers.secp192r1);
+ }
+
+ public static X9ECParameters getByName(
+ String name)
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toUpperCase(name));
+
+ if (oid != null)
+ {
+ return getByOID(oid);
+ }
+
+ return null;
+ }
+
+ /**
+ * return the X9ECParameters object for the named curve represented by
+ * the passed in object identifier. Null if the curve isn't present.
+ *
+ * @param oid an object identifier representing a named curve, if present.
+ */
+ public static X9ECParameters getByOID(
+ ASN1ObjectIdentifier oid)
+ {
+ return SECNamedCurves.getByOID(oid);
+ }
+
+ /**
+ * return the object identifier signified by the passed in name. Null
+ * if there is no object identifier associated with name.
+ *
+ * @return the object identifier associated with name, if present.
+ */
+ public static ASN1ObjectIdentifier getOID(
+ String name)
+ {
+ return (ASN1ObjectIdentifier)objIds.get(Strings.toUpperCase(name));
+ }
+
+ /**
+ * return the named curve name represented by the given object identifier.
+ */
+ public static String getName(
+ ASN1ObjectIdentifier oid)
+ {
+ return (String)names.get(oid);
+ }
+
+ /**
+ * returns an enumeration containing the name strings for curves
+ * contained in this structure.
+ */
+ public static Enumeration getNames()
+ {
+ return objIds.keys();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
new file mode 100644
index 00000000..db60cf09
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
@@ -0,0 +1,163 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.nist;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ *
+ * NIST:
+ * iso/itu(2) joint-assign(16) us(840) organization(1) gov(101) csor(3)
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface NISTObjectIdentifiers
+{
+ //
+ // nistalgorithms(4)
+ //
+ /** 2.16.840.1.101.3.4 -- algorithms */
+ static final ASN1ObjectIdentifier nistAlgorithm = new ASN1ObjectIdentifier("2.16.840.1.101.3.4");
+
+ /** 2.16.840.1.101.3.4.2 */
+ static final ASN1ObjectIdentifier hashAlgs = nistAlgorithm.branch("2");
+
+ /** 2.16.840.1.101.3.4.2.1 */
+ static final ASN1ObjectIdentifier id_sha256 = hashAlgs.branch("1");
+ /** 2.16.840.1.101.3.4.2.2 */
+ static final ASN1ObjectIdentifier id_sha384 = hashAlgs.branch("2");
+ /** 2.16.840.1.101.3.4.2.3 */
+ static final ASN1ObjectIdentifier id_sha512 = hashAlgs.branch("3");
+ /** 2.16.840.1.101.3.4.2.4 */
+ static final ASN1ObjectIdentifier id_sha224 = hashAlgs.branch("4");
+ /** 2.16.840.1.101.3.4.2.5 */
+ static final ASN1ObjectIdentifier id_sha512_224 = hashAlgs.branch("5");
+ /** 2.16.840.1.101.3.4.2.6 */
+ static final ASN1ObjectIdentifier id_sha512_256 = hashAlgs.branch("6");
+
+ /** 2.16.840.1.101.3.4.2.7 */
+ static final ASN1ObjectIdentifier id_sha3_224 = hashAlgs.branch("7");
+ /** 2.16.840.1.101.3.4.2.8 */
+ static final ASN1ObjectIdentifier id_sha3_256 = hashAlgs.branch("8");
+ /** 2.16.840.1.101.3.4.2.9 */
+ static final ASN1ObjectIdentifier id_sha3_384 = hashAlgs.branch("9");
+ /** 2.16.840.1.101.3.4.2.10 */
+ static final ASN1ObjectIdentifier id_sha3_512 = hashAlgs.branch("10");
+ /** 2.16.840.1.101.3.4.2.11 */
+ static final ASN1ObjectIdentifier id_shake128 = hashAlgs.branch("11");
+ /** 2.16.840.1.101.3.4.2.12 */
+ static final ASN1ObjectIdentifier id_shake256 = hashAlgs.branch("12");
+ /** 2.16.840.1.101.3.4.2.13 */
+ static final ASN1ObjectIdentifier id_hmacWithSHA3_224 = hashAlgs.branch("13");
+ /** 2.16.840.1.101.3.4.2.14 */
+ static final ASN1ObjectIdentifier id_hmacWithSHA3_256 = hashAlgs.branch("14");
+ /** 2.16.840.1.101.3.4.2.15 */
+ static final ASN1ObjectIdentifier id_hmacWithSHA3_384 = hashAlgs.branch("15");
+ /** 2.16.840.1.101.3.4.2.16 */
+ static final ASN1ObjectIdentifier id_hmacWithSHA3_512 = hashAlgs.branch("16");
+ /** 2.16.840.1.101.3.4.2.17 */
+ static final ASN1ObjectIdentifier id_shake128_len = hashAlgs.branch("17");
+ /** 2.16.840.1.101.3.4.2.18 */
+ static final ASN1ObjectIdentifier id_shake256_len = hashAlgs.branch("18");
+ /** 2.16.840.1.101.3.4.2.19 */
+ static final ASN1ObjectIdentifier id_KmacWithSHAKE128 = hashAlgs.branch("19");
+ /** 2.16.840.1.101.3.4.2.20 */
+ static final ASN1ObjectIdentifier id_KmacWithSHAKE256 = hashAlgs.branch("20");
+
+ /** 2.16.840.1.101.3.4.1 */
+ static final ASN1ObjectIdentifier aes = nistAlgorithm.branch("1");
+
+ /** 2.16.840.1.101.3.4.1.1 */
+ static final ASN1ObjectIdentifier id_aes128_ECB = aes.branch("1");
+ /** 2.16.840.1.101.3.4.1.2 */
+ static final ASN1ObjectIdentifier id_aes128_CBC = aes.branch("2");
+ /** 2.16.840.1.101.3.4.1.3 */
+ static final ASN1ObjectIdentifier id_aes128_OFB = aes.branch("3");
+ /** 2.16.840.1.101.3.4.1.4 */
+ static final ASN1ObjectIdentifier id_aes128_CFB = aes.branch("4");
+ /** 2.16.840.1.101.3.4.1.5 */
+ static final ASN1ObjectIdentifier id_aes128_wrap = aes.branch("5");
+ /** 2.16.840.1.101.3.4.1.6 */
+ static final ASN1ObjectIdentifier id_aes128_GCM = aes.branch("6");
+ /** 2.16.840.1.101.3.4.1.7 */
+ static final ASN1ObjectIdentifier id_aes128_CCM = aes.branch("7");
+ /** 2.16.840.1.101.3.4.1.28 */
+ static final ASN1ObjectIdentifier id_aes128_wrap_pad = aes.branch("8");
+
+ /** 2.16.840.1.101.3.4.1.21 */
+ static final ASN1ObjectIdentifier id_aes192_ECB = aes.branch("21");
+ /** 2.16.840.1.101.3.4.1.22 */
+ static final ASN1ObjectIdentifier id_aes192_CBC = aes.branch("22");
+ /** 2.16.840.1.101.3.4.1.23 */
+ static final ASN1ObjectIdentifier id_aes192_OFB = aes.branch("23");
+ /** 2.16.840.1.101.3.4.1.24 */
+ static final ASN1ObjectIdentifier id_aes192_CFB = aes.branch("24");
+ /** 2.16.840.1.101.3.4.1.25 */
+ static final ASN1ObjectIdentifier id_aes192_wrap = aes.branch("25");
+ /** 2.16.840.1.101.3.4.1.26 */
+ static final ASN1ObjectIdentifier id_aes192_GCM = aes.branch("26");
+ /** 2.16.840.1.101.3.4.1.27 */
+ static final ASN1ObjectIdentifier id_aes192_CCM = aes.branch("27");
+ /** 2.16.840.1.101.3.4.1.28 */
+ static final ASN1ObjectIdentifier id_aes192_wrap_pad = aes.branch("28");
+
+ /** 2.16.840.1.101.3.4.1.41 */
+ static final ASN1ObjectIdentifier id_aes256_ECB = aes.branch("41");
+ /** 2.16.840.1.101.3.4.1.42 */
+ static final ASN1ObjectIdentifier id_aes256_CBC = aes.branch("42");
+ /** 2.16.840.1.101.3.4.1.43 */
+ static final ASN1ObjectIdentifier id_aes256_OFB = aes.branch("43");
+ /** 2.16.840.1.101.3.4.1.44 */
+ static final ASN1ObjectIdentifier id_aes256_CFB = aes.branch("44");
+ /** 2.16.840.1.101.3.4.1.45 */
+ static final ASN1ObjectIdentifier id_aes256_wrap = aes.branch("45");
+ /** 2.16.840.1.101.3.4.1.46 */
+ static final ASN1ObjectIdentifier id_aes256_GCM = aes.branch("46");
+ /** 2.16.840.1.101.3.4.1.47 */
+ static final ASN1ObjectIdentifier id_aes256_CCM = aes.branch("47");
+ /** 2.16.840.1.101.3.4.1.48 */
+ static final ASN1ObjectIdentifier id_aes256_wrap_pad = aes.branch("48");
+
+ //
+ // signatures
+ //
+ /** 2.16.840.1.101.3.4.3 */
+ static final ASN1ObjectIdentifier sigAlgs = nistAlgorithm.branch("3");
+
+ static final ASN1ObjectIdentifier id_dsa_with_sha2 = sigAlgs;
+
+ /** 2.16.840.1.101.3.4.3.1 */
+ static final ASN1ObjectIdentifier dsa_with_sha224 = sigAlgs.branch("1");
+ /** 2.16.840.1.101.3.4.3.2 */
+ static final ASN1ObjectIdentifier dsa_with_sha256 = sigAlgs.branch("2");
+ /** 2.16.840.1.101.3.4.3.3 */
+ static final ASN1ObjectIdentifier dsa_with_sha384 = sigAlgs.branch("3");
+ /** 2.16.840.1.101.3.4.3.4 */
+ static final ASN1ObjectIdentifier dsa_with_sha512 = sigAlgs.branch("4");
+ /** 2.16.840.1.101.3.4.3.5 */
+ static final ASN1ObjectIdentifier id_dsa_with_sha3_224 = sigAlgs.branch("5");
+ /** 2.16.840.1.101.3.4.3.6 */
+ static final ASN1ObjectIdentifier id_dsa_with_sha3_256 = sigAlgs.branch("6");
+ /** 2.16.840.1.101.3.4.3.7 */
+ static final ASN1ObjectIdentifier id_dsa_with_sha3_384 = sigAlgs.branch("7");
+ /** 2.16.840.1.101.3.4.3.8 */
+ static final ASN1ObjectIdentifier id_dsa_with_sha3_512 = sigAlgs.branch("8");
+
+ // ECDSA with SHA-3
+ /** 2.16.840.1.101.3.4.3.9 */
+ static final ASN1ObjectIdentifier id_ecdsa_with_sha3_224 = sigAlgs.branch("9");
+ /** 2.16.840.1.101.3.4.3.10 */
+ static final ASN1ObjectIdentifier id_ecdsa_with_sha3_256 = sigAlgs.branch("10");
+ /** 2.16.840.1.101.3.4.3.11 */
+ static final ASN1ObjectIdentifier id_ecdsa_with_sha3_384 = sigAlgs.branch("11");
+ /** 2.16.840.1.101.3.4.3.12 */
+ static final ASN1ObjectIdentifier id_ecdsa_with_sha3_512 = sigAlgs.branch("12");
+
+ // RSA PKCS #1 v1.5 Signature with SHA-3 family.
+ /** 2.16.840.1.101.3.4.3.9 */
+ static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_224 = sigAlgs.branch("13");
+ /** 2.16.840.1.101.3.4.3.10 */
+ static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_256 = sigAlgs.branch("14");
+ /** 2.16.840.1.101.3.4.3.11 */
+ static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_384 = sigAlgs.branch("15");
+ /** 2.16.840.1.101.3.4.3.12 */
+ static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_512 = sigAlgs.branch("16");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nsri/NSRIObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nsri/NSRIObjectIdentifiers.java
new file mode 100644
index 00000000..51ce8f02
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nsri/NSRIObjectIdentifiers.java
@@ -0,0 +1,62 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.nsri;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface NSRIObjectIdentifiers
+{
+ ASN1ObjectIdentifier nsri = new ASN1ObjectIdentifier("1.2.410.200046");
+
+ ASN1ObjectIdentifier id_algorithm = nsri.branch("1");
+
+ ASN1ObjectIdentifier id_sea = id_algorithm.branch("1");
+ ASN1ObjectIdentifier id_pad = id_algorithm.branch("2");
+
+ ASN1ObjectIdentifier id_pad_null = id_algorithm.branch("0");
+ ASN1ObjectIdentifier id_pad_1 = id_algorithm.branch("1");
+
+ ASN1ObjectIdentifier id_aria128_ecb = id_sea.branch("1");
+ ASN1ObjectIdentifier id_aria128_cbc = id_sea.branch("2");
+ ASN1ObjectIdentifier id_aria128_cfb = id_sea.branch("3");
+ ASN1ObjectIdentifier id_aria128_ofb = id_sea.branch("4");
+ ASN1ObjectIdentifier id_aria128_ctr = id_sea.branch("5");
+
+ ASN1ObjectIdentifier id_aria192_ecb = id_sea.branch("6");
+ ASN1ObjectIdentifier id_aria192_cbc = id_sea.branch("7");
+ ASN1ObjectIdentifier id_aria192_cfb = id_sea.branch("8");
+ ASN1ObjectIdentifier id_aria192_ofb = id_sea.branch("9");
+ ASN1ObjectIdentifier id_aria192_ctr = id_sea.branch("10");
+
+ ASN1ObjectIdentifier id_aria256_ecb = id_sea.branch("11");
+ ASN1ObjectIdentifier id_aria256_cbc = id_sea.branch("12");
+ ASN1ObjectIdentifier id_aria256_cfb = id_sea.branch("13");
+ ASN1ObjectIdentifier id_aria256_ofb = id_sea.branch("14");
+ ASN1ObjectIdentifier id_aria256_ctr = id_sea.branch("15");
+
+ ASN1ObjectIdentifier id_aria128_cmac = id_sea.branch("21");
+ ASN1ObjectIdentifier id_aria192_cmac = id_sea.branch("22");
+ ASN1ObjectIdentifier id_aria256_cmac = id_sea.branch("23");
+
+ ASN1ObjectIdentifier id_aria128_ocb2 = id_sea.branch("31");
+ ASN1ObjectIdentifier id_aria192_ocb2 = id_sea.branch("32");
+ ASN1ObjectIdentifier id_aria256_ocb2 = id_sea.branch("33");
+
+ ASN1ObjectIdentifier id_aria128_gcm = id_sea.branch("34");
+ ASN1ObjectIdentifier id_aria192_gcm = id_sea.branch("35");
+ ASN1ObjectIdentifier id_aria256_gcm = id_sea.branch("36");
+
+ ASN1ObjectIdentifier id_aria128_ccm = id_sea.branch("37");
+ ASN1ObjectIdentifier id_aria192_ccm = id_sea.branch("38");
+ ASN1ObjectIdentifier id_aria256_ccm = id_sea.branch("39");
+
+ ASN1ObjectIdentifier id_aria128_kw = id_sea.branch("40");
+ ASN1ObjectIdentifier id_aria192_kw = id_sea.branch("41");
+ ASN1ObjectIdentifier id_aria256_kw = id_sea.branch("42");
+
+ ASN1ObjectIdentifier id_aria128_kwp = id_sea.branch("43");
+ ASN1ObjectIdentifier id_aria192_kwp = id_sea.branch("44");
+ ASN1ObjectIdentifier id_aria256_kwp = id_sea.branch("45");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java
new file mode 100644
index 00000000..5ba6bbbd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ntt;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * From <a href="https://tools.ietf.org/html/rfc3657">RFC 3657</a>
+ * Use of the Camellia Encryption Algorithm
+ * in Cryptographic Message Syntax (CMS)
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface NTTObjectIdentifiers
+{
+ /** id-camellia128-cbc; OID 1.2.392.200011.61.1.1.1.2 */
+ static final ASN1ObjectIdentifier id_camellia128_cbc = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.1.2");
+ /** id-camellia192-cbc; OID 1.2.392.200011.61.1.1.1.3 */
+ static final ASN1ObjectIdentifier id_camellia192_cbc = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.1.3");
+ /** id-camellia256-cbc; OID 1.2.392.200011.61.1.1.1.4 */
+ static final ASN1ObjectIdentifier id_camellia256_cbc = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.1.4");
+
+ /** id-camellia128-wrap; OID 1.2.392.200011.61.1.1.3.2 */
+ static final ASN1ObjectIdentifier id_camellia128_wrap = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.3.2");
+ /** id-camellia192-wrap; OID 1.2.392.200011.61.1.1.3.3 */
+ static final ASN1ObjectIdentifier id_camellia192_wrap = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.3.3");
+ /** id-camellia256-wrap; OID 1.2.392.200011.61.1.1.3.4 */
+ static final ASN1ObjectIdentifier id_camellia256_wrap = new ASN1ObjectIdentifier("1.2.392.200011.61.1.1.3.4");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/BasicOCSPResponse.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/BasicOCSPResponse.java
new file mode 100644
index 00000000..7bc4eebf
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/BasicOCSPResponse.java
@@ -0,0 +1,124 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * BasicOCSPResponse ::= SEQUENCE {
+ * tbsResponseData ResponseData,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING,
+ * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BasicOCSPResponse
+ extends ASN1Object
+{
+ private ResponseData tbsResponseData;
+ private AlgorithmIdentifier signatureAlgorithm;
+ private DERBitString signature;
+ private ASN1Sequence certs;
+
+ public BasicOCSPResponse(
+ ResponseData tbsResponseData,
+ AlgorithmIdentifier signatureAlgorithm,
+ DERBitString signature,
+ ASN1Sequence certs)
+ {
+ this.tbsResponseData = tbsResponseData;
+ this.signatureAlgorithm = signatureAlgorithm;
+ this.signature = signature;
+ this.certs = certs;
+ }
+
+ private BasicOCSPResponse(
+ ASN1Sequence seq)
+ {
+ this.tbsResponseData = ResponseData.getInstance(seq.getObjectAt(0));
+ this.signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
+ this.signature = (DERBitString)seq.getObjectAt(2);
+
+ if (seq.size() > 3)
+ {
+ this.certs = ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(3), true);
+ }
+ }
+
+ public static BasicOCSPResponse getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static BasicOCSPResponse getInstance(
+ Object obj)
+ {
+ if (obj instanceof BasicOCSPResponse)
+ {
+ return (BasicOCSPResponse)obj;
+ }
+ else if (obj != null)
+ {
+ return new BasicOCSPResponse(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ResponseData getTbsResponseData()
+ {
+ return tbsResponseData;
+ }
+
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return signatureAlgorithm;
+ }
+
+ public DERBitString getSignature()
+ {
+ return signature;
+ }
+
+ public ASN1Sequence getCerts()
+ {
+ return certs;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * BasicOCSPResponse ::= SEQUENCE {
+ * tbsResponseData ResponseData,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING,
+ * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ v.add(tbsResponseData);
+ v.add(signatureAlgorithm);
+ v.add(signature);
+ if (certs != null)
+ {
+ v.add(new DERTaggedObject(true, 0, certs));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CertID.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CertID.java
new file mode 100644
index 00000000..a209ed46
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CertID.java
@@ -0,0 +1,109 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertID
+ extends ASN1Object
+{
+ AlgorithmIdentifier hashAlgorithm;
+ ASN1OctetString issuerNameHash;
+ ASN1OctetString issuerKeyHash;
+ ASN1Integer serialNumber;
+
+ public CertID(
+ AlgorithmIdentifier hashAlgorithm,
+ ASN1OctetString issuerNameHash,
+ ASN1OctetString issuerKeyHash,
+ ASN1Integer serialNumber)
+ {
+ this.hashAlgorithm = hashAlgorithm;
+ this.issuerNameHash = issuerNameHash;
+ this.issuerKeyHash = issuerKeyHash;
+ this.serialNumber = serialNumber;
+ }
+
+ private CertID(
+ ASN1Sequence seq)
+ {
+ hashAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0));
+ issuerNameHash = (ASN1OctetString)seq.getObjectAt(1);
+ issuerKeyHash = (ASN1OctetString)seq.getObjectAt(2);
+ serialNumber = (ASN1Integer)seq.getObjectAt(3);
+ }
+
+ public static CertID getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static CertID getInstance(
+ Object obj)
+ {
+ if (obj instanceof CertID)
+ {
+ return (CertID)obj;
+ }
+ else if (obj != null)
+ {
+ return new CertID(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public AlgorithmIdentifier getHashAlgorithm()
+ {
+ return hashAlgorithm;
+ }
+
+ public ASN1OctetString getIssuerNameHash()
+ {
+ return issuerNameHash;
+ }
+
+ public ASN1OctetString getIssuerKeyHash()
+ {
+ return issuerKeyHash;
+ }
+
+ public ASN1Integer getSerialNumber()
+ {
+ return serialNumber;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * CertID ::= SEQUENCE {
+ * hashAlgorithm AlgorithmIdentifier,
+ * issuerNameHash OCTET STRING, -- Hash of Issuer's DN
+ * issuerKeyHash OCTET STRING, -- Hash of Issuers public key
+ * serialNumber CertificateSerialNumber }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ v.add(hashAlgorithm);
+ v.add(issuerNameHash);
+ v.add(issuerKeyHash);
+ v.add(serialNumber);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CertStatus.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CertStatus.java
new file mode 100644
index 00000000..25ba4157
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CertStatus.java
@@ -0,0 +1,112 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertStatus
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private int tagNo;
+ private ASN1Encodable value;
+
+ /**
+ * create a CertStatus object with a tag of zero.
+ */
+ public CertStatus()
+ {
+ tagNo = 0;
+ value = DERNull.INSTANCE;
+ }
+
+ public CertStatus(
+ RevokedInfo info)
+ {
+ tagNo = 1;
+ value = info;
+ }
+
+ public CertStatus(
+ int tagNo,
+ ASN1Encodable value)
+ {
+ this.tagNo = tagNo;
+ this.value = value;
+ }
+
+ private CertStatus(
+ ASN1TaggedObject choice)
+ {
+ this.tagNo = choice.getTagNo();
+
+ switch (choice.getTagNo())
+ {
+ case 0:
+ value = DERNull.INSTANCE;
+ break;
+ case 1:
+ value = RevokedInfo.getInstance(choice, false);
+ break;
+ case 2:
+ value = DERNull.INSTANCE;
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown tag encountered: " + choice.getTagNo());
+ }
+ }
+
+ public static CertStatus getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof CertStatus)
+ {
+ return (CertStatus)obj;
+ }
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ return new CertStatus((ASN1TaggedObject)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
+ }
+
+ public static CertStatus getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject()); // must be explicitly tagged
+ }
+
+ public int getTagNo()
+ {
+ return tagNo;
+ }
+
+ public ASN1Encodable getStatus()
+ {
+ return value;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * CertStatus ::= CHOICE {
+ * good [0] IMPLICIT NULL,
+ * revoked [1] IMPLICIT RevokedInfo,
+ * unknown [2] IMPLICIT UnknownInfo }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new DERTaggedObject(false, tagNo, value);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CrlID.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CrlID.java
new file mode 100644
index 00000000..403a4aca
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CrlID.java
@@ -0,0 +1,114 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERIA5String;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CrlID
+ extends ASN1Object
+{
+ private DERIA5String crlUrl;
+ private ASN1Integer crlNum;
+ private ASN1GeneralizedTime crlTime;
+
+ private CrlID(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ ASN1TaggedObject o = (ASN1TaggedObject)e.nextElement();
+
+ switch (o.getTagNo())
+ {
+ case 0:
+ crlUrl = DERIA5String.getInstance(o, true);
+ break;
+ case 1:
+ crlNum = ASN1Integer.getInstance(o, true);
+ break;
+ case 2:
+ crlTime = ASN1GeneralizedTime.getInstance(o, true);
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "unknown tag number: " + o.getTagNo());
+ }
+ }
+ }
+
+ public static CrlID getInstance(
+ Object obj)
+ {
+ if (obj instanceof CrlID)
+ {
+ return (CrlID)obj;
+ }
+ else if (obj != null)
+ {
+ return new CrlID(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public DERIA5String getCrlUrl()
+ {
+ return crlUrl;
+ }
+
+ public ASN1Integer getCrlNum()
+ {
+ return crlNum;
+ }
+
+ public ASN1GeneralizedTime getCrlTime()
+ {
+ return crlTime;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * CrlID ::= SEQUENCE {
+ * crlUrl [0] EXPLICIT IA5String OPTIONAL,
+ * crlNum [1] EXPLICIT INTEGER OPTIONAL,
+ * crlTime [2] EXPLICIT GeneralizedTime OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ if (crlUrl != null)
+ {
+ v.add(new DERTaggedObject(true, 0, crlUrl));
+ }
+
+ if (crlNum != null)
+ {
+ v.add(new DERTaggedObject(true, 1, crlNum));
+ }
+
+ if (crlTime != null)
+ {
+ v.add(new DERTaggedObject(true, 2, crlTime));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPObjectIdentifiers.java
new file mode 100644
index 00000000..8203dcf9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPObjectIdentifiers.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * OIDs for <a href="https://tools.ietf.org/html/rfc2560">RFC 2560</a> and <a href="https://tools.ietf.org/html/rfc6960">RFC 6960</a>
+ * Online Certificate Status Protocol - OCSP.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface OCSPObjectIdentifiers
+{
+ /** OID: 1.3.6.1.5.5.7.48.1 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1");
+ /** OID: 1.3.6.1.5.5.7.48.1.1 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp_basic = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.1");
+
+ /** OID: 1.3.6.1.5.5.7.48.1.2 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp_nonce = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.2");
+ /** OID: 1.3.6.1.5.5.7.48.1.3 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp_crl = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.3");
+
+ /** OID: 1.3.6.1.5.5.7.48.1.4 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp_response = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.4");
+ /** OID: 1.3.6.1.5.5.7.48.1.5 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp_nocheck = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.5");
+ /** OID: 1.3.6.1.5.5.7.48.1.6 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp_archive_cutoff = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.6");
+ /** OID: 1.3.6.1.5.5.7.48.1.7 */
+ static final ASN1ObjectIdentifier id_pkix_ocsp_service_locator = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.7");
+
+
+ static final ASN1ObjectIdentifier id_pkix_ocsp_pref_sig_algs = id_pkix_ocsp.branch("8");
+
+ static final ASN1ObjectIdentifier id_pkix_ocsp_extended_revoke = id_pkix_ocsp.branch("9");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPRequest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPRequest.java
new file mode 100644
index 00000000..48b98bb7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPRequest.java
@@ -0,0 +1,94 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OCSPRequest
+ extends ASN1Object
+{
+ TBSRequest tbsRequest;
+ Signature optionalSignature;
+
+ public OCSPRequest(
+ TBSRequest tbsRequest,
+ Signature optionalSignature)
+ {
+ this.tbsRequest = tbsRequest;
+ this.optionalSignature = optionalSignature;
+ }
+
+ private OCSPRequest(
+ ASN1Sequence seq)
+ {
+ tbsRequest = TBSRequest.getInstance(seq.getObjectAt(0));
+
+ if (seq.size() == 2)
+ {
+ optionalSignature = Signature.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(1), true);
+ }
+ }
+
+ public static OCSPRequest getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static OCSPRequest getInstance(
+ Object obj)
+ {
+ if (obj instanceof OCSPRequest)
+ {
+ return (OCSPRequest)obj;
+ }
+ else if (obj != null)
+ {
+ return new OCSPRequest(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public TBSRequest getTbsRequest()
+ {
+ return tbsRequest;
+ }
+
+ public Signature getOptionalSignature()
+ {
+ return optionalSignature;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * OCSPRequest ::= SEQUENCE {
+ * tbsRequest TBSRequest,
+ * optionalSignature [0] EXPLICIT Signature OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(tbsRequest);
+
+ if (optionalSignature != null)
+ {
+ v.add(new DERTaggedObject(true, 0, optionalSignature));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPResponse.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPResponse.java
new file mode 100644
index 00000000..f54ca405
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPResponse.java
@@ -0,0 +1,103 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * OCSPResponse ::= SEQUENCE {
+ * responseStatus OCSPResponseStatus,
+ * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
+ * </pre>
+ * @see OCSPResponseStatus
+ * @see ResponseBytes
+ * @hide This class is not part of the Android public SDK API
+ */
+
+public class OCSPResponse
+ extends ASN1Object
+{
+ OCSPResponseStatus responseStatus;
+ ResponseBytes responseBytes;
+
+ public OCSPResponse(
+ OCSPResponseStatus responseStatus,
+ ResponseBytes responseBytes)
+ {
+ this.responseStatus = responseStatus;
+ this.responseBytes = responseBytes;
+ }
+
+ private OCSPResponse(
+ ASN1Sequence seq)
+ {
+ responseStatus = OCSPResponseStatus.getInstance(seq.getObjectAt(0));
+
+ if (seq.size() == 2)
+ {
+ responseBytes = ResponseBytes.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(1), true);
+ }
+ }
+
+ public static OCSPResponse getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static OCSPResponse getInstance(
+ Object obj)
+ {
+ if (obj instanceof OCSPResponse)
+ {
+ return (OCSPResponse)obj;
+ }
+ else if (obj != null)
+ {
+ return new OCSPResponse(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public OCSPResponseStatus getResponseStatus()
+ {
+ return responseStatus;
+ }
+
+ public ResponseBytes getResponseBytes()
+ {
+ return responseBytes;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * OCSPResponse ::= SEQUENCE {
+ * responseStatus OCSPResponseStatus,
+ * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(responseStatus);
+
+ if (responseBytes != null)
+ {
+ v.add(new DERTaggedObject(true, 0, responseBytes));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPResponseStatus.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPResponseStatus.java
new file mode 100644
index 00000000..8c6308c7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPResponseStatus.java
@@ -0,0 +1,97 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <p>
+ * The OCSPResponseStatus enumeration.
+ * <pre>
+ * OCSPResponseStatus ::= ENUMERATED {
+ * successful (0), --Response has valid confirmations
+ * malformedRequest (1), --Illegal confirmation request
+ * internalError (2), --Internal error in issuer
+ * tryLater (3), --Try again later
+ * --(4) is not used
+ * sigRequired (5), --Must sign the request
+ * unauthorized (6) --Request unauthorized
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OCSPResponseStatus
+ extends ASN1Object
+{
+ public static final int SUCCESSFUL = 0;
+ public static final int MALFORMED_REQUEST = 1;
+ public static final int INTERNAL_ERROR = 2;
+ public static final int TRY_LATER = 3;
+ public static final int SIG_REQUIRED = 5;
+ public static final int UNAUTHORIZED = 6;
+
+ private ASN1Enumerated value;
+
+ /**
+ * RFC 2560, RFC 6960
+ * <p>
+ * The OCSPResponseStatus enumeration.
+ * <pre>
+ * OCSPResponseStatus ::= ENUMERATED {
+ * successful (0), --Response has valid confirmations
+ * malformedRequest (1), --Illegal confirmation request
+ * internalError (2), --Internal error in issuer
+ * tryLater (3), --Try again later
+ * --(4) is not used
+ * sigRequired (5), --Must sign the request
+ * unauthorized (6) --Request unauthorized
+ * }
+ * </pre>
+ */
+ public OCSPResponseStatus(
+ int value)
+ {
+ this(new ASN1Enumerated(value));
+ }
+
+ private OCSPResponseStatus(
+ ASN1Enumerated value)
+ {
+ this.value = value;
+ }
+
+ public static OCSPResponseStatus getInstance(
+ Object obj)
+ {
+ if (obj instanceof OCSPResponseStatus)
+ {
+ return (OCSPResponseStatus)obj;
+ }
+ else if (obj != null)
+ {
+ return new OCSPResponseStatus(ASN1Enumerated.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public int getIntValue()
+ {
+ return value.intValueExact();
+ }
+
+ public BigInteger getValue()
+ {
+ return value.getValue();
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return value;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/Request.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/Request.java
new file mode 100644
index 00000000..039c28d0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/Request.java
@@ -0,0 +1,95 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Request
+ extends ASN1Object
+{
+ CertID reqCert;
+ Extensions singleRequestExtensions;
+
+ public Request(
+ CertID reqCert,
+ Extensions singleRequestExtensions)
+ {
+ this.reqCert = reqCert;
+ this.singleRequestExtensions = singleRequestExtensions;
+ }
+
+ private Request(
+ ASN1Sequence seq)
+ {
+ reqCert = CertID.getInstance(seq.getObjectAt(0));
+
+ if (seq.size() == 2)
+ {
+ singleRequestExtensions = Extensions.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(1), true);
+ }
+ }
+
+ public static Request getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static Request getInstance(
+ Object obj)
+ {
+ if (obj instanceof Request)
+ {
+ return (Request)obj;
+ }
+ else if (obj != null)
+ {
+ return new Request(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public CertID getReqCert()
+ {
+ return reqCert;
+ }
+
+ public Extensions getSingleRequestExtensions()
+ {
+ return singleRequestExtensions;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * Request ::= SEQUENCE {
+ * reqCert CertID,
+ * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(reqCert);
+
+ if (singleRequestExtensions != null)
+ {
+ v.add(new DERTaggedObject(true, 0, singleRequestExtensions));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponderID.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponderID.java
new file mode 100644
index 00000000..ad421208
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponderID.java
@@ -0,0 +1,108 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ResponderID
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private ASN1Encodable value;
+
+ public ResponderID(
+ ASN1OctetString value)
+ {
+ this.value = value;
+ }
+
+ public ResponderID(
+ X500Name value)
+ {
+ this.value = value;
+ }
+
+ public static ResponderID getInstance(
+ Object obj)
+ {
+ if (obj instanceof ResponderID)
+ {
+ return (ResponderID)obj;
+ }
+ else if (obj instanceof DEROctetString)
+ {
+ return new ResponderID((DEROctetString)obj);
+ }
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject o = (ASN1TaggedObject)obj;
+
+ if (o.getTagNo() == 1)
+ {
+ return new ResponderID(X500Name.getInstance(o, true));
+ }
+ else
+ {
+ return new ResponderID(ASN1OctetString.getInstance(o, true));
+ }
+ }
+
+ return new ResponderID(X500Name.getInstance(obj));
+ }
+
+ public static ResponderID getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject()); // must be explicitly tagged
+ }
+
+ public byte[] getKeyHash()
+ {
+ if (this.value instanceof ASN1OctetString)
+ {
+ ASN1OctetString octetString = (ASN1OctetString)this.value;
+ return octetString.getOctets();
+ }
+
+ return null;
+ }
+
+ public X500Name getName()
+ {
+ if (this.value instanceof ASN1OctetString)
+ {
+ return null;
+ }
+
+ return X500Name.getInstance(value);
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * ResponderID ::= CHOICE {
+ * byName [1] Name,
+ * byKey [2] KeyHash }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ if (value instanceof ASN1OctetString)
+ {
+ return new DERTaggedObject(true, 2, value);
+ }
+
+ return new DERTaggedObject(true, 1, value);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseBytes.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseBytes.java
new file mode 100644
index 00000000..2480e2f3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseBytes.java
@@ -0,0 +1,95 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * ResponseBytes ::= SEQUENCE {
+ * responseType OBJECT IDENTIFIER,
+ * response OCTET STRING }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ResponseBytes
+ extends ASN1Object
+{
+ ASN1ObjectIdentifier responseType;
+ ASN1OctetString response;
+
+ public ResponseBytes(
+ ASN1ObjectIdentifier responseType,
+ ASN1OctetString response)
+ {
+ this.responseType = responseType;
+ this.response = response;
+ }
+
+ /**
+ * @deprecated use getInstance()
+ */
+ public ResponseBytes(
+ ASN1Sequence seq)
+ {
+ responseType = (ASN1ObjectIdentifier)seq.getObjectAt(0);
+ response = (ASN1OctetString)seq.getObjectAt(1);
+ }
+
+ public static ResponseBytes getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static ResponseBytes getInstance(
+ Object obj)
+ {
+ if (obj instanceof ResponseBytes)
+ {
+ return (ResponseBytes)obj;
+ }
+ else if (obj != null)
+ {
+ return new ResponseBytes(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1ObjectIdentifier getResponseType()
+ {
+ return responseType;
+ }
+
+ public ASN1OctetString getResponse()
+ {
+ return response;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * ResponseBytes ::= SEQUENCE {
+ * responseType OBJECT IDENTIFIER,
+ * response OCTET STRING }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(responseType);
+ v.add(response);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseData.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseData.java
new file mode 100644
index 00000000..24af4927
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseData.java
@@ -0,0 +1,194 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.asn1.x509.X509Extensions;
+
+/**
+ * OCSP RFC 2560, RFC 6960
+ * <pre>
+ * ResponseData ::= SEQUENCE {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * responderID ResponderID,
+ * producedAt GeneralizedTime,
+ * responses SEQUENCE OF SingleResponse,
+ * responseExtensions [1] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ResponseData
+ extends ASN1Object
+{
+ private static final ASN1Integer V1 = new ASN1Integer(0);
+
+ private boolean versionPresent;
+
+ private ASN1Integer version;
+ private ResponderID responderID;
+ private ASN1GeneralizedTime producedAt;
+ private ASN1Sequence responses;
+ private Extensions responseExtensions;
+
+ public ResponseData(
+ ASN1Integer version,
+ ResponderID responderID,
+ ASN1GeneralizedTime producedAt,
+ ASN1Sequence responses,
+ Extensions responseExtensions)
+ {
+ this.version = version;
+ this.responderID = responderID;
+ this.producedAt = producedAt;
+ this.responses = responses;
+ this.responseExtensions = responseExtensions;
+ }
+
+ /**
+ * @deprecated use method taking Extensions
+ * @param responderID
+ * @param producedAt
+ * @param responses
+ * @param responseExtensions
+ */
+ public ResponseData(
+ ResponderID responderID,
+ ASN1GeneralizedTime producedAt,
+ ASN1Sequence responses,
+ X509Extensions responseExtensions)
+ {
+ this(V1, responderID, ASN1GeneralizedTime.getInstance(producedAt), responses, Extensions.getInstance(responseExtensions));
+ }
+
+ public ResponseData(
+ ResponderID responderID,
+ ASN1GeneralizedTime producedAt,
+ ASN1Sequence responses,
+ Extensions responseExtensions)
+ {
+ this(V1, responderID, producedAt, responses, responseExtensions);
+ }
+
+ private ResponseData(
+ ASN1Sequence seq)
+ {
+ int index = 0;
+
+ if (seq.getObjectAt(0) instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(0);
+
+ if (o.getTagNo() == 0)
+ {
+ this.versionPresent = true;
+ this.version = ASN1Integer.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(0), true);
+ index++;
+ }
+ else
+ {
+ this.version = V1;
+ }
+ }
+ else
+ {
+ this.version = V1;
+ }
+
+ this.responderID = ResponderID.getInstance(seq.getObjectAt(index++));
+ this.producedAt = ASN1GeneralizedTime.getInstance(seq.getObjectAt(index++));
+ this.responses = (ASN1Sequence)seq.getObjectAt(index++);
+
+ if (seq.size() > index)
+ {
+ this.responseExtensions = Extensions.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(index), true);
+ }
+ }
+
+ public static ResponseData getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static ResponseData getInstance(
+ Object obj)
+ {
+ if (obj instanceof ResponseData)
+ {
+ return (ResponseData)obj;
+ }
+ else if (obj != null)
+ {
+ return new ResponseData(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public ResponderID getResponderID()
+ {
+ return responderID;
+ }
+
+ public ASN1GeneralizedTime getProducedAt()
+ {
+ return producedAt;
+ }
+
+ public ASN1Sequence getResponses()
+ {
+ return responses;
+ }
+
+ public Extensions getResponseExtensions()
+ {
+ return responseExtensions;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * ResponseData ::= SEQUENCE {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * responderID ResponderID,
+ * producedAt GeneralizedTime,
+ * responses SEQUENCE OF SingleResponse,
+ * responseExtensions [1] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
+
+ if (versionPresent || !version.equals(V1))
+ {
+ v.add(new DERTaggedObject(true, 0, version));
+ }
+
+ v.add(responderID);
+ v.add(producedAt);
+ v.add(responses);
+ if (responseExtensions != null)
+ {
+ v.add(new DERTaggedObject(true, 1, responseExtensions));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/RevokedInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/RevokedInfo.java
new file mode 100644
index 00000000..7c6b7b92
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/RevokedInfo.java
@@ -0,0 +1,96 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x509.CRLReason;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RevokedInfo
+ extends ASN1Object
+{
+ private ASN1GeneralizedTime revocationTime;
+ private CRLReason revocationReason;
+
+ public RevokedInfo(
+ ASN1GeneralizedTime revocationTime,
+ CRLReason revocationReason)
+ {
+ this.revocationTime = revocationTime;
+ this.revocationReason = revocationReason;
+ }
+
+ private RevokedInfo(
+ ASN1Sequence seq)
+ {
+ this.revocationTime = ASN1GeneralizedTime.getInstance(seq.getObjectAt(0));
+
+ if (seq.size() > 1)
+ {
+ this.revocationReason = CRLReason.getInstance(ASN1Enumerated.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(1), true));
+ }
+ }
+
+ public static RevokedInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static RevokedInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof RevokedInfo)
+ {
+ return (RevokedInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new RevokedInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1GeneralizedTime getRevocationTime()
+ {
+ return revocationTime;
+ }
+
+ public CRLReason getRevocationReason()
+ {
+ return revocationReason;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * RevokedInfo ::= SEQUENCE {
+ * revocationTime GeneralizedTime,
+ * revocationReason [0] EXPLICIT CRLReason OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(revocationTime);
+ if (revocationReason != null)
+ {
+ v.add(new DERTaggedObject(true, 0, revocationReason));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/Signature.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/Signature.java
new file mode 100644
index 00000000..3d5a4821
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/Signature.java
@@ -0,0 +1,115 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Signature
+ extends ASN1Object
+{
+ AlgorithmIdentifier signatureAlgorithm;
+ DERBitString signature;
+ ASN1Sequence certs;
+
+ public Signature(
+ AlgorithmIdentifier signatureAlgorithm,
+ DERBitString signature)
+ {
+ this.signatureAlgorithm = signatureAlgorithm;
+ this.signature = signature;
+ }
+
+ public Signature(
+ AlgorithmIdentifier signatureAlgorithm,
+ DERBitString signature,
+ ASN1Sequence certs)
+ {
+ this.signatureAlgorithm = signatureAlgorithm;
+ this.signature = signature;
+ this.certs = certs;
+ }
+
+ private Signature(
+ ASN1Sequence seq)
+ {
+ signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0));
+ signature = (DERBitString)seq.getObjectAt(1);
+
+ if (seq.size() == 3)
+ {
+ certs = ASN1Sequence.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(2), true);
+ }
+ }
+
+ public static Signature getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static Signature getInstance(
+ Object obj)
+ {
+ if (obj instanceof Signature)
+ {
+ return (Signature)obj;
+ }
+ else if (obj != null)
+ {
+ return new Signature(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return signatureAlgorithm;
+ }
+
+ public DERBitString getSignature()
+ {
+ return signature;
+ }
+
+ public ASN1Sequence getCerts()
+ {
+ return certs;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * Signature ::= SEQUENCE {
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING,
+ * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL}
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(signatureAlgorithm);
+ v.add(signature);
+
+ if (certs != null)
+ {
+ v.add(new DERTaggedObject(true, 0, certs));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/SingleResponse.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/SingleResponse.java
new file mode 100644
index 00000000..297c716d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/SingleResponse.java
@@ -0,0 +1,166 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.asn1.x509.X509Extensions;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SingleResponse
+ extends ASN1Object
+{
+ private CertID certID;
+ private CertStatus certStatus;
+ private ASN1GeneralizedTime thisUpdate;
+ private ASN1GeneralizedTime nextUpdate;
+ private Extensions singleExtensions;
+
+ /**
+ * @deprecated use method taking ASN1GeneralizedTime and Extensions
+ * @param certID
+ * @param certStatus
+ * @param thisUpdate
+ * @param nextUpdate
+ * @param singleExtensions
+ */
+ public SingleResponse(
+ CertID certID,
+ CertStatus certStatus,
+ ASN1GeneralizedTime thisUpdate,
+ ASN1GeneralizedTime nextUpdate,
+ X509Extensions singleExtensions)
+ {
+ this(certID, certStatus, thisUpdate, nextUpdate, Extensions.getInstance(singleExtensions));
+ }
+
+ public SingleResponse(
+ CertID certID,
+ CertStatus certStatus,
+ ASN1GeneralizedTime thisUpdate,
+ ASN1GeneralizedTime nextUpdate,
+ Extensions singleExtensions)
+ {
+ this.certID = certID;
+ this.certStatus = certStatus;
+ this.thisUpdate = thisUpdate;
+ this.nextUpdate = nextUpdate;
+ this.singleExtensions = singleExtensions;
+ }
+
+ private SingleResponse(
+ ASN1Sequence seq)
+ {
+ this.certID = CertID.getInstance(seq.getObjectAt(0));
+ this.certStatus = CertStatus.getInstance(seq.getObjectAt(1));
+ this.thisUpdate = ASN1GeneralizedTime.getInstance(seq.getObjectAt(2));
+
+ if (seq.size() > 4)
+ {
+ this.nextUpdate = ASN1GeneralizedTime.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(3), true);
+ this.singleExtensions = Extensions.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(4), true);
+ }
+ else if (seq.size() > 3)
+ {
+ ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(3);
+
+ if (o.getTagNo() == 0)
+ {
+ this.nextUpdate = ASN1GeneralizedTime.getInstance(o, true);
+ }
+ else
+ {
+ this.singleExtensions = Extensions.getInstance(o, true);
+ }
+ }
+ }
+
+ public static SingleResponse getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static SingleResponse getInstance(
+ Object obj)
+ {
+ if (obj instanceof SingleResponse)
+ {
+ return (SingleResponse)obj;
+ }
+ else if (obj != null)
+ {
+ return new SingleResponse(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public CertID getCertID()
+ {
+ return certID;
+ }
+
+ public CertStatus getCertStatus()
+ {
+ return certStatus;
+ }
+
+ public ASN1GeneralizedTime getThisUpdate()
+ {
+ return thisUpdate;
+ }
+
+ public ASN1GeneralizedTime getNextUpdate()
+ {
+ return nextUpdate;
+ }
+
+ public Extensions getSingleExtensions()
+ {
+ return singleExtensions;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * SingleResponse ::= SEQUENCE {
+ * certID CertID,
+ * certStatus CertStatus,
+ * thisUpdate GeneralizedTime,
+ * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
+ * singleExtensions [1] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
+
+ v.add(certID);
+ v.add(certStatus);
+ v.add(thisUpdate);
+
+ if (nextUpdate != null)
+ {
+ v.add(new DERTaggedObject(true, 0, nextUpdate));
+ }
+
+ if (singleExtensions != null)
+ {
+ v.add(new DERTaggedObject(true, 1, singleExtensions));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/TBSRequest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/TBSRequest.java
new file mode 100644
index 00000000..74d7c3e4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/TBSRequest.java
@@ -0,0 +1,176 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.ocsp;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+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.X509Extensions;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TBSRequest
+ extends ASN1Object
+{
+ private static final ASN1Integer V1 = new ASN1Integer(0);
+
+ ASN1Integer version;
+ GeneralName requestorName;
+ ASN1Sequence requestList;
+ Extensions requestExtensions;
+
+ boolean versionSet;
+
+ /**
+ * @deprecated use method taking Extensions
+ * @param requestorName
+ * @param requestList
+ * @param requestExtensions
+ */
+ public TBSRequest(
+ GeneralName requestorName,
+ ASN1Sequence requestList,
+ X509Extensions requestExtensions)
+ {
+ this.version = V1;
+ this.requestorName = requestorName;
+ this.requestList = requestList;
+ this.requestExtensions = Extensions.getInstance(requestExtensions);
+ }
+
+ public TBSRequest(
+ GeneralName requestorName,
+ ASN1Sequence requestList,
+ Extensions requestExtensions)
+ {
+ this.version = V1;
+ this.requestorName = requestorName;
+ this.requestList = requestList;
+ this.requestExtensions = requestExtensions;
+ }
+
+ private TBSRequest(
+ ASN1Sequence seq)
+ {
+ int index = 0;
+
+ if (seq.getObjectAt(0) instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(0);
+
+ if (o.getTagNo() == 0)
+ {
+ versionSet = true;
+ version = ASN1Integer.getInstance((ASN1TaggedObject)seq.getObjectAt(0), true);
+ index++;
+ }
+ else
+ {
+ version = V1;
+ }
+ }
+ else
+ {
+ version = V1;
+ }
+
+ if (seq.getObjectAt(index) instanceof ASN1TaggedObject)
+ {
+ requestorName = GeneralName.getInstance((ASN1TaggedObject)seq.getObjectAt(index++), true);
+ }
+
+ requestList = (ASN1Sequence)seq.getObjectAt(index++);
+
+ if (seq.size() == (index + 1))
+ {
+ requestExtensions = Extensions.getInstance((ASN1TaggedObject)seq.getObjectAt(index), true);
+ }
+ }
+
+ public static TBSRequest getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static TBSRequest getInstance(
+ Object obj)
+ {
+ if (obj instanceof TBSRequest)
+ {
+ return (TBSRequest)obj;
+ }
+ else if (obj != null)
+ {
+ return new TBSRequest(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public GeneralName getRequestorName()
+ {
+ return requestorName;
+ }
+
+ public ASN1Sequence getRequestList()
+ {
+ return requestList;
+ }
+
+ public Extensions getRequestExtensions()
+ {
+ return requestExtensions;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * TBSRequest ::= SEQUENCE {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * requestorName [1] EXPLICIT GeneralName OPTIONAL,
+ * requestList SEQUENCE OF Request,
+ * requestExtensions [2] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ //
+ // if default don't include - unless explicitly provided. Not strictly correct
+ // but required for some requests
+ //
+ if (!version.equals(V1) || versionSet)
+ {
+ v.add(new DERTaggedObject(true, 0, version));
+ }
+
+ if (requestorName != null)
+ {
+ v.add(new DERTaggedObject(true, 1, requestorName));
+ }
+
+ v.add(requestList);
+
+ if (requestExtensions != null)
+ {
+ v.add(new DERTaggedObject(true, 2, requestExtensions));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/oiw/OIWObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/oiw/OIWObjectIdentifiers.java
new file mode 100644
index 00000000..5aa88267
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/oiw/OIWObjectIdentifiers.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.oiw;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * OIW organization's OIDs:
+ * <p>
+ * id-SHA1 OBJECT IDENTIFIER ::=
+ * {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 }
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface OIWObjectIdentifiers
+{
+ /** OID: 1.3.14.3.2.2 */
+ static final ASN1ObjectIdentifier md4WithRSA = new ASN1ObjectIdentifier("1.3.14.3.2.2");
+ /** OID: 1.3.14.3.2.3 */
+ static final ASN1ObjectIdentifier md5WithRSA = new ASN1ObjectIdentifier("1.3.14.3.2.3");
+ /** OID: 1.3.14.3.2.4 */
+ static final ASN1ObjectIdentifier md4WithRSAEncryption = new ASN1ObjectIdentifier("1.3.14.3.2.4");
+
+ /** OID: 1.3.14.3.2.6 */
+ static final ASN1ObjectIdentifier desECB = new ASN1ObjectIdentifier("1.3.14.3.2.6");
+ /** OID: 1.3.14.3.2.7 */
+ static final ASN1ObjectIdentifier desCBC = new ASN1ObjectIdentifier("1.3.14.3.2.7");
+ /** OID: 1.3.14.3.2.8 */
+ static final ASN1ObjectIdentifier desOFB = new ASN1ObjectIdentifier("1.3.14.3.2.8");
+ /** OID: 1.3.14.3.2.9 */
+ static final ASN1ObjectIdentifier desCFB = new ASN1ObjectIdentifier("1.3.14.3.2.9");
+
+ /** OID: 1.3.14.3.2.17 */
+ static final ASN1ObjectIdentifier desEDE = new ASN1ObjectIdentifier("1.3.14.3.2.17");
+
+ /** OID: 1.3.14.3.2.26 */
+ static final ASN1ObjectIdentifier idSHA1 = new ASN1ObjectIdentifier("1.3.14.3.2.26");
+
+ /** OID: 1.3.14.3.2.27 */
+ static final ASN1ObjectIdentifier dsaWithSHA1 = new ASN1ObjectIdentifier("1.3.14.3.2.27");
+
+ /** OID: 1.3.14.3.2.29 */
+ static final ASN1ObjectIdentifier sha1WithRSA = new ASN1ObjectIdentifier("1.3.14.3.2.29");
+
+ /**
+ * <pre>
+ * ElGamal Algorithm OBJECT IDENTIFIER ::=
+ * {iso(1) identified-organization(3) oiw(14) dirservsig(7) algorithm(2) encryption(1) 1 }
+ * </pre>
+ * OID: 1.3.14.7.2.1.1
+ */
+ static final ASN1ObjectIdentifier elGamalAlgorithm = new ASN1ObjectIdentifier("1.3.14.7.2.1.1");
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Attribute.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Attribute.java
new file mode 100644
index 00000000..2114df52
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Attribute.java
@@ -0,0 +1,92 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Attribute
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier attrType;
+ private ASN1Set attrValues;
+
+ /**
+ * return an Attribute object from the given object.
+ *
+ * @param o the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static Attribute getInstance(
+ Object o)
+ {
+ if (o == null || o instanceof Attribute)
+ {
+ return (Attribute)o;
+ }
+
+ if (o instanceof ASN1Sequence)
+ {
+ return new Attribute((ASN1Sequence)o);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory: " + o.getClass().getName());
+ }
+
+ public Attribute(
+ ASN1Sequence seq)
+ {
+ attrType = (ASN1ObjectIdentifier)seq.getObjectAt(0);
+ attrValues = (ASN1Set)seq.getObjectAt(1);
+ }
+
+ public Attribute(
+ ASN1ObjectIdentifier attrType,
+ ASN1Set attrValues)
+ {
+ this.attrType = attrType;
+ this.attrValues = attrValues;
+ }
+
+ public ASN1ObjectIdentifier getAttrType()
+ {
+ return attrType;
+ }
+
+ public ASN1Set getAttrValues()
+ {
+ return attrValues;
+ }
+
+ public ASN1Encodable[] getAttributeValues()
+ {
+ return attrValues.toArray();
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * Attribute ::= SEQUENCE {
+ * attrType OBJECT IDENTIFIER,
+ * attrValues SET OF AttributeValue
+ * }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(attrType);
+ v.add(attrValues);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java
new file mode 100644
index 00000000..cdf87d02
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java
@@ -0,0 +1,80 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.BERSequence;
+import com.android.internal.org.bouncycastle.asn1.DLSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AuthenticatedSafe
+ extends ASN1Object
+{
+ private ContentInfo[] info;
+ private boolean isBer = true;
+
+ private AuthenticatedSafe(
+ ASN1Sequence seq)
+ {
+ info = new ContentInfo[seq.size()];
+
+ for (int i = 0; i != info.length; i++)
+ {
+ info[i] = ContentInfo.getInstance(seq.getObjectAt(i));
+ }
+
+ isBer = seq instanceof BERSequence;
+ }
+
+ public static AuthenticatedSafe getInstance(
+ Object o)
+ {
+ if (o instanceof AuthenticatedSafe)
+ {
+ return (AuthenticatedSafe)o;
+ }
+
+ if (o != null)
+ {
+ return new AuthenticatedSafe(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public AuthenticatedSafe(
+ ContentInfo[] info)
+ {
+ this.info = copy(info);
+ }
+
+ public ContentInfo[] getContentInfo()
+ {
+ return copy(info);
+ }
+
+ private ContentInfo[] copy(ContentInfo[] infos)
+ {
+ ContentInfo[] tmp = new ContentInfo[infos.length];
+
+ System.arraycopy(infos, 0, tmp, 0, tmp.length);
+
+ return tmp;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ if (isBer)
+ {
+ return new BERSequence(info);
+ }
+ else
+ {
+ return new DLSequence(info);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CRLBag.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CRLBag.java
new file mode 100644
index 00000000..a12a870d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CRLBag.java
@@ -0,0 +1,88 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * CRL Bag for PKCS#12
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CRLBag
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier crlId;
+ private ASN1Encodable crlValue;
+
+ private CRLBag(
+ ASN1Sequence seq)
+ {
+ this.crlId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
+ this.crlValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getObject();
+ }
+
+ public static CRLBag getInstance(Object o)
+ {
+ if (o instanceof CRLBag)
+ {
+ return (CRLBag)o;
+ }
+ else if (o != null)
+ {
+ return new CRLBag(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public CRLBag(
+ ASN1ObjectIdentifier crlId,
+ ASN1Encodable crlValue)
+ {
+ this.crlId = crlId;
+ this.crlValue = crlValue;
+ }
+
+ public ASN1ObjectIdentifier getCrlId()
+ {
+ return crlId;
+ }
+
+ public ASN1Encodable getCrlValue()
+ {
+ return crlValue;
+ }
+
+ /**
+ * <pre>
+ * CRLBag ::= SEQUENCE {
+ * crlId BAG-TYPE.&amp;id ({CRLTypes}),
+ * crlValue [0] EXPLICIT BAG-TYPE.&amp;Type ({CRLTypes}{&#64;crlId})
+ * }
+ *
+ * x509CRL BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {certTypes 1}
+ * -- DER-encoded X.509 CRL stored in OCTET STRING
+ *
+ * CRLTypes BAG-TYPE ::= {
+ * x509CRL,
+ * ... -- For future extensions
+ * }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(crlId);
+ v.add(new DERTaggedObject(0, crlValue));
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertBag.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertBag.java
new file mode 100644
index 00000000..60f7506c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertBag.java
@@ -0,0 +1,71 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertBag
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier certId;
+ private ASN1Encodable certValue;
+
+ private CertBag(
+ ASN1Sequence seq)
+ {
+ this.certId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+ this.certValue = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getObject();
+ }
+
+ public static CertBag getInstance(Object o)
+ {
+ if (o instanceof CertBag)
+ {
+ return (CertBag)o;
+ }
+ else if (o != null)
+ {
+ return new CertBag(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public CertBag(
+ ASN1ObjectIdentifier certId,
+ ASN1Encodable certValue)
+ {
+ this.certId = certId;
+ this.certValue = certValue;
+ }
+
+ public ASN1ObjectIdentifier getCertId()
+ {
+ return certId;
+ }
+
+ public ASN1Encodable getCertValue()
+ {
+ return certValue;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(certId);
+ v.add(new DERTaggedObject(0, certValue));
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequest.java
new file mode 100644
index 00000000..b3ee00e3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequest.java
@@ -0,0 +1,96 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * PKCS10 Certification request object.
+ * <pre>
+ * CertificationRequest ::= SEQUENCE {
+ * certificationRequestInfo CertificationRequestInfo,
+ * signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
+ * signature BIT STRING
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertificationRequest
+ extends ASN1Object
+{
+ protected CertificationRequestInfo reqInfo = null;
+ protected AlgorithmIdentifier sigAlgId = null;
+ protected DERBitString sigBits = null;
+
+ public static CertificationRequest getInstance(Object o)
+ {
+ if (o instanceof CertificationRequest)
+ {
+ return (CertificationRequest)o;
+ }
+
+ if (o != null)
+ {
+ return new CertificationRequest(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ protected CertificationRequest()
+ {
+ }
+
+ public CertificationRequest(
+ CertificationRequestInfo requestInfo,
+ AlgorithmIdentifier algorithm,
+ DERBitString signature)
+ {
+ this.reqInfo = requestInfo;
+ this.sigAlgId = algorithm;
+ this.sigBits = signature;
+ }
+
+ /**
+ * @deprecated use getInstance()
+ */
+ public CertificationRequest(
+ ASN1Sequence seq)
+ {
+ reqInfo = CertificationRequestInfo.getInstance(seq.getObjectAt(0));
+ sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
+ sigBits = (DERBitString)seq.getObjectAt(2);
+ }
+
+ public CertificationRequestInfo getCertificationRequestInfo()
+ {
+ return reqInfo;
+ }
+
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return sigAlgId;
+ }
+
+ public DERBitString getSignature()
+ {
+ return sigBits;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ // Construct the CertificateRequest
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(reqInfo);
+ v.add(sigAlgId);
+ v.add(sigBits);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
new file mode 100644
index 00000000..bce5f0e6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
@@ -0,0 +1,186 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.X509Name;
+
+/**
+ * PKCS10 CertificationRequestInfo object.
+ * <pre>
+ * CertificationRequestInfo ::= SEQUENCE {
+ * version INTEGER { v1(0) } (v1,...),
+ * subject Name,
+ * subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
+ * attributes [0] Attributes{{ CRIAttributes }}
+ * }
+ *
+ * Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
+ *
+ * Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
+ * type ATTRIBUTE.&amp;id({IOSet}),
+ * values SET SIZE(1..MAX) OF ATTRIBUTE.&amp;Type({IOSet}{\@type})
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertificationRequestInfo
+ extends ASN1Object
+{
+ ASN1Integer version = new ASN1Integer(0);
+ X500Name subject;
+ SubjectPublicKeyInfo subjectPKInfo;
+ ASN1Set attributes = null;
+
+ public static CertificationRequestInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof CertificationRequestInfo)
+ {
+ return (CertificationRequestInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new CertificationRequestInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * Basic constructor.
+ * <p>
+ * Note: Early on a lot of CAs would only accept messages with attributes missing. As the ASN.1 def shows
+ * the attributes field is not optional so should always at least contain an empty set. If a fully compliant
+ * request is required, pass in an empty set, the class will otherwise interpret a null as it should
+ * encode the request with the field missing.
+ * </p>
+ *
+ * @param subject subject to be associated with the public key
+ * @param pkInfo public key to be associated with subject
+ * @param attributes any attributes to be associated with the request.
+ */
+ public CertificationRequestInfo(
+ X500Name subject,
+ SubjectPublicKeyInfo pkInfo,
+ ASN1Set attributes)
+ {
+ if ((subject == null) || (pkInfo == null))
+ {
+ throw new IllegalArgumentException("Not all mandatory fields set in CertificationRequestInfo generator.");
+ }
+
+ validateAttributes(attributes);
+
+ this.subject = subject;
+ this.subjectPKInfo = pkInfo;
+ this.attributes = attributes;
+ }
+
+ /**
+ * @deprecated use X500Name method.
+ */
+ public CertificationRequestInfo(
+ X509Name subject,
+ SubjectPublicKeyInfo pkInfo,
+ ASN1Set attributes)
+ {
+ this(X500Name.getInstance(subject.toASN1Primitive()), pkInfo, attributes);
+ }
+
+ /**
+ * @deprecated use getInstance().
+ */
+ public CertificationRequestInfo(
+ ASN1Sequence seq)
+ {
+ version = (ASN1Integer)seq.getObjectAt(0);
+
+ subject = X500Name.getInstance(seq.getObjectAt(1));
+ subjectPKInfo = SubjectPublicKeyInfo.getInstance(seq.getObjectAt(2));
+
+ //
+ // some CertificationRequestInfo objects seem to treat this field
+ // as optional.
+ //
+ if (seq.size() > 3)
+ {
+ ASN1TaggedObject tagobj = (ASN1TaggedObject)seq.getObjectAt(3);
+ attributes = ASN1Set.getInstance(tagobj, false);
+ }
+
+ validateAttributes(attributes);
+
+ if ((subject == null) || (version == null) || (subjectPKInfo == null))
+ {
+ throw new IllegalArgumentException("Not all mandatory fields set in CertificationRequestInfo generator.");
+ }
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public X500Name getSubject()
+ {
+ return subject;
+ }
+
+ public SubjectPublicKeyInfo getSubjectPublicKeyInfo()
+ {
+ return subjectPKInfo;
+ }
+
+ public ASN1Set getAttributes()
+ {
+ return attributes;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ v.add(version);
+ v.add(subject);
+ v.add(subjectPKInfo);
+
+ if (attributes != null)
+ {
+ v.add(new DERTaggedObject(false, 0, attributes));
+ }
+
+ return new DERSequence(v);
+ }
+
+ private static void validateAttributes(ASN1Set attributes)
+ {
+ if (attributes == null)
+ {
+ return;
+ }
+
+ for (Enumeration en = attributes.getObjects(); en.hasMoreElements();)
+ {
+ Attribute attr = Attribute.getInstance(en.nextElement());
+ if (attr.getAttrType().equals(PKCSObjectIdentifiers.pkcs_9_at_challengePassword))
+ {
+ if (attr.getAttrValues().size() != 1)
+ {
+ throw new IllegalArgumentException("challengePassword attribute must have one value");
+ }
+ }
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/ContentInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/ContentInfo.java
new file mode 100644
index 00000000..ed6988d5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/ContentInfo.java
@@ -0,0 +1,106 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.BERSequence;
+import com.android.internal.org.bouncycastle.asn1.BERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DLSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ContentInfo
+ extends ASN1Object
+ implements PKCSObjectIdentifiers
+{
+ private ASN1ObjectIdentifier contentType;
+ private ASN1Encodable content;
+ private boolean isBer = true;
+
+ public static ContentInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof ContentInfo)
+ {
+ return (ContentInfo)obj;
+ }
+
+ if (obj != null)
+ {
+ return new ContentInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private ContentInfo(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ contentType = (ASN1ObjectIdentifier)e.nextElement();
+
+ if (e.hasMoreElements())
+ {
+ content = ((ASN1TaggedObject)e.nextElement()).getObject();
+ }
+
+ isBer = seq instanceof BERSequence;
+ }
+
+ public ContentInfo(
+ ASN1ObjectIdentifier contentType,
+ ASN1Encodable content)
+ {
+ this.contentType = contentType;
+ this.content = content;
+ }
+
+ public ASN1ObjectIdentifier getContentType()
+ {
+ return contentType;
+ }
+
+ public ASN1Encodable getContent()
+ {
+ return content;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * ContentInfo ::= SEQUENCE {
+ * contentType ContentType,
+ * content
+ * [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(contentType);
+
+ if (content != null)
+ {
+ v.add(new BERTaggedObject(true, 0, content));
+ }
+
+ if (isBer)
+ {
+ return new BERSequence(v);
+ }
+ else
+ {
+ return new DLSequence(v);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/DHParameter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/DHParameter.java
new file mode 100644
index 00000000..4cafc7db
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/DHParameter.java
@@ -0,0 +1,108 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHParameter
+ extends ASN1Object
+{
+ ASN1Integer p, g, l;
+
+ public DHParameter(
+ BigInteger p,
+ BigInteger g,
+ int l)
+ {
+ this.p = new ASN1Integer(p);
+ this.g = new ASN1Integer(g);
+
+ if (l != 0)
+ {
+ this.l = new ASN1Integer(l);
+ }
+ else
+ {
+ this.l = null;
+ }
+ }
+
+ public static DHParameter getInstance(
+ Object obj)
+ {
+ if (obj instanceof DHParameter)
+ {
+ return (DHParameter)obj;
+ }
+
+ if (obj != null)
+ {
+ return new DHParameter(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private DHParameter(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ p = ASN1Integer.getInstance(e.nextElement());
+ g = ASN1Integer.getInstance(e.nextElement());
+
+ if (e.hasMoreElements())
+ {
+ l = (ASN1Integer)e.nextElement();
+ }
+ else
+ {
+ l = null;
+ }
+ }
+
+ public BigInteger getP()
+ {
+ return p.getPositiveValue();
+ }
+
+ public BigInteger getG()
+ {
+ return g.getPositiveValue();
+ }
+
+ public BigInteger getL()
+ {
+ if (l == null)
+ {
+ return null;
+ }
+
+ return l.getPositiveValue();
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(p);
+ v.add(g);
+
+ if (this.getL() != null)
+ {
+ v.add(l);
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedData.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedData.java
new file mode 100644
index 00000000..600b9d2e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedData.java
@@ -0,0 +1,115 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.BERSequence;
+import com.android.internal.org.bouncycastle.asn1.BERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * The EncryptedData object.
+ * <pre>
+ * EncryptedData ::= SEQUENCE {
+ * version Version,
+ * encryptedContentInfo EncryptedContentInfo
+ * }
+ *
+ *
+ * EncryptedContentInfo ::= SEQUENCE {
+ * contentType ContentType,
+ * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+ * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
+ * }
+ *
+ * EncryptedContent ::= OCTET STRING
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EncryptedData
+ extends ASN1Object
+{
+ ASN1Sequence data;
+
+ public static EncryptedData getInstance(
+ Object obj)
+ {
+ if (obj instanceof EncryptedData)
+ {
+ return (EncryptedData)obj;
+ }
+
+ if (obj != null)
+ {
+ return new EncryptedData(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private EncryptedData(
+ ASN1Sequence seq)
+ {
+ int version = ((ASN1Integer)seq.getObjectAt(0)).intValueExact();
+
+ if (version != 0)
+ {
+ throw new IllegalArgumentException("sequence not version 0");
+ }
+
+ this.data = ASN1Sequence.getInstance(seq.getObjectAt(1));
+ }
+
+ public EncryptedData(
+ ASN1ObjectIdentifier contentType,
+ AlgorithmIdentifier encryptionAlgorithm,
+ ASN1Encodable content)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(contentType);
+ v.add(encryptionAlgorithm.toASN1Primitive());
+ v.add(new BERTaggedObject(false, 0, content));
+
+ data = new BERSequence(v);
+ }
+
+ public ASN1ObjectIdentifier getContentType()
+ {
+ return ASN1ObjectIdentifier.getInstance(data.getObjectAt(0));
+ }
+
+ public AlgorithmIdentifier getEncryptionAlgorithm()
+ {
+ return AlgorithmIdentifier.getInstance(data.getObjectAt(1));
+ }
+
+ public ASN1OctetString getContent()
+ {
+ if (data.size() == 3)
+ {
+ ASN1TaggedObject o = ASN1TaggedObject.getInstance(data.getObjectAt(2));
+
+ return ASN1OctetString.getInstance(o, false);
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(new ASN1Integer(0));
+ v.add(data);
+
+ return new BERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
new file mode 100644
index 00000000..47c61003
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
@@ -0,0 +1,90 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EncryptedPrivateKeyInfo
+ extends ASN1Object
+{
+ private AlgorithmIdentifier algId;
+ private ASN1OctetString data;
+
+ private EncryptedPrivateKeyInfo(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ algId = AlgorithmIdentifier.getInstance(e.nextElement());
+ data = ASN1OctetString.getInstance(e.nextElement());
+ }
+
+ public EncryptedPrivateKeyInfo(
+ AlgorithmIdentifier algId,
+ byte[] encoding)
+ {
+ this.algId = algId;
+ this.data = new DEROctetString(encoding);
+ }
+
+ public static EncryptedPrivateKeyInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof EncryptedPrivateKeyInfo)
+ {
+ return (EncryptedPrivateKeyInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new EncryptedPrivateKeyInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public AlgorithmIdentifier getEncryptionAlgorithm()
+ {
+ return algId;
+ }
+
+ public byte[] getEncryptedData()
+ {
+ return data.getOctets();
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * EncryptedPrivateKeyInfo ::= SEQUENCE {
+ * encryptionAlgorithm AlgorithmIdentifier {{KeyEncryptionAlgorithms}},
+ * encryptedData EncryptedData
+ * }
+ *
+ * EncryptedData ::= OCTET STRING
+ *
+ * KeyEncryptionAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * ... -- For local profiles
+ * }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(algId);
+ v.add(data);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptionScheme.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptionScheme.java
new file mode 100644
index 00000000..4ebcb91f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptionScheme.java
@@ -0,0 +1,66 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EncryptionScheme
+ extends ASN1Object
+{
+ private AlgorithmIdentifier algId;
+
+ public EncryptionScheme(
+ ASN1ObjectIdentifier objectId)
+ {
+ this.algId = new AlgorithmIdentifier(objectId);
+ }
+
+ public EncryptionScheme(
+ ASN1ObjectIdentifier objectId,
+ ASN1Encodable parameters)
+ {
+ this.algId = new AlgorithmIdentifier(objectId, parameters);
+ }
+
+ private EncryptionScheme(
+ ASN1Sequence seq)
+ {
+ this.algId = AlgorithmIdentifier.getInstance(seq);
+ }
+
+ public static EncryptionScheme getInstance(Object obj)
+ {
+ if (obj instanceof EncryptionScheme)
+ {
+ return (EncryptionScheme)obj;
+ }
+ else if (obj != null)
+ {
+ return new EncryptionScheme(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1ObjectIdentifier getAlgorithm()
+ {
+ return algId.getAlgorithm();
+ }
+
+ public ASN1Encodable getParameters()
+ {
+ return algId.getParameters();
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return algId.toASN1Primitive();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java
new file mode 100644
index 00000000..d88f45a3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java
@@ -0,0 +1,89 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.X509Name;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class IssuerAndSerialNumber
+ extends ASN1Object
+{
+ X500Name name;
+ ASN1Integer certSerialNumber;
+
+ public static IssuerAndSerialNumber getInstance(
+ Object obj)
+ {
+ if (obj instanceof IssuerAndSerialNumber)
+ {
+ return (IssuerAndSerialNumber)obj;
+ }
+ else if (obj != null)
+ {
+ return new IssuerAndSerialNumber(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private IssuerAndSerialNumber(
+ ASN1Sequence seq)
+ {
+ this.name = X500Name.getInstance(seq.getObjectAt(0));
+ this.certSerialNumber = (ASN1Integer)seq.getObjectAt(1);
+ }
+
+ public IssuerAndSerialNumber(
+ X509Name name,
+ BigInteger certSerialNumber)
+ {
+ this.name = X500Name.getInstance(name.toASN1Primitive());
+ this.certSerialNumber = new ASN1Integer(certSerialNumber);
+ }
+
+ public IssuerAndSerialNumber(
+ X509Name name,
+ ASN1Integer certSerialNumber)
+ {
+ this.name = X500Name.getInstance(name.toASN1Primitive());
+ this.certSerialNumber = certSerialNumber;
+ }
+
+ public IssuerAndSerialNumber(
+ X500Name name,
+ BigInteger certSerialNumber)
+ {
+ this.name = name;
+ this.certSerialNumber = new ASN1Integer(certSerialNumber);
+ }
+
+ public X500Name getName()
+ {
+ return name;
+ }
+
+ public ASN1Integer getCertificateSerialNumber()
+ {
+ return certSerialNumber;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(name);
+ v.add(certSerialNumber);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/KeyDerivationFunc.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/KeyDerivationFunc.java
new file mode 100644
index 00000000..3e5fe909
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/KeyDerivationFunc.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyDerivationFunc
+ extends ASN1Object
+{
+ private AlgorithmIdentifier algId;
+
+ public KeyDerivationFunc(
+ ASN1ObjectIdentifier objectId,
+ ASN1Encodable parameters)
+ {
+ this.algId = new AlgorithmIdentifier(objectId, parameters);
+ }
+
+ private KeyDerivationFunc(
+ ASN1Sequence seq)
+ {
+ this.algId = AlgorithmIdentifier.getInstance(seq);
+ }
+
+ public static KeyDerivationFunc getInstance(Object obj)
+ {
+ if (obj instanceof KeyDerivationFunc)
+ {
+ return (KeyDerivationFunc)obj;
+ }
+ else if (obj != null)
+ {
+ return new KeyDerivationFunc(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1ObjectIdentifier getAlgorithm()
+ {
+ return algId.getAlgorithm();
+ }
+
+ public ASN1Encodable getParameters()
+ {
+ return algId.getParameters();
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return algId.toASN1Primitive();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/MacData.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/MacData.java
new file mode 100644
index 00000000..63c01547
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/MacData.java
@@ -0,0 +1,111 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.x509.DigestInfo;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class MacData
+ extends ASN1Object
+{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+
+ DigestInfo digInfo;
+ byte[] salt;
+ BigInteger iterationCount;
+
+ public static MacData getInstance(
+ Object obj)
+ {
+ if (obj instanceof MacData)
+ {
+ return (MacData)obj;
+ }
+ else if (obj != null)
+ {
+ return new MacData(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private MacData(
+ ASN1Sequence seq)
+ {
+ this.digInfo = DigestInfo.getInstance(seq.getObjectAt(0));
+
+ this.salt = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets());
+
+ if (seq.size() == 3)
+ {
+ this.iterationCount = ASN1Integer.getInstance(seq.getObjectAt(2)).getValue();
+ }
+ else
+ {
+ this.iterationCount = ONE;
+ }
+ }
+
+ public MacData(
+ DigestInfo digInfo,
+ byte[] salt,
+ int iterationCount)
+ {
+ this.digInfo = digInfo;
+ this.salt = Arrays.clone(salt);
+ this.iterationCount = BigInteger.valueOf(iterationCount);
+ }
+
+ public DigestInfo getMac()
+ {
+ return digInfo;
+ }
+
+ public byte[] getSalt()
+ {
+ return Arrays.clone(salt);
+ }
+
+ public BigInteger getIterationCount()
+ {
+ return iterationCount;
+ }
+
+ /**
+ * <pre>
+ * MacData ::= SEQUENCE {
+ * mac DigestInfo,
+ * macSalt OCTET STRING,
+ * iterations INTEGER DEFAULT 1
+ * -- Note: The default is for historic reasons and its use is deprecated. A
+ * -- higher value, like 1024 is recommended.
+ * </pre>
+ * @return the basic ASN1Primitive construction.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(digInfo);
+ v.add(new DEROctetString(salt));
+
+ if (!iterationCount.equals(ONE))
+ {
+ v.add(new ASN1Integer(iterationCount));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBEParameter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBEParameter.java
new file mode 100644
index 00000000..1ac91122
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBEParameter.java
@@ -0,0 +1,77 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PBEParameter
+ extends ASN1Object
+{
+ ASN1Integer iterations;
+ ASN1OctetString salt;
+
+ public PBEParameter(
+ byte[] salt,
+ int iterations)
+ {
+ if (salt.length != 8)
+ {
+ throw new IllegalArgumentException("salt length must be 8");
+ }
+ this.salt = new DEROctetString(salt);
+ this.iterations = new ASN1Integer(iterations);
+ }
+
+ private PBEParameter(
+ ASN1Sequence seq)
+ {
+ salt = (ASN1OctetString)seq.getObjectAt(0);
+ iterations = (ASN1Integer)seq.getObjectAt(1);
+ }
+
+ public static PBEParameter getInstance(
+ Object obj)
+ {
+ if (obj instanceof PBEParameter)
+ {
+ return (PBEParameter)obj;
+ }
+ else if (obj != null)
+ {
+ return new PBEParameter(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public BigInteger getIterationCount()
+ {
+ return iterations.getValue();
+ }
+
+ public byte[] getSalt()
+ {
+ return salt.getOctets();
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(salt);
+ v.add(iterations);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBES2Parameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBES2Parameters.java
new file mode 100644
index 00000000..0f4a9d4b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBES2Parameters.java
@@ -0,0 +1,81 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PBES2Parameters
+ extends ASN1Object
+ implements PKCSObjectIdentifiers
+{
+ private KeyDerivationFunc func;
+ private EncryptionScheme scheme;
+
+ public static PBES2Parameters getInstance(
+ Object obj)
+ {
+ if (obj instanceof PBES2Parameters)
+ {
+ return (PBES2Parameters)obj;
+ }
+ if (obj != null)
+ {
+ return new PBES2Parameters(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public PBES2Parameters(KeyDerivationFunc keyDevFunc, EncryptionScheme encScheme)
+ {
+ this.func = keyDevFunc;
+ this.scheme = encScheme;
+ }
+
+ private PBES2Parameters(
+ ASN1Sequence obj)
+ {
+ Enumeration e = obj.getObjects();
+ ASN1Sequence funcSeq = ASN1Sequence.getInstance(((ASN1Encodable)e.nextElement()).toASN1Primitive());
+
+ if (funcSeq.getObjectAt(0).equals(id_PBKDF2))
+ {
+ func = new KeyDerivationFunc(id_PBKDF2, PBKDF2Params.getInstance(funcSeq.getObjectAt(1)));
+ }
+ else
+ {
+ func = KeyDerivationFunc.getInstance(funcSeq);
+ }
+
+ scheme = EncryptionScheme.getInstance(e.nextElement());
+ }
+
+ public KeyDerivationFunc getKeyDerivationFunc()
+ {
+ return func;
+ }
+
+ public EncryptionScheme getEncryptionScheme()
+ {
+ return scheme;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(func);
+ v.add(scheme);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBKDF2Params.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
new file mode 100644
index 00000000..82a22eca
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
@@ -0,0 +1,265 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * PBKDF2-params ::= SEQUENCE {
+ * salt CHOICE {
+ * specified OCTET STRING,
+ * otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}}
+ * },
+ * iterationCount INTEGER (1..MAX),
+ * keyLength INTEGER (1..MAX) OPTIONAL,
+ * prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PBKDF2Params
+ extends ASN1Object
+{
+ private static final AlgorithmIdentifier algid_hmacWithSHA1 = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA1, DERNull.INSTANCE);
+
+ private final ASN1OctetString octStr;
+ private final ASN1Integer iterationCount;
+ private final ASN1Integer keyLength;
+ private final AlgorithmIdentifier prf;
+
+ /**
+ * Create PBKDF2Params from the passed in object,
+ *
+ * @param obj either PBKDF2Params or an ASN1Sequence.
+ * @return a PBKDF2Params instance.
+ */
+ public static PBKDF2Params getInstance(
+ Object obj)
+ {
+ if (obj instanceof PBKDF2Params)
+ {
+ return (PBKDF2Params)obj;
+ }
+
+ if (obj != null)
+ {
+ return new PBKDF2Params(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * Create a PBKDF2Params with the specified salt, iteration count, and algid-hmacWithSHA1 for the prf.
+ *
+ * @param salt input salt.
+ * @param iterationCount input iteration count.
+ */
+ public PBKDF2Params(
+ byte[] salt,
+ int iterationCount)
+ {
+ this(salt, iterationCount, 0);
+ }
+
+ /**
+ * Create a PBKDF2Params with the specified salt, iteration count, keyLength, and algid-hmacWithSHA1 for the prf.
+ *
+ * @param salt input salt.
+ * @param iterationCount input iteration count.
+ * @param keyLength intended key length to be produced.
+ */
+ public PBKDF2Params(
+ byte[] salt,
+ int iterationCount,
+ int keyLength)
+ {
+ this(salt, iterationCount, keyLength, null);
+ }
+
+ /**
+ * Create a PBKDF2Params with the specified salt, iteration count, keyLength, and a defined prf.
+ *
+ * @param salt input salt.
+ * @param iterationCount input iteration count.
+ * @param keyLength intended key length to be produced.
+ * @param prf the pseudo-random function to use.
+ */
+ public PBKDF2Params(
+ byte[] salt,
+ int iterationCount,
+ int keyLength,
+ AlgorithmIdentifier prf)
+ {
+ this.octStr = new DEROctetString(Arrays.clone(salt));
+ this.iterationCount = new ASN1Integer(iterationCount);
+
+ if (keyLength > 0)
+ {
+ this.keyLength = new ASN1Integer(keyLength);
+ }
+ else
+ {
+ this.keyLength = null;
+ }
+
+ this.prf = prf;
+ }
+
+ /**
+ * Create a PBKDF2Params with the specified salt, iteration count, and a defined prf.
+ *
+ * @param salt input salt.
+ * @param iterationCount input iteration count.
+ * @param prf the pseudo-random function to use.
+ */
+ public PBKDF2Params(
+ byte[] salt,
+ int iterationCount,
+ AlgorithmIdentifier prf)
+ {
+ this(salt, iterationCount, 0, prf);
+ }
+
+ private PBKDF2Params(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ octStr = (ASN1OctetString)e.nextElement();
+ iterationCount = (ASN1Integer)e.nextElement();
+
+ if (e.hasMoreElements())
+ {
+ Object o = e.nextElement();
+
+ if (o instanceof ASN1Integer)
+ {
+ keyLength = ASN1Integer.getInstance(o);
+ if (e.hasMoreElements())
+ {
+ o = e.nextElement();
+ }
+ else
+ {
+ o = null;
+ }
+ }
+ else
+ {
+ keyLength = null;
+ }
+
+ if (o != null)
+ {
+ prf = AlgorithmIdentifier.getInstance(o);
+ }
+ else
+ {
+ prf = null;
+ }
+ }
+ else
+ {
+ keyLength = null;
+ prf = null;
+ }
+ }
+
+ /**
+ * Return the salt to use.
+ *
+ * @return the input salt.
+ */
+ public byte[] getSalt()
+ {
+ return octStr.getOctets();
+ }
+
+ /**
+ * Return the iteration count to use.
+ *
+ * @return the input iteration count.
+ */
+ public BigInteger getIterationCount()
+ {
+ return iterationCount.getValue();
+ }
+
+ /**
+ * Return the intended length in octets of the derived key.
+ *
+ * @return length in octets for derived key, if specified.
+ */
+ public BigInteger getKeyLength()
+ {
+ if (keyLength != null)
+ {
+ return keyLength.getValue();
+ }
+
+ return null;
+ }
+
+ /**
+ * Return true if the PRF is the default (hmacWithSHA1)
+ *
+ * @return true if PRF is default, false otherwise.
+ */
+ public boolean isDefaultPrf()
+ {
+ return prf == null || prf.equals(algid_hmacWithSHA1);
+ }
+
+ /**
+ * Return the algId of the underlying pseudo random function to use.
+ *
+ * @return the prf algorithm identifier.
+ */
+ public AlgorithmIdentifier getPrf()
+ {
+ if (prf != null)
+ {
+ return prf;
+ }
+
+ return algid_hmacWithSHA1;
+ }
+
+ /**
+ * Return an ASN.1 structure suitable for encoding.
+ *
+ * @return the object as an ASN.1 encodable structure.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ v.add(octStr);
+ v.add(iterationCount);
+
+ if (keyLength != null)
+ {
+ v.add(keyLength);
+ }
+
+ if (prf != null && !prf.equals(algid_hmacWithSHA1))
+ {
+ v.add(prf);
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java
new file mode 100644
index 00000000..d7c4d0b0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java
@@ -0,0 +1,73 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS12PBEParams
+ extends ASN1Object
+{
+ ASN1Integer iterations;
+ ASN1OctetString iv;
+
+ public PKCS12PBEParams(
+ byte[] salt,
+ int iterations)
+ {
+ this.iv = new DEROctetString(salt);
+ this.iterations = new ASN1Integer(iterations);
+ }
+
+ private PKCS12PBEParams(
+ ASN1Sequence seq)
+ {
+ iv = (ASN1OctetString)seq.getObjectAt(0);
+ iterations = ASN1Integer.getInstance(seq.getObjectAt(1));
+ }
+
+ public static PKCS12PBEParams getInstance(
+ Object obj)
+ {
+ if (obj instanceof PKCS12PBEParams)
+ {
+ return (PKCS12PBEParams)obj;
+ }
+ else if (obj != null)
+ {
+ return new PKCS12PBEParams(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public BigInteger getIterations()
+ {
+ return iterations.getValue();
+ }
+
+ public byte[] getIV()
+ {
+ return iv.getOctets();
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(iv);
+ v.add(iterations);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
new file mode 100644
index 00000000..040a1c26
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
@@ -0,0 +1,481 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * pkcs-1 OBJECT IDENTIFIER ::=<p>
+ * { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
+ * @hide This class is not part of the Android public SDK API
+ *
+ */
+public interface PKCSObjectIdentifiers
+{
+ /** PKCS#1: 1.2.840.113549.1.1 */
+ ASN1ObjectIdentifier pkcs_1 = new ASN1ObjectIdentifier("1.2.840.113549.1.1");
+ /** PKCS#1: 1.2.840.113549.1.1.1 */
+ ASN1ObjectIdentifier rsaEncryption = pkcs_1.branch("1");
+ // BEGIN Android-removed: MD2 and MD4 are unsupported
+ /*
+ /** PKCS#1: 1.2.840.113549.1.1.2 *
+ ASN1ObjectIdentifier md2WithRSAEncryption = pkcs_1.branch("2");
+ /** PKCS#1: 1.2.840.113549.1.1.3 *
+ ASN1ObjectIdentifier md4WithRSAEncryption = pkcs_1.branch("3");
+ */
+ // END Android-removed: MD2 and MD4 are unsupported
+ /** PKCS#1: 1.2.840.113549.1.1.4 */
+ ASN1ObjectIdentifier md5WithRSAEncryption = pkcs_1.branch("4");
+ /** PKCS#1: 1.2.840.113549.1.1.5 */
+ ASN1ObjectIdentifier sha1WithRSAEncryption = pkcs_1.branch("5");
+ /** PKCS#1: 1.2.840.113549.1.1.6 */
+ ASN1ObjectIdentifier srsaOAEPEncryptionSET = pkcs_1.branch("6");
+ /** PKCS#1: 1.2.840.113549.1.1.7 */
+ ASN1ObjectIdentifier id_RSAES_OAEP = pkcs_1.branch("7");
+ /** PKCS#1: 1.2.840.113549.1.1.8 */
+ ASN1ObjectIdentifier id_mgf1 = pkcs_1.branch("8");
+ /** PKCS#1: 1.2.840.113549.1.1.9 */
+ ASN1ObjectIdentifier id_pSpecified = pkcs_1.branch("9");
+ /** PKCS#1: 1.2.840.113549.1.1.10 */
+ ASN1ObjectIdentifier id_RSASSA_PSS = pkcs_1.branch("10");
+ /** PKCS#1: 1.2.840.113549.1.1.11 */
+ ASN1ObjectIdentifier sha256WithRSAEncryption = pkcs_1.branch("11");
+ /** PKCS#1: 1.2.840.113549.1.1.12 */
+ ASN1ObjectIdentifier sha384WithRSAEncryption = pkcs_1.branch("12");
+ /** PKCS#1: 1.2.840.113549.1.1.13 */
+ ASN1ObjectIdentifier sha512WithRSAEncryption = pkcs_1.branch("13");
+ /** PKCS#1: 1.2.840.113549.1.1.14 */
+ ASN1ObjectIdentifier sha224WithRSAEncryption = pkcs_1.branch("14");
+ /** PKCS#1: 1.2.840.113549.1.1.15 */
+ ASN1ObjectIdentifier sha512_224WithRSAEncryption = pkcs_1.branch("15");
+ /** PKCS#1: 1.2.840.113549.1.1.16 */
+ ASN1ObjectIdentifier sha512_256WithRSAEncryption = pkcs_1.branch("16");
+
+ //
+ // pkcs-3 OBJECT IDENTIFIER ::= {
+ // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 3 }
+ //
+ /** PKCS#3: 1.2.840.113549.1.3 */
+ ASN1ObjectIdentifier pkcs_3 = new ASN1ObjectIdentifier("1.2.840.113549.1.3");
+ /** PKCS#3: 1.2.840.113549.1.3.1 */
+ ASN1ObjectIdentifier dhKeyAgreement = pkcs_3.branch("1");
+
+ //
+ // pkcs-5 OBJECT IDENTIFIER ::= {
+ // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 }
+ //
+ /** PKCS#5: 1.2.840.113549.1.5 */
+ ASN1ObjectIdentifier pkcs_5 = new ASN1ObjectIdentifier("1.2.840.113549.1.5");
+
+ /** PKCS#5: 1.2.840.113549.1.5.1 */
+ ASN1ObjectIdentifier pbeWithMD2AndDES_CBC = pkcs_5.branch("1");
+ /** PKCS#5: 1.2.840.113549.1.5.4 */
+ ASN1ObjectIdentifier pbeWithMD2AndRC2_CBC = pkcs_5.branch("4");
+ /** PKCS#5: 1.2.840.113549.1.5.3 */
+ ASN1ObjectIdentifier pbeWithMD5AndDES_CBC = pkcs_5.branch("3");
+ /** PKCS#5: 1.2.840.113549.1.5.6 */
+ ASN1ObjectIdentifier pbeWithMD5AndRC2_CBC = pkcs_5.branch("6");
+ /** PKCS#5: 1.2.840.113549.1.5.10 */
+ ASN1ObjectIdentifier pbeWithSHA1AndDES_CBC = pkcs_5.branch("10");
+ /** PKCS#5: 1.2.840.113549.1.5.11 */
+ ASN1ObjectIdentifier pbeWithSHA1AndRC2_CBC = pkcs_5.branch("11");
+ /** PKCS#5: 1.2.840.113549.1.5.13 */
+ ASN1ObjectIdentifier id_PBES2 = pkcs_5.branch("13");
+ /** PKCS#5: 1.2.840.113549.1.5.12 */
+ ASN1ObjectIdentifier id_PBKDF2 = pkcs_5.branch("12");
+
+ //
+ // encryptionAlgorithm OBJECT IDENTIFIER ::= {
+ // iso(1) member-body(2) us(840) rsadsi(113549) 3 }
+ //
+ /** 1.2.840.113549.3 */
+ ASN1ObjectIdentifier encryptionAlgorithm = new ASN1ObjectIdentifier("1.2.840.113549.3");
+
+ /** 1.2.840.113549.3.7 */
+ ASN1ObjectIdentifier des_EDE3_CBC = encryptionAlgorithm.branch("7");
+ /** 1.2.840.113549.3.2 */
+ ASN1ObjectIdentifier RC2_CBC = encryptionAlgorithm.branch("2");
+ /** 1.2.840.113549.3.4 */
+ ASN1ObjectIdentifier rc4 = encryptionAlgorithm.branch("4");
+
+ //
+ // object identifiers for digests
+ //
+ /** 1.2.840.113549.2 */
+ ASN1ObjectIdentifier digestAlgorithm = new ASN1ObjectIdentifier("1.2.840.113549.2");
+ //
+ // md2 OBJECT IDENTIFIER ::=
+ // {iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 2}
+ //
+ // BEGIN android-removed
+ // /** 1.2.840.113549.2.2 */
+ // ASN1ObjectIdentifier md2 = digestAlgorithm.branch("2");
+ // END android-removed
+
+ //
+ // md4 OBJECT IDENTIFIER ::=
+ // {iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 4}
+ //
+ // BEGIN android-removed
+ // /** 1.2.840.113549.2.4 */
+ // ASN1ObjectIdentifier md4 = digestAlgorithm.branch("4");
+ // END android-removed
+
+ //
+ // md5 OBJECT IDENTIFIER ::=
+ // {iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5}
+ //
+ /** 1.2.840.113549.2.5 */
+ ASN1ObjectIdentifier md5 = digestAlgorithm.branch("5");
+
+ /** 1.2.840.113549.2.7 */
+ ASN1ObjectIdentifier id_hmacWithSHA1 = digestAlgorithm.branch("7").intern();
+ /** 1.2.840.113549.2.8 */
+ ASN1ObjectIdentifier id_hmacWithSHA224 = digestAlgorithm.branch("8").intern();
+ /** 1.2.840.113549.2.9 */
+ ASN1ObjectIdentifier id_hmacWithSHA256 = digestAlgorithm.branch("9").intern();
+ /** 1.2.840.113549.2.10 */
+ ASN1ObjectIdentifier id_hmacWithSHA384 = digestAlgorithm.branch("10").intern();
+ /** 1.2.840.113549.2.11 */
+ ASN1ObjectIdentifier id_hmacWithSHA512 = digestAlgorithm.branch("11").intern();
+
+ //
+ // pkcs-7 OBJECT IDENTIFIER ::= {
+ // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 }
+ //
+ /** pkcs#7: 1.2.840.113549.1.7 */
+ ASN1ObjectIdentifier pkcs_7 = new ASN1ObjectIdentifier("1.2.840.113549.1.7").intern();
+ /** PKCS#7: 1.2.840.113549.1.7.1 */
+ ASN1ObjectIdentifier data = new ASN1ObjectIdentifier("1.2.840.113549.1.7.1").intern();
+ /** PKCS#7: 1.2.840.113549.1.7.2 */
+ ASN1ObjectIdentifier signedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.2").intern();
+ /** PKCS#7: 1.2.840.113549.1.7.3 */
+ ASN1ObjectIdentifier envelopedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.3").intern();
+ /** PKCS#7: 1.2.840.113549.1.7.4 */
+ ASN1ObjectIdentifier signedAndEnvelopedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.4").intern();
+ /** PKCS#7: 1.2.840.113549.1.7.5 */
+ ASN1ObjectIdentifier digestedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.5").intern();
+ /** PKCS#7: 1.2.840.113549.1.7.76 */
+ ASN1ObjectIdentifier encryptedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.6").intern();
+
+ //
+ // pkcs-9 OBJECT IDENTIFIER ::= {
+ // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 }
+ //
+ /** PKCS#9: 1.2.840.113549.1.9 */
+ ASN1ObjectIdentifier pkcs_9 = new ASN1ObjectIdentifier("1.2.840.113549.1.9");
+
+ /** PKCS#9: 1.2.840.113549.1.9.1 */
+ ASN1ObjectIdentifier pkcs_9_at_emailAddress = pkcs_9.branch("1").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.2 */
+ ASN1ObjectIdentifier pkcs_9_at_unstructuredName = pkcs_9.branch("2").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.3 */
+ ASN1ObjectIdentifier pkcs_9_at_contentType = pkcs_9.branch("3").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.4 */
+ ASN1ObjectIdentifier pkcs_9_at_messageDigest = pkcs_9.branch("4").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.5 */
+ ASN1ObjectIdentifier pkcs_9_at_signingTime = pkcs_9.branch("5").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.6 */
+ ASN1ObjectIdentifier pkcs_9_at_counterSignature = pkcs_9.branch("6").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.7 */
+ ASN1ObjectIdentifier pkcs_9_at_challengePassword = pkcs_9.branch("7").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.8 */
+ ASN1ObjectIdentifier pkcs_9_at_unstructuredAddress = pkcs_9.branch("8").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.9 */
+ ASN1ObjectIdentifier pkcs_9_at_extendedCertificateAttributes = pkcs_9.branch("9").intern();
+
+ /** PKCS#9: 1.2.840.113549.1.9.13 */
+ ASN1ObjectIdentifier pkcs_9_at_signingDescription = pkcs_9.branch("13").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.14 */
+ ASN1ObjectIdentifier pkcs_9_at_extensionRequest = pkcs_9.branch("14").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.15 */
+ ASN1ObjectIdentifier pkcs_9_at_smimeCapabilities = pkcs_9.branch("15").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.16 */
+ ASN1ObjectIdentifier id_smime = pkcs_9.branch("16").intern();
+
+ /** PKCS#9: 1.2.840.113549.1.9.20 */
+ ASN1ObjectIdentifier pkcs_9_at_friendlyName = pkcs_9.branch("20").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.21 */
+ ASN1ObjectIdentifier pkcs_9_at_localKeyId = pkcs_9.branch("21").intern();
+
+ /** PKCS#9: 1.2.840.113549.1.9.22.1
+ * @deprecated use x509Certificate instead */
+ ASN1ObjectIdentifier x509certType = pkcs_9.branch("22.1");
+
+ /** PKCS#9: 1.2.840.113549.1.9.22 */
+ ASN1ObjectIdentifier certTypes = pkcs_9.branch("22");
+ /** PKCS#9: 1.2.840.113549.1.9.22.1 */
+ ASN1ObjectIdentifier x509Certificate = certTypes.branch("1").intern();
+ /** PKCS#9: 1.2.840.113549.1.9.22.2 */
+ ASN1ObjectIdentifier sdsiCertificate = certTypes.branch("2").intern();
+
+ /** PKCS#9: 1.2.840.113549.1.9.23 */
+ ASN1ObjectIdentifier crlTypes = pkcs_9.branch("23");
+ /** PKCS#9: 1.2.840.113549.1.9.23.1 */
+ ASN1ObjectIdentifier x509Crl = crlTypes.branch("1").intern();
+
+ /** RFC 6211 - id-aa-cmsAlgorithmProtect OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+ pkcs9(9) 52 } */
+ ASN1ObjectIdentifier id_aa_cmsAlgorithmProtect = pkcs_9.branch("52").intern();
+
+ //
+ // SMIME capability sub oids.
+ //
+ /** PKCS#9: 1.2.840.113549.1.9.15.1 -- smime capability */
+ ASN1ObjectIdentifier preferSignedData = pkcs_9.branch("15.1");
+ /** PKCS#9: 1.2.840.113549.1.9.15.2 -- smime capability */
+ ASN1ObjectIdentifier canNotDecryptAny = pkcs_9.branch("15.2");
+ /** PKCS#9: 1.2.840.113549.1.9.15.3 -- smime capability */
+ ASN1ObjectIdentifier sMIMECapabilitiesVersions = pkcs_9.branch("15.3");
+
+ //
+ // id-ct OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
+ // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1)}
+ //
+ /** PKCS#9: 1.2.840.113549.1.9.16.1 -- smime ct */
+ ASN1ObjectIdentifier id_ct = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.1");
+
+ /** PKCS#9: 1.2.840.113549.1.9.16.1.2 -- smime ct authData */
+ ASN1ObjectIdentifier id_ct_authData = id_ct.branch("2");
+ /** PKCS#9: 1.2.840.113549.1.9.16.1.4 -- smime ct TSTInfo*/
+ ASN1ObjectIdentifier id_ct_TSTInfo = id_ct.branch("4");
+ /** PKCS#9: 1.2.840.113549.1.9.16.1.9 -- smime ct compressedData */
+ ASN1ObjectIdentifier id_ct_compressedData = id_ct.branch("9");
+ /** PKCS#9: 1.2.840.113549.1.9.16.1.23 -- smime ct authEnvelopedData */
+ ASN1ObjectIdentifier id_ct_authEnvelopedData = id_ct.branch("23");
+ /** PKCS#9: 1.2.840.113549.1.9.16.1.31 -- smime ct timestampedData*/
+ ASN1ObjectIdentifier id_ct_timestampedData = id_ct.branch("31");
+
+
+ /** S/MIME: Algorithm Identifiers ; 1.2.840.113549.1.9.16.3 */
+ ASN1ObjectIdentifier id_alg = id_smime.branch("3");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.9 */
+ ASN1ObjectIdentifier id_alg_PWRI_KEK = id_alg.branch("9");
+ /**
+ * <pre>
+ * -- RSA-KEM Key Transport Algorithm RFC 5990
+ *
+ * id-rsa-kem OID ::= {
+ * iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+ * pkcs-9(9) smime(16) alg(3) 14
+ * }
+ * </pre>
+ */
+ ASN1ObjectIdentifier id_rsa_KEM = id_alg.branch("14");
+
+
+ /**
+ * id-alg-hss-lms-hashsig OBJECT IDENTIFIER ::= { iso(1)
+ * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
+ * smime(16) alg(3) 17 }
+ */
+ public static final ASN1ObjectIdentifier id_alg_hss_lms_hashsig = id_alg.branch("17");
+
+ /**
+ * <pre>
+ * id-alg-AEADChaCha20Poly1305 OBJECT IDENTIFIER ::=
+ * { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+ * pkcs9(9) smime(16) alg(3) 18 }
+ *
+ * AEADChaCha20Poly1305Nonce ::= OCTET STRING (SIZE(12))
+ * </pre>
+ */
+ ASN1ObjectIdentifier id_alg_AEADChaCha20Poly1305 = id_alg.branch("18");
+
+ /**
+ * <pre>
+ * id-alg-hkdf-with-sha256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ * us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 28 }
+ * </pre>
+ */
+ ASN1ObjectIdentifier id_alg_hkdf_with_sha256 = id_alg.branch("28");
+
+ /**
+ * <pre>
+ * id-alg-hkdf-with-sha384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ * us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 29 }
+ * </pre>
+ */
+ ASN1ObjectIdentifier id_alg_hkdf_with_sha384 = id_alg.branch("29");
+
+ /**
+ * <pre>
+ * id-alg-hkdf-with-sha512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ * us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 30 }
+ * </pre>
+ */
+ ASN1ObjectIdentifier id_alg_hkdf_with_sha512 = id_alg.branch("30");
+
+ //
+ // id-cti OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
+ // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) cti(6)}
+ //
+ /** PKCS#9: 1.2.840.113549.1.9.16.6 -- smime cti */
+ ASN1ObjectIdentifier id_cti = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.6");
+
+ /** PKCS#9: 1.2.840.113549.1.9.16.6.1 -- smime cti proofOfOrigin */
+ ASN1ObjectIdentifier id_cti_ets_proofOfOrigin = id_cti.branch("1");
+ /** PKCS#9: 1.2.840.113549.1.9.16.6.2 -- smime cti proofOfReceipt*/
+ ASN1ObjectIdentifier id_cti_ets_proofOfReceipt = id_cti.branch("2");
+ /** PKCS#9: 1.2.840.113549.1.9.16.6.3 -- smime cti proofOfDelivery */
+ ASN1ObjectIdentifier id_cti_ets_proofOfDelivery = id_cti.branch("3");
+ /** PKCS#9: 1.2.840.113549.1.9.16.6.4 -- smime cti proofOfSender */
+ ASN1ObjectIdentifier id_cti_ets_proofOfSender = id_cti.branch("4");
+ /** PKCS#9: 1.2.840.113549.1.9.16.6.5 -- smime cti proofOfApproval */
+ ASN1ObjectIdentifier id_cti_ets_proofOfApproval = id_cti.branch("5");
+ /** PKCS#9: 1.2.840.113549.1.9.16.6.6 -- smime cti proofOfCreation */
+ ASN1ObjectIdentifier id_cti_ets_proofOfCreation = id_cti.branch("6");
+
+ //
+ // id-aa OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
+ // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) attributes(2)}
+ //
+ /** PKCS#9: 1.2.840.113549.1.9.16.2 - smime attributes */
+ ASN1ObjectIdentifier id_aa = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.2");
+
+
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.1 -- smime attribute receiptRequest */
+ ASN1ObjectIdentifier id_aa_receiptRequest = id_aa.branch("1");
+
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.4 - See <a href="https://tools.ietf.org/html/rfc2634">RFC 2634</a> */
+ ASN1ObjectIdentifier id_aa_contentHint = id_aa.branch("4"); // See RFC 2634
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.5 */
+ ASN1ObjectIdentifier id_aa_msgSigDigest = id_aa.branch("5");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.10 */
+ ASN1ObjectIdentifier id_aa_contentReference = id_aa.branch("10");
+ /*
+ * id-aa-encrypKeyPref OBJECT IDENTIFIER ::= {id-aa 11}
+ *
+ */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.11 */
+ ASN1ObjectIdentifier id_aa_encrypKeyPref = id_aa.branch("11");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.12 */
+ ASN1ObjectIdentifier id_aa_signingCertificate = id_aa.branch("12");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.47 */
+ ASN1ObjectIdentifier id_aa_signingCertificateV2 = id_aa.branch("47");
+
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.7 - See <a href="https://tools.ietf.org/html/rfc2634">RFC 2634</a> */
+ ASN1ObjectIdentifier id_aa_contentIdentifier = id_aa.branch("7"); // See RFC 2634
+
+ /*
+ * RFC 3126
+ */
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.14 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ ASN1ObjectIdentifier id_aa_signatureTimeStampToken = id_aa.branch("14");
+
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.15 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ ASN1ObjectIdentifier id_aa_ets_sigPolicyId = id_aa.branch("15");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.16 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ ASN1ObjectIdentifier id_aa_ets_commitmentType = id_aa.branch("16");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.17 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ ASN1ObjectIdentifier id_aa_ets_signerLocation = id_aa.branch("17");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.18 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ ASN1ObjectIdentifier id_aa_ets_signerAttr = id_aa.branch("18");
+ /** PKCS#9: 1.2.840.113549.1.9.16.6.2.19 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ ASN1ObjectIdentifier id_aa_ets_otherSigCert = id_aa.branch("19");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.20 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ ASN1ObjectIdentifier id_aa_ets_contentTimestamp = id_aa.branch("20");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.21 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ ASN1ObjectIdentifier id_aa_ets_certificateRefs = id_aa.branch("21");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.22 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ ASN1ObjectIdentifier id_aa_ets_revocationRefs = id_aa.branch("22");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.23 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ ASN1ObjectIdentifier id_aa_ets_certValues = id_aa.branch("23");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.24 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ ASN1ObjectIdentifier id_aa_ets_revocationValues = id_aa.branch("24");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.25 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ ASN1ObjectIdentifier id_aa_ets_escTimeStamp = id_aa.branch("25");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.26 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ ASN1ObjectIdentifier id_aa_ets_certCRLTimestamp = id_aa.branch("26");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.27 - <a href="https://tools.ietf.org/html/rfc3126">RFC 3126</a> */
+ ASN1ObjectIdentifier id_aa_ets_archiveTimestamp = id_aa.branch("27");
+
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.37 - <a href="https://tools.ietf.org/html/rfc4108#section-2.2.5">RFC 4108</a> */
+ ASN1ObjectIdentifier id_aa_decryptKeyID = id_aa.branch("37");
+
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.38 - <a href="https://tools.ietf.org/html/rfc4108#section-2.2.6">RFC 4108</a> */
+ ASN1ObjectIdentifier id_aa_implCryptoAlgs = id_aa.branch("38");
+
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.54 <a href="https://tools.ietf.org/html/rfc7030">RFC7030</a>*/
+ ASN1ObjectIdentifier id_aa_asymmDecryptKeyID = id_aa.branch("54");
+
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.43 <a href="https://tools.ietf.org/html/rfc7030">RFC7030</a>*/
+ ASN1ObjectIdentifier id_aa_implCompressAlgs = id_aa.branch("43");
+ /** PKCS#9: 1.2.840.113549.1.9.16.2.40 <a href="https://tools.ietf.org/html/rfc7030">RFC7030</a>*/
+ ASN1ObjectIdentifier id_aa_communityIdentifiers = id_aa.branch("40");
+
+ /** @deprecated use id_aa_ets_sigPolicyId instead */
+ ASN1ObjectIdentifier id_aa_sigPolicyId = id_aa_ets_sigPolicyId;
+ /** @deprecated use id_aa_ets_commitmentType instead */
+ ASN1ObjectIdentifier id_aa_commitmentType = id_aa_ets_commitmentType;
+ /** @deprecated use id_aa_ets_signerLocation instead */
+ ASN1ObjectIdentifier id_aa_signerLocation = id_aa_ets_signerLocation;
+ /** @deprecated use id_aa_ets_otherSigCert instead */
+ ASN1ObjectIdentifier id_aa_otherSigCert = id_aa_ets_otherSigCert;
+
+ /**
+ * id-spq OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
+ * rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) id-spq(5)}; <p>
+ * 1.2.840.113549.1.9.16.5
+ */
+ final String id_spq = "1.2.840.113549.1.9.16.5";
+
+ /** SMIME SPQ URI: 1.2.840.113549.1.9.16.5.1 */
+ ASN1ObjectIdentifier id_spq_ets_uri = new ASN1ObjectIdentifier(id_spq + ".1");
+ /** SMIME SPQ UNOTICE: 1.2.840.113549.1.9.16.5.2 */
+ ASN1ObjectIdentifier id_spq_ets_unotice = new ASN1ObjectIdentifier(id_spq + ".2");
+
+ //
+ // pkcs-12 OBJECT IDENTIFIER ::= {
+ // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 }
+ //
+ /** PKCS#12: 1.2.840.113549.1.12 */
+ ASN1ObjectIdentifier pkcs_12 = new ASN1ObjectIdentifier("1.2.840.113549.1.12");
+ /** PKCS#12: 1.2.840.113549.1.12.10.1 */
+ ASN1ObjectIdentifier bagtypes = pkcs_12.branch("10.1");
+
+ /** PKCS#12: 1.2.840.113549.1.12.10.1.1 */
+ ASN1ObjectIdentifier keyBag = bagtypes.branch("1");
+ /** PKCS#12: 1.2.840.113549.1.12.10.1.2 */
+ ASN1ObjectIdentifier pkcs8ShroudedKeyBag = bagtypes.branch("2");
+ /** PKCS#12: 1.2.840.113549.1.12.10.1.3 */
+ ASN1ObjectIdentifier certBag = bagtypes.branch("3");
+ /** PKCS#12: 1.2.840.113549.1.12.10.1.4 */
+ ASN1ObjectIdentifier crlBag = bagtypes.branch("4");
+ /** PKCS#12: 1.2.840.113549.1.12.10.1.5 */
+ ASN1ObjectIdentifier secretBag = bagtypes.branch("5");
+ /** PKCS#12: 1.2.840.113549.1.12.10.1.6 */
+ ASN1ObjectIdentifier safeContentsBag = bagtypes.branch("6");
+
+ /** PKCS#12: 1.2.840.113549.1.12.1 */
+ ASN1ObjectIdentifier pkcs_12PbeIds = pkcs_12.branch("1");
+
+ /** PKCS#12: 1.2.840.113549.1.12.1.1 */
+ ASN1ObjectIdentifier pbeWithSHAAnd128BitRC4 = pkcs_12PbeIds.branch("1");
+ /** PKCS#12: 1.2.840.113549.1.12.1.2 */
+ ASN1ObjectIdentifier pbeWithSHAAnd40BitRC4 = pkcs_12PbeIds.branch("2");
+ /** PKCS#12: 1.2.840.113549.1.12.1.3 */
+ ASN1ObjectIdentifier pbeWithSHAAnd3_KeyTripleDES_CBC = pkcs_12PbeIds.branch("3");
+ /** PKCS#12: 1.2.840.113549.1.12.1.4 */
+ ASN1ObjectIdentifier pbeWithSHAAnd2_KeyTripleDES_CBC = pkcs_12PbeIds.branch("4");
+ /** PKCS#12: 1.2.840.113549.1.12.1.5 */
+ ASN1ObjectIdentifier pbeWithSHAAnd128BitRC2_CBC = pkcs_12PbeIds.branch("5");
+ /** PKCS#12: 1.2.840.113549.1.12.1.6 */
+ ASN1ObjectIdentifier pbeWithSHAAnd40BitRC2_CBC = pkcs_12PbeIds.branch("6");
+
+ /**
+ * PKCS#12: 1.2.840.113549.1.12.1.6
+ * @deprecated use pbeWithSHAAnd40BitRC2_CBC
+ */
+ ASN1ObjectIdentifier pbewithSHAAnd40BitRC2_CBC = pkcs_12PbeIds.branch("6");
+
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.6 */
+ ASN1ObjectIdentifier id_alg_CMS3DESwrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.6");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.7 */
+ ASN1ObjectIdentifier id_alg_CMSRC2wrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.7");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.5 */
+ ASN1ObjectIdentifier id_alg_ESDH = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.5");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.10 */
+ ASN1ObjectIdentifier id_alg_SSDH = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.10");
+}
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Pfx.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Pfx.java
new file mode 100644
index 00000000..a7825003
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Pfx.java
@@ -0,0 +1,87 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.BERSequence;
+
+/**
+ * the infamous Pfx from PKCS12
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Pfx
+ extends ASN1Object
+ implements PKCSObjectIdentifiers
+{
+ private ContentInfo contentInfo;
+ private MacData macData = null;
+
+ private Pfx(
+ ASN1Sequence seq)
+ {
+ ASN1Integer version = ASN1Integer.getInstance(seq.getObjectAt(0));
+ if (version.intValueExact() != 3)
+ {
+ throw new IllegalArgumentException("wrong version for PFX PDU");
+ }
+
+ contentInfo = ContentInfo.getInstance(seq.getObjectAt(1));
+
+ if (seq.size() == 3)
+ {
+ macData = MacData.getInstance(seq.getObjectAt(2));
+ }
+ }
+
+ public static Pfx getInstance(
+ Object obj)
+ {
+ if (obj instanceof Pfx)
+ {
+ return (Pfx)obj;
+ }
+
+ if (obj != null)
+ {
+ return new Pfx(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public Pfx(
+ ContentInfo contentInfo,
+ MacData macData)
+ {
+ this.contentInfo = contentInfo;
+ this.macData = macData;
+ }
+
+ public ContentInfo getAuthSafe()
+ {
+ return contentInfo;
+ }
+
+ public MacData getMacData()
+ {
+ return macData;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(new ASN1Integer(3));
+ v.add(contentInfo);
+
+ if (macData != null)
+ {
+ v.add(macData);
+ }
+
+ return new BERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
new file mode 100644
index 00000000..9d8e99d7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
@@ -0,0 +1,260 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * RFC 5958
+ *
+ * <pre>
+ * [IMPLICIT TAGS]
+ *
+ * OneAsymmetricKey ::= SEQUENCE {
+ * version Version,
+ * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
+ * privateKey PrivateKey,
+ * attributes [0] Attributes OPTIONAL,
+ * ...,
+ * [[2: publicKey [1] PublicKey OPTIONAL ]],
+ * ...
+ * }
+ *
+ * PrivateKeyInfo ::= OneAsymmetricKey
+ *
+ * Version ::= INTEGER { v1(0), v2(1) } (v1, ..., v2)
+ *
+ * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
+ * { PUBLIC-KEY,
+ * { PrivateKeyAlgorithms } }
+ *
+ * PrivateKey ::= OCTET STRING
+ * -- Content varies based on type of key. The
+ * -- algorithm identifier dictates the format of
+ * -- the key.
+ *
+ * PublicKey ::= BIT STRING
+ * -- Content varies based on type of key. The
+ * -- algorithm identifier dictates the format of
+ * -- the key.
+ *
+ * Attributes ::= SET OF Attribute { { OneAsymmetricKeyAttributes } }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PrivateKeyInfo
+ extends ASN1Object
+{
+ private ASN1Integer version;
+ private AlgorithmIdentifier privateKeyAlgorithm;
+ private ASN1OctetString privateKey;
+ private ASN1Set attributes;
+ private ASN1BitString publicKey;
+
+ public static PrivateKeyInfo getInstance(ASN1TaggedObject obj, boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static PrivateKeyInfo getInstance(Object obj)
+ {
+ if (obj instanceof PrivateKeyInfo)
+ {
+ return (PrivateKeyInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new PrivateKeyInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private static int getVersionValue(ASN1Integer version)
+ {
+ int versionValue = version.intValueExact();
+ if (versionValue < 0 || versionValue > 1)
+ {
+ throw new IllegalArgumentException("invalid version for private key info");
+ }
+ return versionValue;
+ }
+
+ public PrivateKeyInfo(
+ AlgorithmIdentifier privateKeyAlgorithm,
+ ASN1Encodable privateKey)
+ throws IOException
+ {
+ this(privateKeyAlgorithm, privateKey, null, null);
+ }
+
+ public PrivateKeyInfo(
+ AlgorithmIdentifier privateKeyAlgorithm,
+ ASN1Encodable privateKey,
+ ASN1Set attributes)
+ throws IOException
+ {
+ this(privateKeyAlgorithm, privateKey, attributes, null);
+ }
+
+ public PrivateKeyInfo(
+ AlgorithmIdentifier privateKeyAlgorithm,
+ ASN1Encodable privateKey,
+ ASN1Set attributes,
+ byte[] publicKey)
+ throws IOException
+ {
+ this.version = new ASN1Integer(publicKey != null ? BigIntegers.ONE : BigIntegers.ZERO);
+ this.privateKeyAlgorithm = privateKeyAlgorithm;
+ this.privateKey = new DEROctetString(privateKey);
+ this.attributes = attributes;
+ this.publicKey = publicKey == null ? null : new DERBitString(publicKey);
+ }
+
+ private PrivateKeyInfo(ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ this.version = ASN1Integer.getInstance(e.nextElement());
+
+ int versionValue = getVersionValue(version);
+
+ this.privateKeyAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement());
+ this.privateKey = ASN1OctetString.getInstance(e.nextElement());
+
+ int lastTag = -1;
+ while (e.hasMoreElements())
+ {
+ ASN1TaggedObject tagged = (ASN1TaggedObject)e.nextElement();
+
+ int tag = tagged.getTagNo();
+ if (tag <= lastTag)
+ {
+ throw new IllegalArgumentException("invalid optional field in private key info");
+ }
+
+ lastTag = tag;
+
+ switch (tag)
+ {
+ case 0:
+ {
+ this.attributes = ASN1Set.getInstance(tagged, false);
+ break;
+ }
+ case 1:
+ {
+ if (versionValue < 1)
+ {
+ throw new IllegalArgumentException("'publicKey' requires version v2(1) or later");
+ }
+
+ this.publicKey = DERBitString.getInstance(tagged, false);
+ break;
+ }
+ default:
+ {
+ throw new IllegalArgumentException("unknown optional field in private key info");
+ }
+ }
+ }
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public ASN1Set getAttributes()
+ {
+ return attributes;
+ }
+
+ public AlgorithmIdentifier getPrivateKeyAlgorithm()
+ {
+ return privateKeyAlgorithm;
+ }
+
+ public ASN1OctetString getPrivateKey()
+ {
+ return new DEROctetString(privateKey.getOctets());
+ }
+
+ public ASN1Encodable parsePrivateKey()
+ throws IOException
+ {
+ return ASN1Primitive.fromByteArray(privateKey.getOctets());
+ }
+
+ /**
+ * Return true if a public key is present, false otherwise.
+ *
+ * @return true if public included, otherwise false.
+ */
+ public boolean hasPublicKey()
+ {
+ return publicKey != null;
+ }
+
+ /**
+ * for when the public key is an encoded object - if the bitstring
+ * can't be decoded this routine throws an IOException.
+ *
+ * @return the public key as an ASN.1 primitive.
+ * @throws IOException - if the bit string doesn't represent a DER
+ * encoded object.
+ */
+ public ASN1Encodable parsePublicKey()
+ throws IOException
+ {
+ return publicKey == null ? null : ASN1Primitive.fromByteArray(publicKey.getOctets());
+ }
+
+ /**
+ * for when the public key is raw bits.
+ *
+ * @return the public key as the raw bit string...
+ */
+ public ASN1BitString getPublicKeyData()
+ {
+ return publicKey;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
+
+ v.add(version);
+ v.add(privateKeyAlgorithm);
+ v.add(privateKey);
+
+ if (attributes != null)
+ {
+ v.add(new DERTaggedObject(false, 0, attributes));
+ }
+
+ if (publicKey != null)
+ {
+ v.add(new DERTaggedObject(false, 1, publicKey));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
new file mode 100644
index 00000000..6cd16150
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
@@ -0,0 +1,159 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RSAESOAEPparams
+ extends ASN1Object
+{
+ private AlgorithmIdentifier hashAlgorithm;
+ private AlgorithmIdentifier maskGenAlgorithm;
+ private AlgorithmIdentifier pSourceAlgorithm;
+
+ public final static AlgorithmIdentifier DEFAULT_HASH_ALGORITHM = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
+ public final static AlgorithmIdentifier DEFAULT_MASK_GEN_FUNCTION = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, DEFAULT_HASH_ALGORITHM);
+ public final static AlgorithmIdentifier DEFAULT_P_SOURCE_ALGORITHM = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0]));
+
+ public static RSAESOAEPparams getInstance(
+ Object obj)
+ {
+ if (obj instanceof RSAESOAEPparams)
+ {
+ return (RSAESOAEPparams)obj;
+ }
+ else if (obj != null)
+ {
+ return new RSAESOAEPparams(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * The default version
+ */
+ public RSAESOAEPparams()
+ {
+ hashAlgorithm = DEFAULT_HASH_ALGORITHM;
+ maskGenAlgorithm = DEFAULT_MASK_GEN_FUNCTION;
+ pSourceAlgorithm = DEFAULT_P_SOURCE_ALGORITHM;
+ }
+
+ public RSAESOAEPparams(
+ AlgorithmIdentifier hashAlgorithm,
+ AlgorithmIdentifier maskGenAlgorithm,
+ AlgorithmIdentifier pSourceAlgorithm)
+ {
+ this.hashAlgorithm = hashAlgorithm;
+ this.maskGenAlgorithm = maskGenAlgorithm;
+ this.pSourceAlgorithm = pSourceAlgorithm;
+ }
+
+ /**
+ * @deprecated use getInstance()
+ * @param seq
+ */
+ public RSAESOAEPparams(
+ ASN1Sequence seq)
+ {
+ hashAlgorithm = DEFAULT_HASH_ALGORITHM;
+ maskGenAlgorithm = DEFAULT_MASK_GEN_FUNCTION;
+ pSourceAlgorithm = DEFAULT_P_SOURCE_ALGORITHM;
+
+ for (int i = 0; i != seq.size(); i++)
+ {
+ ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(i);
+
+ switch (o.getTagNo())
+ {
+ case 0:
+ hashAlgorithm = AlgorithmIdentifier.getInstance(o, true);
+ break;
+ case 1:
+ maskGenAlgorithm = AlgorithmIdentifier.getInstance(o, true);
+ break;
+ case 2:
+ pSourceAlgorithm = AlgorithmIdentifier.getInstance(o, true);
+ break;
+ default:
+ throw new IllegalArgumentException("unknown tag");
+ }
+ }
+ }
+
+ public AlgorithmIdentifier getHashAlgorithm()
+ {
+ return hashAlgorithm;
+ }
+
+ public AlgorithmIdentifier getMaskGenAlgorithm()
+ {
+ return maskGenAlgorithm;
+ }
+
+ public AlgorithmIdentifier getPSourceAlgorithm()
+ {
+ return pSourceAlgorithm;
+ }
+
+ /**
+ * <pre>
+ * RSAES-OAEP-params ::= SEQUENCE {
+ * hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1,
+ * maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1,
+ * pSourceAlgorithm [2] PKCS1PSourceAlgorithms DEFAULT pSpecifiedEmpty
+ * }
+ *
+ * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * { OID id-sha1 PARAMETERS NULL }|
+ * { OID id-sha256 PARAMETERS NULL }|
+ * { OID id-sha384 PARAMETERS NULL }|
+ * { OID id-sha512 PARAMETERS NULL },
+ * ... -- Allows for future expansion --
+ * }
+ * PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
+ * ... -- Allows for future expansion --
+ * }
+ * PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * { OID id-pSpecified PARAMETERS OCTET STRING },
+ * ... -- Allows for future expansion --
+ * }
+ * </pre>
+ * @return the asn1 primitive representing the parameters.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ if (!hashAlgorithm.equals(DEFAULT_HASH_ALGORITHM))
+ {
+ v.add(new DERTaggedObject(true, 0, hashAlgorithm));
+ }
+
+ if (!maskGenAlgorithm.equals(DEFAULT_MASK_GEN_FUNCTION))
+ {
+ v.add(new DERTaggedObject(true, 1, maskGenAlgorithm));
+ }
+
+ if (!pSourceAlgorithm.equals(DEFAULT_P_SOURCE_ALGORITHM))
+ {
+ v.add(new DERTaggedObject(true, 2, pSourceAlgorithm));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java
new file mode 100644
index 00000000..95b4d04f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java
@@ -0,0 +1,192 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RSAPrivateKey
+ extends ASN1Object
+{
+ private BigInteger version;
+ private BigInteger modulus;
+ private BigInteger publicExponent;
+ private BigInteger privateExponent;
+ private BigInteger prime1;
+ private BigInteger prime2;
+ private BigInteger exponent1;
+ private BigInteger exponent2;
+ private BigInteger coefficient;
+ private ASN1Sequence otherPrimeInfos = null;
+
+ public static RSAPrivateKey getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static RSAPrivateKey getInstance(
+ Object obj)
+ {
+ if (obj instanceof RSAPrivateKey)
+ {
+ return (RSAPrivateKey)obj;
+ }
+
+ if (obj != null)
+ {
+ return new RSAPrivateKey(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public RSAPrivateKey(
+ BigInteger modulus,
+ BigInteger publicExponent,
+ BigInteger privateExponent,
+ BigInteger prime1,
+ BigInteger prime2,
+ BigInteger exponent1,
+ BigInteger exponent2,
+ BigInteger coefficient)
+ {
+ this.version = BigInteger.valueOf(0);
+ this.modulus = modulus;
+ this.publicExponent = publicExponent;
+ this.privateExponent = privateExponent;
+ this.prime1 = prime1;
+ this.prime2 = prime2;
+ this.exponent1 = exponent1;
+ this.exponent2 = exponent2;
+ this.coefficient = coefficient;
+ }
+
+ private RSAPrivateKey(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ ASN1Integer v = (ASN1Integer)e.nextElement();
+ int versionValue = v.intValueExact();
+ if (versionValue < 0 || versionValue > 1)
+ {
+ throw new IllegalArgumentException("wrong version for RSA private key");
+ }
+
+ version = v.getValue();
+ modulus = ((ASN1Integer)e.nextElement()).getValue();
+ publicExponent = ((ASN1Integer)e.nextElement()).getValue();
+ privateExponent = ((ASN1Integer)e.nextElement()).getValue();
+ prime1 = ((ASN1Integer)e.nextElement()).getValue();
+ prime2 = ((ASN1Integer)e.nextElement()).getValue();
+ exponent1 = ((ASN1Integer)e.nextElement()).getValue();
+ exponent2 = ((ASN1Integer)e.nextElement()).getValue();
+ coefficient = ((ASN1Integer)e.nextElement()).getValue();
+
+ if (e.hasMoreElements())
+ {
+ otherPrimeInfos = (ASN1Sequence)e.nextElement();
+ }
+ }
+
+ public BigInteger getVersion()
+ {
+ return version;
+ }
+
+ public BigInteger getModulus()
+ {
+ return modulus;
+ }
+
+ public BigInteger getPublicExponent()
+ {
+ return publicExponent;
+ }
+
+ public BigInteger getPrivateExponent()
+ {
+ return privateExponent;
+ }
+
+ public BigInteger getPrime1()
+ {
+ return prime1;
+ }
+
+ public BigInteger getPrime2()
+ {
+ return prime2;
+ }
+
+ public BigInteger getExponent1()
+ {
+ return exponent1;
+ }
+
+ public BigInteger getExponent2()
+ {
+ return exponent2;
+ }
+
+ public BigInteger getCoefficient()
+ {
+ return coefficient;
+ }
+
+ /**
+ * This outputs the key in PKCS1v2 format.
+ * <pre>
+ * RSAPrivateKey ::= SEQUENCE {
+ * version Version,
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER, -- e
+ * privateExponent INTEGER, -- d
+ * prime1 INTEGER, -- p
+ * prime2 INTEGER, -- q
+ * exponent1 INTEGER, -- d mod (p-1)
+ * exponent2 INTEGER, -- d mod (q-1)
+ * coefficient INTEGER, -- (inverse of q) mod p
+ * otherPrimeInfos OtherPrimeInfos OPTIONAL
+ * }
+ *
+ * Version ::= INTEGER { two-prime(0), multi(1) }
+ * (CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --})
+ * </pre>
+ * <p>
+ * This routine is written to output PKCS1 version 2.1, private keys.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(10);
+
+ v.add(new ASN1Integer(version)); // version
+ v.add(new ASN1Integer(getModulus()));
+ v.add(new ASN1Integer(getPublicExponent()));
+ v.add(new ASN1Integer(getPrivateExponent()));
+ v.add(new ASN1Integer(getPrime1()));
+ v.add(new ASN1Integer(getPrime2()));
+ v.add(new ASN1Integer(getExponent1()));
+ v.add(new ASN1Integer(getExponent2()));
+ v.add(new ASN1Integer(getCoefficient()));
+
+ if (otherPrimeInfos != null)
+ {
+ v.add(otherPrimeInfos);
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java
new file mode 100644
index 00000000..2cf4a2a1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java
@@ -0,0 +1,192 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @deprecated use RSAPrivateKey
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RSAPrivateKeyStructure
+ extends ASN1Object
+{
+ private int version;
+ private BigInteger modulus;
+ private BigInteger publicExponent;
+ private BigInteger privateExponent;
+ private BigInteger prime1;
+ private BigInteger prime2;
+ private BigInteger exponent1;
+ private BigInteger exponent2;
+ private BigInteger coefficient;
+ private ASN1Sequence otherPrimeInfos = null;
+
+ public static RSAPrivateKeyStructure getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static RSAPrivateKeyStructure getInstance(
+ Object obj)
+ {
+ if (obj instanceof RSAPrivateKeyStructure)
+ {
+ return (RSAPrivateKeyStructure)obj;
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ return new RSAPrivateKeyStructure((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
+ }
+
+ public RSAPrivateKeyStructure(
+ BigInteger modulus,
+ BigInteger publicExponent,
+ BigInteger privateExponent,
+ BigInteger prime1,
+ BigInteger prime2,
+ BigInteger exponent1,
+ BigInteger exponent2,
+ BigInteger coefficient)
+ {
+ this.version = 0;
+ this.modulus = modulus;
+ this.publicExponent = publicExponent;
+ this.privateExponent = privateExponent;
+ this.prime1 = prime1;
+ this.prime2 = prime2;
+ this.exponent1 = exponent1;
+ this.exponent2 = exponent2;
+ this.coefficient = coefficient;
+ }
+
+ public RSAPrivateKeyStructure(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ ASN1Integer v = (ASN1Integer)e.nextElement();
+ int versionValue = v.intValueExact();
+ if (versionValue < 0 || versionValue > 1)
+ {
+ throw new IllegalArgumentException("wrong version for RSA private key");
+ }
+
+ version = versionValue;
+ modulus = ((ASN1Integer)e.nextElement()).getValue();
+ publicExponent = ((ASN1Integer)e.nextElement()).getValue();
+ privateExponent = ((ASN1Integer)e.nextElement()).getValue();
+ prime1 = ((ASN1Integer)e.nextElement()).getValue();
+ prime2 = ((ASN1Integer)e.nextElement()).getValue();
+ exponent1 = ((ASN1Integer)e.nextElement()).getValue();
+ exponent2 = ((ASN1Integer)e.nextElement()).getValue();
+ coefficient = ((ASN1Integer)e.nextElement()).getValue();
+
+ if (e.hasMoreElements())
+ {
+ otherPrimeInfos = (ASN1Sequence)e.nextElement();
+ }
+ }
+
+ public int getVersion()
+ {
+ return version;
+ }
+
+ public BigInteger getModulus()
+ {
+ return modulus;
+ }
+
+ public BigInteger getPublicExponent()
+ {
+ return publicExponent;
+ }
+
+ public BigInteger getPrivateExponent()
+ {
+ return privateExponent;
+ }
+
+ public BigInteger getPrime1()
+ {
+ return prime1;
+ }
+
+ public BigInteger getPrime2()
+ {
+ return prime2;
+ }
+
+ public BigInteger getExponent1()
+ {
+ return exponent1;
+ }
+
+ public BigInteger getExponent2()
+ {
+ return exponent2;
+ }
+
+ public BigInteger getCoefficient()
+ {
+ return coefficient;
+ }
+
+ /**
+ * This outputs the key in PKCS1v2 format.
+ * <pre>
+ * RSAPrivateKey ::= SEQUENCE {
+ * version Version,
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER, -- e
+ * privateExponent INTEGER, -- d
+ * prime1 INTEGER, -- p
+ * prime2 INTEGER, -- q
+ * exponent1 INTEGER, -- d mod (p-1)
+ * exponent2 INTEGER, -- d mod (q-1)
+ * coefficient INTEGER, -- (inverse of q) mod p
+ * otherPrimeInfos OtherPrimeInfos OPTIONAL
+ * }
+ *
+ * Version ::= INTEGER { two-prime(0), multi(1) }
+ * (CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --})
+ * </pre>
+ * <p>
+ * This routine is written to output PKCS1 version 2.1, private keys.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(10);
+
+ v.add(new ASN1Integer(version)); // version
+ v.add(new ASN1Integer(getModulus()));
+ v.add(new ASN1Integer(getPublicExponent()));
+ v.add(new ASN1Integer(getPrivateExponent()));
+ v.add(new ASN1Integer(getPrime1()));
+ v.add(new ASN1Integer(getPrime2()));
+ v.add(new ASN1Integer(getExponent1()));
+ v.add(new ASN1Integer(getExponent2()));
+ v.add(new ASN1Integer(getCoefficient()));
+
+ if (otherPrimeInfos != null)
+ {
+ v.add(otherPrimeInfos);
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPublicKey.java
new file mode 100644
index 00000000..a1a8e529
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPublicKey.java
@@ -0,0 +1,99 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RSAPublicKey
+ extends ASN1Object
+{
+ private BigInteger modulus;
+ private BigInteger publicExponent;
+
+ public static RSAPublicKey getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static RSAPublicKey getInstance(
+ Object obj)
+ {
+ if (obj instanceof RSAPublicKey)
+ {
+ return (RSAPublicKey)obj;
+ }
+
+ if (obj != null)
+ {
+ return new RSAPublicKey(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public RSAPublicKey(
+ BigInteger modulus,
+ BigInteger publicExponent)
+ {
+ this.modulus = modulus;
+ this.publicExponent = publicExponent;
+ }
+
+ private RSAPublicKey(
+ ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("Bad sequence size: "
+ + seq.size());
+ }
+
+ Enumeration e = seq.getObjects();
+
+ modulus = ASN1Integer.getInstance(e.nextElement()).getPositiveValue();
+ publicExponent = ASN1Integer.getInstance(e.nextElement()).getPositiveValue();
+ }
+
+ public BigInteger getModulus()
+ {
+ return modulus;
+ }
+
+ public BigInteger getPublicExponent()
+ {
+ return publicExponent;
+ }
+
+ /**
+ * This outputs the key in PKCS1v2 format.
+ * <pre>
+ * RSAPublicKey ::= SEQUENCE {
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER, -- e
+ * }
+ * </pre>
+ * <p>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(new ASN1Integer(getModulus()));
+ v.add(new ASN1Integer(getPublicExponent()));
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java
new file mode 100644
index 00000000..3a5157c2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java
@@ -0,0 +1,176 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RSASSAPSSparams
+ extends ASN1Object
+{
+ private AlgorithmIdentifier hashAlgorithm;
+ private AlgorithmIdentifier maskGenAlgorithm;
+ private ASN1Integer saltLength;
+ private ASN1Integer trailerField;
+
+ public final static AlgorithmIdentifier DEFAULT_HASH_ALGORITHM = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
+ public final static AlgorithmIdentifier DEFAULT_MASK_GEN_FUNCTION = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, DEFAULT_HASH_ALGORITHM);
+ public final static ASN1Integer DEFAULT_SALT_LENGTH = new ASN1Integer(20);
+ public final static ASN1Integer DEFAULT_TRAILER_FIELD = new ASN1Integer(1);
+
+ public static RSASSAPSSparams getInstance(
+ Object obj)
+ {
+ if (obj instanceof RSASSAPSSparams)
+ {
+ return (RSASSAPSSparams)obj;
+ }
+ else if (obj != null)
+ {
+ return new RSASSAPSSparams(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * The default version
+ */
+ public RSASSAPSSparams()
+ {
+ hashAlgorithm = DEFAULT_HASH_ALGORITHM;
+ maskGenAlgorithm = DEFAULT_MASK_GEN_FUNCTION;
+ saltLength = DEFAULT_SALT_LENGTH;
+ trailerField = DEFAULT_TRAILER_FIELD;
+ }
+
+ public RSASSAPSSparams(
+ AlgorithmIdentifier hashAlgorithm,
+ AlgorithmIdentifier maskGenAlgorithm,
+ ASN1Integer saltLength,
+ ASN1Integer trailerField)
+ {
+ this.hashAlgorithm = hashAlgorithm;
+ this.maskGenAlgorithm = maskGenAlgorithm;
+ this.saltLength = saltLength;
+ this.trailerField = trailerField;
+ }
+
+ private RSASSAPSSparams(
+ ASN1Sequence seq)
+ {
+ hashAlgorithm = DEFAULT_HASH_ALGORITHM;
+ maskGenAlgorithm = DEFAULT_MASK_GEN_FUNCTION;
+ saltLength = DEFAULT_SALT_LENGTH;
+ trailerField = DEFAULT_TRAILER_FIELD;
+
+ for (int i = 0; i != seq.size(); i++)
+ {
+ ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(i);
+
+ switch (o.getTagNo())
+ {
+ case 0:
+ hashAlgorithm = AlgorithmIdentifier.getInstance(o, true);
+ break;
+ case 1:
+ maskGenAlgorithm = AlgorithmIdentifier.getInstance(o, true);
+ break;
+ case 2:
+ saltLength = ASN1Integer.getInstance(o, true);
+ break;
+ case 3:
+ trailerField = ASN1Integer.getInstance(o, true);
+ break;
+ default:
+ throw new IllegalArgumentException("unknown tag");
+ }
+ }
+ }
+
+ public AlgorithmIdentifier getHashAlgorithm()
+ {
+ return hashAlgorithm;
+ }
+
+ public AlgorithmIdentifier getMaskGenAlgorithm()
+ {
+ return maskGenAlgorithm;
+ }
+
+ public BigInteger getSaltLength()
+ {
+ return saltLength.getValue();
+ }
+
+ public BigInteger getTrailerField()
+ {
+ return trailerField.getValue();
+ }
+
+ /**
+ * <pre>
+ * RSASSA-PSS-params ::= SEQUENCE {
+ * hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1,
+ * maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1,
+ * saltLength [2] INTEGER DEFAULT 20,
+ * trailerField [3] TrailerField DEFAULT trailerFieldBC
+ * }
+ *
+ * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * { OID id-sha1 PARAMETERS NULL }|
+ * { OID id-sha256 PARAMETERS NULL }|
+ * { OID id-sha384 PARAMETERS NULL }|
+ * { OID id-sha512 PARAMETERS NULL },
+ * ... -- Allows for future expansion --
+ * }
+ *
+ * PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
+ * ... -- Allows for future expansion --
+ * }
+ *
+ * TrailerField ::= INTEGER { trailerFieldBC(1) }
+ * </pre>
+ * @return the asn1 primitive representing the parameters.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ if (!hashAlgorithm.equals(DEFAULT_HASH_ALGORITHM))
+ {
+ v.add(new DERTaggedObject(true, 0, hashAlgorithm));
+ }
+
+ if (!maskGenAlgorithm.equals(DEFAULT_MASK_GEN_FUNCTION))
+ {
+ v.add(new DERTaggedObject(true, 1, maskGenAlgorithm));
+ }
+
+ if (!saltLength.equals(DEFAULT_SALT_LENGTH))
+ {
+ v.add(new DERTaggedObject(true, 2, saltLength));
+ }
+
+ if (!trailerField.equals(DEFAULT_TRAILER_FIELD))
+ {
+ v.add(new DERTaggedObject(true, 3, trailerField));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SafeBag.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SafeBag.java
new file mode 100644
index 00000000..93fec390
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SafeBag.java
@@ -0,0 +1,100 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DLSequence;
+import com.android.internal.org.bouncycastle.asn1.DLTaggedObject;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SafeBag
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier bagId;
+ private ASN1Encodable bagValue;
+ private ASN1Set bagAttributes;
+
+ public SafeBag(
+ ASN1ObjectIdentifier oid,
+ ASN1Encodable obj)
+ {
+ this.bagId = oid;
+ this.bagValue = obj;
+ this.bagAttributes = null;
+ }
+
+ public SafeBag(
+ ASN1ObjectIdentifier oid,
+ ASN1Encodable obj,
+ ASN1Set bagAttributes)
+ {
+ this.bagId = oid;
+ this.bagValue = obj;
+ this.bagAttributes = bagAttributes;
+ }
+
+ public static SafeBag getInstance(
+ Object obj)
+ {
+ if (obj instanceof SafeBag)
+ {
+ return (SafeBag)obj;
+ }
+
+ if (obj != null)
+ {
+ return new SafeBag(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private SafeBag(
+ ASN1Sequence seq)
+ {
+ this.bagId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
+ this.bagValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getObject();
+ if (seq.size() == 3)
+ {
+ this.bagAttributes = (ASN1Set)seq.getObjectAt(2);
+ }
+ }
+
+ public ASN1ObjectIdentifier getBagId()
+ {
+ return bagId;
+ }
+
+ public ASN1Encodable getBagValue()
+ {
+ return bagValue;
+ }
+
+ public ASN1Set getBagAttributes()
+ {
+ return bagAttributes;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(bagId);
+ v.add(new DLTaggedObject(true, 0, bagValue));
+
+ if (bagAttributes != null)
+ {
+ v.add(bagAttributes);
+ }
+
+ return new DLSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SignedData.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SignedData.java
new file mode 100644
index 00000000..9aa084f1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SignedData.java
@@ -0,0 +1,169 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.pkcs;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.BERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * a PKCS#7 signed data object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignedData
+ extends ASN1Object
+ implements PKCSObjectIdentifiers
+{
+ private ASN1Integer version;
+ private ASN1Set digestAlgorithms;
+ private ContentInfo contentInfo;
+ private ASN1Set certificates;
+ private ASN1Set crls;
+ private ASN1Set signerInfos;
+
+ public static SignedData getInstance(
+ Object o)
+ {
+ if (o instanceof SignedData)
+ {
+ return (SignedData)o;
+ }
+ else if (o != null)
+ {
+ return new SignedData(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public SignedData(
+ ASN1Integer _version,
+ ASN1Set _digestAlgorithms,
+ ContentInfo _contentInfo,
+ ASN1Set _certificates,
+ ASN1Set _crls,
+ ASN1Set _signerInfos)
+ {
+ version = _version;
+ digestAlgorithms = _digestAlgorithms;
+ contentInfo = _contentInfo;
+ certificates = _certificates;
+ crls = _crls;
+ signerInfos = _signerInfos;
+ }
+
+ public SignedData(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ version = (ASN1Integer)e.nextElement();
+ digestAlgorithms = ((ASN1Set)e.nextElement());
+ contentInfo = ContentInfo.getInstance(e.nextElement());
+
+ while (e.hasMoreElements())
+ {
+ ASN1Primitive o = (ASN1Primitive)e.nextElement();
+
+ //
+ // an interesting feature of SignedData is that there appear to be varying implementations...
+ // for the moment we ignore anything which doesn't fit.
+ //
+ if (o instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagged = (ASN1TaggedObject)o;
+
+ switch (tagged.getTagNo())
+ {
+ case 0:
+ certificates = ASN1Set.getInstance(tagged, false);
+ break;
+ case 1:
+ crls = ASN1Set.getInstance(tagged, false);
+ break;
+ default:
+ throw new IllegalArgumentException("unknown tag value " + tagged.getTagNo());
+ }
+ }
+ else
+ {
+ signerInfos = (ASN1Set)o;
+ }
+ }
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public ASN1Set getDigestAlgorithms()
+ {
+ return digestAlgorithms;
+ }
+
+ public ContentInfo getContentInfo()
+ {
+ return contentInfo;
+ }
+
+ public ASN1Set getCertificates()
+ {
+ return certificates;
+ }
+
+ public ASN1Set getCRLs()
+ {
+ return crls;
+ }
+
+ public ASN1Set getSignerInfos()
+ {
+ return signerInfos;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * SignedData ::= SEQUENCE {
+ * version Version,
+ * digestAlgorithms DigestAlgorithmIdentifiers,
+ * contentInfo ContentInfo,
+ * certificates
+ * [0] IMPLICIT ExtendedCertificatesAndCertificates
+ * OPTIONAL,
+ * crls
+ * [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+ * signerInfos SignerInfos }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(6);
+
+ v.add(version);
+ v.add(digestAlgorithms);
+ v.add(contentInfo);
+
+ if (certificates != null)
+ {
+ v.add(new DERTaggedObject(false, 0, certificates));
+ }
+
+ if (crls != null)
+ {
+ v.add(new DERTaggedObject(false, 1, crls));
+ }
+
+ v.add(signerInfos);
+
+ return new BERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKey.java
new file mode 100644
index 00000000..e8b76a7b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKey.java
@@ -0,0 +1,184 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.sec;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * the elliptic curve private key object from SEC 1
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECPrivateKey
+ extends ASN1Object
+{
+ private ASN1Sequence seq;
+
+ private ECPrivateKey(
+ ASN1Sequence seq)
+ {
+ this.seq = seq;
+ }
+
+ public static ECPrivateKey getInstance(
+ Object obj)
+ {
+ if (obj instanceof ECPrivateKey)
+ {
+ return (ECPrivateKey)obj;
+ }
+
+ if (obj != null)
+ {
+ return new ECPrivateKey(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * @deprecated use constructor which takes orderBitLength to guarantee correct encoding.
+ */
+ public ECPrivateKey(
+ BigInteger key)
+ {
+ this(key.bitLength(), key);
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param orderBitLength the bitLength of the order of the curve.
+ * @param key the private key value.
+ */
+ public ECPrivateKey(
+ int orderBitLength,
+ BigInteger key)
+ {
+ byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key);
+
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(new ASN1Integer(1));
+ v.add(new DEROctetString(bytes));
+
+ seq = new DERSequence(v);
+ }
+
+ /**
+ * @deprecated use constructor which takes orderBitLength to guarantee correct encoding.
+ */
+ public ECPrivateKey(
+ BigInteger key,
+ ASN1Encodable parameters)
+ {
+ this(key, null, parameters);
+ }
+
+ /**
+ * @deprecated use constructor which takes orderBitLength to guarantee correct encoding.
+ */
+ public ECPrivateKey(
+ BigInteger key,
+ DERBitString publicKey,
+ ASN1Encodable parameters)
+ {
+ this(key.bitLength(), key, publicKey, parameters);
+ }
+
+ public ECPrivateKey(
+ int orderBitLength,
+ BigInteger key,
+ ASN1Encodable parameters)
+ {
+ this(orderBitLength, key, null, parameters);
+ }
+
+ public ECPrivateKey(
+ int orderBitLength,
+ BigInteger key,
+ DERBitString publicKey,
+ ASN1Encodable parameters)
+ {
+ byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key);
+
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ v.add(new ASN1Integer(1));
+ v.add(new DEROctetString(bytes));
+
+ if (parameters != null)
+ {
+ v.add(new DERTaggedObject(true, 0, parameters));
+ }
+
+ if (publicKey != null)
+ {
+ v.add(new DERTaggedObject(true, 1, publicKey));
+ }
+
+ seq = new DERSequence(v);
+ }
+
+ public BigInteger getKey()
+ {
+ ASN1OctetString octs = (ASN1OctetString)seq.getObjectAt(1);
+
+ return new BigInteger(1, octs.getOctets());
+ }
+
+ public DERBitString getPublicKey()
+ {
+ return (DERBitString)getObjectInTag(1);
+ }
+
+ public ASN1Primitive getParameters()
+ {
+ return getObjectInTag(0);
+ }
+
+ private ASN1Primitive getObjectInTag(int tagNo)
+ {
+ Enumeration e = seq.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ ASN1Encodable obj = (ASN1Encodable)e.nextElement();
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tag = (ASN1TaggedObject)obj;
+ if (tag.getTagNo() == tagNo)
+ {
+ return tag.getObject().toASN1Primitive();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * ECPrivateKey ::= SEQUENCE {
+ * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
+ * privateKey OCTET STRING,
+ * parameters [0] Parameters OPTIONAL,
+ * publicKey [1] BIT STRING OPTIONAL }
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return seq;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
new file mode 100644
index 00000000..4cb9eab1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
@@ -0,0 +1,130 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.sec;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * the elliptic curve private key object from SEC 1
+ * @deprecated use ECPrivateKey
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECPrivateKeyStructure
+ extends ASN1Object
+{
+ private ASN1Sequence seq;
+
+ public ECPrivateKeyStructure(
+ ASN1Sequence seq)
+ {
+ this.seq = seq;
+ }
+
+ public ECPrivateKeyStructure(
+ BigInteger key)
+ {
+ byte[] bytes = BigIntegers.asUnsignedByteArray(key);
+
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(new ASN1Integer(1));
+ v.add(new DEROctetString(bytes));
+
+ seq = new DERSequence(v);
+ }
+
+ public ECPrivateKeyStructure(
+ BigInteger key,
+ ASN1Encodable parameters)
+ {
+ this(key, null, parameters);
+ }
+
+ public ECPrivateKeyStructure(
+ BigInteger key,
+ DERBitString publicKey,
+ ASN1Encodable parameters)
+ {
+ byte[] bytes = BigIntegers.asUnsignedByteArray(key);
+
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ v.add(new ASN1Integer(1));
+ v.add(new DEROctetString(bytes));
+
+ if (parameters != null)
+ {
+ v.add(new DERTaggedObject(true, 0, parameters));
+ }
+
+ if (publicKey != null)
+ {
+ v.add(new DERTaggedObject(true, 1, publicKey));
+ }
+
+ seq = new DERSequence(v);
+ }
+
+ public BigInteger getKey()
+ {
+ ASN1OctetString octs = (ASN1OctetString)seq.getObjectAt(1);
+
+ return new BigInteger(1, octs.getOctets());
+ }
+
+ public DERBitString getPublicKey()
+ {
+ return (DERBitString)getObjectInTag(1);
+ }
+
+ public ASN1Primitive getParameters()
+ {
+ return getObjectInTag(0);
+ }
+
+ private ASN1Primitive getObjectInTag(int tagNo)
+ {
+ Enumeration e = seq.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ ASN1Encodable obj = (ASN1Encodable)e.nextElement();
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tag = (ASN1TaggedObject)obj;
+ if (tag.getTagNo() == tagNo)
+ {
+ return (ASN1Primitive)((ASN1Encodable)tag.getObject()).toASN1Primitive();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * ECPrivateKey ::= SEQUENCE {
+ * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
+ * privateKey OCTET STRING,
+ * parameters [0] Parameters OPTIONAL,
+ * publicKey [1] BIT STRING OPTIONAL }
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return seq;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECNamedCurves.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECNamedCurves.java
new file mode 100644
index 00000000..31cbd7ff
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECNamedCurves.java
@@ -0,0 +1,1039 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.sec;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParametersHolder;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECPoint;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.WNafUtil;
+import com.android.internal.org.bouncycastle.math.ec.endo.GLVTypeBEndomorphism;
+import com.android.internal.org.bouncycastle.math.ec.endo.GLVTypeBParameters;
+import com.android.internal.org.bouncycastle.math.ec.endo.ScalarSplitParameters;
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SECNamedCurves
+{
+ private static X9ECPoint configureBasepoint(ECCurve curve, String encoding)
+ {
+ X9ECPoint G = new X9ECPoint(curve, Hex.decodeStrict(encoding));
+ WNafUtil.configureBasepoint(G.getPoint());
+ return G;
+ }
+
+ private static ECCurve configureCurve(ECCurve curve)
+ {
+ return curve;
+ }
+
+ private static ECCurve configureCurveGLV(ECCurve c, GLVTypeBParameters p)
+ {
+ return c.configure().setEndomorphism(new GLVTypeBEndomorphism(c, p)).create();
+ }
+
+ private static BigInteger fromHex(String hex)
+ {
+ return new BigInteger(1, Hex.decodeStrict(hex));
+ }
+
+ /*
+ * secp112r1
+ */
+ static X9ECParametersHolder secp112r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = (2^128 - 3) / 76439
+ BigInteger p = fromHex("DB7C2ABF62E35E668076BEAD208B");
+ BigInteger a = fromHex("DB7C2ABF62E35E668076BEAD2088");
+ BigInteger b = fromHex("659EF8BA043916EEDE8911702B22");
+ byte[] S = Hex.decodeStrict("00F50B028E4D696E676875615175290472783FB1");
+ BigInteger n = fromHex("DB7C2ABF62E35E7628DFAC6561C5");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0FF77500");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * secp112r2
+ */
+ static X9ECParametersHolder secp112r2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = (2^128 - 3) / 76439
+ BigInteger p = fromHex("DB7C2ABF62E35E668076BEAD208B");
+ BigInteger a = fromHex("6127C24C05F38A0AAAF65C0EF02C");
+ BigInteger b = fromHex("51DEF1815DB5ED74FCC34C85D709");
+ byte[] S = Hex.decodeStrict("002757A1114D696E6768756151755316C05E0BD4");
+ BigInteger n = fromHex("36DF0AAFD8B8D7597CA10520D04B");
+ BigInteger h = BigInteger.valueOf(4);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * secp128r1
+ */
+ static X9ECParametersHolder secp128r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = 2^128 - 2^97 - 1
+ BigInteger p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF");
+ BigInteger a = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC");
+ BigInteger b = fromHex("E87579C11079F43DD824993C2CEE5ED3");
+ byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
+ BigInteger n = fromHex("FFFFFFFE0000000075A30D1B9038A115");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * secp128r2
+ */
+ static X9ECParametersHolder secp128r2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = 2^128 - 2^97 - 1
+ BigInteger p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF");
+ BigInteger a = fromHex("D6031998D1B3BBFEBF59CC9BBFF9AEE1");
+ BigInteger b = fromHex("5EEEFCA380D02919DC2C6558BB6D8A5D");
+ byte[] S = Hex.decodeStrict("004D696E67687561517512D8F03431FCE63B88F4");
+ BigInteger n = fromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3");
+ BigInteger h = BigInteger.valueOf(4);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "047B6AA5D85E572983E6FB32A7CDEBC14027B6916A894D3AEE7106FE805FC34B44");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * secp160k1
+ */
+ static X9ECParametersHolder secp160k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1
+ BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73");
+ BigInteger a = ECConstants.ZERO;
+ BigInteger b = BigInteger.valueOf(7);
+ byte[] S = null;
+ BigInteger n = fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3");
+ BigInteger h = BigInteger.valueOf(1);
+
+ GLVTypeBParameters glv = new GLVTypeBParameters(
+ new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16),
+ new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16),
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("9162fbe73984472a0a9e", 16),
+ new BigInteger("-96341f1138933bc2f505", 16) },
+ new BigInteger[]{
+ new BigInteger("127971af8721782ecffa3", 16),
+ new BigInteger("9162fbe73984472a0a9e", 16) },
+ new BigInteger("9162fbe73984472a0a9d0590", 16),
+ new BigInteger("96341f1138933bc2f503fd44", 16),
+ 176));
+
+ ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+
+ X9ECPoint G = configureBasepoint(curve,
+ "043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * secp160r1
+ */
+ static X9ECParametersHolder secp160r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = 2^160 - 2^31 - 1
+ BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF");
+ BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC");
+ BigInteger b = fromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45");
+ byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
+ BigInteger n = fromHex("0100000000000000000001F4C8F927AED3CA752257");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * secp160r2
+ */
+ static X9ECParametersHolder secp160r2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1
+ BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73");
+ BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70");
+ BigInteger b = fromHex("B4E134D3FB59EB8BAB57274904664D5AF50388BA");
+ byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
+ BigInteger n = fromHex("0100000000000000000000351EE786A818F3A1A16B");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * secp192k1
+ */
+ static X9ECParametersHolder secp192k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1
+ BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37");
+ BigInteger a = ECConstants.ZERO;
+ BigInteger b = BigInteger.valueOf(3);
+ byte[] S = null;
+ BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D");
+ BigInteger h = BigInteger.valueOf(1);
+
+ GLVTypeBParameters glv = new GLVTypeBParameters(
+ new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16),
+ new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16),
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("71169be7330b3038edb025f1", 16),
+ new BigInteger("-b3fb3400dec5c4adceb8655c", 16) },
+ new BigInteger[]{
+ new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
+ new BigInteger("71169be7330b3038edb025f1", 16) },
+ new BigInteger("71169be7330b3038edb025f1d0f9", 16),
+ new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
+ 208));
+
+ ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * secp192r1
+ */
+ static X9ECParametersHolder secp192r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = 2^192 - 2^64 - 1
+ BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF");
+ BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC");
+ BigInteger b = fromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1");
+ byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
+ BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * secp224k1
+ */
+ static X9ECParametersHolder secp224k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1
+ BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D");
+ BigInteger a = ECConstants.ZERO;
+ BigInteger b = BigInteger.valueOf(5);
+ byte[] S = null;
+ BigInteger n = fromHex("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
+ BigInteger h = BigInteger.valueOf(1);
+
+ GLVTypeBParameters glv = new GLVTypeBParameters(
+ new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16),
+ new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16),
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
+ new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) },
+ new BigInteger[]{
+ new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) },
+ new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
+ new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
+ 240));
+
+ ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * secp224r1
+ */
+ static X9ECParametersHolder secp224r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = 2^224 - 2^96 + 1
+ BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001");
+ BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE");
+ BigInteger b = fromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4");
+ byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
+ BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * secp256k1
+ */
+ static X9ECParametersHolder secp256k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
+ BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F");
+ BigInteger a = ECConstants.ZERO;
+ BigInteger b = BigInteger.valueOf(7);
+ byte[] S = null;
+ BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
+ BigInteger h = BigInteger.valueOf(1);
+
+ GLVTypeBParameters glv = new GLVTypeBParameters(
+ new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16),
+ new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16),
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
+ new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) },
+ new BigInteger[]{
+ new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) },
+ new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
+ new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
+ 272));
+
+ ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * secp256r1
+ */
+ static X9ECParametersHolder secp256r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1
+ BigInteger p = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF");
+ BigInteger a = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC");
+ BigInteger b = fromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B");
+ byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
+ BigInteger n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * secp384r1
+ */
+ static X9ECParametersHolder secp384r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = 2^384 - 2^128 - 2^96 + 2^32 - 1
+ BigInteger p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF");
+ BigInteger a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC");
+ BigInteger b = fromHex("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF");
+ byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
+ BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
+ + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * secp521r1
+ */
+ static X9ECParametersHolder secp521r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ // p = 2^521 - 1
+ BigInteger p = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
+ BigInteger a = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC");
+ BigInteger b = fromHex("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00");
+ byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
+ BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
+ + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect113r1
+ */
+ static X9ECParametersHolder sect113r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 113;
+ int k = 9;
+
+ BigInteger a = fromHex("003088250CA6E7C7FE649CE85820F7");
+ BigInteger b = fromHex("00E8BEE4D3E2260744188BE0E9C723");
+ byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
+ BigInteger n = fromHex("0100000000000000D9CCEC8A39E56F");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect113r2
+ */
+ static X9ECParametersHolder sect113r2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 113;
+ int k = 9;
+
+ BigInteger a = fromHex("00689918DBEC7E5A0DD6DFC0AA55C7");
+ BigInteger b = fromHex("0095E9A9EC9B297BD4BF36E059184F");
+ byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
+ BigInteger n = fromHex("010000000000000108789B2496AF93");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect131r1
+ */
+ static X9ECParametersHolder sect131r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 131;
+ int k1 = 2;
+ int k2 = 3;
+ int k3 = 8;
+
+ BigInteger a = fromHex("07A11B09A76B562144418FF3FF8C2570B8");
+ BigInteger b = fromHex("0217C05610884B63B9C6C7291678F9D341");
+ byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
+ BigInteger n = fromHex("0400000000000000023123953A9464B54D");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect131r2
+ */
+ static X9ECParametersHolder sect131r2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 131;
+ int k1 = 2;
+ int k2 = 3;
+ int k3 = 8;
+
+ BigInteger a = fromHex("03E5A88919D7CAFCBF415F07C2176573B2");
+ BigInteger b = fromHex("04B8266A46C55657AC734CE38F018F2192");
+ byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
+ BigInteger n = fromHex("0400000000000000016954A233049BA98F");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect163k1
+ */
+ static X9ECParametersHolder sect163k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 163;
+ int k1 = 3;
+ int k2 = 6;
+ int k3 = 7;
+
+ BigInteger a = BigInteger.valueOf(1);
+ BigInteger b = BigInteger.valueOf(1);
+ byte[] S = null;
+ BigInteger n = fromHex("04000000000000000000020108A2E0CC0D99F8A5EF");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect163r1
+ */
+ static X9ECParametersHolder sect163r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 163;
+ int k1 = 3;
+ int k2 = 6;
+ int k3 = 7;
+
+ BigInteger a = fromHex("07B6882CAAEFA84F9554FF8428BD88E246D2782AE2");
+ BigInteger b = fromHex("0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9");
+ byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
+ BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect163r2
+ */
+ static X9ECParametersHolder sect163r2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 163;
+ int k1 = 3;
+ int k2 = 6;
+ int k3 = 7;
+
+ BigInteger a = BigInteger.valueOf(1);
+ BigInteger b = fromHex("020A601907B8C953CA1481EB10512F78744A3205FD");
+ byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
+ BigInteger n = fromHex("040000000000000000000292FE77E70C12A4234C33");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect193r1
+ */
+ static X9ECParametersHolder sect193r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 193;
+ int k = 15;
+
+ BigInteger a = fromHex("0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01");
+ BigInteger b = fromHex("00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814");
+ byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
+ BigInteger n = fromHex("01000000000000000000000000C7F34A778F443ACC920EBA49");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect193r2
+ */
+ static X9ECParametersHolder sect193r2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 193;
+ int k = 15;
+
+ BigInteger a = fromHex("0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B");
+ BigInteger b = fromHex("00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE");
+ byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
+ BigInteger n = fromHex("010000000000000000000000015AAB561B005413CCD4EE99D5");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect233k1
+ */
+ static X9ECParametersHolder sect233k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 233;
+ int k = 74;
+
+ BigInteger a = ECConstants.ZERO;
+ BigInteger b = BigInteger.valueOf(1);
+ byte[] S = null;
+ BigInteger n = fromHex("8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF");
+ BigInteger h = BigInteger.valueOf(4);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect233r1
+ */
+ static X9ECParametersHolder sect233r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 233;
+ int k = 74;
+
+ BigInteger a = BigInteger.valueOf(1);
+ BigInteger b = fromHex("0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD");
+ byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
+ BigInteger n = fromHex("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect239k1
+ */
+ static X9ECParametersHolder sect239k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 239;
+ int k = 158;
+
+ BigInteger a = ECConstants.ZERO;
+ BigInteger b = BigInteger.valueOf(1);
+ byte[] S = null;
+ BigInteger n = fromHex("2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5");
+ BigInteger h = BigInteger.valueOf(4);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect283k1
+ */
+ static X9ECParametersHolder sect283k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 283;
+ int k1 = 5;
+ int k2 = 7;
+ int k3 = 12;
+
+ BigInteger a = ECConstants.ZERO;
+ BigInteger b = BigInteger.valueOf(1);
+ byte[] S = null;
+ BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61");
+ BigInteger h = BigInteger.valueOf(4);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
+ + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect283r1
+ */
+ static X9ECParametersHolder sect283r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 283;
+ int k1 = 5;
+ int k2 = 7;
+ int k3 = 12;
+
+ BigInteger a = BigInteger.valueOf(1);
+ BigInteger b = fromHex("027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5");
+ byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
+ BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
+ + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect409k1
+ */
+ static X9ECParametersHolder sect409k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 409;
+ int k = 87;
+
+ BigInteger a = ECConstants.ZERO;
+ BigInteger b = BigInteger.valueOf(1);
+ byte[] S = null;
+ BigInteger n = fromHex("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF");
+ BigInteger h = BigInteger.valueOf(4);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
+ + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect409r1
+ */
+ static X9ECParametersHolder sect409r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 409;
+ int k = 87;
+
+ BigInteger a = BigInteger.valueOf(1);
+ BigInteger b = fromHex("0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F");
+ byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
+ BigInteger n = fromHex("010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
+ + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect571k1
+ */
+ static X9ECParametersHolder sect571k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 571;
+ int k1 = 2;
+ int k2 = 5;
+ int k3 = 10;
+
+ BigInteger a = ECConstants.ZERO;
+ BigInteger b = BigInteger.valueOf(1);
+ byte[] S = null;
+ BigInteger n = fromHex("020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001");
+ BigInteger h = BigInteger.valueOf(4);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
+ + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+ /*
+ * sect571r1
+ */
+ static X9ECParametersHolder sect571r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ int m = 571;
+ int k1 = 2;
+ int k2 = 5;
+ int k3 = 10;
+
+ BigInteger a = BigInteger.valueOf(1);
+ BigInteger b = fromHex("02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A");
+ byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
+ BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
+
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
+ + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B");
+
+ return new X9ECParameters(curve, G, n, h, S);
+ }
+ };
+
+
+ static final Hashtable objIds = new Hashtable();
+ static final Hashtable curves = new Hashtable();
+ static final Hashtable names = new Hashtable();
+
+ static void defineCurve(String name, ASN1ObjectIdentifier oid, X9ECParametersHolder holder)
+ {
+ objIds.put(name, oid);
+ names.put(oid, name);
+ curves.put(oid, holder);
+ }
+
+ static
+ {
+ defineCurve("secp112r1", SECObjectIdentifiers.secp112r1, secp112r1);
+ defineCurve("secp112r2", SECObjectIdentifiers.secp112r2, secp112r2);
+ defineCurve("secp128r1", SECObjectIdentifiers.secp128r1, secp128r1);
+ defineCurve("secp128r2", SECObjectIdentifiers.secp128r2, secp128r2);
+ defineCurve("secp160k1", SECObjectIdentifiers.secp160k1, secp160k1);
+ defineCurve("secp160r1", SECObjectIdentifiers.secp160r1, secp160r1);
+ defineCurve("secp160r2", SECObjectIdentifiers.secp160r2, secp160r2);
+ defineCurve("secp192k1", SECObjectIdentifiers.secp192k1, secp192k1);
+ defineCurve("secp192r1", SECObjectIdentifiers.secp192r1, secp192r1);
+ defineCurve("secp224k1", SECObjectIdentifiers.secp224k1, secp224k1);
+ defineCurve("secp224r1", SECObjectIdentifiers.secp224r1, secp224r1);
+ defineCurve("secp256k1", SECObjectIdentifiers.secp256k1, secp256k1);
+ defineCurve("secp256r1", SECObjectIdentifiers.secp256r1, secp256r1);
+ defineCurve("secp384r1", SECObjectIdentifiers.secp384r1, secp384r1);
+ defineCurve("secp521r1", SECObjectIdentifiers.secp521r1, secp521r1);
+
+ defineCurve("sect113r1", SECObjectIdentifiers.sect113r1, sect113r1);
+ defineCurve("sect113r2", SECObjectIdentifiers.sect113r2, sect113r2);
+ defineCurve("sect131r1", SECObjectIdentifiers.sect131r1, sect131r1);
+ defineCurve("sect131r2", SECObjectIdentifiers.sect131r2, sect131r2);
+ defineCurve("sect163k1", SECObjectIdentifiers.sect163k1, sect163k1);
+ defineCurve("sect163r1", SECObjectIdentifiers.sect163r1, sect163r1);
+ defineCurve("sect163r2", SECObjectIdentifiers.sect163r2, sect163r2);
+ defineCurve("sect193r1", SECObjectIdentifiers.sect193r1, sect193r1);
+ defineCurve("sect193r2", SECObjectIdentifiers.sect193r2, sect193r2);
+ defineCurve("sect233k1", SECObjectIdentifiers.sect233k1, sect233k1);
+ defineCurve("sect233r1", SECObjectIdentifiers.sect233r1, sect233r1);
+ defineCurve("sect239k1", SECObjectIdentifiers.sect239k1, sect239k1);
+ defineCurve("sect283k1", SECObjectIdentifiers.sect283k1, sect283k1);
+ defineCurve("sect283r1", SECObjectIdentifiers.sect283r1, sect283r1);
+ defineCurve("sect409k1", SECObjectIdentifiers.sect409k1, sect409k1);
+ defineCurve("sect409r1", SECObjectIdentifiers.sect409r1, sect409r1);
+ defineCurve("sect571k1", SECObjectIdentifiers.sect571k1, sect571k1);
+ defineCurve("sect571r1", SECObjectIdentifiers.sect571r1, sect571r1);
+ }
+
+ public static X9ECParameters getByName(
+ String name)
+ {
+ ASN1ObjectIdentifier oid = getOID(name);
+ return oid == null ? null : getByOID(oid);
+ }
+
+ /**
+ * return the X9ECParameters object for the named curve represented by
+ * the passed in object identifier. Null if the curve isn't present.
+ *
+ * @param oid an object identifier representing a named curve, if present.
+ */
+ public static X9ECParameters getByOID(
+ ASN1ObjectIdentifier oid)
+ {
+ X9ECParametersHolder holder = (X9ECParametersHolder)curves.get(oid);
+ return holder == null ? null : holder.getParameters();
+ }
+
+ /**
+ * return the object identifier signified by the passed in name. Null
+ * if there is no object identifier associated with name.
+ *
+ * @return the object identifier associated with name, if present.
+ */
+ public static ASN1ObjectIdentifier getOID(
+ String name)
+ {
+ return (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name));
+ }
+
+ /**
+ * return the named curve name represented by the given object identifier.
+ */
+ public static String getName(
+ ASN1ObjectIdentifier oid)
+ {
+ return (String)names.get(oid);
+ }
+
+ /**
+ * returns an enumeration containing the name strings for curves
+ * contained in this structure.
+ */
+ public static Enumeration getNames()
+ {
+ return names.elements();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java
new file mode 100644
index 00000000..a0175a63
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java
@@ -0,0 +1,112 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.sec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+
+/**
+ * Certicom object identifiers
+ * <pre>
+ * ellipticCurve OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) certicom(132) curve(0)
+ * }
+ * secg-scheme OBJECT IDENTIFIER ::= {
+ * iso(1) identified-organization(3) certicom(132) schemes(1) }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface SECObjectIdentifiers
+{
+ /** Base OID: 1.3.132.0 */
+ static final ASN1ObjectIdentifier ellipticCurve = new ASN1ObjectIdentifier("1.3.132.0");
+
+ /** sect163k1 OID: 1.3.132.0.1 */
+ static final ASN1ObjectIdentifier sect163k1 = ellipticCurve.branch("1");
+ /** sect163r1 OID: 1.3.132.0.2 */
+ static final ASN1ObjectIdentifier sect163r1 = ellipticCurve.branch("2");
+ /** sect239k1 OID: 1.3.132.0.3 */
+ static final ASN1ObjectIdentifier sect239k1 = ellipticCurve.branch("3");
+ /** sect113r1 OID: 1.3.132.0.4 */
+ static final ASN1ObjectIdentifier sect113r1 = ellipticCurve.branch("4");
+ /** sect113r2 OID: 1.3.132.0.5 */
+ static final ASN1ObjectIdentifier sect113r2 = ellipticCurve.branch("5");
+ /** secp112r1 OID: 1.3.132.0.6 */
+ static final ASN1ObjectIdentifier secp112r1 = ellipticCurve.branch("6");
+ /** secp112r2 OID: 1.3.132.0.7 */
+ static final ASN1ObjectIdentifier secp112r2 = ellipticCurve.branch("7");
+ /** secp160r1 OID: 1.3.132.0.8 */
+ static final ASN1ObjectIdentifier secp160r1 = ellipticCurve.branch("8");
+ /** secp160k1 OID: 1.3.132.0.9 */
+ static final ASN1ObjectIdentifier secp160k1 = ellipticCurve.branch("9");
+ /** secp256k1 OID: 1.3.132.0.10 */
+ static final ASN1ObjectIdentifier secp256k1 = ellipticCurve.branch("10");
+ /** sect163r2 OID: 1.3.132.0.15 */
+ static final ASN1ObjectIdentifier sect163r2 = ellipticCurve.branch("15");
+ /** sect283k1 OID: 1.3.132.0.16 */
+ static final ASN1ObjectIdentifier sect283k1 = ellipticCurve.branch("16");
+ /** sect283r1 OID: 1.3.132.0.17 */
+ static final ASN1ObjectIdentifier sect283r1 = ellipticCurve.branch("17");
+ /** sect131r1 OID: 1.3.132.0.22 */
+ static final ASN1ObjectIdentifier sect131r1 = ellipticCurve.branch("22");
+ /** sect131r2 OID: 1.3.132.0.23 */
+ static final ASN1ObjectIdentifier sect131r2 = ellipticCurve.branch("23");
+ /** sect193r1 OID: 1.3.132.0.24 */
+ static final ASN1ObjectIdentifier sect193r1 = ellipticCurve.branch("24");
+ /** sect193r2 OID: 1.3.132.0.25 */
+ static final ASN1ObjectIdentifier sect193r2 = ellipticCurve.branch("25");
+ /** sect233k1 OID: 1.3.132.0.26 */
+ static final ASN1ObjectIdentifier sect233k1 = ellipticCurve.branch("26");
+ /** sect233r1 OID: 1.3.132.0.27 */
+ static final ASN1ObjectIdentifier sect233r1 = ellipticCurve.branch("27");
+ /** secp128r1 OID: 1.3.132.0.28 */
+ static final ASN1ObjectIdentifier secp128r1 = ellipticCurve.branch("28");
+ /** secp128r2 OID: 1.3.132.0.29 */
+ static final ASN1ObjectIdentifier secp128r2 = ellipticCurve.branch("29");
+ /** secp160r2 OID: 1.3.132.0.30 */
+ static final ASN1ObjectIdentifier secp160r2 = ellipticCurve.branch("30");
+ /** secp192k1 OID: 1.3.132.0.31 */
+ static final ASN1ObjectIdentifier secp192k1 = ellipticCurve.branch("31");
+ /** secp224k1 OID: 1.3.132.0.32 */
+ static final ASN1ObjectIdentifier secp224k1 = ellipticCurve.branch("32");
+ /** secp224r1 OID: 1.3.132.0.33 */
+ static final ASN1ObjectIdentifier secp224r1 = ellipticCurve.branch("33");
+ /** secp384r1 OID: 1.3.132.0.34 */
+ static final ASN1ObjectIdentifier secp384r1 = ellipticCurve.branch("34");
+ /** secp521r1 OID: 1.3.132.0.35 */
+ static final ASN1ObjectIdentifier secp521r1 = ellipticCurve.branch("35");
+ /** sect409k1 OID: 1.3.132.0.36 */
+ static final ASN1ObjectIdentifier sect409k1 = ellipticCurve.branch("36");
+ /** sect409r1 OID: 1.3.132.0.37 */
+ static final ASN1ObjectIdentifier sect409r1 = ellipticCurve.branch("37");
+ /** sect571k1 OID: 1.3.132.0.38 */
+ static final ASN1ObjectIdentifier sect571k1 = ellipticCurve.branch("38");
+ /** sect571r1 OID: 1.3.132.0.39 */
+ static final ASN1ObjectIdentifier sect571r1 = ellipticCurve.branch("39");
+
+ /** secp192r1 OID: 1.3.132.0.prime192v1 */
+ static final ASN1ObjectIdentifier secp192r1 = X9ObjectIdentifiers.prime192v1;
+ /** secp256r1 OID: 1.3.132.0.prime256v1 */
+ static final ASN1ObjectIdentifier secp256r1 = X9ObjectIdentifiers.prime256v1;
+
+ static final ASN1ObjectIdentifier secg_scheme = new ASN1ObjectIdentifier("1.3.132.1");
+
+ static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha224kdf_scheme = secg_scheme.branch("11.0");
+ static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha256kdf_scheme = secg_scheme.branch("11.1");
+ static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha384kdf_scheme = secg_scheme.branch("11.2");
+ static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha512kdf_scheme = secg_scheme.branch("11.3");
+
+ static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha224kdf_scheme = secg_scheme.branch("14.0");
+ static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha256kdf_scheme = secg_scheme.branch("14.1");
+ static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha384kdf_scheme = secg_scheme.branch("14.2");
+ static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha512kdf_scheme = secg_scheme.branch("14.3");
+
+ static final ASN1ObjectIdentifier mqvSinglePass_sha224kdf_scheme = secg_scheme.branch("15.0");
+ static final ASN1ObjectIdentifier mqvSinglePass_sha256kdf_scheme = secg_scheme.branch("15.1");
+ static final ASN1ObjectIdentifier mqvSinglePass_sha384kdf_scheme = secg_scheme.branch("15.2");
+ static final ASN1ObjectIdentifier mqvSinglePass_sha512kdf_scheme = secg_scheme.branch("15.3");
+
+ static final ASN1ObjectIdentifier mqvFull_sha224kdf_scheme = secg_scheme.branch("16.0");
+ static final ASN1ObjectIdentifier mqvFull_sha256kdf_scheme = secg_scheme.branch("16.1");
+ static final ASN1ObjectIdentifier mqvFull_sha384kdf_scheme = secg_scheme.branch("16.2");
+ static final ASN1ObjectIdentifier mqvFull_sha512kdf_scheme = secg_scheme.branch("16.3");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/teletrust/TeleTrusTObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/teletrust/TeleTrusTObjectIdentifiers.java
new file mode 100644
index 00000000..5c7041e8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/teletrust/TeleTrusTObjectIdentifiers.java
@@ -0,0 +1,79 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.teletrust;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * Object identifiers based on the TeleTrust branch.
+ * <pre>
+ * TeleTrusT:
+ * { iso(1) identifier-organization(3) teleTrust(36) algorithm(3)
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface TeleTrusTObjectIdentifiers
+{
+ /** 1.3.36.3 */
+ static final ASN1ObjectIdentifier teleTrusTAlgorithm = new ASN1ObjectIdentifier("1.3.36.3");
+
+ /** 1.3.36.3.2.1 */
+ static final ASN1ObjectIdentifier ripemd160 = teleTrusTAlgorithm.branch("2.1");
+ /** 1.3.36.3.2.2 */
+ static final ASN1ObjectIdentifier ripemd128 = teleTrusTAlgorithm.branch("2.2");
+ /** 1.3.36.3.2.3 */
+ static final ASN1ObjectIdentifier ripemd256 = teleTrusTAlgorithm.branch("2.3");
+
+ /** 1.3.36.3.3.1 */
+ static final ASN1ObjectIdentifier teleTrusTRSAsignatureAlgorithm = teleTrusTAlgorithm.branch("3.1");
+
+ /** 1.3.36.3.3.1.2 */
+ static final ASN1ObjectIdentifier rsaSignatureWithripemd160 = teleTrusTRSAsignatureAlgorithm.branch("2");
+ /** 1.3.36.3.3.1.3 */
+ static final ASN1ObjectIdentifier rsaSignatureWithripemd128 = teleTrusTRSAsignatureAlgorithm.branch("3");
+ /** 1.3.36.3.3.1.4 */
+ static final ASN1ObjectIdentifier rsaSignatureWithripemd256 = teleTrusTRSAsignatureAlgorithm.branch("4");
+
+ /** 1.3.36.3.3.2 */
+ static final ASN1ObjectIdentifier ecSign = teleTrusTAlgorithm.branch("3.2");
+
+ /** 1.3.36.3.3.2,1 */
+ static final ASN1ObjectIdentifier ecSignWithSha1 = ecSign.branch("1");
+ /** 1.3.36.3.3.2.2 */
+ static final ASN1ObjectIdentifier ecSignWithRipemd160 = ecSign.branch("2");
+
+ /** 1.3.36.3.3.2.8 */
+ static final ASN1ObjectIdentifier ecc_brainpool = teleTrusTAlgorithm.branch("3.2.8");
+ /** 1.3.36.3.3.2.8.1 */
+ static final ASN1ObjectIdentifier ellipticCurve = ecc_brainpool.branch("1");
+ /** 1.3.36.3.3.2.8.1.1 */
+ static final ASN1ObjectIdentifier versionOne = ellipticCurve.branch("1");
+
+ /** 1.3.36.3.3.2.8.1.1.1 */
+ static final ASN1ObjectIdentifier brainpoolP160r1 = versionOne.branch("1");
+ /** 1.3.36.3.3.2.8.1.1.2 */
+ static final ASN1ObjectIdentifier brainpoolP160t1 = versionOne.branch("2");
+ /** 1.3.36.3.3.2.8.1.1.3 */
+ static final ASN1ObjectIdentifier brainpoolP192r1 = versionOne.branch("3");
+ /** 1.3.36.3.3.2.8.1.1.4 */
+ static final ASN1ObjectIdentifier brainpoolP192t1 = versionOne.branch("4");
+ /** 1.3.36.3.3.2.8.1.1.5 */
+ static final ASN1ObjectIdentifier brainpoolP224r1 = versionOne.branch("5");
+ /** 1.3.36.3.3.2.8.1.1.6 */
+ static final ASN1ObjectIdentifier brainpoolP224t1 = versionOne.branch("6");
+ /** 1.3.36.3.3.2.8.1.1.7 */
+ static final ASN1ObjectIdentifier brainpoolP256r1 = versionOne.branch("7");
+ /** 1.3.36.3.3.2.8.1.1.8 */
+ static final ASN1ObjectIdentifier brainpoolP256t1 = versionOne.branch("8");
+ /** 1.3.36.3.3.2.8.1.1.9 */
+ static final ASN1ObjectIdentifier brainpoolP320r1 = versionOne.branch("9");
+ /** 1.3.36.3.3.2.8.1.1.10 */
+ static final ASN1ObjectIdentifier brainpoolP320t1 = versionOne.branch("10");
+ /** 1.3.36.3.3.2.8.1.1.11 */
+ static final ASN1ObjectIdentifier brainpoolP384r1 = versionOne.branch("11");
+ /** 1.3.36.3.3.2.8.1.1.12 */
+ static final ASN1ObjectIdentifier brainpoolP384t1 = versionOne.branch("12");
+ /** 1.3.36.3.3.2.8.1.1.13 */
+ static final ASN1ObjectIdentifier brainpoolP512r1 = versionOne.branch("13");
+ /** 1.3.36.3.3.2.8.1.1.14 */
+ static final ASN1ObjectIdentifier brainpoolP512t1 = versionOne.branch("14");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/util/ASN1Dump.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/util/ASN1Dump.java
new file mode 100644
index 00000000..786d4842
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/util/ASN1Dump.java
@@ -0,0 +1,420 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.util;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ApplicationSpecific;
+import com.android.internal.org.bouncycastle.asn1.ASN1Boolean;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.internal.org.bouncycastle.asn1.ASN1External;
+import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.ASN1UTCTime;
+import com.android.internal.org.bouncycastle.asn1.BERApplicationSpecific;
+import com.android.internal.org.bouncycastle.asn1.BEROctetString;
+import com.android.internal.org.bouncycastle.asn1.BERSequence;
+import com.android.internal.org.bouncycastle.asn1.BERSet;
+import com.android.internal.org.bouncycastle.asn1.BERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.BERTags;
+import com.android.internal.org.bouncycastle.asn1.DERApplicationSpecific;
+import com.android.internal.org.bouncycastle.asn1.DERBMPString;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERGraphicString;
+import com.android.internal.org.bouncycastle.asn1.DERIA5String;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DERPrintableString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERSet;
+import com.android.internal.org.bouncycastle.asn1.DERT61String;
+import com.android.internal.org.bouncycastle.asn1.DERUTF8String;
+import com.android.internal.org.bouncycastle.asn1.DERVideotexString;
+import com.android.internal.org.bouncycastle.asn1.DERVisibleString;
+import com.android.internal.org.bouncycastle.asn1.DLApplicationSpecific;
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * Utility class for dumping ASN.1 objects as (hopefully) human friendly strings.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ASN1Dump
+{
+ private static final String TAB = " ";
+ private static final int SAMPLE_SIZE = 32;
+
+ /**
+ * dump a DER object as a formatted string with indentation
+ *
+ * @param obj the ASN1Primitive to be dumped out.
+ */
+ static void _dumpAsString(
+ String indent,
+ boolean verbose,
+ ASN1Primitive obj,
+ StringBuffer buf)
+ {
+ String nl = Strings.lineSeparator();
+ if (obj instanceof ASN1Sequence)
+ {
+ Enumeration e = ((ASN1Sequence)obj).getObjects();
+ String tab = indent + TAB;
+
+ buf.append(indent);
+ if (obj instanceof BERSequence)
+ {
+ buf.append("BER Sequence");
+ }
+ else if (obj instanceof DERSequence)
+ {
+ buf.append("DER Sequence");
+ }
+ else
+ {
+ buf.append("Sequence");
+ }
+
+ buf.append(nl);
+
+ while (e.hasMoreElements())
+ {
+ Object o = e.nextElement();
+
+ if (o == null || o.equals(DERNull.INSTANCE))
+ {
+ buf.append(tab);
+ buf.append("NULL");
+ buf.append(nl);
+ }
+ else if (o instanceof ASN1Primitive)
+ {
+ _dumpAsString(tab, verbose, (ASN1Primitive)o, buf);
+ }
+ else
+ {
+ _dumpAsString(tab, verbose, ((ASN1Encodable)o).toASN1Primitive(), buf);
+ }
+ }
+ }
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ String tab = indent + TAB;
+
+ buf.append(indent);
+ if (obj instanceof BERTaggedObject)
+ {
+ buf.append("BER Tagged [");
+ }
+ else
+ {
+ buf.append("Tagged [");
+ }
+
+ ASN1TaggedObject o = (ASN1TaggedObject)obj;
+
+ buf.append(Integer.toString(o.getTagNo()));
+ buf.append(']');
+
+ if (!o.isExplicit())
+ {
+ buf.append(" IMPLICIT ");
+ }
+
+ buf.append(nl);
+
+ _dumpAsString(tab, verbose, o.getObject(), buf);
+ }
+ else if (obj instanceof ASN1Set)
+ {
+ Enumeration e = ((ASN1Set)obj).getObjects();
+ String tab = indent + TAB;
+
+ buf.append(indent);
+
+ if (obj instanceof BERSet)
+ {
+ buf.append("BER Set");
+ }
+ else if (obj instanceof DERSet)
+ {
+ buf.append("DER Set");
+ }
+ else
+ {
+ buf.append("Set");
+ }
+ buf.append(nl);
+
+ while (e.hasMoreElements())
+ {
+ Object o = e.nextElement();
+
+ if (o == null)
+ {
+ buf.append(tab);
+ buf.append("NULL");
+ buf.append(nl);
+ }
+ else if (o instanceof ASN1Primitive)
+ {
+ _dumpAsString(tab, verbose, (ASN1Primitive)o, buf);
+ }
+ else
+ {
+ _dumpAsString(tab, verbose, ((ASN1Encodable)o).toASN1Primitive(), buf);
+ }
+ }
+ }
+ else if (obj instanceof ASN1OctetString)
+ {
+ ASN1OctetString oct = (ASN1OctetString)obj;
+
+ if (obj instanceof BEROctetString)
+ {
+ buf.append(indent + "BER Constructed Octet String" + "[" + oct.getOctets().length + "] ");
+ }
+ else
+ {
+ buf.append(indent + "DER Octet String" + "[" + oct.getOctets().length + "] ");
+ }
+ if (verbose)
+ {
+ buf.append(dumpBinaryDataAsString(indent, oct.getOctets()));
+ }
+ else
+ {
+ buf.append(nl);
+ }
+ }
+ else if (obj instanceof ASN1ObjectIdentifier)
+ {
+ buf.append(indent + "ObjectIdentifier(" + ((ASN1ObjectIdentifier)obj).getId() + ")" + nl);
+ }
+ else if (obj instanceof ASN1Boolean)
+ {
+ buf.append(indent + "Boolean(" + ((ASN1Boolean)obj).isTrue() + ")" + nl);
+ }
+ else if (obj instanceof ASN1Integer)
+ {
+ buf.append(indent + "Integer(" + ((ASN1Integer)obj).getValue() + ")" + nl);
+ }
+ else if (obj instanceof DERBitString)
+ {
+ DERBitString bt = (DERBitString)obj;
+ buf.append(indent + "DER Bit String" + "[" + bt.getBytes().length + ", " + bt.getPadBits() + "] ");
+ if (verbose)
+ {
+ buf.append(dumpBinaryDataAsString(indent, bt.getBytes()));
+ }
+ else
+ {
+ buf.append(nl);
+ }
+ }
+ else if (obj instanceof DERIA5String)
+ {
+ buf.append(indent + "IA5String(" + ((DERIA5String)obj).getString() + ") " + nl);
+ }
+ else if (obj instanceof DERUTF8String)
+ {
+ buf.append(indent + "UTF8String(" + ((DERUTF8String)obj).getString() + ") " + nl);
+ }
+ else if (obj instanceof DERPrintableString)
+ {
+ buf.append(indent + "PrintableString(" + ((DERPrintableString)obj).getString() + ") " + nl);
+ }
+ else if (obj instanceof DERVisibleString)
+ {
+ buf.append(indent + "VisibleString(" + ((DERVisibleString)obj).getString() + ") " + nl);
+ }
+ else if (obj instanceof DERBMPString)
+ {
+ buf.append(indent + "BMPString(" + ((DERBMPString)obj).getString() + ") " + nl);
+ }
+ else if (obj instanceof DERT61String)
+ {
+ buf.append(indent + "T61String(" + ((DERT61String)obj).getString() + ") " + nl);
+ }
+ else if (obj instanceof DERGraphicString)
+ {
+ buf.append(indent + "GraphicString(" + ((DERGraphicString)obj).getString() + ") " + nl);
+ }
+ else if (obj instanceof DERVideotexString)
+ {
+ buf.append(indent + "VideotexString(" + ((DERVideotexString)obj).getString() + ") " + nl);
+ }
+ else if (obj instanceof ASN1UTCTime)
+ {
+ buf.append(indent + "UTCTime(" + ((ASN1UTCTime)obj).getTime() + ") " + nl);
+ }
+ else if (obj instanceof ASN1GeneralizedTime)
+ {
+ buf.append(indent + "GeneralizedTime(" + ((ASN1GeneralizedTime)obj).getTime() + ") " + nl);
+ }
+ else if (obj instanceof BERApplicationSpecific)
+ {
+ buf.append(outputApplicationSpecific("BER", indent, verbose, obj, nl));
+ }
+ else if (obj instanceof DERApplicationSpecific)
+ {
+ buf.append(outputApplicationSpecific("DER", indent, verbose, obj, nl));
+ }
+ else if (obj instanceof DLApplicationSpecific)
+ {
+ buf.append(outputApplicationSpecific("", indent, verbose, obj, nl));
+ }
+ else if (obj instanceof ASN1Enumerated)
+ {
+ ASN1Enumerated en = (ASN1Enumerated) obj;
+ buf.append(indent + "DER Enumerated(" + en.getValue() + ")" + nl);
+ }
+ else if (obj instanceof ASN1External)
+ {
+ ASN1External ext = (ASN1External) obj;
+ buf.append(indent + "External " + nl);
+ String tab = indent + TAB;
+ if (ext.getDirectReference() != null)
+ {
+ buf.append(tab + "Direct Reference: " + ext.getDirectReference().getId() + nl);
+ }
+ if (ext.getIndirectReference() != null)
+ {
+ buf.append(tab + "Indirect Reference: " + ext.getIndirectReference().toString() + nl);
+ }
+ if (ext.getDataValueDescriptor() != null)
+ {
+ _dumpAsString(tab, verbose, ext.getDataValueDescriptor(), buf);
+ }
+ buf.append(tab + "Encoding: " + ext.getEncoding() + nl);
+ _dumpAsString(tab, verbose, ext.getExternalContent(), buf);
+ }
+ else
+ {
+ buf.append(indent + obj.toString() + nl);
+ }
+ }
+
+ private static String outputApplicationSpecific(String type, String indent, boolean verbose, ASN1Primitive obj, String nl)
+ {
+ ASN1ApplicationSpecific app = ASN1ApplicationSpecific.getInstance(obj);
+ StringBuffer buf = new StringBuffer();
+
+ if (app.isConstructed())
+ {
+ try
+ {
+ ASN1Sequence s = ASN1Sequence.getInstance(app.getObject(BERTags.SEQUENCE));
+ buf.append(indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "]" + nl);
+ for (Enumeration e = s.getObjects(); e.hasMoreElements();)
+ {
+ _dumpAsString(indent + TAB, verbose, (ASN1Primitive)e.nextElement(), buf);
+ }
+ }
+ catch (IOException e)
+ {
+ buf.append(e);
+ }
+ return buf.toString();
+ }
+
+ return indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "] (" + Strings.fromByteArray(Hex.encode(app.getContents())) + ")" + nl;
+ }
+
+ /**
+ * dump out a DER object as a formatted string, in non-verbose mode.
+ *
+ * @param obj the ASN1Primitive to be dumped out.
+ * @return the resulting string.
+ */
+ public static String dumpAsString(
+ Object obj)
+ {
+ return dumpAsString(obj, false);
+ }
+
+ /**
+ * Dump out the object as a string.
+ *
+ * @param obj the object to be dumped
+ * @param verbose if true, dump out the contents of octet and bit strings.
+ * @return the resulting string.
+ */
+ public static String dumpAsString(
+ Object obj,
+ boolean verbose)
+ {
+ StringBuffer buf = new StringBuffer();
+
+ if (obj instanceof ASN1Primitive)
+ {
+ _dumpAsString("", verbose, (ASN1Primitive)obj, buf);
+ }
+ else if (obj instanceof ASN1Encodable)
+ {
+ _dumpAsString("", verbose, ((ASN1Encodable)obj).toASN1Primitive(), buf);
+ }
+ else
+ {
+ return "unknown object type " + obj.toString();
+ }
+
+ return buf.toString();
+ }
+
+ private static String dumpBinaryDataAsString(String indent, byte[] bytes)
+ {
+ String nl = Strings.lineSeparator();
+ StringBuffer buf = new StringBuffer();
+
+ indent += TAB;
+
+ buf.append(nl);
+ for (int i = 0; i < bytes.length; i += SAMPLE_SIZE)
+ {
+ if (bytes.length - i > SAMPLE_SIZE)
+ {
+ buf.append(indent);
+ buf.append(Strings.fromByteArray(Hex.encode(bytes, i, SAMPLE_SIZE)));
+ buf.append(TAB);
+ buf.append(calculateAscString(bytes, i, SAMPLE_SIZE));
+ buf.append(nl);
+ }
+ else
+ {
+ buf.append(indent);
+ buf.append(Strings.fromByteArray(Hex.encode(bytes, i, bytes.length - i)));
+ for (int j = bytes.length - i; j != SAMPLE_SIZE; j++)
+ {
+ buf.append(" ");
+ }
+ buf.append(TAB);
+ buf.append(calculateAscString(bytes, i, bytes.length - i));
+ buf.append(nl);
+ }
+ }
+
+ return buf.toString();
+ }
+
+ private static String calculateAscString(byte[] bytes, int off, int len)
+ {
+ StringBuffer buf = new StringBuffer();
+
+ for (int i = off; i != off + len; i++)
+ {
+ if (bytes[i] >= ' ' && bytes[i] <= '~')
+ {
+ buf.append((char)bytes[i]);
+ }
+ }
+
+ return buf.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java
new file mode 100644
index 00000000..413343a7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java
@@ -0,0 +1,77 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x500;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * Holding class for the AttributeTypeAndValue structures that make up an RDN.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AttributeTypeAndValue
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier type;
+ private ASN1Encodable value;
+
+ private AttributeTypeAndValue(ASN1Sequence seq)
+ {
+ type = (ASN1ObjectIdentifier)seq.getObjectAt(0);
+ value = (ASN1Encodable)seq.getObjectAt(1);
+ }
+
+ public static AttributeTypeAndValue getInstance(Object o)
+ {
+ if (o instanceof AttributeTypeAndValue)
+ {
+ return (AttributeTypeAndValue)o;
+ }
+ else if (o != null)
+ {
+ return new AttributeTypeAndValue(ASN1Sequence.getInstance(o));
+ }
+
+ throw new IllegalArgumentException("null value in getInstance()");
+ }
+
+ public AttributeTypeAndValue(
+ ASN1ObjectIdentifier type,
+ ASN1Encodable value)
+ {
+ this.type = type;
+ this.value = value;
+ }
+
+ public ASN1ObjectIdentifier getType()
+ {
+ return type;
+ }
+
+ public ASN1Encodable getValue()
+ {
+ return value;
+ }
+
+ /**
+ * <pre>
+ * AttributeTypeAndValue ::= SEQUENCE {
+ * type OBJECT IDENTIFIER,
+ * value ANY DEFINED BY type }
+ * </pre>
+ * @return a basic ASN.1 object representation.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(type);
+ v.add(value);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/DirectoryString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/DirectoryString.java
new file mode 100644
index 00000000..d13ae8f0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/DirectoryString.java
@@ -0,0 +1,130 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x500;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1String;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBMPString;
+import com.android.internal.org.bouncycastle.asn1.DERPrintableString;
+import com.android.internal.org.bouncycastle.asn1.DERT61String;
+import com.android.internal.org.bouncycastle.asn1.DERUTF8String;
+import com.android.internal.org.bouncycastle.asn1.DERUniversalString;
+
+/**
+ * The DirectoryString CHOICE object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DirectoryString
+ extends ASN1Object
+ implements ASN1Choice, ASN1String
+{
+ private ASN1String string;
+
+ public static DirectoryString getInstance(Object o)
+ {
+ if (o == null || o instanceof DirectoryString)
+ {
+ return (DirectoryString)o;
+ }
+
+ if (o instanceof DERT61String)
+ {
+ return new DirectoryString((DERT61String)o);
+ }
+
+ if (o instanceof DERPrintableString)
+ {
+ return new DirectoryString((DERPrintableString)o);
+ }
+
+ if (o instanceof DERUniversalString)
+ {
+ return new DirectoryString((DERUniversalString)o);
+ }
+
+ if (o instanceof DERUTF8String)
+ {
+ return new DirectoryString((DERUTF8String)o);
+ }
+
+ if (o instanceof DERBMPString)
+ {
+ return new DirectoryString((DERBMPString)o);
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + o.getClass().getName());
+ }
+
+ public static DirectoryString getInstance(ASN1TaggedObject o, boolean explicit)
+ {
+ if (!explicit)
+ {
+ throw new IllegalArgumentException("choice item must be explicitly tagged");
+ }
+
+ return getInstance(o.getObject());
+ }
+
+ private DirectoryString(
+ DERT61String string)
+ {
+ this.string = string;
+ }
+
+ private DirectoryString(
+ DERPrintableString string)
+ {
+ this.string = string;
+ }
+
+ private DirectoryString(
+ DERUniversalString string)
+ {
+ this.string = string;
+ }
+
+ private DirectoryString(
+ DERUTF8String string)
+ {
+ this.string = string;
+ }
+
+ private DirectoryString(
+ DERBMPString string)
+ {
+ this.string = string;
+ }
+
+ public DirectoryString(String string)
+ {
+ this.string = new DERUTF8String(string);
+ }
+
+ public String getString()
+ {
+ return string.getString();
+ }
+
+ public String toString()
+ {
+ return string.getString();
+ }
+
+ /**
+ * <pre>
+ * DirectoryString ::= CHOICE {
+ * teletexString TeletexString (SIZE (1..MAX)),
+ * printableString PrintableString (SIZE (1..MAX)),
+ * universalString UniversalString (SIZE (1..MAX)),
+ * utf8String UTF8String (SIZE (1..MAX)),
+ * bmpString BMPString (SIZE (1..MAX)) }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return ((ASN1Encodable)string).toASN1Primitive();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/RDN.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/RDN.java
new file mode 100644
index 00000000..fc078820
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/RDN.java
@@ -0,0 +1,149 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x500;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERSet;
+
+/**
+ * Holding class for a single Relative Distinguished Name (RDN).
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RDN
+ extends ASN1Object
+{
+ private ASN1Set values;
+
+ private RDN(ASN1Set values)
+ {
+ this.values = values;
+ }
+
+ public static RDN getInstance(Object obj)
+ {
+ if (obj instanceof RDN)
+ {
+ return (RDN)obj;
+ }
+ else if (obj != null)
+ {
+ return new RDN(ASN1Set.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * Create a single valued RDN.
+ *
+ * @param oid RDN type.
+ * @param value RDN value.
+ */
+ public RDN(ASN1ObjectIdentifier oid, ASN1Encodable value)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(oid);
+ v.add(value);
+
+ this.values = new DERSet(new DERSequence(v));
+ }
+
+ public RDN(AttributeTypeAndValue attrTAndV)
+ {
+ this.values = new DERSet(attrTAndV);
+ }
+
+ /**
+ * Create a multi-valued RDN.
+ *
+ * @param aAndVs attribute type/value pairs making up the RDN
+ */
+ public RDN(AttributeTypeAndValue[] aAndVs)
+ {
+ this.values = new DERSet(aAndVs);
+ }
+
+ public boolean isMultiValued()
+ {
+ return this.values.size() > 1;
+ }
+
+ /**
+ * Return the number of AttributeTypeAndValue objects in this RDN,
+ *
+ * @return size of RDN, greater than 1 if multi-valued.
+ */
+ public int size()
+ {
+ return this.values.size();
+ }
+
+ public AttributeTypeAndValue getFirst()
+ {
+ if (this.values.size() == 0)
+ {
+ return null;
+ }
+
+ return AttributeTypeAndValue.getInstance(this.values.getObjectAt(0));
+ }
+
+ public AttributeTypeAndValue[] getTypesAndValues()
+ {
+ AttributeTypeAndValue[] tmp = new AttributeTypeAndValue[values.size()];
+
+ for (int i = 0; i != tmp.length; i++)
+ {
+ tmp[i] = AttributeTypeAndValue.getInstance(values.getObjectAt(i));
+ }
+
+ return tmp;
+ }
+
+ int collectAttributeTypes(ASN1ObjectIdentifier[] oids, int oidsOff)
+ {
+ int count = values.size();
+ for (int i = 0; i < count; ++i)
+ {
+ AttributeTypeAndValue attr = AttributeTypeAndValue.getInstance(values.getObjectAt(i));
+ oids[oidsOff + i] = attr.getType();
+ }
+ return count;
+ }
+
+ boolean containsAttributeType(ASN1ObjectIdentifier attributeType)
+ {
+ int count = values.size();
+ for (int i = 0; i < count; ++i)
+ {
+ AttributeTypeAndValue attr = AttributeTypeAndValue.getInstance(values.getObjectAt(i));
+ if (attr.getType().equals(attributeType))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * <pre>
+ * RelativeDistinguishedName ::=
+ * SET OF AttributeTypeAndValue
+
+ * AttributeTypeAndValue ::= SEQUENCE {
+ * type AttributeType,
+ * value AttributeValue }
+ * </pre>
+ * @return this object as its ASN1Primitive type
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return values;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500Name.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500Name.java
new file mode 100644
index 00000000..ed3f3789
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500Name.java
@@ -0,0 +1,314 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x500;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.x500.style.BCStyle;
+
+/**
+ * The X.500 Name object.
+ * <pre>
+ * Name ::= CHOICE {
+ * RDNSequence }
+ *
+ * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+ *
+ * RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
+ *
+ * AttributeTypeAndValue ::= SEQUENCE {
+ * type OBJECT IDENTIFIER,
+ * value ANY }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X500Name
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private static X500NameStyle defaultStyle = BCStyle.INSTANCE;
+
+ private boolean isHashCodeCalculated;
+ private int hashCodeValue;
+
+ private X500NameStyle style;
+ private RDN[] rdns;
+ private DERSequence rdnSeq;
+
+ /**
+ * @deprecated use the getInstance() method that takes a style.
+ */
+ public X500Name(X500NameStyle style, X500Name name)
+ {
+ this.style = style;
+ this.rdns = name.rdns;
+ this.rdnSeq = name.rdnSeq;
+ }
+
+ /**
+ * Return a X500Name based on the passed in tagged object.
+ *
+ * @param obj tag object holding name.
+ * @param explicit true if explicitly tagged false otherwise.
+ * @return the X500Name
+ */
+ public static X500Name getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ // must be true as choice item
+ return getInstance(ASN1Sequence.getInstance(obj, true));
+ }
+
+ public static X500Name getInstance(
+ Object obj)
+ {
+ if (obj instanceof X500Name)
+ {
+ return (X500Name)obj;
+ }
+ else if (obj != null)
+ {
+ return new X500Name(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static X500Name getInstance(
+ X500NameStyle style,
+ Object obj)
+ {
+ if (obj instanceof X500Name)
+ {
+ return new X500Name(style, (X500Name)obj);
+ }
+ else if (obj != null)
+ {
+ return new X500Name(style, ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * Constructor from ASN1Sequence
+ *
+ * the principal will be a list of constructed sets, each containing an (OID, String) pair.
+ */
+ private X500Name(
+ ASN1Sequence seq)
+ {
+ this(defaultStyle, seq);
+ }
+
+ private X500Name(
+ X500NameStyle style,
+ ASN1Sequence seq)
+ {
+ this.style = style;
+ this.rdns = new RDN[seq.size()];
+
+ boolean inPlace = true;
+
+ int index = 0;
+ for (Enumeration e = seq.getObjects(); e.hasMoreElements();)
+ {
+ Object element = e.nextElement();
+ RDN rdn = RDN.getInstance(element);
+ inPlace &= (rdn == element);
+ rdns[index++] = rdn;
+ }
+
+ if (inPlace)
+ {
+ this.rdnSeq = DERSequence.convert(seq);
+ }
+ else
+ {
+ this.rdnSeq = new DERSequence(this.rdns);
+ }
+ }
+
+ public X500Name(
+ RDN[] rDNs)
+ {
+ this(defaultStyle, rDNs);
+ }
+
+ public X500Name(
+ X500NameStyle style,
+ RDN[] rDNs)
+ {
+ this.style = style;
+ this.rdns = (RDN[])rDNs.clone();
+ this.rdnSeq = new DERSequence(this.rdns);
+ }
+
+ public X500Name(
+ String dirName)
+ {
+ this(defaultStyle, dirName);
+ }
+
+ public X500Name(
+ X500NameStyle style,
+ String dirName)
+ {
+ this(style.fromString(dirName));
+
+ this.style = style;
+ }
+
+ /**
+ * return an array of RDNs in structure order.
+ *
+ * @return an array of RDN objects.
+ */
+ public RDN[] getRDNs()
+ {
+ return (RDN[])rdns.clone();
+ }
+
+ /**
+ * return an array of OIDs contained in the attribute type of each RDN in structure order.
+ *
+ * @return an array, possibly zero length, of ASN1ObjectIdentifiers objects.
+ */
+ public ASN1ObjectIdentifier[] getAttributeTypes()
+ {
+ int count = rdns.length, totalSize = 0;
+ for (int i = 0; i < count; ++i)
+ {
+ RDN rdn = rdns[i];
+ totalSize += rdn.size();
+ }
+
+ ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[totalSize];
+ int oidsOff = 0;
+ for (int i = 0; i < count; ++i)
+ {
+ RDN rdn = rdns[i];
+ oidsOff += rdn.collectAttributeTypes(oids, oidsOff);
+ }
+ return oids;
+ }
+
+ /**
+ * return an array of RDNs containing the attribute type given by OID in structure order.
+ *
+ * @param attributeType the type OID we are looking for.
+ * @return an array, possibly zero length, of RDN objects.
+ */
+ public RDN[] getRDNs(ASN1ObjectIdentifier attributeType)
+ {
+ RDN[] res = new RDN[rdns.length];
+ int count = 0;
+
+ for (int i = 0; i != rdns.length; i++)
+ {
+ RDN rdn = rdns[i];
+ if (rdn.containsAttributeType(attributeType))
+ {
+ res[count++] = rdn;
+ }
+ }
+
+ if (count < res.length)
+ {
+ RDN[] tmp = new RDN[count];
+ System.arraycopy(res, 0, tmp, 0, tmp.length);
+ res = tmp;
+ }
+
+ return res;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return rdnSeq;
+ }
+
+ public int hashCode()
+ {
+ if (isHashCodeCalculated)
+ {
+ return hashCodeValue;
+ }
+
+ isHashCodeCalculated = true;
+
+ hashCodeValue = style.calculateHashCode(this);
+
+ return hashCodeValue;
+ }
+
+ /**
+ * test for equality - note: case is ignored.
+ */
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (!(obj instanceof X500Name || obj instanceof ASN1Sequence))
+ {
+ return false;
+ }
+
+ ASN1Primitive derO = ((ASN1Encodable)obj).toASN1Primitive();
+
+ if (this.toASN1Primitive().equals(derO))
+ {
+ return true;
+ }
+
+ try
+ {
+ return style.areEqual(this, new X500Name(ASN1Sequence.getInstance(((ASN1Encodable)obj).toASN1Primitive())));
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ }
+
+ public String toString()
+ {
+ return style.toString(this);
+ }
+
+ /**
+ * Set the default style for X500Name construction.
+ *
+ * @param style an X500NameStyle
+ */
+ public static void setDefaultStyle(X500NameStyle style)
+ {
+ if (style == null)
+ {
+ throw new NullPointerException("cannot set style to null");
+ }
+
+ defaultStyle = style;
+ }
+
+ /**
+ * Return the current default style.
+ *
+ * @return default style for X500Name construction.
+ */
+ public static X500NameStyle getDefaultStyle()
+ {
+ return defaultStyle;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500NameBuilder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500NameBuilder.java
new file mode 100644
index 00000000..8091b6d9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500NameBuilder.java
@@ -0,0 +1,145 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x500;
+
+import java.util.Vector;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x500.style.BCStyle;
+
+/**
+ * A builder class for making X.500 Name objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X500NameBuilder
+{
+ private X500NameStyle template;
+ private Vector rdns = new Vector();
+
+ /**
+ * Constructor using the default style (BCStyle).
+ */
+ public X500NameBuilder()
+ {
+ this(BCStyle.INSTANCE);
+ }
+
+ /**
+ * Constructor using a specified style.
+ *
+ * @param template the style template for string to DN conversion.
+ */
+ public X500NameBuilder(X500NameStyle template)
+ {
+ this.template = template;
+ }
+
+ /**
+ * Add an RDN based on a single OID and a string representation of its value.
+ *
+ * @param oid the OID for this RDN.
+ * @param value the string representation of the value the OID refers to.
+ * @return the current builder instance.
+ */
+ public X500NameBuilder addRDN(ASN1ObjectIdentifier oid, String value)
+ {
+ this.addRDN(oid, template.stringToValue(oid, value));
+
+ return this;
+ }
+
+ /**
+ * Add an RDN based on a single OID and an ASN.1 value.
+ *
+ * @param oid the OID for this RDN.
+ * @param value the ASN.1 value the OID refers to.
+ * @return the current builder instance.
+ */
+ public X500NameBuilder addRDN(ASN1ObjectIdentifier oid, ASN1Encodable value)
+ {
+ rdns.addElement(new RDN(oid, value));
+
+ return this;
+ }
+
+ /**
+ * Add an RDN based on the passed in AttributeTypeAndValue.
+ *
+ * @param attrTAndV the AttributeTypeAndValue to build the RDN from.
+ * @return the current builder instance.
+ */
+ public X500NameBuilder addRDN(AttributeTypeAndValue attrTAndV)
+ {
+ rdns.addElement(new RDN(attrTAndV));
+
+ return this;
+ }
+
+ /**
+ * Add a multi-valued RDN made up of the passed in OIDs and associated string values.
+ *
+ * @param oids the OIDs making up the RDN.
+ * @param values the string representation of the values the OIDs refer to.
+ * @return the current builder instance.
+ */
+ public X500NameBuilder addMultiValuedRDN(ASN1ObjectIdentifier[] oids, String[] values)
+ {
+ ASN1Encodable[] vals = new ASN1Encodable[values.length];
+
+ for (int i = 0; i != vals.length; i++)
+ {
+ vals[i] = template.stringToValue(oids[i], values[i]);
+ }
+
+ return addMultiValuedRDN(oids, vals);
+ }
+
+ /**
+ * Add a multi-valued RDN made up of the passed in OIDs and associated ASN.1 values.
+ *
+ * @param oids the OIDs making up the RDN.
+ * @param values the ASN.1 values the OIDs refer to.
+ * @return the current builder instance.
+ */
+ public X500NameBuilder addMultiValuedRDN(ASN1ObjectIdentifier[] oids, ASN1Encodable[] values)
+ {
+ AttributeTypeAndValue[] avs = new AttributeTypeAndValue[oids.length];
+
+ for (int i = 0; i != oids.length; i++)
+ {
+ avs[i] = new AttributeTypeAndValue(oids[i], values[i]);
+ }
+
+ return addMultiValuedRDN(avs);
+ }
+
+ /**
+ * Add an RDN based on the passed in AttributeTypeAndValues.
+ *
+ * @param attrTAndVs the AttributeTypeAndValues to build the RDN from.
+ * @return the current builder instance.
+ */
+ public X500NameBuilder addMultiValuedRDN(AttributeTypeAndValue[] attrTAndVs)
+ {
+ rdns.addElement(new RDN(attrTAndVs));
+
+ return this;
+ }
+
+ /**
+ * Build an X.500 name for the current builder state.
+ *
+ * @return a new X.500 name.
+ */
+ public X500Name build()
+ {
+ RDN[] vals = new RDN[rdns.size()];
+
+ for (int i = 0; i != vals.length; i++)
+ {
+ vals[i] = (RDN)rdns.elementAt(i);
+ }
+
+ return new X500Name(template, vals);
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500NameStyle.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500NameStyle.java
new file mode 100644
index 00000000..dfdde964
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500NameStyle.java
@@ -0,0 +1,81 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x500;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * This interface provides a profile to conform to when
+ * DNs are being converted into strings and back. The idea being that we'll be able to deal with
+ * the number of standard ways the fields in a DN should be
+ * encoded into their ASN.1 counterparts - a number that is rapidly approaching the
+ * number of machines on the internet.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface X500NameStyle
+{
+ /**
+ * Convert the passed in String value into the appropriate ASN.1
+ * encoded object.
+ *
+ * @param oid the OID associated with the value in the DN.
+ * @param value the value of the particular DN component.
+ * @return the ASN.1 equivalent for the value.
+ */
+ ASN1Encodable stringToValue(ASN1ObjectIdentifier oid, String value);
+
+ /**
+ * Return the OID associated with the passed in name.
+ *
+ * @param attrName the string to match.
+ * @return an OID
+ */
+ ASN1ObjectIdentifier attrNameToOID(String attrName);
+
+ /**
+ * Return an array of RDN generated from the passed in String.
+ * @param dirName the String representation.
+ * @return an array of corresponding RDNs.
+ */
+ RDN[] fromString(String dirName);
+
+ /**
+ * Return true if the two names are equal.
+ *
+ * @param name1 first name for comparison.
+ * @param name2 second name for comparison.
+ * @return true if name1 = name 2, false otherwise.
+ */
+ boolean areEqual(X500Name name1, X500Name name2);
+
+ /**
+ * Calculate a hashCode for the passed in name.
+ *
+ * @param name the name the hashCode is required for.
+ * @return the calculated hashCode.
+ */
+ int calculateHashCode(X500Name name);
+
+ /**
+ * Convert the passed in X500Name to a String.
+ * @param name the name to convert.
+ * @return a String representation.
+ */
+ String toString(X500Name name);
+
+ /**
+ * Return the display name for toString() associated with the OID.
+ *
+ * @param oid the OID of interest.
+ * @return the name displayed in toString(), null if no mapping provided.
+ */
+ String oidToDisplayName(ASN1ObjectIdentifier oid);
+
+ /**
+ * Return the acceptable names in a String DN that map to OID.
+ *
+ * @param oid the OID of interest.
+ * @return an array of String aliases for the OID, zero length if there are none.
+ */
+ String[] oidToAttrNames(ASN1ObjectIdentifier oid);
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
new file mode 100644
index 00000000..3580944a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
@@ -0,0 +1,194 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x500.style;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1ParsingException;
+import com.android.internal.org.bouncycastle.asn1.DERUTF8String;
+import com.android.internal.org.bouncycastle.asn1.x500.AttributeTypeAndValue;
+import com.android.internal.org.bouncycastle.asn1.x500.RDN;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x500.X500NameStyle;
+
+/**
+ * This class provides some default behavior and common implementation for a
+ * X500NameStyle. It should be easily extendable to support implementing the
+ * desired X500NameStyle.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class AbstractX500NameStyle
+ implements X500NameStyle
+{
+
+ /**
+ * Tool function to shallow copy a Hashtable.
+ *
+ * @param paramsMap table to copy
+ * @return the copy of the table
+ */
+ public 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;
+ }
+
+ private int calcHashCode(ASN1Encodable enc)
+ {
+ String value = IETFUtils.canonicalString(enc);
+ return value.hashCode();
+ }
+
+ public int calculateHashCode(X500Name name)
+ {
+ int hashCodeValue = 0;
+ RDN[] rdns = name.getRDNs();
+
+ // this needs to be order independent, like equals
+ for (int i = 0; i != rdns.length; i++)
+ {
+ if (rdns[i].isMultiValued())
+ {
+ AttributeTypeAndValue[] atv = rdns[i].getTypesAndValues();
+
+ for (int j = 0; j != atv.length; j++)
+ {
+ hashCodeValue ^= atv[j].getType().hashCode();
+ hashCodeValue ^= calcHashCode(atv[j].getValue());
+ }
+ }
+ else
+ {
+ hashCodeValue ^= rdns[i].getFirst().getType().hashCode();
+ hashCodeValue ^= calcHashCode(rdns[i].getFirst().getValue());
+ }
+ }
+
+ return hashCodeValue;
+ }
+
+
+ /**
+ * For all string values starting with '#' is assumed, that these are
+ * already valid ASN.1 objects encoded in hex.
+ * <p>
+ * All other string values are send to
+ * {@link AbstractX500NameStyle#encodeStringValue(ASN1ObjectIdentifier, String)}.
+ * </p>
+ * Subclasses should overwrite
+ * {@link AbstractX500NameStyle#encodeStringValue(ASN1ObjectIdentifier, String)}
+ * to change the encoding of specific types.
+ *
+ * @param oid the DN name of the value.
+ * @param value the String representation of the value.
+ */
+ public ASN1Encodable stringToValue(ASN1ObjectIdentifier oid, String value)
+ {
+ if (value.length() != 0 && value.charAt(0) == '#')
+ {
+ try
+ {
+ return IETFUtils.valueFromHexString(value, 1);
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("can't recode value for oid " + oid.getId());
+ }
+ }
+
+ if (value.length() != 0 && value.charAt(0) == '\\')
+ {
+ value = value.substring(1);
+ }
+
+ return encodeStringValue(oid, value);
+ }
+
+ /**
+ * Encoded every value into a UTF8String.
+ * <p>
+ * Subclasses should overwrite
+ * this method to change the encoding of specific types.
+ * </p>
+ *
+ * @param oid the DN oid of the value
+ * @param value the String representation of the value
+ * @return a the value encoded into a ASN.1 object. Never returns <code>null</code>.
+ */
+ protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid, String value)
+ {
+ return new DERUTF8String(value);
+ }
+
+ public boolean areEqual(X500Name name1, X500Name name2)
+ {
+ RDN[] rdns1 = name1.getRDNs();
+ RDN[] rdns2 = name2.getRDNs();
+
+ if (rdns1.length != rdns2.length)
+ {
+ return false;
+ }
+
+ boolean reverse = false;
+
+ if (rdns1[0].getFirst() != null && rdns2[0].getFirst() != null)
+ {
+ reverse = !rdns1[0].getFirst().getType().equals(rdns2[0].getFirst().getType()); // guess forward
+ }
+
+ for (int i = 0; i != rdns1.length; i++)
+ {
+ if (!foundMatch(reverse, rdns1[i], rdns2))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private boolean foundMatch(boolean reverse, RDN rdn, RDN[] possRDNs)
+ {
+ if (reverse)
+ {
+ for (int i = possRDNs.length - 1; i >= 0; i--)
+ {
+ if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i]))
+ {
+ possRDNs[i] = null;
+ return true;
+ }
+ }
+ }
+ else
+ {
+ for (int i = 0; i != possRDNs.length; i++)
+ {
+ if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i]))
+ {
+ possRDNs[i] = null;
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ protected boolean rdnAreEqual(RDN rdn1, RDN rdn2)
+ {
+ return IETFUtils.rDNAreEqual(rdn1, rdn2);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStrictStyle.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStrictStyle.java
new file mode 100644
index 00000000..86f124f3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStrictStyle.java
@@ -0,0 +1,38 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x500.style;
+
+import com.android.internal.org.bouncycastle.asn1.x500.RDN;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x500.X500NameStyle;
+
+/**
+ * Variation of BCStyle that insists on strict ordering for equality
+ * and hashCode comparisons
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCStrictStyle
+ extends BCStyle
+{
+ public static final X500NameStyle INSTANCE = new BCStrictStyle();
+
+ public boolean areEqual(X500Name name1, X500Name name2)
+ {
+ RDN[] rdns1 = name1.getRDNs();
+ RDN[] rdns2 = name2.getRDNs();
+
+ if (rdns1.length != rdns2.length)
+ {
+ return false;
+ }
+
+ for (int i = 0; i != rdns1.length; i++)
+ {
+ if (!rdnAreEqual(rdns1[i], rdns2[i]))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStyle.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStyle.java
new file mode 100644
index 00000000..e320f828
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStyle.java
@@ -0,0 +1,358 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x500.style;
+
+import java.util.Hashtable;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DERIA5String;
+import com.android.internal.org.bouncycastle.asn1.DERPrintableString;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x500.RDN;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x500.X500NameStyle;
+import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCStyle
+ extends AbstractX500NameStyle
+{
+ /**
+ * country code - StringType(SIZE(2))
+ */
+ public static final ASN1ObjectIdentifier C = new ASN1ObjectIdentifier("2.5.4.6").intern();
+
+ /**
+ * organization - StringType(SIZE(1..64))
+ */
+ public static final ASN1ObjectIdentifier O = new ASN1ObjectIdentifier("2.5.4.10").intern();
+
+ /**
+ * organizational unit name - StringType(SIZE(1..64))
+ */
+ public static final ASN1ObjectIdentifier OU = new ASN1ObjectIdentifier("2.5.4.11").intern();
+
+ /**
+ * Title
+ */
+ public static final ASN1ObjectIdentifier T = new ASN1ObjectIdentifier("2.5.4.12").intern();
+
+ /**
+ * common name - StringType(SIZE(1..64))
+ */
+ public static final ASN1ObjectIdentifier CN = new ASN1ObjectIdentifier("2.5.4.3").intern();
+
+ /**
+ * device serial number name - StringType(SIZE(1..64))
+ * @deprecated use SERIALNUMBER or SURNAME
+ */
+ public static final ASN1ObjectIdentifier SN = new ASN1ObjectIdentifier("2.5.4.5").intern();
+
+ /**
+ * street - StringType(SIZE(1..64))
+ */
+ public static final ASN1ObjectIdentifier STREET = new ASN1ObjectIdentifier("2.5.4.9").intern();
+
+ /**
+ * device serial number name - StringType(SIZE(1..64))
+ */
+ public static final ASN1ObjectIdentifier SERIALNUMBER = new ASN1ObjectIdentifier("2.5.4.5").intern();
+
+ /**
+ * locality name - StringType(SIZE(1..64))
+ */
+ public static final ASN1ObjectIdentifier L = new ASN1ObjectIdentifier("2.5.4.7").intern();
+
+ /**
+ * state, or province name - StringType(SIZE(1..64))
+ */
+ public static final ASN1ObjectIdentifier ST = new ASN1ObjectIdentifier("2.5.4.8").intern();
+
+ /**
+ * Naming attributes of type X520name
+ */
+ public static final ASN1ObjectIdentifier SURNAME = new ASN1ObjectIdentifier("2.5.4.4").intern();
+ public static final ASN1ObjectIdentifier GIVENNAME = new ASN1ObjectIdentifier("2.5.4.42").intern();
+ public static final ASN1ObjectIdentifier INITIALS = new ASN1ObjectIdentifier("2.5.4.43").intern();
+ public static final ASN1ObjectIdentifier GENERATION = new ASN1ObjectIdentifier("2.5.4.44").intern();
+ public static final ASN1ObjectIdentifier UNIQUE_IDENTIFIER = new ASN1ObjectIdentifier("2.5.4.45").intern();
+
+ public static final ASN1ObjectIdentifier DESCRIPTION = new ASN1ObjectIdentifier("2.5.4.13").intern();
+
+ /**
+ * businessCategory - DirectoryString(SIZE(1..128)
+ */
+ public static final ASN1ObjectIdentifier BUSINESS_CATEGORY = new ASN1ObjectIdentifier("2.5.4.15").intern();
+
+ /**
+ * postalCode - DirectoryString(SIZE(1..40)
+ */
+ public static final ASN1ObjectIdentifier POSTAL_CODE = new ASN1ObjectIdentifier("2.5.4.17").intern();
+
+ /**
+ * dnQualifier - DirectoryString(SIZE(1..64)
+ */
+ public static final ASN1ObjectIdentifier DN_QUALIFIER = new ASN1ObjectIdentifier("2.5.4.46").intern();
+
+ /**
+ * RFC 3039 Pseudonym - DirectoryString(SIZE(1..64)
+ */
+ public static final ASN1ObjectIdentifier PSEUDONYM = new ASN1ObjectIdentifier("2.5.4.65").intern();
+
+ public static final ASN1ObjectIdentifier ROLE = new ASN1ObjectIdentifier("2.5.4.72").intern();
+
+ /**
+ * RFC 3039 DateOfBirth - GeneralizedTime - YYYYMMDD000000Z
+ */
+ public static final ASN1ObjectIdentifier DATE_OF_BIRTH = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.1").intern();
+
+ /**
+ * RFC 3039 PlaceOfBirth - DirectoryString(SIZE(1..128)
+ */
+ public static final ASN1ObjectIdentifier PLACE_OF_BIRTH = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.2").intern();
+
+ /**
+ * RFC 3039 Gender - PrintableString (SIZE(1)) -- "M", "F", "m" or "f"
+ */
+ public static final ASN1ObjectIdentifier GENDER = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.3").intern();
+
+ /**
+ * RFC 3039 CountryOfCitizenship - PrintableString (SIZE (2)) -- ISO 3166
+ * codes only
+ */
+ public static final ASN1ObjectIdentifier COUNTRY_OF_CITIZENSHIP = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.4").intern();
+
+ /**
+ * RFC 3039 CountryOfResidence - PrintableString (SIZE (2)) -- ISO 3166
+ * codes only
+ */
+ public static final ASN1ObjectIdentifier COUNTRY_OF_RESIDENCE = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.5").intern();
+
+
+ /**
+ * ISIS-MTT NameAtBirth - DirectoryString(SIZE(1..64)
+ */
+ public static final ASN1ObjectIdentifier NAME_AT_BIRTH = new ASN1ObjectIdentifier("1.3.36.8.3.14").intern();
+
+ /**
+ * RFC 3039 PostalAddress - SEQUENCE SIZE (1..6) OF
+ * DirectoryString(SIZE(1..30))
+ */
+ public static final ASN1ObjectIdentifier POSTAL_ADDRESS = new ASN1ObjectIdentifier("2.5.4.16").intern();
+
+ /**
+ * RFC 2256 dmdName
+ */
+ public static final ASN1ObjectIdentifier DMD_NAME = new ASN1ObjectIdentifier("2.5.4.54").intern();
+
+ /**
+ * id-at-telephoneNumber
+ */
+ public static final ASN1ObjectIdentifier TELEPHONE_NUMBER = X509ObjectIdentifiers.id_at_telephoneNumber;
+
+ /**
+ * id-at-name
+ */
+ public static final ASN1ObjectIdentifier NAME = X509ObjectIdentifiers.id_at_name;
+
+
+ /**
+ * id-at-organizationIdentifier
+ */
+ public static final ASN1ObjectIdentifier ORGANIZATION_IDENTIFIER = X509ObjectIdentifiers.id_at_organizationIdentifier;
+
+ /**
+ * Email address (RSA PKCS#9 extension) - IA5String.
+ * <p>Note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here.
+ */
+ public static final ASN1ObjectIdentifier EmailAddress = PKCSObjectIdentifiers.pkcs_9_at_emailAddress;
+
+ /**
+ * more from PKCS#9
+ */
+ public static final ASN1ObjectIdentifier UnstructuredName = PKCSObjectIdentifiers.pkcs_9_at_unstructuredName;
+ public static final ASN1ObjectIdentifier UnstructuredAddress = PKCSObjectIdentifiers.pkcs_9_at_unstructuredAddress;
+
+ /**
+ * email address in Verisign certificates
+ */
+ public static final ASN1ObjectIdentifier E = EmailAddress;
+
+ /*
+ * others...
+ */
+ public static final ASN1ObjectIdentifier DC = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.25");
+
+ /**
+ * LDAP User id.
+ */
+ public static final ASN1ObjectIdentifier UID = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1");
+
+ /**
+ * default look up table translating OID values into their common symbols following
+ * the convention in RFC 2253 with a few extras
+ */
+ private static final Hashtable DefaultSymbols = new Hashtable();
+
+ /**
+ * look up table translating common symbols into their OIDS.
+ */
+ private static final Hashtable DefaultLookUp = new Hashtable();
+
+ static
+ {
+ DefaultSymbols.put(C, "C");
+ DefaultSymbols.put(O, "O");
+ DefaultSymbols.put(T, "T");
+ DefaultSymbols.put(OU, "OU");
+ DefaultSymbols.put(CN, "CN");
+ DefaultSymbols.put(L, "L");
+ DefaultSymbols.put(ST, "ST");
+ DefaultSymbols.put(SERIALNUMBER, "SERIALNUMBER");
+ DefaultSymbols.put(EmailAddress, "E");
+ DefaultSymbols.put(DC, "DC");
+ DefaultSymbols.put(UID, "UID");
+ DefaultSymbols.put(STREET, "STREET");
+ DefaultSymbols.put(SURNAME, "SURNAME");
+ DefaultSymbols.put(GIVENNAME, "GIVENNAME");
+ DefaultSymbols.put(INITIALS, "INITIALS");
+ DefaultSymbols.put(GENERATION, "GENERATION");
+ DefaultSymbols.put(DESCRIPTION, "DESCRIPTION");
+ DefaultSymbols.put(ROLE, "ROLE");
+ DefaultSymbols.put(UnstructuredAddress, "unstructuredAddress");
+ DefaultSymbols.put(UnstructuredName, "unstructuredName");
+ DefaultSymbols.put(UNIQUE_IDENTIFIER, "UniqueIdentifier");
+ DefaultSymbols.put(DN_QUALIFIER, "DN");
+ DefaultSymbols.put(PSEUDONYM, "Pseudonym");
+ DefaultSymbols.put(POSTAL_ADDRESS, "PostalAddress");
+ DefaultSymbols.put(NAME_AT_BIRTH, "NameAtBirth");
+ DefaultSymbols.put(COUNTRY_OF_CITIZENSHIP, "CountryOfCitizenship");
+ DefaultSymbols.put(COUNTRY_OF_RESIDENCE, "CountryOfResidence");
+ DefaultSymbols.put(GENDER, "Gender");
+ DefaultSymbols.put(PLACE_OF_BIRTH, "PlaceOfBirth");
+ DefaultSymbols.put(DATE_OF_BIRTH, "DateOfBirth");
+ DefaultSymbols.put(POSTAL_CODE, "PostalCode");
+ DefaultSymbols.put(BUSINESS_CATEGORY, "BusinessCategory");
+ DefaultSymbols.put(TELEPHONE_NUMBER, "TelephoneNumber");
+ DefaultSymbols.put(NAME, "Name");
+ DefaultSymbols.put(ORGANIZATION_IDENTIFIER, "organizationIdentifier");
+
+ DefaultLookUp.put("c", C);
+ DefaultLookUp.put("o", O);
+ DefaultLookUp.put("t", T);
+ DefaultLookUp.put("ou", OU);
+ DefaultLookUp.put("cn", CN);
+ DefaultLookUp.put("l", L);
+ DefaultLookUp.put("st", ST);
+ DefaultLookUp.put("sn", SURNAME);
+ DefaultLookUp.put("serialnumber", SERIALNUMBER);
+ DefaultLookUp.put("street", STREET);
+ DefaultLookUp.put("emailaddress", E);
+ DefaultLookUp.put("dc", DC);
+ DefaultLookUp.put("e", E);
+ DefaultLookUp.put("uid", UID);
+ DefaultLookUp.put("surname", SURNAME);
+ DefaultLookUp.put("givenname", GIVENNAME);
+ DefaultLookUp.put("initials", INITIALS);
+ DefaultLookUp.put("generation", GENERATION);
+ DefaultLookUp.put("description", DESCRIPTION);
+ DefaultLookUp.put("role", ROLE);
+ DefaultLookUp.put("unstructuredaddress", UnstructuredAddress);
+ DefaultLookUp.put("unstructuredname", UnstructuredName);
+ DefaultLookUp.put("uniqueidentifier", UNIQUE_IDENTIFIER);
+ DefaultLookUp.put("dn", DN_QUALIFIER);
+ DefaultLookUp.put("pseudonym", PSEUDONYM);
+ DefaultLookUp.put("postaladdress", POSTAL_ADDRESS);
+ DefaultLookUp.put("nameatbirth", NAME_AT_BIRTH);
+ DefaultLookUp.put("countryofcitizenship", COUNTRY_OF_CITIZENSHIP);
+ DefaultLookUp.put("countryofresidence", COUNTRY_OF_RESIDENCE);
+ DefaultLookUp.put("gender", GENDER);
+ DefaultLookUp.put("placeofbirth", PLACE_OF_BIRTH);
+ DefaultLookUp.put("dateofbirth", DATE_OF_BIRTH);
+ DefaultLookUp.put("postalcode", POSTAL_CODE);
+ DefaultLookUp.put("businesscategory", BUSINESS_CATEGORY);
+ DefaultLookUp.put("telephonenumber", TELEPHONE_NUMBER);
+ DefaultLookUp.put("name", NAME);
+ DefaultLookUp.put("organizationidentifier", ORGANIZATION_IDENTIFIER);
+ }
+
+ /**
+ * Singleton instance.
+ */
+ public static final X500NameStyle INSTANCE = new BCStyle();
+
+ protected final Hashtable defaultLookUp;
+ protected final Hashtable defaultSymbols;
+
+ protected BCStyle()
+ {
+ defaultSymbols = copyHashTable(DefaultSymbols);
+ defaultLookUp = copyHashTable(DefaultLookUp);
+ }
+
+ protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid,
+ String value) {
+ if (oid.equals(EmailAddress) || oid.equals(DC))
+ {
+ return new DERIA5String(value);
+ }
+ else if (oid.equals(DATE_OF_BIRTH)) // accept time string as well as # (for compatibility)
+ {
+ return new ASN1GeneralizedTime(value);
+ }
+ else if (oid.equals(C) || oid.equals(SN) || oid.equals(DN_QUALIFIER)
+ || oid.equals(TELEPHONE_NUMBER))
+ {
+ return new DERPrintableString(value);
+ }
+
+ return super.encodeStringValue(oid, value);
+ }
+
+ public String oidToDisplayName(ASN1ObjectIdentifier oid)
+ {
+ return (String)DefaultSymbols.get(oid);
+ }
+
+ public String[] oidToAttrNames(ASN1ObjectIdentifier oid)
+ {
+ return IETFUtils.findAttrNamesForOID(oid, defaultLookUp);
+ }
+
+ public ASN1ObjectIdentifier attrNameToOID(String attrName)
+ {
+ return IETFUtils.decodeAttrName(attrName, defaultLookUp);
+ }
+
+ public RDN[] fromString(String dirName)
+ {
+ return IETFUtils.rDNsFromString(dirName, this);
+ }
+
+ public String toString(X500Name name)
+ {
+ StringBuffer buf = new StringBuffer();
+ boolean first = true;
+
+ RDN[] rdns = name.getRDNs();
+
+ for (int i = 0; i < rdns.length; i++)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ buf.append(',');
+ }
+
+ IETFUtils.appendRDN(buf, rdns[i], defaultSymbols);
+ }
+
+ return buf.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/IETFUtils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/IETFUtils.java
new file mode 100644
index 00000000..130a589e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/IETFUtils.java
@@ -0,0 +1,577 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x500.style;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+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.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1String;
+import com.android.internal.org.bouncycastle.asn1.DERUniversalString;
+import com.android.internal.org.bouncycastle.asn1.x500.AttributeTypeAndValue;
+import com.android.internal.org.bouncycastle.asn1.x500.RDN;
+import com.android.internal.org.bouncycastle.asn1.x500.X500NameBuilder;
+import com.android.internal.org.bouncycastle.asn1.x500.X500NameStyle;
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class IETFUtils
+{
+ private static String unescape(String elt)
+ {
+ if (elt.length() == 0 || (elt.indexOf('\\') < 0 && elt.indexOf('"') < 0))
+ {
+ return elt.trim();
+ }
+
+ char[] elts = elt.toCharArray();
+ boolean escaped = false;
+ boolean quoted = false;
+ StringBuffer buf = new StringBuffer(elt.length());
+ int start = 0;
+
+ // if it's an escaped hash string and not an actual encoding in string form
+ // we need to leave it escaped.
+ if (elts[0] == '\\')
+ {
+ if (elts[1] == '#')
+ {
+ start = 2;
+ buf.append("\\#");
+ }
+ }
+
+ boolean nonWhiteSpaceEncountered = false;
+ int lastEscaped = 0;
+ char hex1 = 0;
+
+ for (int i = start; i != elts.length; i++)
+ {
+ char c = elts[i];
+
+ if (c != ' ')
+ {
+ nonWhiteSpaceEncountered = true;
+ }
+
+ if (c == '"')
+ {
+ if (!escaped)
+ {
+ quoted = !quoted;
+ }
+ else
+ {
+ buf.append(c);
+ }
+ escaped = false;
+ }
+ else if (c == '\\' && !(escaped || quoted))
+ {
+ escaped = true;
+ lastEscaped = buf.length();
+ }
+ else
+ {
+ if (c == ' ' && !escaped && !nonWhiteSpaceEncountered)
+ {
+ continue;
+ }
+ if (escaped && isHexDigit(c))
+ {
+ if (hex1 != 0)
+ {
+ buf.append((char)(convertHex(hex1) * 16 + convertHex(c)));
+ escaped = false;
+ hex1 = 0;
+ continue;
+ }
+ hex1 = c;
+ continue;
+ }
+ buf.append(c);
+ escaped = false;
+ }
+ }
+
+ if (buf.length() > 0)
+ {
+ while (buf.charAt(buf.length() - 1) == ' ' && lastEscaped != (buf.length() - 1))
+ {
+ buf.setLength(buf.length() - 1);
+ }
+ }
+
+ return buf.toString();
+ }
+
+ private static boolean isHexDigit(char c)
+ {
+ return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F');
+ }
+
+ private static int convertHex(char c)
+ {
+ if ('0' <= c && c <= '9')
+ {
+ return c - '0';
+ }
+ if ('a' <= c && c <= 'f')
+ {
+ return c - 'a' + 10;
+ }
+ return c - 'A' + 10;
+ }
+
+ public static RDN[] rDNsFromString(String name, X500NameStyle x500Style)
+ {
+ X500NameTokenizer nTok = new X500NameTokenizer(name);
+ X500NameBuilder builder = new X500NameBuilder(x500Style);
+
+ while (nTok.hasMoreTokens())
+ {
+ String token = nTok.nextToken();
+
+ if (token.indexOf('+') > 0)
+ {
+ X500NameTokenizer pTok = new X500NameTokenizer(token, '+');
+ X500NameTokenizer vTok = new X500NameTokenizer(pTok.nextToken(), '=');
+
+ String attr = vTok.nextToken();
+
+ if (!vTok.hasMoreTokens())
+ {
+ throw new IllegalArgumentException("badly formatted directory string");
+ }
+
+ String value = vTok.nextToken();
+ ASN1ObjectIdentifier oid = x500Style.attrNameToOID(attr.trim());
+
+ if (pTok.hasMoreTokens())
+ {
+ Vector oids = new Vector();
+ Vector values = new Vector();
+
+ oids.addElement(oid);
+ values.addElement(unescape(value));
+
+ while (pTok.hasMoreTokens())
+ {
+ vTok = new X500NameTokenizer(pTok.nextToken(), '=');
+
+ attr = vTok.nextToken();
+
+ if (!vTok.hasMoreTokens())
+ {
+ throw new IllegalArgumentException("badly formatted directory string");
+ }
+
+ value = vTok.nextToken();
+ oid = x500Style.attrNameToOID(attr.trim());
+
+
+ oids.addElement(oid);
+ values.addElement(unescape(value));
+ }
+
+ builder.addMultiValuedRDN(toOIDArray(oids), toValueArray(values));
+ }
+ else
+ {
+ builder.addRDN(oid, unescape(value));
+ }
+ }
+ else
+ {
+ X500NameTokenizer vTok = new X500NameTokenizer(token, '=');
+
+ String attr = vTok.nextToken();
+
+ if (!vTok.hasMoreTokens())
+ {
+ throw new IllegalArgumentException("badly formatted directory string");
+ }
+
+ String value = vTok.nextToken();
+ ASN1ObjectIdentifier oid = x500Style.attrNameToOID(attr.trim());
+
+ builder.addRDN(oid, unescape(value));
+ }
+ }
+
+ return builder.build().getRDNs();
+ }
+
+ private static String[] toValueArray(Vector values)
+ {
+ String[] tmp = new String[values.size()];
+
+ for (int i = 0; i != tmp.length; i++)
+ {
+ tmp[i] = (String)values.elementAt(i);
+ }
+
+ return tmp;
+ }
+
+ private static ASN1ObjectIdentifier[] toOIDArray(Vector oids)
+ {
+ ASN1ObjectIdentifier[] tmp = new ASN1ObjectIdentifier[oids.size()];
+
+ for (int i = 0; i != tmp.length; i++)
+ {
+ tmp[i] = (ASN1ObjectIdentifier)oids.elementAt(i);
+ }
+
+ return tmp;
+ }
+
+ public static String[] findAttrNamesForOID(
+ ASN1ObjectIdentifier oid,
+ Hashtable lookup)
+ {
+ int count = 0;
+ for (Enumeration en = lookup.elements(); en.hasMoreElements();)
+ {
+ if (oid.equals(en.nextElement()))
+ {
+ count++;
+ }
+ }
+
+ String[] aliases = new String[count];
+ count = 0;
+
+ for (Enumeration en = lookup.keys(); en.hasMoreElements();)
+ {
+ String key = (String)en.nextElement();
+ if (oid.equals(lookup.get(key)))
+ {
+ aliases[count++] = key;
+ }
+ }
+
+ return aliases;
+ }
+
+ public static ASN1ObjectIdentifier decodeAttrName(
+ String name,
+ Hashtable lookUp)
+ {
+ if (Strings.toUpperCase(name).startsWith("OID."))
+ {
+ return new ASN1ObjectIdentifier(name.substring(4));
+ }
+ else if (name.charAt(0) >= '0' && name.charAt(0) <= '9')
+ {
+ return new ASN1ObjectIdentifier(name);
+ }
+
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)lookUp.get(Strings.toLowerCase(name));
+ if (oid == null)
+ {
+ throw new IllegalArgumentException("Unknown object id - " + name + " - passed to distinguished name");
+ }
+
+ return oid;
+ }
+
+ public static ASN1Encodable valueFromHexString(
+ String str,
+ int off)
+ throws IOException
+ {
+ byte[] data = new byte[(str.length() - off) / 2];
+ for (int index = 0; index != data.length; index++)
+ {
+ char left = str.charAt((index * 2) + off);
+ char right = str.charAt((index * 2) + off + 1);
+
+ data[index] = (byte)((convertHex(left) << 4) | convertHex(right));
+ }
+
+ return ASN1Primitive.fromByteArray(data);
+ }
+
+ public static void appendRDN(
+ StringBuffer buf,
+ RDN rdn,
+ Hashtable oidSymbols)
+ {
+ if (rdn.isMultiValued())
+ {
+ AttributeTypeAndValue[] atv = rdn.getTypesAndValues();
+ boolean firstAtv = true;
+
+ for (int j = 0; j != atv.length; j++)
+ {
+ if (firstAtv)
+ {
+ firstAtv = false;
+ }
+ else
+ {
+ buf.append('+');
+ }
+
+ IETFUtils.appendTypeAndValue(buf, atv[j], oidSymbols);
+ }
+ }
+ else
+ {
+ if (rdn.getFirst() != null)
+ {
+ IETFUtils.appendTypeAndValue(buf, rdn.getFirst(), oidSymbols);
+ }
+ }
+ }
+
+ public static void appendTypeAndValue(
+ StringBuffer buf,
+ AttributeTypeAndValue typeAndValue,
+ Hashtable oidSymbols)
+ {
+ String sym = (String)oidSymbols.get(typeAndValue.getType());
+
+ if (sym != null)
+ {
+ buf.append(sym);
+ }
+ else
+ {
+ buf.append(typeAndValue.getType().getId());
+ }
+
+ buf.append('=');
+
+ buf.append(valueToString(typeAndValue.getValue()));
+ }
+
+ public static String valueToString(ASN1Encodable value)
+ {
+ StringBuffer vBuf = new StringBuffer();
+
+ if (value instanceof ASN1String && !(value instanceof DERUniversalString))
+ {
+ String v = ((ASN1String)value).getString();
+ if (v.length() > 0 && v.charAt(0) == '#')
+ {
+ vBuf.append('\\');
+ }
+
+ vBuf.append(v);
+ }
+ else
+ {
+ try
+ {
+ vBuf.append('#');
+ vBuf.append(Hex.toHexString(value.toASN1Primitive().getEncoded(ASN1Encoding.DER)));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("Other value has no encoded form");
+ }
+ }
+
+ int end = vBuf.length();
+ int index = 0;
+
+ if (vBuf.length() >= 2 && vBuf.charAt(0) == '\\' && vBuf.charAt(1) == '#')
+ {
+ index += 2;
+ }
+
+ while (index != end)
+ {
+ switch (vBuf.charAt(index))
+ {
+ case ',':
+ case '"':
+ case '\\':
+ case '+':
+ case '=':
+ case '<':
+ case '>':
+ case ';':
+ {
+ vBuf.insert(index, "\\");
+ index += 2;
+ ++end;
+ break;
+ }
+ default:
+ {
+ ++index;
+ break;
+ }
+ }
+ }
+
+ int start = 0;
+ if (vBuf.length() > 0)
+ {
+ while (vBuf.length() > start && vBuf.charAt(start) == ' ')
+ {
+ vBuf.insert(start, "\\");
+ start += 2;
+ }
+ }
+
+ int endBuf = vBuf.length() - 1;
+
+ while (endBuf >= 0 && vBuf.charAt(endBuf) == ' ')
+ {
+ vBuf.insert(endBuf, '\\');
+ endBuf--;
+ }
+
+ return vBuf.toString();
+ }
+
+ public static String canonicalize(String s)
+ {
+ if (s.length() > 0 && s.charAt(0) == '#')
+ {
+ ASN1Primitive obj = decodeObject(s);
+ if (obj instanceof ASN1String)
+ {
+ s = ((ASN1String)obj).getString();
+ }
+ }
+
+ s = Strings.toLowerCase(s);
+
+ int length = s.length();
+ if (length < 2)
+ {
+ return s;
+ }
+
+ int start = 0, last = length - 1;
+ while (start < last && s.charAt(start) == '\\' && s.charAt(start + 1) == ' ')
+ {
+ start += 2;
+ }
+
+ int end = last, first = start + 1;
+ while (end > first && s.charAt(end - 1) == '\\' && s.charAt(end) == ' ')
+ {
+ end -= 2;
+ }
+
+ if (start > 0 || end < last)
+ {
+ s = s.substring(start, end + 1);
+ }
+
+ return stripInternalSpaces(s);
+ }
+
+ public static String canonicalString(ASN1Encodable value)
+ {
+ return canonicalize(valueToString(value));
+ }
+
+ private static ASN1Primitive decodeObject(String oValue)
+ {
+ try
+ {
+ return ASN1Primitive.fromByteArray(Hex.decodeStrict(oValue, 1, oValue.length() - 1));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unknown encoding in name: " + e);
+ }
+ }
+
+ public static String stripInternalSpaces(
+ String str)
+ {
+ if (str.indexOf(" ") < 0)
+ {
+ return str;
+ }
+
+ StringBuffer res = new StringBuffer();
+
+ char c1 = str.charAt(0);
+ res.append(c1);
+
+ for (int k = 1; k < str.length(); k++)
+ {
+ char c2 = str.charAt(k);
+ if (!(c1 == ' ' && c2 == ' '))
+ {
+ res.append(c2);
+ c1 = c2;
+ }
+ }
+
+ return res.toString();
+ }
+
+ public static boolean rDNAreEqual(RDN rdn1, RDN rdn2)
+ {
+ if (rdn1.size() != rdn2.size())
+ {
+ return false;
+ }
+
+ AttributeTypeAndValue[] atvs1 = rdn1.getTypesAndValues();
+ AttributeTypeAndValue[] atvs2 = rdn2.getTypesAndValues();
+
+ if (atvs1.length != atvs2.length)
+ {
+ return false;
+ }
+
+ for (int i = 0; i != atvs1.length; i++)
+ {
+ if (!atvAreEqual(atvs1[i], atvs2[i]))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private static boolean atvAreEqual(AttributeTypeAndValue atv1, AttributeTypeAndValue atv2)
+ {
+ if (atv1 == atv2)
+ {
+ return true;
+ }
+
+ if (null == atv1 || null == atv2)
+ {
+ return false;
+ }
+
+ ASN1ObjectIdentifier o1 = atv1.getType();
+ ASN1ObjectIdentifier o2 = atv2.getType();
+
+ if (!o1.equals(o2))
+ {
+ return false;
+ }
+
+ String v1 = canonicalString(atv1.getValue());
+ String v2 = canonicalString(atv2.getValue());
+
+ if (!v1.equals(v2))
+ {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/RFC4519Style.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/RFC4519Style.java
new file mode 100644
index 00000000..7d8f6760
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/RFC4519Style.java
@@ -0,0 +1,252 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x500.style;
+
+import java.util.Hashtable;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DERIA5String;
+import com.android.internal.org.bouncycastle.asn1.DERPrintableString;
+import com.android.internal.org.bouncycastle.asn1.x500.RDN;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x500.X500NameStyle;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RFC4519Style
+ extends AbstractX500NameStyle
+{
+ public static final ASN1ObjectIdentifier businessCategory = new ASN1ObjectIdentifier("2.5.4.15").intern();
+ public static final ASN1ObjectIdentifier c = new ASN1ObjectIdentifier("2.5.4.6").intern();
+ public static final ASN1ObjectIdentifier cn = new ASN1ObjectIdentifier("2.5.4.3").intern();
+ public static final ASN1ObjectIdentifier dc = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.25").intern();
+ public static final ASN1ObjectIdentifier description = new ASN1ObjectIdentifier("2.5.4.13").intern();
+ public static final ASN1ObjectIdentifier destinationIndicator = new ASN1ObjectIdentifier("2.5.4.27").intern();
+ public static final ASN1ObjectIdentifier distinguishedName = new ASN1ObjectIdentifier("2.5.4.49").intern();
+ public static final ASN1ObjectIdentifier dnQualifier = new ASN1ObjectIdentifier("2.5.4.46").intern();
+ public static final ASN1ObjectIdentifier enhancedSearchGuide = new ASN1ObjectIdentifier("2.5.4.47").intern();
+ public static final ASN1ObjectIdentifier facsimileTelephoneNumber = new ASN1ObjectIdentifier("2.5.4.23").intern();
+ public static final ASN1ObjectIdentifier generationQualifier = new ASN1ObjectIdentifier("2.5.4.44").intern();
+ public static final ASN1ObjectIdentifier givenName = new ASN1ObjectIdentifier("2.5.4.42").intern();
+ public static final ASN1ObjectIdentifier houseIdentifier = new ASN1ObjectIdentifier("2.5.4.51").intern();
+ public static final ASN1ObjectIdentifier initials = new ASN1ObjectIdentifier("2.5.4.43").intern();
+ public static final ASN1ObjectIdentifier internationalISDNNumber = new ASN1ObjectIdentifier("2.5.4.25").intern();
+ public static final ASN1ObjectIdentifier l = new ASN1ObjectIdentifier("2.5.4.7").intern();
+ public static final ASN1ObjectIdentifier member = new ASN1ObjectIdentifier("2.5.4.31").intern();
+ public static final ASN1ObjectIdentifier name = new ASN1ObjectIdentifier("2.5.4.41").intern();
+ public static final ASN1ObjectIdentifier o = new ASN1ObjectIdentifier("2.5.4.10").intern();
+ public static final ASN1ObjectIdentifier ou = new ASN1ObjectIdentifier("2.5.4.11").intern();
+ public static final ASN1ObjectIdentifier owner = new ASN1ObjectIdentifier("2.5.4.32").intern();
+ public static final ASN1ObjectIdentifier physicalDeliveryOfficeName = new ASN1ObjectIdentifier("2.5.4.19").intern();
+ public static final ASN1ObjectIdentifier postalAddress = new ASN1ObjectIdentifier("2.5.4.16").intern();
+ public static final ASN1ObjectIdentifier postalCode = new ASN1ObjectIdentifier("2.5.4.17").intern();
+ public static final ASN1ObjectIdentifier postOfficeBox = new ASN1ObjectIdentifier("2.5.4.18").intern();
+ public static final ASN1ObjectIdentifier preferredDeliveryMethod = new ASN1ObjectIdentifier("2.5.4.28").intern();
+ public static final ASN1ObjectIdentifier registeredAddress = new ASN1ObjectIdentifier("2.5.4.26").intern();
+ public static final ASN1ObjectIdentifier roleOccupant = new ASN1ObjectIdentifier("2.5.4.33").intern();
+ public static final ASN1ObjectIdentifier searchGuide = new ASN1ObjectIdentifier("2.5.4.14").intern();
+ public static final ASN1ObjectIdentifier seeAlso = new ASN1ObjectIdentifier("2.5.4.34").intern();
+ public static final ASN1ObjectIdentifier serialNumber = new ASN1ObjectIdentifier("2.5.4.5").intern();
+ public static final ASN1ObjectIdentifier sn = new ASN1ObjectIdentifier("2.5.4.4").intern();
+ public static final ASN1ObjectIdentifier st = new ASN1ObjectIdentifier("2.5.4.8").intern();
+ public static final ASN1ObjectIdentifier street = new ASN1ObjectIdentifier("2.5.4.9").intern();
+ public static final ASN1ObjectIdentifier telephoneNumber = new ASN1ObjectIdentifier("2.5.4.20").intern();
+ public static final ASN1ObjectIdentifier teletexTerminalIdentifier = new ASN1ObjectIdentifier("2.5.4.22").intern();
+ public static final ASN1ObjectIdentifier telexNumber = new ASN1ObjectIdentifier("2.5.4.21").intern();
+ public static final ASN1ObjectIdentifier title = new ASN1ObjectIdentifier("2.5.4.12").intern();
+ public static final ASN1ObjectIdentifier uid = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1").intern();
+ public static final ASN1ObjectIdentifier uniqueMember = new ASN1ObjectIdentifier("2.5.4.50").intern();
+ public static final ASN1ObjectIdentifier userPassword = new ASN1ObjectIdentifier("2.5.4.35").intern();
+ public static final ASN1ObjectIdentifier x121Address = new ASN1ObjectIdentifier("2.5.4.24").intern();
+ public static final ASN1ObjectIdentifier x500UniqueIdentifier = new ASN1ObjectIdentifier("2.5.4.45").intern();
+
+ /**
+ * default look up table translating OID values into their common symbols following
+ * the convention in RFC 2253 with a few extras
+ */
+ private static final Hashtable DefaultSymbols = new Hashtable();
+
+ /**
+ * look up table translating common symbols into their OIDS.
+ */
+ private static final Hashtable DefaultLookUp = new Hashtable();
+
+ static
+ {
+ DefaultSymbols.put(businessCategory, "businessCategory");
+ DefaultSymbols.put(c, "c");
+ DefaultSymbols.put(cn, "cn");
+ DefaultSymbols.put(dc, "dc");
+ DefaultSymbols.put(description, "description");
+ DefaultSymbols.put(destinationIndicator, "destinationIndicator");
+ DefaultSymbols.put(distinguishedName, "distinguishedName");
+ DefaultSymbols.put(dnQualifier, "dnQualifier");
+ DefaultSymbols.put(enhancedSearchGuide, "enhancedSearchGuide");
+ DefaultSymbols.put(facsimileTelephoneNumber, "facsimileTelephoneNumber");
+ DefaultSymbols.put(generationQualifier, "generationQualifier");
+ DefaultSymbols.put(givenName, "givenName");
+ DefaultSymbols.put(houseIdentifier, "houseIdentifier");
+ DefaultSymbols.put(initials, "initials");
+ DefaultSymbols.put(internationalISDNNumber, "internationalISDNNumber");
+ DefaultSymbols.put(l, "l");
+ DefaultSymbols.put(member, "member");
+ DefaultSymbols.put(name, "name");
+ DefaultSymbols.put(o, "o");
+ DefaultSymbols.put(ou, "ou");
+ DefaultSymbols.put(owner, "owner");
+ DefaultSymbols.put(physicalDeliveryOfficeName, "physicalDeliveryOfficeName");
+ DefaultSymbols.put(postalAddress, "postalAddress");
+ DefaultSymbols.put(postalCode, "postalCode");
+ DefaultSymbols.put(postOfficeBox, "postOfficeBox");
+ DefaultSymbols.put(preferredDeliveryMethod, "preferredDeliveryMethod");
+ DefaultSymbols.put(registeredAddress, "registeredAddress");
+ DefaultSymbols.put(roleOccupant, "roleOccupant");
+ DefaultSymbols.put(searchGuide, "searchGuide");
+ DefaultSymbols.put(seeAlso, "seeAlso");
+ DefaultSymbols.put(serialNumber, "serialNumber");
+ DefaultSymbols.put(sn, "sn");
+ DefaultSymbols.put(st, "st");
+ DefaultSymbols.put(street, "street");
+ DefaultSymbols.put(telephoneNumber, "telephoneNumber");
+ DefaultSymbols.put(teletexTerminalIdentifier, "teletexTerminalIdentifier");
+ DefaultSymbols.put(telexNumber, "telexNumber");
+ DefaultSymbols.put(title, "title");
+ DefaultSymbols.put(uid, "uid");
+ DefaultSymbols.put(uniqueMember, "uniqueMember");
+ DefaultSymbols.put(userPassword, "userPassword");
+ DefaultSymbols.put(x121Address, "x121Address");
+ DefaultSymbols.put(x500UniqueIdentifier, "x500UniqueIdentifier");
+
+ DefaultLookUp.put("businesscategory", businessCategory);
+ DefaultLookUp.put("c", c);
+ DefaultLookUp.put("cn", cn);
+ DefaultLookUp.put("dc", dc);
+ DefaultLookUp.put("description", description);
+ DefaultLookUp.put("destinationindicator", destinationIndicator);
+ DefaultLookUp.put("distinguishedname", distinguishedName);
+ DefaultLookUp.put("dnqualifier", dnQualifier);
+ DefaultLookUp.put("enhancedsearchguide", enhancedSearchGuide);
+ DefaultLookUp.put("facsimiletelephonenumber", facsimileTelephoneNumber);
+ DefaultLookUp.put("generationqualifier", generationQualifier);
+ DefaultLookUp.put("givenname", givenName);
+ DefaultLookUp.put("houseidentifier", houseIdentifier);
+ DefaultLookUp.put("initials", initials);
+ DefaultLookUp.put("internationalisdnnumber", internationalISDNNumber);
+ DefaultLookUp.put("l", l);
+ DefaultLookUp.put("member", member);
+ DefaultLookUp.put("name", name);
+ DefaultLookUp.put("o", o);
+ DefaultLookUp.put("ou", ou);
+ DefaultLookUp.put("owner", owner);
+ DefaultLookUp.put("physicaldeliveryofficename", physicalDeliveryOfficeName);
+ DefaultLookUp.put("postaladdress", postalAddress);
+ DefaultLookUp.put("postalcode", postalCode);
+ DefaultLookUp.put("postofficebox", postOfficeBox);
+ DefaultLookUp.put("preferreddeliverymethod", preferredDeliveryMethod);
+ DefaultLookUp.put("registeredaddress", registeredAddress);
+ DefaultLookUp.put("roleoccupant", roleOccupant);
+ DefaultLookUp.put("searchguide", searchGuide);
+ DefaultLookUp.put("seealso", seeAlso);
+ DefaultLookUp.put("serialnumber", serialNumber);
+ DefaultLookUp.put("sn", sn);
+ DefaultLookUp.put("st", st);
+ DefaultLookUp.put("street", street);
+ DefaultLookUp.put("telephonenumber", telephoneNumber);
+ DefaultLookUp.put("teletexterminalidentifier", teletexTerminalIdentifier);
+ DefaultLookUp.put("telexnumber", telexNumber);
+ DefaultLookUp.put("title", title);
+ DefaultLookUp.put("uid", uid);
+ DefaultLookUp.put("uniquemember", uniqueMember);
+ DefaultLookUp.put("userpassword", userPassword);
+ DefaultLookUp.put("x121address", x121Address);
+ DefaultLookUp.put("x500uniqueidentifier", x500UniqueIdentifier);
+
+ // TODO: need to add correct matching for equality comparisons.
+ }
+
+ /**
+ * Singleton instance.
+ */
+ public static final X500NameStyle INSTANCE = new RFC4519Style();
+
+ protected final Hashtable defaultLookUp;
+ protected final Hashtable defaultSymbols;
+
+ protected RFC4519Style()
+ {
+ defaultSymbols = copyHashTable(DefaultSymbols);
+ defaultLookUp = copyHashTable(DefaultLookUp);
+ }
+
+ protected ASN1Encodable encodeStringValue(ASN1ObjectIdentifier oid,
+ String value) {
+ if (oid.equals(dc))
+ {
+ return new DERIA5String(value);
+ }
+ else if (oid.equals(c) || oid.equals(serialNumber) || oid.equals(dnQualifier)
+ || oid.equals(telephoneNumber))
+ {
+ return new DERPrintableString(value);
+ }
+
+ return super.encodeStringValue(oid, value);
+ }
+
+ public String oidToDisplayName(ASN1ObjectIdentifier oid)
+ {
+ return (String)DefaultSymbols.get(oid);
+ }
+
+ public String[] oidToAttrNames(ASN1ObjectIdentifier oid)
+ {
+ return IETFUtils.findAttrNamesForOID(oid, defaultLookUp);
+ }
+
+ public ASN1ObjectIdentifier attrNameToOID(String attrName)
+ {
+ return IETFUtils.decodeAttrName(attrName, defaultLookUp);
+ }
+
+ // parse backwards
+ public RDN[] fromString(String dirName)
+ {
+ RDN[] tmp = IETFUtils.rDNsFromString(dirName, this);
+ RDN[] res = new RDN[tmp.length];
+
+ for (int i = 0; i != tmp.length; i++)
+ {
+ res[res.length - i - 1] = tmp[i];
+ }
+
+ return res;
+ }
+
+ // convert in reverse
+ public String toString(X500Name name)
+ {
+ StringBuffer buf = new StringBuffer();
+ boolean first = true;
+
+ RDN[] rdns = name.getRDNs();
+
+ for (int i = rdns.length - 1; i >= 0; i--)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ buf.append(',');
+ }
+
+ IETFUtils.appendRDN(buf, rdns[i], defaultSymbols);
+ }
+
+ return buf.toString();
+ }
+
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java
new file mode 100644
index 00000000..66225500
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/X500NameTokenizer.java
@@ -0,0 +1,92 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x500.style;
+
+/**
+ * class for breaking up an X500 Name into it's component tokens, ala
+ * java.util.StringTokenizer. We need this class as some of the
+ * lightweight Java environment don't support classes like
+ * StringTokenizer.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X500NameTokenizer
+{
+ private String value;
+ private int index;
+ private char separator;
+ private StringBuffer buf = new StringBuffer();
+
+ public X500NameTokenizer(
+ String oid)
+ {
+ this(oid, ',');
+ }
+
+ public X500NameTokenizer(
+ String oid,
+ char separator)
+ {
+ this.value = oid;
+ this.index = -1;
+ this.separator = separator;
+ }
+
+ public boolean hasMoreTokens()
+ {
+ return (index != value.length());
+ }
+
+ public String nextToken()
+ {
+ if (index == value.length())
+ {
+ return null;
+ }
+
+ int end = index + 1;
+ boolean quoted = false;
+ boolean escaped = false;
+
+ buf.setLength(0);
+
+ while (end != value.length())
+ {
+ char c = value.charAt(end);
+
+ if (c == '"')
+ {
+ if (!escaped)
+ {
+ quoted = !quoted;
+ }
+ buf.append(c);
+ escaped = false;
+ }
+ else
+ {
+ if (escaped || quoted)
+ {
+ buf.append(c);
+ escaped = false;
+ }
+ else if (c == '\\')
+ {
+ buf.append(c);
+ escaped = true;
+ }
+ else if (c == separator)
+ {
+ break;
+ }
+ else
+ {
+ buf.append(c);
+ }
+ }
+ end++;
+ }
+
+ index = end;
+
+ return buf.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java
new file mode 100644
index 00000000..99fd6e31
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java
@@ -0,0 +1,110 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AlgorithmIdentifier
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier algorithm;
+ private ASN1Encodable parameters;
+
+ public static AlgorithmIdentifier getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static AlgorithmIdentifier getInstance(
+ Object obj)
+ {
+ if (obj instanceof AlgorithmIdentifier)
+ {
+ return (AlgorithmIdentifier)obj;
+ }
+ else if (obj != null)
+ {
+ return new AlgorithmIdentifier(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public AlgorithmIdentifier(
+ ASN1ObjectIdentifier algorithm)
+ {
+ this.algorithm = algorithm;
+ }
+
+ public AlgorithmIdentifier(
+ ASN1ObjectIdentifier algorithm,
+ ASN1Encodable parameters)
+ {
+ this.algorithm = algorithm;
+ this.parameters = parameters;
+ }
+
+ private AlgorithmIdentifier(
+ ASN1Sequence seq)
+ {
+ if (seq.size() < 1 || seq.size() > 2)
+ {
+ throw new IllegalArgumentException("Bad sequence size: "
+ + seq.size());
+ }
+
+ algorithm = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+
+ if (seq.size() == 2)
+ {
+ parameters = seq.getObjectAt(1);
+ }
+ else
+ {
+ parameters = null;
+ }
+ }
+
+ public ASN1ObjectIdentifier getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ public ASN1Encodable getParameters()
+ {
+ return parameters;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(algorithm);
+
+ if (parameters != null)
+ {
+ v.add(parameters);
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttCertIssuer.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttCertIssuer.java
new file mode 100644
index 00000000..ea2103f0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttCertIssuer.java
@@ -0,0 +1,95 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AttCertIssuer
+ extends ASN1Object
+ implements ASN1Choice
+{
+ ASN1Encodable obj;
+ ASN1Primitive choiceObj;
+
+ public static AttCertIssuer getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof AttCertIssuer)
+ {
+ return (AttCertIssuer)obj;
+ }
+ else if (obj instanceof V2Form)
+ {
+ return new AttCertIssuer(V2Form.getInstance(obj));
+ }
+ else if (obj instanceof GeneralNames)
+ {
+ return new AttCertIssuer((GeneralNames)obj);
+ }
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ return new AttCertIssuer(V2Form.getInstance((ASN1TaggedObject)obj, false));
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ return new AttCertIssuer(GeneralNames.getInstance(obj));
+ }
+
+ throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
+ }
+
+ public static AttCertIssuer getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject()); // must be explicitly tagged
+ }
+
+ /**
+ * Don't use this one if you are trying to be RFC 3281 compliant.
+ * Use it for v1 attribute certificates only.
+ *
+ * @param names our GeneralNames structure
+ */
+ public AttCertIssuer(
+ GeneralNames names)
+ {
+ obj = names;
+ choiceObj = obj.toASN1Primitive();
+ }
+
+ public AttCertIssuer(
+ V2Form v2Form)
+ {
+ obj = v2Form;
+ choiceObj = new DERTaggedObject(false, 0, obj);
+ }
+
+ public ASN1Encodable getIssuer()
+ {
+ return obj;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * AttCertIssuer ::= CHOICE {
+ * v1Form GeneralNames, -- MUST NOT be used in this
+ * -- profile
+ * v2Form [0] V2Form -- v2 only
+ * }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return choiceObj;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java
new file mode 100644
index 00000000..d23cf793
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java
@@ -0,0 +1,88 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AttCertValidityPeriod
+ extends ASN1Object
+{
+ ASN1GeneralizedTime notBeforeTime;
+ ASN1GeneralizedTime notAfterTime;
+
+ public static AttCertValidityPeriod getInstance(
+ Object obj)
+ {
+ if (obj instanceof AttCertValidityPeriod)
+ {
+ return (AttCertValidityPeriod)obj;
+ }
+ else if (obj != null)
+ {
+ return new AttCertValidityPeriod(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private AttCertValidityPeriod(
+ ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("Bad sequence size: "
+ + seq.size());
+ }
+
+ notBeforeTime = ASN1GeneralizedTime.getInstance(seq.getObjectAt(0));
+ notAfterTime = ASN1GeneralizedTime.getInstance(seq.getObjectAt(1));
+ }
+
+ /**
+ * @param notBeforeTime
+ * @param notAfterTime
+ */
+ public AttCertValidityPeriod(
+ ASN1GeneralizedTime notBeforeTime,
+ ASN1GeneralizedTime notAfterTime)
+ {
+ this.notBeforeTime = notBeforeTime;
+ this.notAfterTime = notAfterTime;
+ }
+
+ public ASN1GeneralizedTime getNotBeforeTime()
+ {
+ return notBeforeTime;
+ }
+
+ public ASN1GeneralizedTime getNotAfterTime()
+ {
+ return notAfterTime;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * AttCertValidityPeriod ::= SEQUENCE {
+ * notBeforeTime GeneralizedTime,
+ * notAfterTime GeneralizedTime
+ * }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(notBeforeTime);
+ v.add(notAfterTime);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Attribute.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Attribute.java
new file mode 100644
index 00000000..25f5bd3d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Attribute.java
@@ -0,0 +1,97 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Attribute
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier attrType;
+ private ASN1Set attrValues;
+
+ /**
+ * return an Attribute object from the given object.
+ *
+ * @param o the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static Attribute getInstance(
+ Object o)
+ {
+ if (o instanceof Attribute)
+ {
+ return (Attribute)o;
+ }
+
+ if (o != null)
+ {
+ return new Attribute(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ private Attribute(
+ ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+
+ attrType = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+ attrValues = ASN1Set.getInstance(seq.getObjectAt(1));
+ }
+
+ public Attribute(
+ ASN1ObjectIdentifier attrType,
+ ASN1Set attrValues)
+ {
+ this.attrType = attrType;
+ this.attrValues = attrValues;
+ }
+
+ public ASN1ObjectIdentifier getAttrType()
+ {
+ return new ASN1ObjectIdentifier(attrType.getId());
+ }
+
+ public ASN1Encodable[] getAttributeValues()
+ {
+ return attrValues.toArray();
+ }
+
+ public ASN1Set getAttrValues()
+ {
+ return attrValues;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * Attribute ::= SEQUENCE {
+ * attrType OBJECT IDENTIFIER,
+ * attrValues SET OF AttributeValue
+ * }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(attrType);
+ v.add(attrValues);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificate.java
new file mode 100644
index 00000000..11488623
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificate.java
@@ -0,0 +1,101 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AttributeCertificate
+ extends ASN1Object
+{
+ AttributeCertificateInfo acinfo;
+ AlgorithmIdentifier signatureAlgorithm;
+ DERBitString signatureValue;
+
+ /**
+ * @param obj
+ * @return an AttributeCertificate object
+ */
+ public static AttributeCertificate getInstance(Object obj)
+ {
+ if (obj instanceof AttributeCertificate)
+ {
+ return (AttributeCertificate)obj;
+ }
+ else if (obj != null)
+ {
+ return new AttributeCertificate(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public AttributeCertificate(
+ AttributeCertificateInfo acinfo,
+ AlgorithmIdentifier signatureAlgorithm,
+ DERBitString signatureValue)
+ {
+ this.acinfo = acinfo;
+ this.signatureAlgorithm = signatureAlgorithm;
+ this.signatureValue = signatureValue;
+ }
+
+ /**
+ * @deprecated use getInstance() method.
+ */
+ public AttributeCertificate(
+ ASN1Sequence seq)
+ {
+ if (seq.size() != 3)
+ {
+ throw new IllegalArgumentException("Bad sequence size: "
+ + seq.size());
+ }
+
+ this.acinfo = AttributeCertificateInfo.getInstance(seq.getObjectAt(0));
+ this.signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
+ this.signatureValue = DERBitString.getInstance(seq.getObjectAt(2));
+ }
+
+ public AttributeCertificateInfo getAcinfo()
+ {
+ return acinfo;
+ }
+
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return signatureAlgorithm;
+ }
+
+ public DERBitString getSignatureValue()
+ {
+ return signatureValue;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * AttributeCertificate ::= SEQUENCE {
+ * acinfo AttributeCertificateInfo,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signatureValue BIT STRING
+ * }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(acinfo);
+ v.add(signatureAlgorithm);
+ v.add(signatureValue);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
new file mode 100644
index 00000000..db94e6f1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
@@ -0,0 +1,184 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AttributeCertificateInfo
+ extends ASN1Object
+{
+ private ASN1Integer version;
+ private Holder holder;
+ private AttCertIssuer issuer;
+ private AlgorithmIdentifier signature;
+ private ASN1Integer serialNumber;
+ private AttCertValidityPeriod attrCertValidityPeriod;
+ private ASN1Sequence attributes;
+ private DERBitString issuerUniqueID;
+ private Extensions extensions;
+
+ public static AttributeCertificateInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static AttributeCertificateInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof AttributeCertificateInfo)
+ {
+ return (AttributeCertificateInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new AttributeCertificateInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private AttributeCertificateInfo(
+ ASN1Sequence seq)
+ {
+ if (seq.size() < 6 || seq.size() > 9)
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+
+ int start;
+ if (seq.getObjectAt(0) instanceof ASN1Integer) // in version 1 certs version is DEFAULT v1(0)
+ {
+ this.version = ASN1Integer.getInstance(seq.getObjectAt(0));
+ start = 1;
+ }
+ else
+ {
+ this.version = new ASN1Integer(0);
+ start = 0;
+ }
+
+ this.holder = Holder.getInstance(seq.getObjectAt(start));
+ this.issuer = AttCertIssuer.getInstance(seq.getObjectAt(start + 1));
+ this.signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(start + 2));
+ this.serialNumber = ASN1Integer.getInstance(seq.getObjectAt(start + 3));
+ this.attrCertValidityPeriod = AttCertValidityPeriod.getInstance(seq.getObjectAt(start + 4));
+ this.attributes = ASN1Sequence.getInstance(seq.getObjectAt(start + 5));
+
+ for (int i = start + 6; i < seq.size(); i++)
+ {
+ ASN1Encodable obj = seq.getObjectAt(i);
+
+ if (obj instanceof DERBitString)
+ {
+ this.issuerUniqueID = DERBitString.getInstance(seq.getObjectAt(i));
+ }
+ else if (obj instanceof ASN1Sequence || obj instanceof Extensions)
+ {
+ this.extensions = Extensions.getInstance(seq.getObjectAt(i));
+ }
+ }
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public Holder getHolder()
+ {
+ return holder;
+ }
+
+ public AttCertIssuer getIssuer()
+ {
+ return issuer;
+ }
+
+ public AlgorithmIdentifier getSignature()
+ {
+ return signature;
+ }
+
+ public ASN1Integer getSerialNumber()
+ {
+ return serialNumber;
+ }
+
+ public AttCertValidityPeriod getAttrCertValidityPeriod()
+ {
+ return attrCertValidityPeriod;
+ }
+
+ public ASN1Sequence getAttributes()
+ {
+ return attributes;
+ }
+
+ public DERBitString getIssuerUniqueID()
+ {
+ return issuerUniqueID;
+ }
+
+ public Extensions getExtensions()
+ {
+ return extensions;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * AttributeCertificateInfo ::= SEQUENCE {
+ * version AttCertVersion -- version is v2,
+ * holder Holder,
+ * issuer AttCertIssuer,
+ * signature AlgorithmIdentifier,
+ * serialNumber CertificateSerialNumber,
+ * attrCertValidityPeriod AttCertValidityPeriod,
+ * attributes SEQUENCE OF Attribute,
+ * issuerUniqueID UniqueIdentifier OPTIONAL,
+ * extensions Extensions OPTIONAL
+ * }
+ *
+ * AttCertVersion ::= INTEGER { v2(1) }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(9);
+
+ if (version.intValueExact() != 0)
+ {
+ v.add(version);
+ }
+ v.add(holder);
+ v.add(issuer);
+ v.add(signature);
+ v.add(serialNumber);
+ v.add(attrCertValidityPeriod);
+ v.add(attributes);
+
+ if (issuerUniqueID != null)
+ {
+ v.add(issuerUniqueID);
+ }
+
+ if (extensions != null)
+ {
+ v.add(extensions);
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
new file mode 100644
index 00000000..23ae0c71
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
@@ -0,0 +1,239 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+// Android-changed: Use Android digests
+// import org.bouncycastle.crypto.digests.SHA1Digest;
+import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * The AuthorityKeyIdentifier object.
+ * <pre>
+ * id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 }
+ *
+ * AuthorityKeyIdentifier ::= SEQUENCE {
+ * keyIdentifier [0] IMPLICIT KeyIdentifier OPTIONAL,
+ * authorityCertIssuer [1] IMPLICIT GeneralNames OPTIONAL,
+ * authorityCertSerialNumber [2] IMPLICIT CertificateSerialNumber OPTIONAL }
+ *
+ * KeyIdentifier ::= OCTET STRING
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ *
+ */
+public class AuthorityKeyIdentifier
+ extends ASN1Object
+{
+ ASN1OctetString keyidentifier = null;
+ GeneralNames certissuer = null;
+ ASN1Integer certserno = null;
+
+ public static AuthorityKeyIdentifier getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static AuthorityKeyIdentifier getInstance(
+ Object obj)
+ {
+ if (obj instanceof AuthorityKeyIdentifier)
+ {
+ return (AuthorityKeyIdentifier)obj;
+ }
+ if (obj != null)
+ {
+ return new AuthorityKeyIdentifier(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static AuthorityKeyIdentifier fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.authorityKeyIdentifier));
+ }
+
+ protected AuthorityKeyIdentifier(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement());
+
+ switch (o.getTagNo())
+ {
+ case 0:
+ this.keyidentifier = ASN1OctetString.getInstance(o, false);
+ break;
+ case 1:
+ this.certissuer = GeneralNames.getInstance(o, false);
+ break;
+ case 2:
+ this.certserno = ASN1Integer.getInstance(o, false);
+ break;
+ default:
+ throw new IllegalArgumentException("illegal tag");
+ }
+ }
+ }
+
+ /**
+ *
+ * Calulates the keyidentifier using a SHA1 hash over the BIT STRING
+ * from SubjectPublicKeyInfo as defined in RFC2459.
+ *
+ * Example of making a AuthorityKeyIdentifier:
+ * <pre>
+ * SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(
+ * publicKey.getEncoded()).readObject());
+ * AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki);
+ * </pre>
+ * @deprecated create the extension using org.bouncycastle.cert.X509ExtensionUtils
+ **/
+ public AuthorityKeyIdentifier(
+ SubjectPublicKeyInfo spki)
+ {
+ // Android-changed: Use Android digests
+ // Digest digest = new SHA1Digest();
+ Digest digest = AndroidDigestFactory.getSHA1();
+ byte[] resBuf = new byte[digest.getDigestSize()];
+
+ byte[] bytes = spki.getPublicKeyData().getBytes();
+ digest.update(bytes, 0, bytes.length);
+ digest.doFinal(resBuf, 0);
+ this.keyidentifier = new DEROctetString(resBuf);
+ }
+
+ /**
+ * create an AuthorityKeyIdentifier with the GeneralNames tag and
+ * the serial number provided as well.
+ * @deprecated create the extension using org.bouncycastle.cert.X509ExtensionUtils
+ */
+ public AuthorityKeyIdentifier(
+ SubjectPublicKeyInfo spki,
+ GeneralNames name,
+ BigInteger serialNumber)
+ {
+ // Android-changed: Use Android digests
+ // Digest digest = new SHA1Digest();
+ Digest digest = AndroidDigestFactory.getSHA1();
+ byte[] resBuf = new byte[digest.getDigestSize()];
+
+ byte[] bytes = spki.getPublicKeyData().getBytes();
+ digest.update(bytes, 0, bytes.length);
+ digest.doFinal(resBuf, 0);
+
+ this.keyidentifier = new DEROctetString(resBuf);
+ this.certissuer = name;
+ this.certserno = (serialNumber != null) ? new ASN1Integer(serialNumber) : null;
+ }
+
+ /**
+ * create an AuthorityKeyIdentifier with the GeneralNames tag and
+ * the serial number provided.
+ */
+ public AuthorityKeyIdentifier(
+ GeneralNames name,
+ BigInteger serialNumber)
+ {
+ this((byte[])null, name, serialNumber);
+ }
+
+ /**
+ * create an AuthorityKeyIdentifier with a precomputed key identifier
+ */
+ public AuthorityKeyIdentifier(
+ byte[] keyIdentifier)
+ {
+ this(keyIdentifier, null, null);
+ }
+
+ /**
+ * create an AuthorityKeyIdentifier with a precomputed key identifier
+ * and the GeneralNames tag and the serial number provided as well.
+ */
+ public AuthorityKeyIdentifier(
+ byte[] keyIdentifier,
+ GeneralNames name,
+ BigInteger serialNumber)
+ {
+ this.keyidentifier = (keyIdentifier != null) ? new DEROctetString(keyIdentifier) : null;
+ this.certissuer = name;
+ this.certserno = (serialNumber != null) ? new ASN1Integer(serialNumber) : null;
+ }
+
+ public byte[] getKeyIdentifier()
+ {
+ if (keyidentifier != null)
+ {
+ return keyidentifier.getOctets();
+ }
+
+ return null;
+ }
+
+ public GeneralNames getAuthorityCertIssuer()
+ {
+ return certissuer;
+ }
+
+ public BigInteger getAuthorityCertSerialNumber()
+ {
+ if (certserno != null)
+ {
+ return certserno.getValue();
+ }
+
+ return null;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ if (keyidentifier != null)
+ {
+ v.add(new DERTaggedObject(false, 0, keyidentifier));
+ }
+
+ if (certissuer != null)
+ {
+ v.add(new DERTaggedObject(false, 1, certissuer));
+ }
+
+ if (certserno != null)
+ {
+ v.add(new DERTaggedObject(false, 2, certserno));
+ }
+
+ return new DERSequence(v);
+ }
+
+ public String toString()
+ {
+ String keyID = (keyidentifier != null) ? Hex.toHexString(keyidentifier.getOctets()) : "null";
+
+ return "AuthorityKeyIdentifier: KeyID(" + keyID + ")";
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/BasicConstraints.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/BasicConstraints.java
new file mode 100644
index 00000000..54cb6b78
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/BasicConstraints.java
@@ -0,0 +1,163 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Boolean;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BasicConstraints
+ extends ASN1Object
+{
+ ASN1Boolean cA = ASN1Boolean.getInstance(false);
+ ASN1Integer pathLenConstraint = null;
+
+ public static BasicConstraints getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static BasicConstraints getInstance(
+ Object obj)
+ {
+ if (obj instanceof BasicConstraints)
+ {
+ return (BasicConstraints)obj;
+ }
+ if (obj instanceof X509Extension)
+ {
+ return getInstance(X509Extension.convertValueToObject((X509Extension)obj));
+ }
+ if (obj != null)
+ {
+ return new BasicConstraints(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static BasicConstraints fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.basicConstraints));
+ }
+
+ private BasicConstraints(
+ ASN1Sequence seq)
+ {
+ if (seq.size() == 0)
+ {
+ this.cA = null;
+ this.pathLenConstraint = null;
+ }
+ else
+ {
+ if (seq.getObjectAt(0) instanceof ASN1Boolean)
+ {
+ this.cA = ASN1Boolean.getInstance(seq.getObjectAt(0));
+ }
+ else
+ {
+ this.cA = null;
+ this.pathLenConstraint = ASN1Integer.getInstance(seq.getObjectAt(0));
+ }
+ if (seq.size() > 1)
+ {
+ if (this.cA != null)
+ {
+ this.pathLenConstraint = ASN1Integer.getInstance(seq.getObjectAt(1));
+ }
+ else
+ {
+ throw new IllegalArgumentException("wrong sequence in constructor");
+ }
+ }
+ }
+ }
+
+ public BasicConstraints(
+ boolean cA)
+ {
+ if (cA)
+ {
+ this.cA = ASN1Boolean.getInstance(true);
+ }
+ else
+ {
+ this.cA = null;
+ }
+ this.pathLenConstraint = null;
+ }
+
+ /**
+ * create a cA=true object for the given path length constraint.
+ *
+ * @param pathLenConstraint
+ */
+ public BasicConstraints(
+ int pathLenConstraint)
+ {
+ this.cA = ASN1Boolean.getInstance(true);
+ this.pathLenConstraint = new ASN1Integer(pathLenConstraint);
+ }
+
+ public boolean isCA()
+ {
+ return (cA != null) && cA.isTrue();
+ }
+
+ public BigInteger getPathLenConstraint()
+ {
+ if (pathLenConstraint != null)
+ {
+ return pathLenConstraint.getValue();
+ }
+
+ return null;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * BasicConstraints := SEQUENCE {
+ * cA BOOLEAN DEFAULT FALSE,
+ * pathLenConstraint INTEGER (0..MAX) OPTIONAL
+ * }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ if (cA != null)
+ {
+ v.add(cA);
+ }
+
+ if (pathLenConstraint != null) // yes some people actually do this when cA is false...
+ {
+ v.add(pathLenConstraint);
+ }
+
+ return new DERSequence(v);
+ }
+
+ public String toString()
+ {
+ if (pathLenConstraint == null)
+ {
+ return "BasicConstraints: isCa(" + this.isCA() + ")";
+ }
+ return "BasicConstraints: isCa(" + this.isCA() + "), pathLenConstraint = " + pathLenConstraint.getValue();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLDistPoint.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLDistPoint.java
new file mode 100644
index 00000000..ab7fd7bb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLDistPoint.java
@@ -0,0 +1,102 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CRLDistPoint
+ extends ASN1Object
+{
+ ASN1Sequence seq = null;
+
+ public static CRLDistPoint getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static CRLDistPoint getInstance(
+ Object obj)
+ {
+ if (obj instanceof CRLDistPoint)
+ {
+ return (CRLDistPoint)obj;
+ }
+ else if (obj != null)
+ {
+ return new CRLDistPoint(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static CRLDistPoint fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.cRLDistributionPoints));
+ }
+
+ private CRLDistPoint(
+ ASN1Sequence seq)
+ {
+ this.seq = seq;
+ }
+
+ public CRLDistPoint(
+ DistributionPoint[] points)
+ {
+ seq = new DERSequence(points);
+ }
+
+ /**
+ * Return the distribution points making up the sequence.
+ *
+ * @return DistributionPoint[]
+ */
+ public DistributionPoint[] getDistributionPoints()
+ {
+ DistributionPoint[] dp = new DistributionPoint[seq.size()];
+
+ for (int i = 0; i != seq.size(); i++)
+ {
+ dp[i] = DistributionPoint.getInstance(seq.getObjectAt(i));
+ }
+
+ return dp;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * CRLDistPoint ::= SEQUENCE SIZE {1..MAX} OF DistributionPoint
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return seq;
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String sep = Strings.lineSeparator();
+
+ buf.append("CRLDistPoint:");
+ buf.append(sep);
+ DistributionPoint dp[] = getDistributionPoints();
+ for (int i = 0; i != dp.length; i++)
+ {
+ buf.append(" ");
+ buf.append(dp[i]);
+ buf.append(sep);
+ }
+ return buf.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLNumber.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLNumber.java
new file mode 100644
index 00000000..291bf6c8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLNumber.java
@@ -0,0 +1,56 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * The CRLNumber object.
+ * <pre>
+ * CRLNumber::= INTEGER(0..MAX)
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CRLNumber
+ extends ASN1Object
+{
+ private BigInteger number;
+
+ public CRLNumber(
+ BigInteger number)
+ {
+ this.number = number;
+ }
+
+ public BigInteger getCRLNumber()
+ {
+ return number;
+ }
+
+ public String toString()
+ {
+ return "CRLNumber: " + getCRLNumber();
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new ASN1Integer(number);
+ }
+
+ public static CRLNumber getInstance(Object o)
+ {
+ if (o instanceof CRLNumber)
+ {
+ return (CRLNumber)o;
+ }
+ else if (o != null)
+ {
+ return new CRLNumber(ASN1Integer.getInstance(o).getValue());
+ }
+
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLReason.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLReason.java
new file mode 100644
index 00000000..10552814
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLReason.java
@@ -0,0 +1,153 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.math.BigInteger;
+import java.util.Hashtable;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.util.Integers;
+
+/**
+ * The CRLReason enumeration.
+ * <pre>
+ * CRLReason ::= ENUMERATED {
+ * unspecified (0),
+ * keyCompromise (1),
+ * cACompromise (2),
+ * affiliationChanged (3),
+ * superseded (4),
+ * cessationOfOperation (5),
+ * certificateHold (6),
+ * removeFromCRL (8),
+ * privilegeWithdrawn (9),
+ * aACompromise (10)
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CRLReason
+ extends ASN1Object
+{
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int UNSPECIFIED = 0;
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int KEY_COMPROMISE = 1;
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int CA_COMPROMISE = 2;
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int AFFILIATION_CHANGED = 3;
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int SUPERSEDED = 4;
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int CESSATION_OF_OPERATION = 5;
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int CERTIFICATE_HOLD = 6;
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int REMOVE_FROM_CRL = 8;
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int PRIVILEGE_WITHDRAWN = 9;
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int AA_COMPROMISE = 10;
+
+ public static final int unspecified = 0;
+ public static final int keyCompromise = 1;
+ public static final int cACompromise = 2;
+ public static final int affiliationChanged = 3;
+ public static final int superseded = 4;
+ public static final int cessationOfOperation = 5;
+ public static final int certificateHold = 6;
+ // 7 -> unknown
+ public static final int removeFromCRL = 8;
+ public static final int privilegeWithdrawn = 9;
+ public static final int aACompromise = 10;
+
+ private static final String[] reasonString =
+ {
+ "unspecified", "keyCompromise", "cACompromise", "affiliationChanged",
+ "superseded", "cessationOfOperation", "certificateHold", "unknown",
+ "removeFromCRL", "privilegeWithdrawn", "aACompromise"
+ };
+
+ private static final Hashtable table = new Hashtable();
+
+ private ASN1Enumerated value;
+
+ public static CRLReason getInstance(Object o)
+ {
+ if (o instanceof CRLReason)
+ {
+ return (CRLReason)o;
+ }
+ else if (o != null)
+ {
+ return lookup(ASN1Enumerated.getInstance(o).intValueExact());
+ }
+
+ return null;
+ }
+
+ private CRLReason(
+ int reason)
+ {
+ value = new ASN1Enumerated(reason);
+ }
+
+ public String toString()
+ {
+ String str;
+ int reason = getValue().intValue();
+ if (reason < 0 || reason > 10)
+ {
+ str = "invalid";
+ }
+ else
+ {
+ str = reasonString[reason];
+ }
+ return "CRLReason: " + str;
+ }
+
+ public BigInteger getValue()
+ {
+ return value.getValue();
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return value;
+ }
+
+ public static CRLReason lookup(int value)
+ {
+ Integer idx = Integers.valueOf(value);
+
+ if (!table.containsKey(idx))
+ {
+ table.put(idx, new CRLReason(value));
+ }
+
+ return (CRLReason)table.get(idx);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Certificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Certificate.java
new file mode 100644
index 00000000..667c8349
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Certificate.java
@@ -0,0 +1,133 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+
+/**
+ * an X509Certificate structure.
+ * <pre>
+ * Certificate ::= SEQUENCE {
+ * tbsCertificate TBSCertificate,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Certificate
+ extends ASN1Object
+{
+ ASN1Sequence seq;
+ TBSCertificate tbsCert;
+ AlgorithmIdentifier sigAlgId;
+ DERBitString sig;
+
+ public static Certificate getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static Certificate getInstance(
+ Object obj)
+ {
+ if (obj instanceof Certificate)
+ {
+ return (Certificate)obj;
+ }
+ else if (obj != null)
+ {
+ return new Certificate(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private Certificate(
+ ASN1Sequence seq)
+ {
+ this.seq = seq;
+
+ //
+ // correct x509 certficate
+ //
+ if (seq.size() == 3)
+ {
+ tbsCert = TBSCertificate.getInstance(seq.getObjectAt(0));
+ sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
+
+ sig = DERBitString.getInstance(seq.getObjectAt(2));
+ }
+ else
+ {
+ throw new IllegalArgumentException("sequence wrong size for a certificate");
+ }
+ }
+
+ public TBSCertificate getTBSCertificate()
+ {
+ return tbsCert;
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return tbsCert.getVersion();
+ }
+
+ public int getVersionNumber()
+ {
+ return tbsCert.getVersionNumber();
+ }
+
+ public ASN1Integer getSerialNumber()
+ {
+ return tbsCert.getSerialNumber();
+ }
+
+ public X500Name getIssuer()
+ {
+ return tbsCert.getIssuer();
+ }
+
+ public Time getStartDate()
+ {
+ return tbsCert.getStartDate();
+ }
+
+ public Time getEndDate()
+ {
+ return tbsCert.getEndDate();
+ }
+
+ public X500Name getSubject()
+ {
+ return tbsCert.getSubject();
+ }
+
+ public SubjectPublicKeyInfo getSubjectPublicKeyInfo()
+ {
+ return tbsCert.getSubjectPublicKeyInfo();
+ }
+
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return sigAlgId;
+ }
+
+ public DERBitString getSignature()
+ {
+ return sig;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return seq;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CertificateList.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CertificateList.java
new file mode 100644
index 00000000..218a6237
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CertificateList.java
@@ -0,0 +1,146 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+
+/**
+ * PKIX RFC-2459
+ *
+ * The X.509 v2 CRL syntax is as follows. For signature calculation,
+ * the data that is to be signed is ASN.1 DER encoded.
+ *
+ * <pre>
+ * CertificateList ::= SEQUENCE {
+ * tbsCertList TBSCertList,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signatureValue BIT STRING }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertificateList
+ extends ASN1Object
+{
+ TBSCertList tbsCertList;
+ AlgorithmIdentifier sigAlgId;
+ DERBitString sig;
+ boolean isHashCodeSet = false;
+ int hashCodeValue;
+
+ public static CertificateList getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static CertificateList getInstance(
+ Object obj)
+ {
+ if (obj instanceof CertificateList)
+ {
+ return (CertificateList)obj;
+ }
+ else if (obj != null)
+ {
+ return new CertificateList(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * @deprecated use getInstance() method.
+ * @param seq
+ */
+ public CertificateList(
+ ASN1Sequence seq)
+ {
+ if (seq.size() == 3)
+ {
+ tbsCertList = TBSCertList.getInstance(seq.getObjectAt(0));
+ sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
+ sig = DERBitString.getInstance(seq.getObjectAt(2));
+ }
+ else
+ {
+ throw new IllegalArgumentException("sequence wrong size for CertificateList");
+ }
+ }
+
+ public TBSCertList getTBSCertList()
+ {
+ return tbsCertList;
+ }
+
+ public TBSCertList.CRLEntry[] getRevokedCertificates()
+ {
+ return tbsCertList.getRevokedCertificates();
+ }
+
+ public Enumeration getRevokedCertificateEnumeration()
+ {
+ return tbsCertList.getRevokedCertificateEnumeration();
+ }
+
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return sigAlgId;
+ }
+
+ public DERBitString getSignature()
+ {
+ return sig;
+ }
+
+ public int getVersionNumber()
+ {
+ return tbsCertList.getVersionNumber();
+ }
+
+ public X500Name getIssuer()
+ {
+ return tbsCertList.getIssuer();
+ }
+
+ public Time getThisUpdate()
+ {
+ return tbsCertList.getThisUpdate();
+ }
+
+ public Time getNextUpdate()
+ {
+ return tbsCertList.getNextUpdate();
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(tbsCertList);
+ v.add(sigAlgId);
+ v.add(sig);
+
+ return new DERSequence(v);
+ }
+
+ public int hashCode()
+ {
+ if (!isHashCodeSet)
+ {
+ hashCodeValue = super.hashCode();
+ isHashCodeSet = true;
+ }
+
+ return hashCodeValue;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DSAParameter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DSAParameter.java
new file mode 100644
index 00000000..954ab397
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DSAParameter.java
@@ -0,0 +1,96 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DSAParameter
+ extends ASN1Object
+{
+ ASN1Integer p, q, g;
+
+ public static DSAParameter getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static DSAParameter getInstance(
+ Object obj)
+ {
+ if (obj instanceof DSAParameter)
+ {
+ return (DSAParameter)obj;
+ }
+
+ if(obj != null)
+ {
+ return new DSAParameter(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public DSAParameter(
+ BigInteger p,
+ BigInteger q,
+ BigInteger g)
+ {
+ this.p = new ASN1Integer(p);
+ this.q = new ASN1Integer(q);
+ this.g = new ASN1Integer(g);
+ }
+
+ private DSAParameter(
+ ASN1Sequence seq)
+ {
+ if (seq.size() != 3)
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+
+ Enumeration e = seq.getObjects();
+
+ p = ASN1Integer.getInstance(e.nextElement());
+ q = ASN1Integer.getInstance(e.nextElement());
+ g = ASN1Integer.getInstance(e.nextElement());
+ }
+
+ public BigInteger getP()
+ {
+ return p.getPositiveValue();
+ }
+
+ public BigInteger getQ()
+ {
+ return q.getPositiveValue();
+ }
+
+ public BigInteger getG()
+ {
+ return g.getPositiveValue();
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(p);
+ v.add(q);
+ v.add(g);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DigestInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DigestInfo.java
new file mode 100644
index 00000000..58d4e270
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DigestInfo.java
@@ -0,0 +1,89 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * The DigestInfo object.
+ * <pre>
+ * DigestInfo::=SEQUENCE{
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DigestInfo
+ extends ASN1Object
+{
+ private byte[] digest;
+ private AlgorithmIdentifier algId;
+
+ public static DigestInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static DigestInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof DigestInfo)
+ {
+ return (DigestInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new DigestInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public DigestInfo(
+ AlgorithmIdentifier algId,
+ byte[] digest)
+ {
+ this.digest = Arrays.clone(digest);
+ this.algId = algId;
+ }
+
+ public DigestInfo(
+ ASN1Sequence obj)
+ {
+ Enumeration e = obj.getObjects();
+
+ algId = AlgorithmIdentifier.getInstance(e.nextElement());
+ digest = ASN1OctetString.getInstance(e.nextElement()).getOctets();
+ }
+
+ public AlgorithmIdentifier getAlgorithmId()
+ {
+ return algId;
+ }
+
+ public byte[] getDigest()
+ {
+ return Arrays.clone(digest);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(algId);
+ v.add(new DEROctetString(digest));
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPoint.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPoint.java
new file mode 100644
index 00000000..4d3b786c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPoint.java
@@ -0,0 +1,164 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * The DistributionPoint object.
+ * <pre>
+ * DistributionPoint ::= SEQUENCE {
+ * distributionPoint [0] DistributionPointName OPTIONAL,
+ * reasons [1] ReasonFlags OPTIONAL,
+ * cRLIssuer [2] GeneralNames OPTIONAL
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DistributionPoint
+ extends ASN1Object
+{
+ DistributionPointName distributionPoint;
+ ReasonFlags reasons;
+ GeneralNames cRLIssuer;
+
+ public static DistributionPoint getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static DistributionPoint getInstance(
+ Object obj)
+ {
+ if(obj == null || obj instanceof DistributionPoint)
+ {
+ return (DistributionPoint)obj;
+ }
+
+ if(obj instanceof ASN1Sequence)
+ {
+ return new DistributionPoint((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("Invalid DistributionPoint: " + obj.getClass().getName());
+ }
+
+ public DistributionPoint(
+ ASN1Sequence seq)
+ {
+ for (int i = 0; i != seq.size(); i++)
+ {
+ ASN1TaggedObject t = ASN1TaggedObject.getInstance(seq.getObjectAt(i));
+ switch (t.getTagNo())
+ {
+ case 0:
+ distributionPoint = DistributionPointName.getInstance(t, true);
+ break;
+ case 1:
+ reasons = new ReasonFlags(DERBitString.getInstance(t, false));
+ break;
+ case 2:
+ cRLIssuer = GeneralNames.getInstance(t, false);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown tag encountered in structure: " + t.getTagNo());
+ }
+ }
+ }
+
+ public DistributionPoint(
+ DistributionPointName distributionPoint,
+ ReasonFlags reasons,
+ GeneralNames cRLIssuer)
+ {
+ this.distributionPoint = distributionPoint;
+ this.reasons = reasons;
+ this.cRLIssuer = cRLIssuer;
+ }
+
+ public DistributionPointName getDistributionPoint()
+ {
+ return distributionPoint;
+ }
+
+ public ReasonFlags getReasons()
+ {
+ return reasons;
+ }
+
+ public GeneralNames getCRLIssuer()
+ {
+ return cRLIssuer;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ if (distributionPoint != null)
+ {
+ //
+ // as this is a CHOICE it must be explicitly tagged
+ //
+ v.add(new DERTaggedObject(0, distributionPoint));
+ }
+
+ if (reasons != null)
+ {
+ v.add(new DERTaggedObject(false, 1, reasons));
+ }
+
+ if (cRLIssuer != null)
+ {
+ v.add(new DERTaggedObject(false, 2, cRLIssuer));
+ }
+
+ return new DERSequence(v);
+ }
+
+ public String toString()
+ {
+ String sep = Strings.lineSeparator();
+ StringBuffer buf = new StringBuffer();
+ buf.append("DistributionPoint: [");
+ buf.append(sep);
+ if (distributionPoint != null)
+ {
+ appendObject(buf, sep, "distributionPoint", distributionPoint.toString());
+ }
+ if (reasons != null)
+ {
+ appendObject(buf, sep, "reasons", reasons.toString());
+ }
+ if (cRLIssuer != null)
+ {
+ appendObject(buf, sep, "cRLIssuer", cRLIssuer.toString());
+ }
+ buf.append("]");
+ buf.append(sep);
+ return buf.toString();
+ }
+
+ private void appendObject(StringBuffer buf, String sep, String name, String value)
+ {
+ String indent = " ";
+
+ buf.append(indent);
+ buf.append(name);
+ buf.append(":");
+ buf.append(sep);
+ buf.append(indent);
+ buf.append(indent);
+ buf.append(value);
+ buf.append(sep);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPointName.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPointName.java
new file mode 100644
index 00000000..36154fe0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPointName.java
@@ -0,0 +1,141 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * The DistributionPointName object.
+ * <pre>
+ * DistributionPointName ::= CHOICE {
+ * fullName [0] GeneralNames,
+ * nameRelativeToCRLIssuer [1] RDN
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DistributionPointName
+ extends ASN1Object
+ implements ASN1Choice
+{
+ ASN1Encodable name;
+ int type;
+
+ public static final int FULL_NAME = 0;
+ public static final int NAME_RELATIVE_TO_CRL_ISSUER = 1;
+
+ public static DistributionPointName getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1TaggedObject.getInstance(obj, true));
+ }
+
+ public static DistributionPointName getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DistributionPointName)
+ {
+ return (DistributionPointName)obj;
+ }
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ return new DistributionPointName((ASN1TaggedObject)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
+ }
+
+ public DistributionPointName(
+ int type,
+ ASN1Encodable name)
+ {
+ this.type = type;
+ this.name = name;
+ }
+
+ public DistributionPointName(
+ GeneralNames name)
+ {
+ this(FULL_NAME, name);
+ }
+
+ /**
+ * Return the tag number applying to the underlying choice.
+ *
+ * @return the tag number for this point name.
+ */
+ public int getType()
+ {
+ return this.type;
+ }
+
+ /**
+ * Return the tagged object inside the distribution point name.
+ *
+ * @return the underlying choice item.
+ */
+ public ASN1Encodable getName()
+ {
+ return (ASN1Encodable)name;
+ }
+
+ public DistributionPointName(
+ ASN1TaggedObject obj)
+ {
+ this.type = obj.getTagNo();
+
+ if (type == 0)
+ {
+ this.name = GeneralNames.getInstance(obj, false);
+ }
+ else
+ {
+ this.name = ASN1Set.getInstance(obj, false);
+ }
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new DERTaggedObject(false, type, name);
+ }
+
+ public String toString()
+ {
+ String sep = Strings.lineSeparator();
+ StringBuffer buf = new StringBuffer();
+ buf.append("DistributionPointName: [");
+ buf.append(sep);
+ if (type == FULL_NAME)
+ {
+ appendObject(buf, sep, "fullName", name.toString());
+ }
+ else
+ {
+ appendObject(buf, sep, "nameRelativeToCRLIssuer", name.toString());
+ }
+ buf.append("]");
+ buf.append(sep);
+ return buf.toString();
+ }
+
+ private void appendObject(StringBuffer buf, String sep, String name, String value)
+ {
+ String indent = " ";
+
+ buf.append(indent);
+ buf.append(name);
+ buf.append(":");
+ buf.append(sep);
+ buf.append(indent);
+ buf.append(indent);
+ buf.append(value);
+ buf.append(sep);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java
new file mode 100644
index 00000000..31e60566
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java
@@ -0,0 +1,194 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * The extendedKeyUsage object.
+ * <pre>
+ * extendedKeyUsage ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ExtendedKeyUsage
+ extends ASN1Object
+{
+ Hashtable usageTable = new Hashtable();
+ ASN1Sequence seq;
+
+ /**
+ * Return an ExtendedKeyUsage from the passed in tagged object.
+ *
+ * @param obj the tagged object containing the ExtendedKeyUsage
+ * @param explicit true if the tagged object should be interpreted as explicitly tagged, false if implicit.
+ * @return the ExtendedKeyUsage contained.
+ */
+ public static ExtendedKeyUsage getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return an ExtendedKeyUsage from the passed in object.
+ *
+ * @param obj an ExtendedKeyUsage, some form or encoding of one, or null.
+ * @return an ExtendedKeyUsage object, or null if null is passed in.
+ */
+ public static ExtendedKeyUsage getInstance(
+ Object obj)
+ {
+ if (obj instanceof ExtendedKeyUsage)
+ {
+ return (ExtendedKeyUsage)obj;
+ }
+ else if (obj != null)
+ {
+ return new ExtendedKeyUsage(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * Retrieve an ExtendedKeyUsage for a passed in Extensions object, if present.
+ *
+ * @param extensions the extensions object to be examined.
+ * @return the ExtendedKeyUsage, null if the extension is not present.
+ */
+ public static ExtendedKeyUsage fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.extendedKeyUsage));
+ }
+
+ /**
+ * Base constructor, from a single KeyPurposeId.
+ *
+ * @param usage the keyPurposeId to be included.
+ */
+ public ExtendedKeyUsage(
+ KeyPurposeId usage)
+ {
+ this.seq = new DERSequence(usage);
+
+ this.usageTable.put(usage, usage);
+ }
+
+ private ExtendedKeyUsage(
+ ASN1Sequence seq)
+ {
+ this.seq = seq;
+
+ Enumeration e = seq.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ ASN1Encodable o = (ASN1Encodable)e.nextElement();
+ if (!(o.toASN1Primitive() instanceof ASN1ObjectIdentifier))
+ {
+ throw new IllegalArgumentException("Only ASN1ObjectIdentifiers allowed in ExtendedKeyUsage.");
+ }
+ this.usageTable.put(o, o);
+ }
+ }
+
+ /**
+ * Base constructor, from multiple KeyPurposeIds.
+ *
+ * @param usages an array of KeyPurposeIds.
+ */
+ public ExtendedKeyUsage(
+ KeyPurposeId[] usages)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(usages.length);
+
+ for (int i = 0; i != usages.length; i++)
+ {
+ v.add(usages[i]);
+ this.usageTable.put(usages[i], usages[i]);
+ }
+
+ this.seq = new DERSequence(v);
+ }
+
+ /**
+ * @deprecated use KeyPurposeId[] constructor.
+ */
+ public ExtendedKeyUsage(
+ Vector usages)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(usages.size());
+
+ Enumeration e = usages.elements();
+ while (e.hasMoreElements())
+ {
+ KeyPurposeId o = KeyPurposeId.getInstance(e.nextElement());
+
+ v.add(o);
+ this.usageTable.put(o, o);
+ }
+
+ this.seq = new DERSequence(v);
+ }
+
+ /**
+ * Return true if this ExtendedKeyUsage object contains the passed in keyPurposeId.
+ *
+ * @param keyPurposeId the KeyPurposeId of interest.
+ * @return true if the keyPurposeId is present, false otherwise.
+ */
+ public boolean hasKeyPurposeId(
+ KeyPurposeId keyPurposeId)
+ {
+ return (usageTable.get(keyPurposeId) != null);
+ }
+
+ /**
+ * Returns all extended key usages.
+ *
+ * @return An array with all key purposes.
+ */
+ public KeyPurposeId[] getUsages()
+ {
+ KeyPurposeId[] temp = new KeyPurposeId[seq.size()];
+
+ int i = 0;
+ for (Enumeration it = seq.getObjects(); it.hasMoreElements();)
+ {
+ temp[i++] = KeyPurposeId.getInstance(it.nextElement());
+ }
+ return temp;
+ }
+
+ /**
+ * Return the number of KeyPurposeIds present in this ExtendedKeyUsage.
+ *
+ * @return the number of KeyPurposeIds
+ */
+ public int size()
+ {
+ return usageTable.size();
+ }
+
+ /**
+ * Return the ASN.1 primitive form of this object.
+ *
+ * @return an ASN1Sequence.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return seq;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extension.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extension.java
new file mode 100644
index 00000000..548f9302
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extension.java
@@ -0,0 +1,367 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Boolean;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * an object for the elements in the X.509 V3 extension block.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Extension
+ extends ASN1Object
+{
+ /**
+ * Subject Directory Attributes
+ */
+ public static final ASN1ObjectIdentifier subjectDirectoryAttributes = new ASN1ObjectIdentifier("2.5.29.9").intern();
+
+ /**
+ * Subject Key Identifier
+ */
+ public static final ASN1ObjectIdentifier subjectKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.14").intern();
+
+ /**
+ * Key Usage
+ */
+ public static final ASN1ObjectIdentifier keyUsage = new ASN1ObjectIdentifier("2.5.29.15").intern();
+
+ /**
+ * Private Key Usage Period
+ */
+ public static final ASN1ObjectIdentifier privateKeyUsagePeriod = new ASN1ObjectIdentifier("2.5.29.16").intern();
+
+ /**
+ * Subject Alternative Name
+ */
+ public static final ASN1ObjectIdentifier subjectAlternativeName = new ASN1ObjectIdentifier("2.5.29.17").intern();
+
+ /**
+ * Issuer Alternative Name
+ */
+ public static final ASN1ObjectIdentifier issuerAlternativeName = new ASN1ObjectIdentifier("2.5.29.18").intern();
+
+ /**
+ * Basic Constraints
+ */
+ public static final ASN1ObjectIdentifier basicConstraints = new ASN1ObjectIdentifier("2.5.29.19").intern();
+
+ /**
+ * CRL Number
+ */
+ public static final ASN1ObjectIdentifier cRLNumber = new ASN1ObjectIdentifier("2.5.29.20").intern();
+
+ /**
+ * Reason code
+ */
+ public static final ASN1ObjectIdentifier reasonCode = new ASN1ObjectIdentifier("2.5.29.21").intern();
+
+ /**
+ * Hold Instruction Code
+ */
+ public static final ASN1ObjectIdentifier instructionCode = new ASN1ObjectIdentifier("2.5.29.23").intern();
+
+ /**
+ * Invalidity Date
+ */
+ public static final ASN1ObjectIdentifier invalidityDate = new ASN1ObjectIdentifier("2.5.29.24").intern();
+
+ /**
+ * Delta CRL indicator
+ */
+ public static final ASN1ObjectIdentifier deltaCRLIndicator = new ASN1ObjectIdentifier("2.5.29.27").intern();
+
+ /**
+ * Issuing Distribution Point
+ */
+ public static final ASN1ObjectIdentifier issuingDistributionPoint = new ASN1ObjectIdentifier("2.5.29.28").intern();
+
+ /**
+ * Certificate Issuer
+ */
+ public static final ASN1ObjectIdentifier certificateIssuer = new ASN1ObjectIdentifier("2.5.29.29").intern();
+
+ /**
+ * Name Constraints
+ */
+ public static final ASN1ObjectIdentifier nameConstraints = new ASN1ObjectIdentifier("2.5.29.30").intern();
+
+ /**
+ * CRL Distribution Points
+ */
+ public static final ASN1ObjectIdentifier cRLDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31").intern();
+
+ /**
+ * Certificate Policies
+ */
+ public static final ASN1ObjectIdentifier certificatePolicies = new ASN1ObjectIdentifier("2.5.29.32").intern();
+
+ /**
+ * Policy Mappings
+ */
+ public static final ASN1ObjectIdentifier policyMappings = new ASN1ObjectIdentifier("2.5.29.33").intern();
+
+ /**
+ * Authority Key Identifier
+ */
+ public static final ASN1ObjectIdentifier authorityKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.35").intern();
+
+ /**
+ * Policy Constraints
+ */
+ public static final ASN1ObjectIdentifier policyConstraints = new ASN1ObjectIdentifier("2.5.29.36").intern();
+
+ /**
+ * Extended Key Usage
+ */
+ public static final ASN1ObjectIdentifier extendedKeyUsage = new ASN1ObjectIdentifier("2.5.29.37").intern();
+
+ /**
+ * Freshest CRL
+ */
+ public static final ASN1ObjectIdentifier freshestCRL = new ASN1ObjectIdentifier("2.5.29.46").intern();
+
+ /**
+ * Inhibit Any Policy
+ */
+ public static final ASN1ObjectIdentifier inhibitAnyPolicy = new ASN1ObjectIdentifier("2.5.29.54").intern();
+
+ /**
+ * Authority Info Access
+ */
+ public static final ASN1ObjectIdentifier authorityInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.1").intern();
+
+ /**
+ * Subject Info Access
+ */
+ public static final ASN1ObjectIdentifier subjectInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.11").intern();
+
+ /**
+ * Logo Type
+ */
+ public static final ASN1ObjectIdentifier logoType = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.12").intern();
+
+ /**
+ * BiometricInfo
+ */
+ public static final ASN1ObjectIdentifier biometricInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.2").intern();
+
+ /**
+ * QCStatements
+ */
+ public static final ASN1ObjectIdentifier qCStatements = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.3").intern();
+
+ /**
+ * Audit identity extension in attribute certificates.
+ */
+ public static final ASN1ObjectIdentifier auditIdentity = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.4").intern();
+
+ /**
+ * NoRevAvail extension in attribute certificates.
+ */
+ public static final ASN1ObjectIdentifier noRevAvail = new ASN1ObjectIdentifier("2.5.29.56").intern();
+
+ /**
+ * TargetInformation extension in attribute certificates.
+ */
+ public static final ASN1ObjectIdentifier targetInformation = new ASN1ObjectIdentifier("2.5.29.55").intern();
+
+ /**
+ * Expired Certificates on CRL extension
+ */
+ public static final ASN1ObjectIdentifier expiredCertsOnCRL = new ASN1ObjectIdentifier("2.5.29.60").intern();
+
+ private ASN1ObjectIdentifier extnId;
+ private boolean critical;
+ private ASN1OctetString value;
+
+ /**
+ * Constructor using an ASN1Boolean and an OCTET STRING for the value.
+ *
+ * @param extnId the OID associated with this extension.
+ * @param critical will evaluate to true if the extension is critical, false otherwise.
+ * @param value the extension's value wrapped in an OCTET STRING.
+ */
+ public Extension(
+ ASN1ObjectIdentifier extnId,
+ ASN1Boolean critical,
+ ASN1OctetString value)
+ {
+ this(extnId, critical.isTrue(), value);
+ }
+
+ /**
+ * Constructor using a byte[] for the value.
+ *
+ * @param extnId the OID associated with this extension.
+ * @param critical true if the extension is critical, false otherwise.
+ * @param value the extension's value as a byte[] to be wrapped in an OCTET STRING.
+ */
+ public Extension(
+ ASN1ObjectIdentifier extnId,
+ boolean critical,
+ byte[] value)
+ {
+ this(extnId, critical, new DEROctetString(value));
+ }
+
+ /**
+ * Constructor using an OCTET STRING for the value.
+ *
+ * @param extnId the OID associated with this extension.
+ * @param critical true if the extension is critical, false otherwise.
+ * @param value the extension's value wrapped in an OCTET STRING.
+ */
+ public Extension(
+ ASN1ObjectIdentifier extnId,
+ boolean critical,
+ ASN1OctetString value)
+ {
+ this.extnId = extnId;
+ this.critical = critical;
+ this.value = value;
+ }
+
+ /**
+ * Helper method to create an extension from any ASN.1 encodable object.
+ *
+ * @param extnId the OID associated with this extension.
+ * @param critical true if the extension is critical, false otherwise.
+ * @param value the value to be encoded into the extension's OCTET STRING.
+ * @return a new Extension with the encoding of value in the bytes of the extension's OCTET STRING.
+ * @throws IOException if the value cannot be encoded into bytes.
+ */
+ public static Extension create(
+ ASN1ObjectIdentifier extnId,
+ boolean critical,
+ ASN1Encodable value)
+ throws IOException
+ {
+ return new Extension(extnId, critical, value.toASN1Primitive().getEncoded());
+ }
+
+ private Extension(ASN1Sequence seq)
+ {
+ if (seq.size() == 2)
+ {
+ this.extnId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+ this.critical = false;
+ this.value = ASN1OctetString.getInstance(seq.getObjectAt(1));
+ }
+ else if (seq.size() == 3)
+ {
+ this.extnId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+ this.critical = ASN1Boolean.getInstance(seq.getObjectAt(1)).isTrue();
+ this.value = ASN1OctetString.getInstance(seq.getObjectAt(2));
+ }
+ else
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+ }
+
+ public static Extension getInstance(Object obj)
+ {
+ if (obj instanceof Extension)
+ {
+ return (Extension)obj;
+ }
+ else if (obj != null)
+ {
+ return new Extension(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1ObjectIdentifier getExtnId()
+ {
+ return extnId;
+ }
+
+ public boolean isCritical()
+ {
+ return critical;
+ }
+
+ public ASN1OctetString getExtnValue()
+ {
+ return value;
+ }
+
+ public ASN1Encodable getParsedValue()
+ {
+ return convertValueToObject(this);
+ }
+
+ public int hashCode()
+ {
+ if (this.isCritical())
+ {
+ return this.getExtnValue().hashCode() ^ this.getExtnId().hashCode();
+ }
+
+ return ~(this.getExtnValue().hashCode() ^ this.getExtnId().hashCode());
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof Extension))
+ {
+ return false;
+ }
+
+ Extension other = (Extension)o;
+
+ return other.getExtnId().equals(this.getExtnId())
+ && other.getExtnValue().equals(this.getExtnValue())
+ && (other.isCritical() == this.isCritical());
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(extnId);
+
+ if (critical)
+ {
+ v.add(ASN1Boolean.getInstance(true));
+ }
+
+ v.add(value);
+
+ return new DERSequence(v);
+ }
+
+ /**
+ * Convert the value of the passed in extension to an object
+ * @param ext the extension to parse
+ * @return the object the value string contains
+ * @exception IllegalArgumentException if conversion is not possible
+ */
+ private static ASN1Primitive convertValueToObject(
+ Extension ext)
+ throws IllegalArgumentException
+ {
+ try
+ {
+ return ASN1Primitive.fromByteArray(ext.getExtnValue().getOctets());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("can't convert extension: " + e);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extensions.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extensions.java
new file mode 100644
index 00000000..0d5cec18
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extensions.java
@@ -0,0 +1,249 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ *
+ * Extension ::= SEQUENCE {
+ * extnId EXTENSION.&amp;id ({ExtensionSet}),
+ * critical BOOLEAN DEFAULT FALSE,
+ * extnValue OCTET STRING }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Extensions
+ extends ASN1Object
+{
+ private Hashtable extensions = new Hashtable();
+ private Vector ordering = new Vector();
+
+ public static Extension getExtension(Extensions extensions, ASN1ObjectIdentifier oid)
+ {
+ return null == extensions ? null : extensions.getExtension(oid);
+ }
+
+ public static ASN1Encodable getExtensionParsedValue(Extensions extensions, ASN1ObjectIdentifier oid)
+ {
+ return null == extensions ? null : extensions.getExtensionParsedValue(oid);
+ }
+
+ public static Extensions getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static Extensions getInstance(
+ Object obj)
+ {
+ if (obj instanceof Extensions)
+ {
+ return (Extensions)obj;
+ }
+ else if (obj != null)
+ {
+ return new Extensions(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * Constructor from ASN1Sequence.
+ * <p>
+ * The extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString)
+ * </p>
+ */
+ private Extensions(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ Extension ext = Extension.getInstance(e.nextElement());
+
+ if (extensions.containsKey(ext.getExtnId()))
+ {
+ throw new IllegalArgumentException("repeated extension found: " + ext.getExtnId());
+ }
+
+ extensions.put(ext.getExtnId(), ext);
+ ordering.addElement(ext.getExtnId());
+ }
+ }
+
+ /**
+ * Base Constructor
+ *
+ * @param extension a single extension.
+ */
+ public Extensions(
+ Extension extension)
+ {
+ this.ordering.addElement(extension.getExtnId());
+ this.extensions.put(extension.getExtnId(), extension);
+ }
+
+ /**
+ * Base Constructor
+ *
+ * @param extensions an array of extensions.
+ */
+ public Extensions(
+ Extension[] extensions)
+ {
+ for (int i = 0; i != extensions.length; i++)
+ {
+ Extension ext = extensions[i];
+
+ this.ordering.addElement(ext.getExtnId());
+ this.extensions.put(ext.getExtnId(), ext);
+ }
+ }
+
+ /**
+ * return an Enumeration of the extension field's object ids.
+ */
+ public Enumeration oids()
+ {
+ return ordering.elements();
+ }
+
+ /**
+ * return the extension represented by the object identifier
+ * passed in.
+ *
+ * @return the extension if it's present, null otherwise.
+ */
+ public Extension getExtension(
+ ASN1ObjectIdentifier oid)
+ {
+ return (Extension)extensions.get(oid);
+ }
+
+ /**
+ * return the parsed value of the extension represented by the object identifier
+ * passed in.
+ *
+ * @return the parsed value of the extension if it's present, null otherwise.
+ */
+ public ASN1Encodable getExtensionParsedValue(ASN1ObjectIdentifier oid)
+ {
+ Extension ext = this.getExtension(oid);
+
+ if (ext != null)
+ {
+ return ext.getParsedValue();
+ }
+
+ return null;
+ }
+
+ /**
+ * <pre>
+ * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ *
+ * Extension ::= SEQUENCE {
+ * extnId EXTENSION.&amp;id ({ExtensionSet}),
+ * critical BOOLEAN DEFAULT FALSE,
+ * extnValue OCTET STRING }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector vec = new ASN1EncodableVector(ordering.size());
+
+ Enumeration e = ordering.elements();
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = (Extension)extensions.get(oid);
+
+ vec.add(ext);
+ }
+
+ return new DERSequence(vec);
+ }
+
+ public boolean equivalent(
+ Extensions other)
+ {
+ if (extensions.size() != other.extensions.size())
+ {
+ return false;
+ }
+
+ Enumeration e1 = extensions.keys();
+
+ while (e1.hasMoreElements())
+ {
+ Object key = e1.nextElement();
+
+ if (!extensions.get(key).equals(other.extensions.get(key)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public ASN1ObjectIdentifier[] getExtensionOIDs()
+ {
+ return toOidArray(ordering);
+ }
+
+ public ASN1ObjectIdentifier[] getNonCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(false);
+ }
+
+ public ASN1ObjectIdentifier[] getCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(true);
+ }
+
+ private ASN1ObjectIdentifier[] getExtensionOIDs(boolean isCritical)
+ {
+ Vector oidVec = new Vector();
+
+ for (int i = 0; i != ordering.size(); i++)
+ {
+ Object oid = ordering.elementAt(i);
+
+ if (((Extension)extensions.get(oid)).isCritical() == isCritical)
+ {
+ oidVec.addElement(oid);
+ }
+ }
+
+ return toOidArray(oidVec);
+ }
+
+ private ASN1ObjectIdentifier[] toOidArray(Vector oidVec)
+ {
+ ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[oidVec.size()];
+
+ for (int i = 0; i != oids.length; i++)
+ {
+ oids[i] = (ASN1ObjectIdentifier)oidVec.elementAt(i);
+ }
+ return oids;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtensionsGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
new file mode 100644
index 00000000..7f9db5fa
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
@@ -0,0 +1,201 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Vector;
+
+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.DEROctetString;
+
+/**
+ * Generator for X.509 extensions
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ExtensionsGenerator
+{
+ private Hashtable extensions = new Hashtable();
+ private Vector extOrdering = new Vector();
+
+ /**
+ * Reset the generator
+ */
+ public void reset()
+ {
+ extensions = new Hashtable();
+ extOrdering = new Vector();
+ }
+
+ /**
+ * Add an extension with the given oid and the passed in value to be included
+ * in the OCTET STRING associated with the extension.
+ *
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the ASN.1 object to be included in the extension.
+ */
+ public void addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ ASN1Encodable value)
+ throws IOException
+ {
+ this.addExtension(oid, critical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER));
+ }
+
+ /**
+ * Add an extension with the given oid and the passed in byte array to be wrapped in the
+ * OCTET STRING associated with the extension.
+ *
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the byte array to be wrapped.
+ */
+ public void addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ byte[] value)
+ {
+ if (extensions.containsKey(oid))
+ {
+ throw new IllegalArgumentException("extension " + oid + " already added");
+ }
+
+ extOrdering.addElement(oid);
+ extensions.put(oid, new Extension(oid, critical, new DEROctetString(value)));
+ }
+
+ /**
+ * Add a given extension.
+ *
+ * @param extension the full extension value.
+ */
+ public void addExtension(
+ Extension extension)
+ {
+ if (extensions.containsKey(extension.getExtnId()))
+ {
+ throw new IllegalArgumentException("extension " + extension.getExtnId() + " already added");
+ }
+
+ extOrdering.addElement(extension.getExtnId());
+ extensions.put(extension.getExtnId(), extension);
+ }
+
+ /**
+ * Replace an extension with the given oid and the passed in value to be included
+ * in the OCTET STRING associated with the extension.
+ *
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the ASN.1 object to be included in the extension.
+ */
+ public void replaceExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ ASN1Encodable value)
+ throws IOException
+ {
+ this.replaceExtension(oid, critical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER));
+ }
+
+ /**
+ * Replace an extension with the given oid and the passed in byte array to be wrapped in the
+ * OCTET STRING associated with the extension.
+ *
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the byte array to be wrapped.
+ */
+ public void replaceExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ byte[] value)
+ {
+ this.replaceExtension(new Extension(oid, critical, value));
+ }
+
+ /**
+ * Replace a given extension.
+ *
+ * @param extension the full extension value.
+ */
+ public void replaceExtension(
+ Extension extension)
+ {
+ if (!extensions.containsKey(extension.getExtnId()))
+ {
+ throw new IllegalArgumentException("extension " + extension.getExtnId() + " not present");
+ }
+
+ extensions.put(extension.getExtnId(), extension);
+ }
+
+ /**
+ * Remove a given extension.
+ *
+ * @param oid OID for the extension to remove.
+ */
+ public void removeExtension(
+ ASN1ObjectIdentifier oid)
+ {
+ if (!extensions.containsKey(oid))
+ {
+ throw new IllegalArgumentException("extension " + oid + " not present");
+ }
+
+ extOrdering.removeElement(oid);
+ extensions.remove(oid);
+ }
+
+ /**
+ * 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 extensions.containsKey(oid);
+ }
+
+ /**
+ * 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 (Extension)extensions.get(oid);
+ }
+
+ /**
+ * Return true if there are no extension present in this generator.
+ *
+ * @return true if empty, false otherwise
+ */
+ public boolean isEmpty()
+ {
+ return extOrdering.isEmpty();
+ }
+
+ /**
+ * Generate an Extensions object based on the current state of the generator.
+ *
+ * @return an X09Extensions object.
+ */
+ public Extensions generate()
+ {
+ Extension[] exts = new Extension[extOrdering.size()];
+
+ for (int i = 0; i != extOrdering.size(); i++)
+ {
+ exts[i] = (Extension)extensions.get(extOrdering.elementAt(i));
+ }
+
+ return new Extensions(exts);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralName.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralName.java
new file mode 100644
index 00000000..779009a0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralName.java
@@ -0,0 +1,438 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERIA5String;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.util.IPAddress;
+
+/**
+ * The GeneralName object.
+ * <pre>
+ * GeneralName ::= CHOICE {
+ * otherName [0] OtherName,
+ * rfc822Name [1] IA5String,
+ * dNSName [2] IA5String,
+ * x400Address [3] ORAddress,
+ * directoryName [4] Name,
+ * ediPartyName [5] EDIPartyName,
+ * uniformResourceIdentifier [6] IA5String,
+ * iPAddress [7] OCTET STRING,
+ * registeredID [8] OBJECT IDENTIFIER}
+ *
+ * OtherName ::= SEQUENCE {
+ * type-id OBJECT IDENTIFIER,
+ * value [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ * EDIPartyName ::= SEQUENCE {
+ * nameAssigner [0] DirectoryString OPTIONAL,
+ * partyName [1] DirectoryString }
+ *
+ * Name ::= CHOICE { RDNSequence }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GeneralName
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public static final int otherName = 0;
+ public static final int rfc822Name = 1;
+ public static final int dNSName = 2;
+ public static final int x400Address = 3;
+ public static final int directoryName = 4;
+ public static final int ediPartyName = 5;
+ public static final int uniformResourceIdentifier = 6;
+ public static final int iPAddress = 7;
+ public static final int registeredID = 8;
+
+ private ASN1Encodable obj;
+ private int tag;
+
+ /**
+ * @deprecated use X500Name constructor.
+ * @param dirName
+ */
+ public GeneralName(
+ X509Name dirName)
+ {
+ this.obj = X500Name.getInstance(dirName);
+ this.tag = 4;
+ }
+
+ public GeneralName(
+ X500Name dirName)
+ {
+ this.obj = dirName;
+ this.tag = 4;
+ }
+
+ /**
+ * When the subjectAltName extension contains an Internet mail address,
+ * the address MUST be included as an rfc822Name. The format of an
+ * rfc822Name is an "addr-spec" as defined in RFC 822 [RFC 822].
+ *
+ * When the subjectAltName extension contains a domain name service
+ * label, the domain name MUST be stored in the dNSName (an IA5String).
+ * The name MUST be in the "preferred name syntax," as specified by RFC
+ * 1034 [RFC 1034].
+ *
+ * When the subjectAltName extension contains a URI, the name MUST be
+ * stored in the uniformResourceIdentifier (an IA5String). The name MUST
+ * be a non-relative URL, and MUST follow the URL syntax and encoding
+ * rules specified in [RFC 1738]. The name must include both a scheme
+ * (e.g., "http" or "ftp") and a scheme-specific-part. The scheme-
+ * specific-part must include a fully qualified domain name or IP
+ * address as the host.
+ *
+ * When the subjectAltName extension contains a iPAddress, the address
+ * MUST be stored in the octet string in "network byte order," as
+ * specified in RFC 791 [RFC 791]. The least significant bit (LSB) of
+ * each octet is the LSB of the corresponding byte in the network
+ * address. For IP Version 4, as specified in RFC 791, the octet string
+ * MUST contain exactly four octets. For IP Version 6, as specified in
+ * RFC 1883, the octet string MUST contain exactly sixteen octets [RFC
+ * 1883].
+ */
+ public GeneralName(
+ int tag,
+ ASN1Encodable name)
+ {
+ this.obj = name;
+ this.tag = tag;
+ }
+
+ /**
+ * Create a GeneralName for the given tag from the passed in String.
+ * <p>
+ * This constructor can handle:
+ * <ul>
+ * <li>rfc822Name
+ * <li>iPAddress
+ * <li>directoryName
+ * <li>dNSName
+ * <li>uniformResourceIdentifier
+ * <li>registeredID
+ * </ul>
+ * For x400Address, otherName and ediPartyName there is no common string
+ * format defined.
+ * <p>
+ * Note: A directory name can be encoded in different ways into a byte
+ * representation. Be aware of this if the byte representation is used for
+ * comparing results.
+ *
+ * @param tag tag number
+ * @param name string representation of name
+ * @throws IllegalArgumentException if the string encoding is not correct or * not supported.
+ */
+ public GeneralName(
+ int tag,
+ String name)
+ {
+ this.tag = tag;
+
+ if (tag == rfc822Name || tag == dNSName || tag == uniformResourceIdentifier)
+ {
+ this.obj = new DERIA5String(name);
+ }
+ else if (tag == registeredID)
+ {
+ this.obj = new ASN1ObjectIdentifier(name);
+ }
+ else if (tag == directoryName)
+ {
+ this.obj = new X500Name(name);
+ }
+ else if (tag == iPAddress)
+ {
+ byte[] enc = toGeneralNameEncoding(name);
+ if (enc != null)
+ {
+ this.obj = new DEROctetString(enc);
+ }
+ else
+ {
+ throw new IllegalArgumentException("IP Address is invalid");
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("can't process String for tag: " + tag);
+ }
+ }
+
+ public static GeneralName getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof GeneralName)
+ {
+ return (GeneralName)obj;
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ ASN1TaggedObject tagObj = (ASN1TaggedObject)obj;
+ int tag = tagObj.getTagNo();
+
+ switch (tag)
+ {
+ case ediPartyName:
+ case otherName:
+ case x400Address:
+ return new GeneralName(tag, ASN1Sequence.getInstance(tagObj, false));
+
+ case dNSName:
+ case rfc822Name:
+ case uniformResourceIdentifier:
+ return new GeneralName(tag, DERIA5String.getInstance(tagObj, false));
+
+ case directoryName:
+ return new GeneralName(tag, X500Name.getInstance(tagObj, true));
+ case iPAddress:
+ return new GeneralName(tag, ASN1OctetString.getInstance(tagObj, false));
+ case registeredID:
+ return new GeneralName(tag, ASN1ObjectIdentifier.getInstance(tagObj, false));
+
+ default:
+ throw new IllegalArgumentException("unknown tag: " + tag);
+ }
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return getInstance(ASN1Primitive.fromByteArray((byte[])obj));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to parse encoded general name");
+ }
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
+ }
+
+ public static GeneralName getInstance(
+ ASN1TaggedObject tagObj,
+ boolean explicit)
+ {
+ return GeneralName.getInstance(ASN1TaggedObject.getInstance(tagObj, true));
+ }
+
+ public int getTagNo()
+ {
+ return tag;
+ }
+
+ public ASN1Encodable getName()
+ {
+ return obj;
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+
+ buf.append(tag);
+ buf.append(": ");
+ switch (tag)
+ {
+ case rfc822Name:
+ case dNSName:
+ case uniformResourceIdentifier:
+ buf.append(DERIA5String.getInstance(obj).getString());
+ break;
+ case directoryName:
+ buf.append(X500Name.getInstance(obj).toString());
+ break;
+ default:
+ buf.append(obj.toString());
+ }
+ return buf.toString();
+ }
+
+ private byte[] toGeneralNameEncoding(String ip)
+ {
+ if (IPAddress.isValidIPv6WithNetmask(ip) || IPAddress.isValidIPv6(ip))
+ {
+ int slashIndex = ip.indexOf('/');
+
+ if (slashIndex < 0)
+ {
+ byte[] addr = new byte[16];
+ int[] parsedIp = parseIPv6(ip);
+ copyInts(parsedIp, addr, 0);
+
+ return addr;
+ }
+ else
+ {
+ byte[] addr = new byte[32];
+ int[] parsedIp = parseIPv6(ip.substring(0, slashIndex));
+ copyInts(parsedIp, addr, 0);
+ String mask = ip.substring(slashIndex + 1);
+ if (mask.indexOf(':') > 0)
+ {
+ parsedIp = parseIPv6(mask);
+ }
+ else
+ {
+ parsedIp = parseMask(mask);
+ }
+ copyInts(parsedIp, addr, 16);
+
+ return addr;
+ }
+ }
+ else if (IPAddress.isValidIPv4WithNetmask(ip) || IPAddress.isValidIPv4(ip))
+ {
+ int slashIndex = ip.indexOf('/');
+
+ if (slashIndex < 0)
+ {
+ byte[] addr = new byte[4];
+
+ parseIPv4(ip, addr, 0);
+
+ return addr;
+ }
+ else
+ {
+ byte[] addr = new byte[8];
+
+ parseIPv4(ip.substring(0, slashIndex), addr, 0);
+
+ String mask = ip.substring(slashIndex + 1);
+ if (mask.indexOf('.') > 0)
+ {
+ parseIPv4(mask, addr, 4);
+ }
+ else
+ {
+ parseIPv4Mask(mask, addr, 4);
+ }
+
+ return addr;
+ }
+ }
+
+ return null;
+ }
+
+ private void parseIPv4Mask(String mask, byte[] addr, int offset)
+ {
+ int maskVal = Integer.parseInt(mask);
+
+ for (int i = 0; i != maskVal; i++)
+ {
+ addr[(i / 8) + offset] |= 1 << (7 - (i % 8));
+ }
+ }
+
+ private void parseIPv4(String ip, byte[] addr, int offset)
+ {
+ StringTokenizer sTok = new StringTokenizer(ip, "./");
+ int index = 0;
+
+ while (sTok.hasMoreTokens())
+ {
+ addr[offset + index++] = (byte)Integer.parseInt(sTok.nextToken());
+ }
+ }
+
+ private int[] parseMask(String mask)
+ {
+ int[] res = new int[8];
+ int maskVal = Integer.parseInt(mask);
+
+ for (int i = 0; i != maskVal; i++)
+ {
+ res[i / 16] |= 1 << (15 - (i % 16));
+ }
+ return res;
+ }
+
+ private void copyInts(int[] parsedIp, byte[] addr, int offSet)
+ {
+ for (int i = 0; i != parsedIp.length; i++)
+ {
+ addr[(i * 2) + offSet] = (byte)(parsedIp[i] >> 8);
+ addr[(i * 2 + 1) + offSet] = (byte)parsedIp[i];
+ }
+ }
+
+ private int[] parseIPv6(String ip)
+ {
+ StringTokenizer sTok = new StringTokenizer(ip, ":", true);
+ int index = 0;
+ int[] val = new int[8];
+
+ if (ip.charAt(0) == ':' && ip.charAt(1) == ':')
+ {
+ sTok.nextToken(); // skip the first one
+ }
+
+ int doubleColon = -1;
+
+ while (sTok.hasMoreTokens())
+ {
+ String e = sTok.nextToken();
+
+ if (e.equals(":"))
+ {
+ doubleColon = index;
+ val[index++] = 0;
+ }
+ else
+ {
+ if (e.indexOf('.') < 0)
+ {
+ val[index++] = Integer.parseInt(e, 16);
+ if (sTok.hasMoreTokens())
+ {
+ sTok.nextToken();
+ }
+ }
+ else
+ {
+ StringTokenizer eTok = new StringTokenizer(e, ".");
+
+ val[index++] = (Integer.parseInt(eTok.nextToken()) << 8) | Integer.parseInt(eTok.nextToken());
+ val[index++] = (Integer.parseInt(eTok.nextToken()) << 8) | Integer.parseInt(eTok.nextToken());
+ }
+ }
+ }
+
+ if (index != val.length)
+ {
+ System.arraycopy(val, doubleColon, val, val.length - (index - doubleColon), index - doubleColon);
+ for (int i = doubleColon; i != val.length - (index - doubleColon); i++)
+ {
+ val[i] = 0;
+ }
+ }
+
+ return val;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ // directoryName is explicitly tagged as it is a CHOICE
+ boolean explicit = (tag == directoryName);
+
+ return new DERTaggedObject(explicit, tag, obj);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralNames.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralNames.java
new file mode 100644
index 00000000..6b6a7ce1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralNames.java
@@ -0,0 +1,116 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GeneralNames
+ extends ASN1Object
+{
+ private final GeneralName[] names;
+
+ private static GeneralName[] copy(GeneralName[] names)
+ {
+ GeneralName[] result = new GeneralName[names.length];
+ System.arraycopy(names, 0, result, 0, names.length);
+ return result;
+ }
+
+ public static GeneralNames getInstance(
+ Object obj)
+ {
+ if (obj instanceof GeneralNames)
+ {
+ return (GeneralNames)obj;
+ }
+
+ if (obj != null)
+ {
+ return new GeneralNames(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static GeneralNames getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return new GeneralNames(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static GeneralNames fromExtensions(Extensions extensions, ASN1ObjectIdentifier extOID)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, extOID));
+ }
+
+ /**
+ * Construct a GeneralNames object containing one GeneralName.
+ *
+ * @param name the name to be contained.
+ */
+ public GeneralNames(
+ GeneralName name)
+ {
+ this.names = new GeneralName[] { name };
+ }
+
+
+ public GeneralNames(
+ GeneralName[] names)
+ {
+ this.names = copy(names);
+ }
+
+ private GeneralNames(
+ ASN1Sequence seq)
+ {
+ this.names = new GeneralName[seq.size()];
+
+ for (int i = 0; i != seq.size(); i++)
+ {
+ names[i] = GeneralName.getInstance(seq.getObjectAt(i));
+ }
+ }
+
+ public GeneralName[] getNames()
+ {
+ return copy(names);
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * GeneralNames ::= SEQUENCE SIZE {1..MAX} OF GeneralName
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new DERSequence(names);
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String sep = Strings.lineSeparator();
+
+ buf.append("GeneralNames:");
+ buf.append(sep);
+
+ for (int i = 0; i != names.length; i++)
+ {
+ buf.append(" ");
+ buf.append(names[i]);
+ buf.append(sep);
+ }
+ return buf.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralSubtree.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralSubtree.java
new file mode 100644
index 00000000..64773c66
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralSubtree.java
@@ -0,0 +1,220 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * Class for containing a restriction object subtrees in NameConstraints. See
+ * RFC 3280.
+ *
+ * <pre>
+ *
+ * GeneralSubtree ::= SEQUENCE
+ * {
+ * base GeneralName,
+ * minimum [0] BaseDistance DEFAULT 0,
+ * maximum [1] BaseDistance OPTIONAL
+ * }
+ * </pre>
+ *
+ * @see com.android.internal.org.bouncycastle.asn1.x509.NameConstraints
+ * @hide This class is not part of the Android public SDK API
+ *
+ */
+public class GeneralSubtree
+ extends ASN1Object
+{
+ private static final BigInteger ZERO = BigInteger.valueOf(0);
+
+ private GeneralName base;
+
+ private ASN1Integer minimum;
+
+ private ASN1Integer maximum;
+
+ private GeneralSubtree(
+ ASN1Sequence seq)
+ {
+ base = GeneralName.getInstance(seq.getObjectAt(0));
+
+ switch (seq.size())
+ {
+ case 1:
+ break;
+ case 2:
+ ASN1TaggedObject o = ASN1TaggedObject.getInstance(seq.getObjectAt(1));
+ switch (o.getTagNo())
+ {
+ case 0:
+ minimum = ASN1Integer.getInstance(o, false);
+ break;
+ case 1:
+ maximum = ASN1Integer.getInstance(o, false);
+ break;
+ default:
+ throw new IllegalArgumentException("Bad tag number: "
+ + o.getTagNo());
+ }
+ break;
+ case 3:
+ {
+ {
+ ASN1TaggedObject oMin = ASN1TaggedObject.getInstance(seq.getObjectAt(1));
+ if (oMin.getTagNo() != 0)
+ {
+ throw new IllegalArgumentException("Bad tag number for 'minimum': " + oMin.getTagNo());
+ }
+ minimum = ASN1Integer.getInstance(oMin, false);
+ }
+
+ {
+ ASN1TaggedObject oMax = ASN1TaggedObject.getInstance(seq.getObjectAt(2));
+ if (oMax.getTagNo() != 1)
+ {
+ throw new IllegalArgumentException("Bad tag number for 'maximum': " + oMax.getTagNo());
+ }
+ maximum = ASN1Integer.getInstance(oMax, false);
+ }
+
+ break;
+ }
+ default:
+ throw new IllegalArgumentException("Bad sequence size: "
+ + seq.size());
+ }
+ }
+
+ /**
+ * Constructor from a given details.
+ *
+ * According RFC 3280, the minimum and maximum fields are not used with any
+ * name forms, thus minimum MUST be zero, and maximum MUST be absent.
+ * <p>
+ * If minimum is <code>null</code>, zero is assumed, if
+ * maximum is <code>null</code>, maximum is absent.
+ *
+ * @param base
+ * A restriction.
+ * @param minimum
+ * Minimum
+ *
+ * @param maximum
+ * Maximum
+ */
+ public GeneralSubtree(
+ GeneralName base,
+ BigInteger minimum,
+ BigInteger maximum)
+ {
+ this.base = base;
+ if (maximum != null)
+ {
+ this.maximum = new ASN1Integer(maximum);
+ }
+ if (minimum == null)
+ {
+ this.minimum = null;
+ }
+ else
+ {
+ this.minimum = new ASN1Integer(minimum);
+ }
+ }
+
+ public GeneralSubtree(GeneralName base)
+ {
+ this(base, null, null);
+ }
+
+ public static GeneralSubtree getInstance(
+ ASN1TaggedObject o,
+ boolean explicit)
+ {
+ return new GeneralSubtree(ASN1Sequence.getInstance(o, explicit));
+ }
+
+ public static GeneralSubtree getInstance(
+ Object obj)
+ {
+ if (obj == null)
+ {
+ return null;
+ }
+
+ if (obj instanceof GeneralSubtree)
+ {
+ return (GeneralSubtree) obj;
+ }
+
+ return new GeneralSubtree(ASN1Sequence.getInstance(obj));
+ }
+
+ public GeneralName getBase()
+ {
+ return base;
+ }
+
+ public BigInteger getMinimum()
+ {
+ if (minimum == null)
+ {
+ return ZERO;
+ }
+
+ return minimum.getValue();
+ }
+
+ public BigInteger getMaximum()
+ {
+ if (maximum == null)
+ {
+ return null;
+ }
+
+ return maximum.getValue();
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ *
+ * Returns:
+ *
+ * <pre>
+ * GeneralSubtree ::= SEQUENCE
+ * {
+ * base GeneralName,
+ * minimum [0] BaseDistance DEFAULT 0,
+ * maximum [1] BaseDistance OPTIONAL
+ * }
+ * </pre>
+ *
+ * @return a ASN1Primitive
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(base);
+
+ if (minimum != null && !minimum.hasValue(ZERO))
+ {
+ v.add(new DERTaggedObject(false, 0, minimum));
+ }
+
+ if (maximum != null)
+ {
+ v.add(new DERTaggedObject(false, 1, maximum));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Holder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Holder.java
new file mode 100644
index 00000000..9a4eed12
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Holder.java
@@ -0,0 +1,247 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * The Holder object.
+ * <p>
+ * For an v2 attribute certificate this is:
+ *
+ * <pre>
+ * Holder ::= SEQUENCE {
+ * baseCertificateID [0] IssuerSerial OPTIONAL,
+ * -- the issuer and serial number of
+ * -- the holder's Public Key Certificate
+ * entityName [1] GeneralNames OPTIONAL,
+ * -- the name of the claimant or role
+ * objectDigestInfo [2] ObjectDigestInfo OPTIONAL
+ * -- used to directly authenticate the holder,
+ * -- for example, an executable
+ * }
+ * </pre>
+ *
+ * <p>
+ * For an v1 attribute certificate this is:
+ *
+ * <pre>
+ * subject CHOICE {
+ * baseCertificateID [0] EXPLICIT IssuerSerial,
+ * -- associated with a Public Key Certificate
+ * subjectName [1] EXPLICIT GeneralNames },
+ * -- associated with a name
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Holder
+ extends ASN1Object
+{
+ public static final int V1_CERTIFICATE_HOLDER = 0;
+ public static final int V2_CERTIFICATE_HOLDER = 1;
+
+ IssuerSerial baseCertificateID;
+
+ GeneralNames entityName;
+
+ ObjectDigestInfo objectDigestInfo;
+
+ private int version = V2_CERTIFICATE_HOLDER;
+
+ public static Holder getInstance(Object obj)
+ {
+ if (obj instanceof Holder)
+ {
+ return (Holder)obj;
+ }
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ return new Holder(ASN1TaggedObject.getInstance(obj));
+ }
+ else if (obj != null)
+ {
+ return new Holder(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * Constructor for a holder for an V1 attribute certificate.
+ *
+ * @param tagObj The ASN.1 tagged holder object.
+ */
+ private Holder(ASN1TaggedObject tagObj)
+ {
+ switch (tagObj.getTagNo())
+ {
+ case 0:
+ baseCertificateID = IssuerSerial.getInstance(tagObj, true);
+ break;
+ case 1:
+ entityName = GeneralNames.getInstance(tagObj, true);
+ break;
+ default:
+ throw new IllegalArgumentException("unknown tag in Holder");
+ }
+ version = 0;
+ }
+
+ /**
+ * Constructor for a holder for an V2 attribute certificate.
+ *
+ * @param seq The ASN.1 sequence.
+ */
+ private Holder(ASN1Sequence seq)
+ {
+ if (seq.size() > 3)
+ {
+ throw new IllegalArgumentException("Bad sequence size: "
+ + seq.size());
+ }
+
+ for (int i = 0; i != seq.size(); i++)
+ {
+ ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(seq
+ .getObjectAt(i));
+
+ switch (tObj.getTagNo())
+ {
+ case 0:
+ baseCertificateID = IssuerSerial.getInstance(tObj, false);
+ break;
+ case 1:
+ entityName = GeneralNames.getInstance(tObj, false);
+ break;
+ case 2:
+ objectDigestInfo = ObjectDigestInfo.getInstance(tObj, false);
+ break;
+ default:
+ throw new IllegalArgumentException("unknown tag in Holder");
+ }
+ }
+ version = 1;
+ }
+
+ public Holder(IssuerSerial baseCertificateID)
+ {
+ this(baseCertificateID, V2_CERTIFICATE_HOLDER);
+ }
+
+ /**
+ * Constructs a holder from a IssuerSerial for a V1 or V2 certificate.
+ * .
+ * @param baseCertificateID The IssuerSerial.
+ * @param version The version of the attribute certificate.
+ */
+ public Holder(IssuerSerial baseCertificateID, int version)
+ {
+ this.baseCertificateID = baseCertificateID;
+ this.version = version;
+ }
+
+ /**
+ * Returns 1 for V2 attribute certificates or 0 for V1 attribute
+ * certificates.
+ * @return The version of the attribute certificate.
+ */
+ public int getVersion()
+ {
+ return version;
+ }
+
+ /**
+ * Constructs a holder with an entityName for V2 attribute certificates.
+ *
+ * @param entityName The entity or subject name.
+ */
+ public Holder(GeneralNames entityName)
+ {
+ this(entityName, V2_CERTIFICATE_HOLDER);
+ }
+
+ /**
+ * Constructs a holder with an entityName for V2 attribute certificates or
+ * with a subjectName for V1 attribute certificates.
+ *
+ * @param entityName The entity or subject name.
+ * @param version The version of the attribute certificate.
+ */
+ public Holder(GeneralNames entityName, int version)
+ {
+ this.entityName = entityName;
+ this.version = version;
+ }
+
+ /**
+ * Constructs a holder from an object digest info.
+ *
+ * @param objectDigestInfo The object digest info object.
+ */
+ public Holder(ObjectDigestInfo objectDigestInfo)
+ {
+ this.objectDigestInfo = objectDigestInfo;
+ }
+
+ public IssuerSerial getBaseCertificateID()
+ {
+ return baseCertificateID;
+ }
+
+ /**
+ * Returns the entityName for an V2 attribute certificate or the subjectName
+ * for an V1 attribute certificate.
+ *
+ * @return The entityname or subjectname.
+ */
+ public GeneralNames getEntityName()
+ {
+ return entityName;
+ }
+
+ public ObjectDigestInfo getObjectDigestInfo()
+ {
+ return objectDigestInfo;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ if (version == 1)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ if (baseCertificateID != null)
+ {
+ v.add(new DERTaggedObject(false, 0, baseCertificateID));
+ }
+
+ if (entityName != null)
+ {
+ v.add(new DERTaggedObject(false, 1, entityName));
+ }
+
+ if (objectDigestInfo != null)
+ {
+ v.add(new DERTaggedObject(false, 2, objectDigestInfo));
+ }
+
+ return new DERSequence(v);
+ }
+ else
+ {
+ if (entityName != null)
+ {
+ return new DERTaggedObject(true, 1, entityName);
+ }
+ else
+ {
+ return new DERTaggedObject(true, 0, baseCertificateID);
+ }
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuerSerial.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuerSerial.java
new file mode 100644
index 00000000..0c5aba5f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuerSerial.java
@@ -0,0 +1,127 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class IssuerSerial
+ extends ASN1Object
+{
+ GeneralNames issuer;
+ ASN1Integer serial;
+ DERBitString issuerUID;
+
+ public static IssuerSerial getInstance(
+ Object obj)
+ {
+ if (obj instanceof IssuerSerial)
+ {
+ return (IssuerSerial)obj;
+ }
+
+ if (obj != null)
+ {
+ return new IssuerSerial(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static IssuerSerial getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ private IssuerSerial(
+ ASN1Sequence seq)
+ {
+ if (seq.size() != 2 && seq.size() != 3)
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+
+ issuer = GeneralNames.getInstance(seq.getObjectAt(0));
+ serial = ASN1Integer.getInstance(seq.getObjectAt(1));
+
+ if (seq.size() == 3)
+ {
+ issuerUID = DERBitString.getInstance(seq.getObjectAt(2));
+ }
+ }
+
+ public IssuerSerial(
+ X500Name issuer,
+ BigInteger serial)
+ {
+ this(new GeneralNames(new GeneralName(issuer)), new ASN1Integer(serial));
+ }
+
+ public IssuerSerial(
+ GeneralNames issuer,
+ BigInteger serial)
+ {
+ this(issuer, new ASN1Integer(serial));
+ }
+
+ public IssuerSerial(
+ GeneralNames issuer,
+ ASN1Integer serial)
+ {
+ this.issuer = issuer;
+ this.serial = serial;
+ }
+
+ public GeneralNames getIssuer()
+ {
+ return issuer;
+ }
+
+ public ASN1Integer getSerial()
+ {
+ return serial;
+ }
+
+ public DERBitString getIssuerUID()
+ {
+ return issuerUID;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * IssuerSerial ::= SEQUENCE {
+ * issuer GeneralNames,
+ * serial CertificateSerialNumber,
+ * issuerUID UniqueIdentifier OPTIONAL
+ * }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ v.add(issuer);
+ v.add(serial);
+
+ if (issuerUID != null)
+ {
+ v.add(issuerUID);
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
new file mode 100644
index 00000000..43d1c23b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
@@ -0,0 +1,277 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Boolean;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * <pre>
+ * IssuingDistributionPoint ::= SEQUENCE {
+ * distributionPoint [0] DistributionPointName OPTIONAL,
+ * onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
+ * onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
+ * onlySomeReasons [3] ReasonFlags OPTIONAL,
+ * indirectCRL [4] BOOLEAN DEFAULT FALSE,
+ * onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class IssuingDistributionPoint
+ extends ASN1Object
+{
+ private DistributionPointName distributionPoint;
+
+ private boolean onlyContainsUserCerts;
+
+ private boolean onlyContainsCACerts;
+
+ private ReasonFlags onlySomeReasons;
+
+ private boolean indirectCRL;
+
+ private boolean onlyContainsAttributeCerts;
+
+ private ASN1Sequence seq;
+
+ public static IssuingDistributionPoint getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static IssuingDistributionPoint getInstance(
+ Object obj)
+ {
+ if (obj instanceof IssuingDistributionPoint)
+ {
+ return (IssuingDistributionPoint)obj;
+ }
+ else if (obj != null)
+ {
+ return new IssuingDistributionPoint(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * Constructor from given details.
+ *
+ * @param distributionPoint
+ * May contain an URI as pointer to most current CRL.
+ * @param onlyContainsUserCerts Covers revocation information for end certificates.
+ * @param onlyContainsCACerts Covers revocation information for CA certificates.
+ *
+ * @param onlySomeReasons
+ * Which revocation reasons does this point cover.
+ * @param indirectCRL
+ * If <code>true</code> then the CRL contains revocation
+ * information about certificates ssued by other CAs.
+ * @param onlyContainsAttributeCerts Covers revocation information for attribute certificates.
+ */
+ public IssuingDistributionPoint(
+ DistributionPointName distributionPoint,
+ boolean onlyContainsUserCerts,
+ boolean onlyContainsCACerts,
+ ReasonFlags onlySomeReasons,
+ boolean indirectCRL,
+ boolean onlyContainsAttributeCerts)
+ {
+ this.distributionPoint = distributionPoint;
+ this.indirectCRL = indirectCRL;
+ this.onlyContainsAttributeCerts = onlyContainsAttributeCerts;
+ this.onlyContainsCACerts = onlyContainsCACerts;
+ this.onlyContainsUserCerts = onlyContainsUserCerts;
+ this.onlySomeReasons = onlySomeReasons;
+
+ ASN1EncodableVector vec = new ASN1EncodableVector(6);
+ if (distributionPoint != null)
+ { // CHOICE item so explicitly tagged
+ vec.add(new DERTaggedObject(true, 0, distributionPoint));
+ }
+ if (onlyContainsUserCerts)
+ {
+ vec.add(new DERTaggedObject(false, 1, ASN1Boolean.getInstance(true)));
+ }
+ if (onlyContainsCACerts)
+ {
+ vec.add(new DERTaggedObject(false, 2, ASN1Boolean.getInstance(true)));
+ }
+ if (onlySomeReasons != null)
+ {
+ vec.add(new DERTaggedObject(false, 3, onlySomeReasons));
+ }
+ if (indirectCRL)
+ {
+ vec.add(new DERTaggedObject(false, 4, ASN1Boolean.getInstance(true)));
+ }
+ if (onlyContainsAttributeCerts)
+ {
+ vec.add(new DERTaggedObject(false, 5, ASN1Boolean.getInstance(true)));
+ }
+
+ seq = new DERSequence(vec);
+ }
+
+ /**
+ * Shorthand Constructor from given details.
+ *
+ * @param distributionPoint
+ * May contain an URI as pointer to most current CRL.
+ * @param indirectCRL
+ * If <code>true</code> then the CRL contains revocation
+ * information about certificates ssued by other CAs.
+ * @param onlyContainsAttributeCerts Covers revocation information for attribute certificates.
+ */
+ public IssuingDistributionPoint(
+ DistributionPointName distributionPoint,
+ boolean indirectCRL,
+ boolean onlyContainsAttributeCerts)
+ {
+ this(distributionPoint, false, false, null, indirectCRL, onlyContainsAttributeCerts);
+ }
+
+ /**
+ * Constructor from ASN1Sequence
+ */
+ private IssuingDistributionPoint(
+ ASN1Sequence seq)
+ {
+ this.seq = seq;
+
+ for (int i = 0; i != seq.size(); i++)
+ {
+ ASN1TaggedObject o = ASN1TaggedObject.getInstance(seq.getObjectAt(i));
+
+ switch (o.getTagNo())
+ {
+ case 0:
+ // CHOICE so explicit
+ distributionPoint = DistributionPointName.getInstance(o, true);
+ break;
+ case 1:
+ onlyContainsUserCerts = ASN1Boolean.getInstance(o, false).isTrue();
+ break;
+ case 2:
+ onlyContainsCACerts = ASN1Boolean.getInstance(o, false).isTrue();
+ break;
+ case 3:
+ onlySomeReasons = new ReasonFlags(ReasonFlags.getInstance(o, false));
+ break;
+ case 4:
+ indirectCRL = ASN1Boolean.getInstance(o, false).isTrue();
+ break;
+ case 5:
+ onlyContainsAttributeCerts = ASN1Boolean.getInstance(o, false).isTrue();
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "unknown tag in IssuingDistributionPoint");
+ }
+ }
+ }
+
+ public boolean onlyContainsUserCerts()
+ {
+ return onlyContainsUserCerts;
+ }
+
+ public boolean onlyContainsCACerts()
+ {
+ return onlyContainsCACerts;
+ }
+
+ public boolean isIndirectCRL()
+ {
+ return indirectCRL;
+ }
+
+ public boolean onlyContainsAttributeCerts()
+ {
+ return onlyContainsAttributeCerts;
+ }
+
+ /**
+ * @return Returns the distributionPoint.
+ */
+ public DistributionPointName getDistributionPoint()
+ {
+ return distributionPoint;
+ }
+
+ /**
+ * @return Returns the onlySomeReasons.
+ */
+ public ReasonFlags getOnlySomeReasons()
+ {
+ return onlySomeReasons;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return seq;
+ }
+
+ public String toString()
+ {
+ String sep = Strings.lineSeparator();
+ StringBuffer buf = new StringBuffer();
+
+ buf.append("IssuingDistributionPoint: [");
+ buf.append(sep);
+ if (distributionPoint != null)
+ {
+ appendObject(buf, sep, "distributionPoint", distributionPoint.toString());
+ }
+ if (onlyContainsUserCerts)
+ {
+ appendObject(buf, sep, "onlyContainsUserCerts", booleanToString(onlyContainsUserCerts));
+ }
+ if (onlyContainsCACerts)
+ {
+ appendObject(buf, sep, "onlyContainsCACerts", booleanToString(onlyContainsCACerts));
+ }
+ if (onlySomeReasons != null)
+ {
+ appendObject(buf, sep, "onlySomeReasons", onlySomeReasons.toString());
+ }
+ if (onlyContainsAttributeCerts)
+ {
+ appendObject(buf, sep, "onlyContainsAttributeCerts", booleanToString(onlyContainsAttributeCerts));
+ }
+ if (indirectCRL)
+ {
+ appendObject(buf, sep, "indirectCRL", booleanToString(indirectCRL));
+ }
+ buf.append("]");
+ buf.append(sep);
+ return buf.toString();
+ }
+
+ private void appendObject(StringBuffer buf, String sep, String name, String value)
+ {
+ String indent = " ";
+
+ buf.append(indent);
+ buf.append(name);
+ buf.append(":");
+ buf.append(sep);
+ buf.append(indent);
+ buf.append(indent);
+ buf.append(value);
+ buf.append(sep);
+ }
+
+ private String booleanToString(boolean value)
+ {
+ return value ? "true" : "false";
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyPurposeId.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyPurposeId.java
new file mode 100644
index 00000000..0aac42b6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyPurposeId.java
@@ -0,0 +1,187 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * The KeyPurposeId object.
+ * <pre>
+ * KeyPurposeId ::= OBJECT IDENTIFIER
+ *
+ * id-kp ::= OBJECT IDENTIFIER { iso(1) identified-organization(3)
+ * dod(6) internet(1) security(5) mechanisms(5) pkix(7) 3}
+ *
+ * </pre>
+ * To create a new KeyPurposeId where none of the below suit, use
+ * <pre>
+ * ASN1ObjectIdentifier newKeyPurposeIdOID = new ASN1ObjectIdentifier("1.3.6.1...");
+ *
+ * KeyPurposeId newKeyPurposeId = KeyPurposeId.getInstance(newKeyPurposeIdOID);
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyPurposeId
+ extends ASN1Object
+{
+ private static final ASN1ObjectIdentifier id_kp = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.3");
+
+ /**
+ * { 2 5 29 37 0 }
+ */
+ public static final KeyPurposeId anyExtendedKeyUsage = new KeyPurposeId(Extension.extendedKeyUsage.branch("0"));
+
+ /**
+ * { id-kp 1 }
+ */
+ public static final KeyPurposeId id_kp_serverAuth = new KeyPurposeId(id_kp.branch("1"));
+ /**
+ * { id-kp 2 }
+ */
+ public static final KeyPurposeId id_kp_clientAuth = new KeyPurposeId(id_kp.branch("2"));
+ /**
+ * { id-kp 3 }
+ */
+ public static final KeyPurposeId id_kp_codeSigning = new KeyPurposeId(id_kp.branch("3"));
+ /**
+ * { id-kp 4 }
+ */
+ public static final KeyPurposeId id_kp_emailProtection = new KeyPurposeId(id_kp.branch("4"));
+ /**
+ * Usage deprecated by RFC4945 - was { id-kp 5 }
+ */
+ public static final KeyPurposeId id_kp_ipsecEndSystem = new KeyPurposeId(id_kp.branch("5"));
+ /**
+ * Usage deprecated by RFC4945 - was { id-kp 6 }
+ */
+ public static final KeyPurposeId id_kp_ipsecTunnel = new KeyPurposeId(id_kp.branch("6"));
+ /**
+ * Usage deprecated by RFC4945 - was { idkp 7 }
+ */
+ public static final KeyPurposeId id_kp_ipsecUser = new KeyPurposeId(id_kp.branch("7"));
+ /**
+ * { id-kp 8 }
+ */
+ public static final KeyPurposeId id_kp_timeStamping = new KeyPurposeId(id_kp.branch("8"));
+ /**
+ * { id-kp 9 }
+ */
+ public static final KeyPurposeId id_kp_OCSPSigning = new KeyPurposeId(id_kp.branch("9"));
+ /**
+ * { id-kp 10 }
+ */
+ public static final KeyPurposeId id_kp_dvcs = new KeyPurposeId(id_kp.branch("10"));
+ /**
+ * { id-kp 11 }
+ */
+ public static final KeyPurposeId id_kp_sbgpCertAAServerAuth = new KeyPurposeId(id_kp.branch("11"));
+ /**
+ * { id-kp 12 }
+ */
+ public static final KeyPurposeId id_kp_scvp_responder = new KeyPurposeId(id_kp.branch("12"));
+ /**
+ * { id-kp 13 }
+ */
+ public static final KeyPurposeId id_kp_eapOverPPP = new KeyPurposeId(id_kp.branch("13"));
+ /**
+ * { id-kp 14 }
+ */
+ public static final KeyPurposeId id_kp_eapOverLAN = new KeyPurposeId(id_kp.branch("14"));
+ /**
+ * { id-kp 15 }
+ */
+ public static final KeyPurposeId id_kp_scvpServer = new KeyPurposeId(id_kp.branch("15"));
+ /**
+ * { id-kp 16 }
+ */
+ public static final KeyPurposeId id_kp_scvpClient = new KeyPurposeId(id_kp.branch("16"));
+ /**
+ * { id-kp 17 }
+ */
+ public static final KeyPurposeId id_kp_ipsecIKE = new KeyPurposeId(id_kp.branch("17"));
+ /**
+ * { id-kp 18 }
+ */
+ public static final KeyPurposeId id_kp_capwapAC = new KeyPurposeId(id_kp.branch("18"));
+ /**
+ * { id-kp 19 }
+ */
+ public static final KeyPurposeId id_kp_capwapWTP = new KeyPurposeId(id_kp.branch("19"));
+
+ //
+ // microsoft key purpose ids
+ //
+ /**
+ * { 1 3 6 1 4 1 311 20 2 2 }
+ */
+ public static final KeyPurposeId id_kp_smartcardlogon = new KeyPurposeId(new ASN1ObjectIdentifier("1.3.6.1.4.1.311.20.2.2"));
+
+
+ /**
+ *
+ */
+ public static final KeyPurposeId id_kp_macAddress = new KeyPurposeId(new ASN1ObjectIdentifier("1.3.6.1.1.1.1.22"));
+
+
+ /**
+ * Microsoft Server Gated Crypto (msSGC) see https://www.alvestrand.no/objectid/1.3.6.1.4.1.311.10.3.3.html
+ */
+ public static final KeyPurposeId id_kp_msSGC = new KeyPurposeId(new ASN1ObjectIdentifier("1.3.6.1.4.1.311.10.3.3"));
+
+ /**
+ * Netscape Server Gated Crypto (nsSGC) see https://www.alvestrand.no/objectid/2.16.840.1.113730.4.1.html
+ */
+ public static final KeyPurposeId id_kp_nsSGC = new KeyPurposeId(new ASN1ObjectIdentifier("2.16.840.1.113730.4.1"));
+
+
+ private ASN1ObjectIdentifier id;
+
+ private KeyPurposeId(ASN1ObjectIdentifier id)
+ {
+ this.id = id;
+ }
+
+ /**
+ * @param id string representation of an OID.
+ * @deprecated use getInstance and an OID or one of the constants above.
+ */
+ public KeyPurposeId(String id)
+ {
+ this(new ASN1ObjectIdentifier(id));
+ }
+
+ public static KeyPurposeId getInstance(Object o)
+ {
+ if (o instanceof KeyPurposeId)
+ {
+ return (KeyPurposeId)o;
+ }
+ else if (o != null)
+ {
+ return new KeyPurposeId(ASN1ObjectIdentifier.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public ASN1ObjectIdentifier toOID()
+ {
+ return id;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return id;
+ }
+
+ public String getId()
+ {
+ return id.getId();
+ }
+
+ public String toString()
+ {
+ return id.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyUsage.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyUsage.java
new file mode 100644
index 00000000..94433bf6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyUsage.java
@@ -0,0 +1,115 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+
+/**
+ * The KeyUsage object.
+ * <pre>
+ * id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
+ *
+ * KeyUsage ::= BIT STRING {
+ * digitalSignature (0),
+ * nonRepudiation (1),
+ * keyEncipherment (2),
+ * dataEncipherment (3),
+ * keyAgreement (4),
+ * keyCertSign (5),
+ * cRLSign (6),
+ * encipherOnly (7),
+ * decipherOnly (8) }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyUsage
+ extends ASN1Object
+{
+ public static final int digitalSignature = (1 << 7);
+ public static final int nonRepudiation = (1 << 6);
+ public static final int keyEncipherment = (1 << 5);
+ public static final int dataEncipherment = (1 << 4);
+ public static final int keyAgreement = (1 << 3);
+ public static final int keyCertSign = (1 << 2);
+ public static final int cRLSign = (1 << 1);
+ public static final int encipherOnly = (1 << 0);
+ public static final int decipherOnly = (1 << 15);
+
+ private DERBitString bitString;
+
+ public static KeyUsage getInstance(Object obj) // needs to be DERBitString for other VMs
+ {
+ if (obj instanceof KeyUsage)
+ {
+ return (KeyUsage)obj;
+ }
+ else if (obj != null)
+ {
+ return new KeyUsage(DERBitString.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static KeyUsage fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.keyUsage));
+ }
+
+ /**
+ * Basic constructor.
+ *
+ * @param usage - the bitwise OR of the Key Usage flags giving the
+ * allowed uses for the key.
+ * e.g. (KeyUsage.keyEncipherment | KeyUsage.dataEncipherment)
+ */
+ public KeyUsage(
+ int usage)
+ {
+ this.bitString = new DERBitString(usage);
+ }
+
+ private KeyUsage(
+ DERBitString bitString)
+ {
+ this.bitString = bitString;
+ }
+
+ /**
+ * Return true if a given usage bit is set, false otherwise.
+ *
+ * @param usages combination of usage flags.
+ * @return true if all bits are set, false otherwise.
+ */
+ public boolean hasUsages(int usages)
+ {
+ return (bitString.intValue() & usages) == usages;
+ }
+
+ public byte[] getBytes()
+ {
+ return bitString.getBytes();
+ }
+
+ public int getPadBits()
+ {
+ return bitString.getPadBits();
+ }
+
+ public String toString()
+ {
+ byte[] data = bitString.getBytes();
+
+ if (data.length == 1)
+ {
+ return "KeyUsage: 0x" + Integer.toHexString(data[0] & 0xff);
+ }
+ return "KeyUsage: 0x" + Integer.toHexString((data[1] & 0xff) << 8 | (data[0] & 0xff));
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return bitString;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/NameConstraintValidator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/NameConstraintValidator.java
new file mode 100644
index 00000000..54ad015d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/NameConstraintValidator.java
@@ -0,0 +1,22 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface NameConstraintValidator
+{
+ void checkPermitted(GeneralName name)
+ throws NameConstraintValidatorException;
+
+ void checkExcluded(GeneralName name)
+ throws NameConstraintValidatorException;
+
+ void intersectPermittedSubtree(GeneralSubtree permitted);
+
+ void intersectPermittedSubtree(GeneralSubtree[] permitted);
+
+ void intersectEmptyPermittedSubtree(int nameType);
+
+ void addExcludedSubtree(GeneralSubtree subtree);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/NameConstraintValidatorException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/NameConstraintValidatorException.java
new file mode 100644
index 00000000..3eb4810b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/NameConstraintValidatorException.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class NameConstraintValidatorException
+ extends Exception
+{
+ public NameConstraintValidatorException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/NameConstraints.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/NameConstraints.java
new file mode 100644
index 00000000..fea0b02e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/NameConstraints.java
@@ -0,0 +1,131 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class NameConstraints
+ extends ASN1Object
+{
+ private GeneralSubtree[] permitted, excluded;
+
+ public static NameConstraints getInstance(Object obj)
+ {
+ if (obj instanceof NameConstraints)
+ {
+ return (NameConstraints)obj;
+ }
+ if (obj != null)
+ {
+ return new NameConstraints(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private NameConstraints(ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+ while (e.hasMoreElements())
+ {
+ ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement());
+ switch (o.getTagNo())
+ {
+ case 0:
+ permitted = createArray(ASN1Sequence.getInstance(o, false));
+ break;
+ case 1:
+ excluded = createArray(ASN1Sequence.getInstance(o, false));
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown tag encountered: " + o.getTagNo());
+ }
+ }
+ }
+
+ /**
+ * Constructor from a given details.
+ *
+ * <p>
+ * permitted and excluded are arrays of GeneralSubtree objects.
+ *
+ * @param permitted
+ * Permitted subtrees
+ * @param excluded
+ * Excludes subtrees
+ */
+ public NameConstraints(
+ GeneralSubtree[] permitted,
+ GeneralSubtree[] excluded)
+ {
+ this.permitted = cloneSubtree(permitted);
+ this.excluded = cloneSubtree(excluded);
+ }
+
+ private GeneralSubtree[] createArray(ASN1Sequence subtree)
+ {
+ GeneralSubtree[] ar = new GeneralSubtree[subtree.size()];
+
+ for (int i = 0; i != ar.length; i++)
+ {
+ ar[i] = GeneralSubtree.getInstance(subtree.getObjectAt(i));
+ }
+
+ return ar;
+ }
+
+ public GeneralSubtree[] getPermittedSubtrees()
+ {
+ return cloneSubtree(permitted);
+ }
+
+ public GeneralSubtree[] getExcludedSubtrees()
+ {
+ return cloneSubtree(excluded);
+ }
+
+ /*
+ * NameConstraints ::= SEQUENCE { permittedSubtrees [0] GeneralSubtrees
+ * OPTIONAL, excludedSubtrees [1] GeneralSubtrees OPTIONAL }
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ if (permitted != null)
+ {
+ v.add(new DERTaggedObject(false, 0, new DERSequence(permitted)));
+ }
+
+ if (excluded != null)
+ {
+ v.add(new DERTaggedObject(false, 1, new DERSequence(excluded)));
+ }
+
+ return new DERSequence(v);
+ }
+
+ private static GeneralSubtree[] cloneSubtree(GeneralSubtree[] subtrees)
+ {
+ if (subtrees != null)
+ {
+ GeneralSubtree[] rv = new GeneralSubtree[subtrees.length];
+
+ System.arraycopy(subtrees, 0, rv, 0, rv.length);
+
+ return rv;
+ }
+
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ObjectDigestInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
new file mode 100644
index 00000000..e174f4c5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
@@ -0,0 +1,192 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * ObjectDigestInfo ASN.1 structure used in v2 attribute certificates.
+ *
+ * <pre>
+ *
+ * ObjectDigestInfo ::= SEQUENCE {
+ * digestedObjectType ENUMERATED {
+ * publicKey (0),
+ * publicKeyCert (1),
+ * otherObjectTypes (2) },
+ * -- otherObjectTypes MUST NOT
+ * -- be used in this profile
+ * otherObjectTypeID OBJECT IDENTIFIER OPTIONAL,
+ * digestAlgorithm AlgorithmIdentifier,
+ * objectDigest BIT STRING
+ * }
+ *
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ *
+ */
+public class ObjectDigestInfo
+ extends ASN1Object
+{
+ /**
+ * The public key is hashed.
+ */
+ public final static int publicKey = 0;
+
+ /**
+ * The public key certificate is hashed.
+ */
+ public final static int publicKeyCert = 1;
+
+ /**
+ * An other object is hashed.
+ */
+ public final static int otherObjectDigest = 2;
+
+ ASN1Enumerated digestedObjectType;
+
+ ASN1ObjectIdentifier otherObjectTypeID;
+
+ AlgorithmIdentifier digestAlgorithm;
+
+ DERBitString objectDigest;
+
+ public static ObjectDigestInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof ObjectDigestInfo)
+ {
+ return (ObjectDigestInfo)obj;
+ }
+
+ if (obj != null)
+ {
+ return new ObjectDigestInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static ObjectDigestInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Constructor from given details.
+ * <p>
+ * If <code>digestedObjectType</code> is not {@link #publicKeyCert} or
+ * {@link #publicKey} <code>otherObjectTypeID</code> must be given,
+ * otherwise it is ignored.
+ *
+ * @param digestedObjectType The digest object type.
+ * @param otherObjectTypeID The object type ID for
+ * <code>otherObjectDigest</code>.
+ * @param digestAlgorithm The algorithm identifier for the hash.
+ * @param objectDigest The hash value.
+ */
+ public ObjectDigestInfo(
+ int digestedObjectType,
+ ASN1ObjectIdentifier otherObjectTypeID,
+ AlgorithmIdentifier digestAlgorithm,
+ byte[] objectDigest)
+ {
+ this.digestedObjectType = new ASN1Enumerated(digestedObjectType);
+ if (digestedObjectType == otherObjectDigest)
+ {
+ this.otherObjectTypeID = otherObjectTypeID;
+ }
+
+ this.digestAlgorithm = digestAlgorithm;
+ this.objectDigest = new DERBitString(objectDigest);
+ }
+
+ private ObjectDigestInfo(
+ ASN1Sequence seq)
+ {
+ if (seq.size() > 4 || seq.size() < 3)
+ {
+ throw new IllegalArgumentException("Bad sequence size: "
+ + seq.size());
+ }
+
+ digestedObjectType = ASN1Enumerated.getInstance(seq.getObjectAt(0));
+
+ int offset = 0;
+
+ if (seq.size() == 4)
+ {
+ otherObjectTypeID = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(1));
+ offset++;
+ }
+
+ digestAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1 + offset));
+
+ objectDigest = DERBitString.getInstance(seq.getObjectAt(2 + offset));
+ }
+
+ public ASN1Enumerated getDigestedObjectType()
+ {
+ return digestedObjectType;
+ }
+
+ public ASN1ObjectIdentifier getOtherObjectTypeID()
+ {
+ return otherObjectTypeID;
+ }
+
+ public AlgorithmIdentifier getDigestAlgorithm()
+ {
+ return digestAlgorithm;
+ }
+
+ public DERBitString getObjectDigest()
+ {
+ return objectDigest;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ *
+ * <pre>
+ *
+ * ObjectDigestInfo ::= SEQUENCE {
+ * digestedObjectType ENUMERATED {
+ * publicKey (0),
+ * publicKeyCert (1),
+ * otherObjectTypes (2) },
+ * -- otherObjectTypes MUST NOT
+ * -- be used in this profile
+ * otherObjectTypeID OBJECT IDENTIFIER OPTIONAL,
+ * digestAlgorithm AlgorithmIdentifier,
+ * objectDigest BIT STRING
+ * }
+ *
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(4);
+
+ v.add(digestedObjectType);
+
+ if (otherObjectTypeID != null)
+ {
+ v.add(otherObjectTypeID);
+ }
+
+ v.add(digestAlgorithm);
+ v.add(objectDigest);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/OtherName.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/OtherName.java
new file mode 100644
index 00000000..098b21f5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/OtherName.java
@@ -0,0 +1,94 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * The OtherName object.
+ * <pre>
+ * OtherName ::= SEQUENCE {
+ * type-id OBJECT IDENTIFIER,
+ * value [0] EXPLICIT ANY DEFINED BY type-id }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OtherName
+ extends ASN1Object
+{
+ private final ASN1ObjectIdentifier typeID;
+ private final ASN1Encodable value;
+
+ /**
+ * OtherName factory method.
+ * @param obj the object used to construct an instance of <code>
+ * OtherName</code>. It must be an instance of <code>OtherName
+ * </code> or <code>ASN1Sequence</code>.
+ * @return the instance of <code>OtherName</code> built from the
+ * supplied object.
+ * @throws java.lang.IllegalArgumentException if the object passed
+ * to the factory is not an instance of <code>OtherName</code> or something that
+ * can be converted into an appropriate <code>ASN1Sequence</code>.
+ */
+ public static OtherName getInstance(
+ Object obj)
+ {
+
+ if (obj instanceof OtherName)
+ {
+ return (OtherName)obj;
+ }
+ else if (obj != null)
+ {
+ return new OtherName(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * Base constructor.
+ * @param typeID the type of the other name.
+ * @param value the ANY object that represents the value.
+ */
+ public OtherName(
+ ASN1ObjectIdentifier typeID,
+ ASN1Encodable value)
+ {
+ this.typeID = typeID;
+ this.value = value;
+ }
+
+ private OtherName(ASN1Sequence seq)
+ {
+ this.typeID = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+ this.value = ASN1TaggedObject.getInstance(seq.getObjectAt(1)).getObject(); // explicitly tagged
+ }
+
+ public ASN1ObjectIdentifier getTypeID()
+ {
+ return typeID;
+ }
+
+ public ASN1Encodable getValue()
+ {
+ return value;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(typeID);
+ v.add(new DERTaggedObject(true, 0, value));
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
new file mode 100644
index 00000000..70c7a58e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
@@ -0,0 +1,2167 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERIA5String;
+import com.android.internal.org.bouncycastle.asn1.x500.RDN;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x500.style.IETFUtils;
+import com.android.internal.org.bouncycastle.asn1.x500.style.RFC4519Style;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Integers;
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKIXNameConstraintValidator
+ implements NameConstraintValidator
+{
+ private Set excludedSubtreesDN = new HashSet();
+
+ private Set excludedSubtreesDNS = new HashSet();
+
+ private Set excludedSubtreesEmail = new HashSet();
+
+ private Set excludedSubtreesURI = new HashSet();
+
+ private Set excludedSubtreesIP = new HashSet();
+
+ private Set excludedSubtreesOtherName = new HashSet();
+
+ private Set permittedSubtreesDN;
+
+ private Set permittedSubtreesDNS;
+
+ private Set permittedSubtreesEmail;
+
+ private Set permittedSubtreesURI;
+
+ private Set permittedSubtreesIP;
+
+ private Set permittedSubtreesOtherName;
+
+ public PKIXNameConstraintValidator()
+ {
+ }
+
+ /**
+ * Checks if the given GeneralName is in the permitted set.
+ *
+ * @param name The GeneralName
+ * @throws NameConstraintValidatorException If the <code>name</code>
+ */
+ public void checkPermitted(GeneralName name)
+ throws NameConstraintValidatorException
+ {
+ switch (name.getTagNo())
+ {
+ case GeneralName.otherName:
+ checkPermittedOtherName(permittedSubtreesOtherName, OtherName.getInstance(name.getName()));
+ break;
+ case GeneralName.rfc822Name:
+ checkPermittedEmail(permittedSubtreesEmail, extractNameAsString(name));
+ break;
+ case GeneralName.dNSName:
+ checkPermittedDNS(permittedSubtreesDNS, extractNameAsString(name));
+ break;
+ case GeneralName.directoryName:
+ checkPermittedDN(X500Name.getInstance(name.getName()));
+ break;
+ case GeneralName.uniformResourceIdentifier:
+ checkPermittedURI(permittedSubtreesURI, extractNameAsString(name));
+ break;
+ case GeneralName.iPAddress:
+ checkPermittedIP(permittedSubtreesIP, ASN1OctetString.getInstance(name.getName()).getOctets());
+ break;
+ default:
+ // other tags to be ignored.
+ }
+ }
+
+ /**
+ * Check if the given GeneralName is contained in the excluded set.
+ *
+ * @param name The GeneralName.
+ * @throws NameConstraintValidatorException If the <code>name</code> is
+ * excluded.
+ */
+ public void checkExcluded(GeneralName name)
+ throws NameConstraintValidatorException
+ {
+ switch (name.getTagNo())
+ {
+ case GeneralName.otherName:
+ checkExcludedOtherName(excludedSubtreesOtherName, OtherName.getInstance(name.getName()));
+ break;
+ case GeneralName.rfc822Name:
+ checkExcludedEmail(excludedSubtreesEmail, extractNameAsString(name));
+ break;
+ case GeneralName.dNSName:
+ checkExcludedDNS(excludedSubtreesDNS, extractNameAsString(name));
+ break;
+ case GeneralName.directoryName:
+ checkExcludedDN(X500Name.getInstance(name.getName()));
+ break;
+ case GeneralName.uniformResourceIdentifier:
+ checkExcludedURI(excludedSubtreesURI, extractNameAsString(name));
+ break;
+ case GeneralName.iPAddress:
+ checkExcludedIP(excludedSubtreesIP, ASN1OctetString.getInstance(name.getName()).getOctets());
+ break;
+ default:
+ // other tags to be ignored.
+ }
+ }
+
+ public void intersectPermittedSubtree(GeneralSubtree permitted)
+ {
+ intersectPermittedSubtree(new GeneralSubtree[]{permitted});
+ }
+
+ /**
+ * Updates the permitted set of these name constraints with the intersection
+ * with the given subtree.
+ *
+ * @param permitted The permitted subtrees
+ */
+ public void intersectPermittedSubtree(GeneralSubtree[] permitted)
+ {
+ Map subtreesMap = new HashMap();
+
+ // group in sets in a map ordered by tag no.
+ for (int i = 0; i != permitted.length; i++)
+ {
+ GeneralSubtree subtree = permitted[i];
+ Integer tagNo = Integers.valueOf(subtree.getBase().getTagNo());
+ if (subtreesMap.get(tagNo) == null)
+ {
+ subtreesMap.put(tagNo, new HashSet());
+ }
+ ((Set)subtreesMap.get(tagNo)).add(subtree);
+ }
+
+ for (Iterator it = subtreesMap.entrySet().iterator(); it.hasNext();)
+ {
+ Map.Entry entry = (Map.Entry)it.next();
+
+ // go through all subtree groups
+ int nameType = ((Integer)entry.getKey()).intValue();
+ switch (nameType)
+ {
+ case GeneralName.otherName:
+ permittedSubtreesOtherName = intersectOtherName(permittedSubtreesOtherName,
+ (Set)entry.getValue());
+ break;
+ case GeneralName.rfc822Name:
+ permittedSubtreesEmail = intersectEmail(permittedSubtreesEmail,
+ (Set)entry.getValue());
+ break;
+ case GeneralName.dNSName:
+ permittedSubtreesDNS = intersectDNS(permittedSubtreesDNS,
+ (Set)entry.getValue());
+ break;
+ case GeneralName.directoryName:
+ permittedSubtreesDN = intersectDN(permittedSubtreesDN,
+ (Set)entry.getValue());
+ break;
+ case GeneralName.uniformResourceIdentifier:
+ permittedSubtreesURI = intersectURI(permittedSubtreesURI,
+ (Set)entry.getValue());
+ break;
+ case GeneralName.iPAddress:
+ permittedSubtreesIP = intersectIP(permittedSubtreesIP,
+ (Set)entry.getValue());
+ break;
+ default:
+ throw new IllegalStateException("Unknown tag encountered: " + nameType);
+ }
+ }
+ }
+
+ public void intersectEmptyPermittedSubtree(int nameType)
+ {
+ switch (nameType)
+ {
+ case GeneralName.otherName:
+ permittedSubtreesOtherName = new HashSet();
+ break;
+ case GeneralName.rfc822Name:
+ permittedSubtreesEmail = new HashSet();
+ break;
+ case GeneralName.dNSName:
+ permittedSubtreesDNS = new HashSet();
+ break;
+ case GeneralName.directoryName:
+ permittedSubtreesDN = new HashSet();
+ break;
+ case GeneralName.uniformResourceIdentifier:
+ permittedSubtreesURI = new HashSet();
+ break;
+ case GeneralName.iPAddress:
+ permittedSubtreesIP = new HashSet();
+ break;
+ default:
+ throw new IllegalStateException("Unknown tag encountered: " + nameType);
+ }
+ }
+
+ /**
+ * Adds a subtree to the excluded set of these name constraints.
+ *
+ * @param subtree A subtree with an excluded GeneralName.
+ */
+ public void addExcludedSubtree(GeneralSubtree subtree)
+ {
+ GeneralName base = subtree.getBase();
+
+ switch (base.getTagNo())
+ {
+ case GeneralName.otherName:
+ excludedSubtreesOtherName = unionOtherName(excludedSubtreesOtherName,
+ OtherName.getInstance(base.getName()));
+ break;
+ case GeneralName.rfc822Name:
+ excludedSubtreesEmail = unionEmail(excludedSubtreesEmail,
+ extractNameAsString(base));
+ break;
+ case GeneralName.dNSName:
+ excludedSubtreesDNS = unionDNS(excludedSubtreesDNS,
+ extractNameAsString(base));
+ break;
+ case GeneralName.directoryName:
+ excludedSubtreesDN = unionDN(excludedSubtreesDN,
+ (ASN1Sequence)base.getName().toASN1Primitive());
+ break;
+ case GeneralName.uniformResourceIdentifier:
+ excludedSubtreesURI = unionURI(excludedSubtreesURI,
+ extractNameAsString(base));
+ break;
+ case GeneralName.iPAddress:
+ excludedSubtreesIP = unionIP(excludedSubtreesIP,
+ ASN1OctetString.getInstance(base.getName()).getOctets());
+ break;
+ default:
+ throw new IllegalStateException("Unknown tag encountered: " + base.getTagNo());
+ }
+ }
+
+ public int hashCode()
+ {
+ return hashCollection(excludedSubtreesDN)
+ + hashCollection(excludedSubtreesDNS)
+ + hashCollection(excludedSubtreesEmail)
+ + hashCollection(excludedSubtreesIP)
+ + hashCollection(excludedSubtreesURI)
+ + hashCollection(excludedSubtreesOtherName)
+ + hashCollection(permittedSubtreesDN)
+ + hashCollection(permittedSubtreesDNS)
+ + hashCollection(permittedSubtreesEmail)
+ + hashCollection(permittedSubtreesIP)
+ + hashCollection(permittedSubtreesURI)
+ + hashCollection(permittedSubtreesOtherName);
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof PKIXNameConstraintValidator))
+ {
+ return false;
+ }
+ PKIXNameConstraintValidator constraintValidator = (PKIXNameConstraintValidator)o;
+ return collectionsAreEqual(constraintValidator.excludedSubtreesDN, excludedSubtreesDN)
+ && collectionsAreEqual(constraintValidator.excludedSubtreesDNS, excludedSubtreesDNS)
+ && collectionsAreEqual(constraintValidator.excludedSubtreesEmail, excludedSubtreesEmail)
+ && collectionsAreEqual(constraintValidator.excludedSubtreesIP, excludedSubtreesIP)
+ && collectionsAreEqual(constraintValidator.excludedSubtreesURI, excludedSubtreesURI)
+ && collectionsAreEqual(constraintValidator.excludedSubtreesOtherName, excludedSubtreesOtherName)
+ && collectionsAreEqual(constraintValidator.permittedSubtreesDN, permittedSubtreesDN)
+ && collectionsAreEqual(constraintValidator.permittedSubtreesDNS, permittedSubtreesDNS)
+ && collectionsAreEqual(constraintValidator.permittedSubtreesEmail, permittedSubtreesEmail)
+ && collectionsAreEqual(constraintValidator.permittedSubtreesIP, permittedSubtreesIP)
+ && collectionsAreEqual(constraintValidator.permittedSubtreesURI, permittedSubtreesURI)
+ && collectionsAreEqual(constraintValidator.permittedSubtreesOtherName, permittedSubtreesOtherName);
+ }
+
+ public void checkPermittedDN(X500Name dns)
+ throws NameConstraintValidatorException
+ {
+ checkPermittedDN(permittedSubtreesDN, ASN1Sequence.getInstance(dns.toASN1Primitive()));
+ }
+
+ public void checkExcludedDN(X500Name dns)
+ throws NameConstraintValidatorException
+ {
+ checkExcludedDN(excludedSubtreesDN, ASN1Sequence.getInstance(dns));
+ }
+
+ private static boolean withinDNSubtree(
+ ASN1Sequence dns,
+ ASN1Sequence subtree)
+ {
+ if (subtree.size() < 1)
+ {
+ return false;
+ }
+
+ if (subtree.size() > dns.size())
+ {
+ return false;
+ }
+
+ int start = 0;
+ RDN subtreeRdnStart = RDN.getInstance(subtree.getObjectAt(0));
+ for (int j = 0; j < dns.size(); j++)
+ {
+ start = j;
+ RDN dnsRdn = RDN.getInstance(dns.getObjectAt(j));
+ if (IETFUtils.rDNAreEqual(subtreeRdnStart, dnsRdn))
+ {
+ break;
+ }
+ }
+
+ if (subtree.size() > dns.size() - start)
+ {
+ return false;
+ }
+
+ for (int j = 0; j < subtree.size(); j++)
+ {
+ // both subtree and dns are a ASN.1 Name and the elements are a RDN
+ RDN subtreeRdn = RDN.getInstance(subtree.getObjectAt(j));
+ RDN dnsRdn = RDN.getInstance(dns.getObjectAt(start + j));
+
+ // check if types and values of all naming attributes are matching, other types which are not restricted are allowed, see https://tools.ietf.org/html/rfc5280#section-7.1
+ if (subtreeRdn.size() == dnsRdn.size())
+ {
+ // Two relative distinguished names
+ // RDN1 and RDN2 match if they have the same number of naming attributes
+ // and for each naming attribute in RDN1 there is a matching naming attribute in RDN2.
+ // NOTE: this is checking the attributes in the same order, which might be not necessary, if this is a problem also IETFUtils.rDNAreEqual mus tbe changed.
+ // use new RFC 5280 comparison, NOTE: this is now different from with RFC 3280, where only binary comparison is used
+ // obey RFC 5280 7.1
+ // special treatment of serialNumber for GSMA SGP.22 RSP specification
+ if (!subtreeRdn.getFirst().getType().equals(dnsRdn.getFirst().getType()))
+ {
+ return false;
+ }
+ if (subtreeRdn.size() == 1 && subtreeRdn.getFirst().getType().equals(RFC4519Style.serialNumber))
+ {
+ if (!dnsRdn.getFirst().getValue().toString().startsWith(subtreeRdn.getFirst().getValue().toString()))
+ {
+ return false;
+ }
+ }
+ else if (!IETFUtils.rDNAreEqual(subtreeRdn, dnsRdn))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private void checkPermittedDN(Set permitted, ASN1Sequence dns)
+ throws NameConstraintValidatorException
+ {
+ if (permitted == null)
+ {
+ return;
+ }
+
+ if (permitted.isEmpty() && dns.size() == 0)
+ {
+ return;
+ }
+ Iterator it = permitted.iterator();
+
+ while (it.hasNext())
+ {
+ ASN1Sequence subtree = (ASN1Sequence)it.next();
+
+ if (withinDNSubtree(dns, subtree))
+ {
+ return;
+ }
+ }
+
+ throw new NameConstraintValidatorException(
+ "Subject distinguished name is not from a permitted subtree");
+ }
+
+ private void checkExcludedDN(Set excluded, ASN1Sequence dns)
+ throws NameConstraintValidatorException
+ {
+ if (excluded.isEmpty())
+ {
+ return;
+ }
+
+ Iterator it = excluded.iterator();
+
+ while (it.hasNext())
+ {
+ ASN1Sequence subtree = (ASN1Sequence)it.next();
+
+ if (withinDNSubtree(dns, subtree))
+ {
+ throw new NameConstraintValidatorException(
+ "Subject distinguished name is from an excluded subtree");
+ }
+ }
+ }
+
+ private Set intersectDN(Set permitted, Set dns)
+ {
+ Set intersect = new HashSet();
+ for (Iterator it = dns.iterator(); it.hasNext();)
+ {
+ ASN1Sequence dn = ASN1Sequence.getInstance(((GeneralSubtree)it
+ .next()).getBase().getName().toASN1Primitive());
+ if (permitted == null)
+ {
+ if (dn != null)
+ {
+ intersect.add(dn);
+ }
+ }
+ else
+ {
+ Iterator _iter = permitted.iterator();
+ while (_iter.hasNext())
+ {
+ ASN1Sequence subtree = (ASN1Sequence)_iter.next();
+
+ if (withinDNSubtree(dn, subtree))
+ {
+ intersect.add(dn);
+ }
+ else if (withinDNSubtree(subtree, dn))
+ {
+ intersect.add(subtree);
+ }
+ }
+ }
+ }
+ return intersect;
+ }
+
+ private Set unionDN(Set excluded, ASN1Sequence dn)
+ {
+ if (excluded.isEmpty())
+ {
+ if (dn == null)
+ {
+ return excluded;
+ }
+ excluded.add(dn);
+
+ return excluded;
+ }
+ else
+ {
+ Set intersect = new HashSet();
+
+ Iterator it = excluded.iterator();
+ while (it.hasNext())
+ {
+ ASN1Sequence subtree = ASN1Sequence.getInstance(it.next());
+
+ if (withinDNSubtree(dn, subtree))
+ {
+ intersect.add(subtree);
+ }
+ else if (withinDNSubtree(subtree, dn))
+ {
+ intersect.add(dn);
+ }
+ else
+ {
+ intersect.add(subtree);
+ intersect.add(dn);
+ }
+ }
+
+ return intersect;
+ }
+ }
+
+ private Set intersectOtherName(Set permitted, Set otherNames)
+ {
+ Set intersect = new HashSet();
+ for (Iterator it = otherNames.iterator(); it.hasNext();)
+ {
+ OtherName otName1 = OtherName.getInstance(((GeneralSubtree)it.next()).getBase().getName());
+
+ if (permitted == null)
+ {
+ if (otName1 != null)
+ {
+ intersect.add(otName1);
+ }
+ }
+ else
+ {
+ Iterator it2 = permitted.iterator();
+ while (it2.hasNext())
+ {
+ OtherName otName2 = OtherName.getInstance(it2.next());
+
+ intersectOtherName(otName1, otName2, intersect);
+ }
+ }
+ }
+ return intersect;
+ }
+
+ private void intersectOtherName(OtherName otName1, OtherName otName2, Set intersect)
+ {
+ if (otName1.equals(otName2))
+ {
+ intersect.add(otName1);
+ }
+ }
+
+ private Set unionOtherName(Set permitted, OtherName otherName)
+ {
+ Set union = permitted != null ? new HashSet(permitted) : new HashSet();
+
+ union.add(otherName);
+
+ return union;
+ }
+
+ private Set intersectEmail(Set permitted, Set emails)
+ {
+ Set intersect = new HashSet();
+ for (Iterator it = emails.iterator(); it.hasNext();)
+ {
+ String email = extractNameAsString(((GeneralSubtree)it.next())
+ .getBase());
+
+ if (permitted == null)
+ {
+ if (email != null)
+ {
+ intersect.add(email);
+ }
+ }
+ else
+ {
+ Iterator it2 = permitted.iterator();
+ while (it2.hasNext())
+ {
+ String _permitted = (String)it2.next();
+
+ intersectEmail(email, _permitted, intersect);
+ }
+ }
+ }
+ return intersect;
+ }
+
+ private Set unionEmail(Set excluded, String email)
+ {
+ if (excluded.isEmpty())
+ {
+ if (email == null)
+ {
+ return excluded;
+ }
+ excluded.add(email);
+ return excluded;
+ }
+ else
+ {
+ Set union = new HashSet();
+
+ Iterator it = excluded.iterator();
+ while (it.hasNext())
+ {
+ String _excluded = (String)it.next();
+
+ unionEmail(_excluded, email, union);
+ }
+
+ return union;
+ }
+ }
+
+ /**
+ * Returns the intersection of the permitted IP ranges in
+ * <code>permitted</code> with <code>ip</code>.
+ *
+ * @param permitted A <code>Set</code> of permitted IP addresses with
+ * their subnet mask as byte arrays.
+ * @param ips The IP address with its subnet mask.
+ * @return The <code>Set</code> of permitted IP ranges intersected with
+ * <code>ip</code>.
+ */
+ private Set intersectIP(Set permitted, Set ips)
+ {
+ Set intersect = new HashSet();
+ for (Iterator it = ips.iterator(); it.hasNext();)
+ {
+ byte[] ip = ASN1OctetString.getInstance(
+ ((GeneralSubtree)it.next()).getBase().getName()).getOctets();
+ if (permitted == null)
+ {
+ if (ip != null)
+ {
+ intersect.add(ip);
+ }
+ }
+ else
+ {
+ Iterator it2 = permitted.iterator();
+ while (it2.hasNext())
+ {
+ byte[] _permitted = (byte[])it2.next();
+ intersect.addAll(intersectIPRange(_permitted, ip));
+ }
+ }
+ }
+ return intersect;
+ }
+
+ /**
+ * Returns the union of the excluded IP ranges in <code>excluded</code>
+ * with <code>ip</code>.
+ *
+ * @param excluded A <code>Set</code> of excluded IP addresses with their
+ * subnet mask as byte arrays.
+ * @param ip The IP address with its subnet mask.
+ * @return The <code>Set</code> of excluded IP ranges unified with
+ * <code>ip</code> as byte arrays.
+ */
+ private Set unionIP(Set excluded, byte[] ip)
+ {
+ if (excluded.isEmpty())
+ {
+ if (ip == null)
+ {
+ return excluded;
+ }
+ excluded.add(ip);
+
+ return excluded;
+ }
+ else
+ {
+ Set union = new HashSet();
+
+ Iterator it = excluded.iterator();
+ while (it.hasNext())
+ {
+ byte[] _excluded = (byte[])it.next();
+ union.addAll(unionIPRange(_excluded, ip));
+ }
+
+ return union;
+ }
+ }
+
+ /**
+ * Calculates the union if two IP ranges.
+ *
+ * @param ipWithSubmask1 The first IP address with its subnet mask.
+ * @param ipWithSubmask2 The second IP address with its subnet mask.
+ * @return A <code>Set</code> with the union of both addresses.
+ */
+ private Set unionIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2)
+ {
+ Set set = new HashSet();
+
+ // difficult, adding always all IPs is not wrong
+ if (Arrays.areEqual(ipWithSubmask1, ipWithSubmask2))
+ {
+ set.add(ipWithSubmask1);
+ }
+ else
+ {
+ set.add(ipWithSubmask1);
+ set.add(ipWithSubmask2);
+ }
+ return set;
+ }
+
+ /**
+ * Calculates the intersection if two IP ranges.
+ *
+ * @param ipWithSubmask1 The first IP address with its subnet mask.
+ * @param ipWithSubmask2 The second IP address with its subnet mask.
+ * @return A <code>Set</code> with the single IP address with its subnet
+ * mask as a byte array or an empty <code>Set</code>.
+ */
+ private Set intersectIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2)
+ {
+ if (ipWithSubmask1.length != ipWithSubmask2.length)
+ {
+ return Collections.EMPTY_SET;
+ }
+ byte[][] temp = extractIPsAndSubnetMasks(ipWithSubmask1, ipWithSubmask2);
+ byte ip1[] = temp[0];
+ byte subnetmask1[] = temp[1];
+ byte ip2[] = temp[2];
+ byte subnetmask2[] = temp[3];
+
+ byte minMax[][] = minMaxIPs(ip1, subnetmask1, ip2, subnetmask2);
+ byte[] min;
+ byte[] max;
+ max = min(minMax[1], minMax[3]);
+ min = max(minMax[0], minMax[2]);
+
+ // minimum IP address must be bigger than max
+ if (compareTo(min, max) == 1)
+ {
+ return Collections.EMPTY_SET;
+ }
+ // OR keeps all significant bits
+ byte[] ip = or(minMax[0], minMax[2]);
+ byte[] subnetmask = or(subnetmask1, subnetmask2);
+ return Collections.singleton(ipWithSubnetMask(ip, subnetmask));
+ }
+
+ /**
+ * Concatenates the IP address with its subnet mask.
+ *
+ * @param ip The IP address.
+ * @param subnetMask Its subnet mask.
+ * @return The concatenated IP address with its subnet mask.
+ */
+ private byte[] ipWithSubnetMask(byte[] ip, byte[] subnetMask)
+ {
+ int ipLength = ip.length;
+ byte[] temp = new byte[ipLength * 2];
+ System.arraycopy(ip, 0, temp, 0, ipLength);
+ System.arraycopy(subnetMask, 0, temp, ipLength, ipLength);
+ return temp;
+ }
+
+ /**
+ * Splits the IP addresses and their subnet mask.
+ *
+ * @param ipWithSubmask1 The first IP address with the subnet mask.
+ * @param ipWithSubmask2 The second IP address with the subnet mask.
+ * @return An array with two elements. Each element contains the IP address
+ * and the subnet mask in this order.
+ */
+ private byte[][] extractIPsAndSubnetMasks(
+ byte[] ipWithSubmask1,
+ byte[] ipWithSubmask2)
+ {
+ int ipLength = ipWithSubmask1.length / 2;
+ byte ip1[] = new byte[ipLength];
+ byte subnetmask1[] = new byte[ipLength];
+ System.arraycopy(ipWithSubmask1, 0, ip1, 0, ipLength);
+ System.arraycopy(ipWithSubmask1, ipLength, subnetmask1, 0, ipLength);
+
+ byte ip2[] = new byte[ipLength];
+ byte subnetmask2[] = new byte[ipLength];
+ System.arraycopy(ipWithSubmask2, 0, ip2, 0, ipLength);
+ System.arraycopy(ipWithSubmask2, ipLength, subnetmask2, 0, ipLength);
+ return new byte[][]
+ {ip1, subnetmask1, ip2, subnetmask2};
+ }
+
+ /**
+ * Based on the two IP addresses and their subnet masks the IP range is
+ * computed for each IP address - subnet mask pair and returned as the
+ * minimum IP address and the maximum address of the range.
+ *
+ * @param ip1 The first IP address.
+ * @param subnetmask1 The subnet mask of the first IP address.
+ * @param ip2 The second IP address.
+ * @param subnetmask2 The subnet mask of the second IP address.
+ * @return A array with two elements. The first/second element contains the
+ * min and max IP address of the first/second IP address and its
+ * subnet mask.
+ */
+ private byte[][] minMaxIPs(
+ byte[] ip1,
+ byte[] subnetmask1,
+ byte[] ip2,
+ byte[] subnetmask2)
+ {
+ int ipLength = ip1.length;
+ byte[] min1 = new byte[ipLength];
+ byte[] max1 = new byte[ipLength];
+
+ byte[] min2 = new byte[ipLength];
+ byte[] max2 = new byte[ipLength];
+
+ for (int i = 0; i < ipLength; i++)
+ {
+ min1[i] = (byte)(ip1[i] & subnetmask1[i]);
+ max1[i] = (byte)(ip1[i] & subnetmask1[i] | ~subnetmask1[i]);
+
+ min2[i] = (byte)(ip2[i] & subnetmask2[i]);
+ max2[i] = (byte)(ip2[i] & subnetmask2[i] | ~subnetmask2[i]);
+ }
+
+ return new byte[][]{min1, max1, min2, max2};
+ }
+
+ private void checkPermittedEmail(Set permitted, String email)
+ throws NameConstraintValidatorException
+ {
+ if (permitted == null)
+ {
+ return;
+ }
+
+ Iterator it = permitted.iterator();
+
+ while (it.hasNext())
+ {
+ String str = ((String)it.next());
+
+ if (emailIsConstrained(email, str))
+ {
+ return;
+ }
+ }
+
+ if (email.length() == 0 && permitted.size() == 0)
+ {
+ return;
+ }
+
+ throw new NameConstraintValidatorException(
+ "Subject email address is not from a permitted subtree.");
+ }
+
+ private void checkPermittedOtherName(Set permitted, OtherName name)
+ throws NameConstraintValidatorException
+ {
+ if (permitted == null)
+ {
+ return;
+ }
+
+ Iterator it = permitted.iterator();
+
+ while (it.hasNext())
+ {
+ OtherName str = OtherName.getInstance(it.next());
+
+ if (otherNameIsConstrained(name, str))
+ {
+ return;
+ }
+ }
+
+ throw new NameConstraintValidatorException(
+ "Subject OtherName is not from a permitted subtree.");
+ }
+
+ private void checkExcludedOtherName(Set excluded, OtherName name)
+ throws NameConstraintValidatorException
+ {
+ if (excluded.isEmpty())
+ {
+ return;
+ }
+
+ Iterator it = excluded.iterator();
+
+ while (it.hasNext())
+ {
+ OtherName str = OtherName.getInstance(it.next());
+
+ if (otherNameIsConstrained(name, str))
+ {
+ throw new NameConstraintValidatorException(
+ "OtherName is from an excluded subtree.");
+ }
+ }
+ }
+
+ private void checkExcludedEmail(Set excluded, String email)
+ throws NameConstraintValidatorException
+ {
+ if (excluded.isEmpty())
+ {
+ return;
+ }
+
+ Iterator it = excluded.iterator();
+
+ while (it.hasNext())
+ {
+ String str = (String)it.next();
+
+ if (emailIsConstrained(email, str))
+ {
+ throw new NameConstraintValidatorException(
+ "Email address is from an excluded subtree.");
+ }
+ }
+ }
+
+ /**
+ * Checks if the IP <code>ip</code> is included in the permitted set
+ * <code>permitted</code>.
+ *
+ * @param permitted A <code>Set</code> of permitted IP addresses with
+ * their subnet mask as byte arrays.
+ * @param ip The IP address.
+ * @throws NameConstraintValidatorException if the IP is not permitted.
+ */
+ private void checkPermittedIP(Set permitted, byte[] ip)
+ throws NameConstraintValidatorException
+ {
+ if (permitted == null)
+ {
+ return;
+ }
+
+ Iterator it = permitted.iterator();
+
+ while (it.hasNext())
+ {
+ byte[] ipWithSubnet = (byte[])it.next();
+
+ if (isIPConstrained(ip, ipWithSubnet))
+ {
+ return;
+ }
+ }
+ if (ip.length == 0 && permitted.size() == 0)
+ {
+ return;
+ }
+ throw new NameConstraintValidatorException(
+ "IP is not from a permitted subtree.");
+ }
+
+ /**
+ * Checks if the IP <code>ip</code> is included in the excluded set
+ * <code>excluded</code>.
+ *
+ * @param excluded A <code>Set</code> of excluded IP addresses with their
+ * subnet mask as byte arrays.
+ * @param ip The IP address.
+ * @throws NameConstraintValidatorException if the IP is excluded.
+ */
+ private void checkExcludedIP(Set excluded, byte[] ip)
+ throws NameConstraintValidatorException
+ {
+ if (excluded.isEmpty())
+ {
+ return;
+ }
+
+ Iterator it = excluded.iterator();
+
+ while (it.hasNext())
+ {
+ byte[] ipWithSubnet = (byte[])it.next();
+
+ if (isIPConstrained(ip, ipWithSubnet))
+ {
+ throw new NameConstraintValidatorException(
+ "IP is from an excluded subtree.");
+ }
+ }
+ }
+
+ /**
+ * Checks if the IP address <code>ip</code> is constrained by
+ * <code>constraint</code>.
+ *
+ * @param ip The IP address.
+ * @param constraint The constraint. This is an IP address concatenated with
+ * its subnetmask.
+ * @return <code>true</code> if constrained, <code>false</code>
+ * otherwise.
+ */
+ private boolean isIPConstrained(byte ip[], byte[] constraint)
+ {
+ int ipLength = ip.length;
+
+ if (ipLength != (constraint.length / 2))
+ {
+ return false;
+ }
+
+ byte[] subnetMask = new byte[ipLength];
+ System.arraycopy(constraint, ipLength, subnetMask, 0, ipLength);
+
+ byte[] permittedSubnetAddress = new byte[ipLength];
+
+ byte[] ipSubnetAddress = new byte[ipLength];
+
+ // the resulting IP address by applying the subnet mask
+ for (int i = 0; i < ipLength; i++)
+ {
+ permittedSubnetAddress[i] = (byte)(constraint[i] & subnetMask[i]);
+ ipSubnetAddress[i] = (byte)(ip[i] & subnetMask[i]);
+ }
+
+ return Arrays.areEqual(permittedSubnetAddress, ipSubnetAddress);
+ }
+
+ private boolean otherNameIsConstrained(OtherName name, OtherName constraint)
+ {
+ if (constraint.equals(name))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean emailIsConstrained(String email, String constraint)
+ {
+ String sub = email.substring(email.indexOf('@') + 1);
+ // a particular mailbox
+ if (constraint.indexOf('@') != -1)
+ {
+ if (email.equalsIgnoreCase(constraint))
+ {
+ return true;
+ }
+ if (sub.equalsIgnoreCase(constraint.substring(1)))
+ {
+ return true;
+ }
+ }
+ // on particular host
+ else if (!(constraint.charAt(0) == '.'))
+ {
+ if (sub.equalsIgnoreCase(constraint))
+ {
+ return true;
+ }
+ }
+ // address in sub domain
+ else if (withinDomain(sub, constraint))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean withinDomain(String testDomain, String domain)
+ {
+ String tempDomain = domain;
+ if (tempDomain.startsWith("."))
+ {
+ tempDomain = tempDomain.substring(1);
+ }
+ String[] domainParts = Strings.split(tempDomain, '.');
+ String[] testDomainParts = Strings.split(testDomain, '.');
+ // must have at least one subdomain
+ if (testDomainParts.length <= domainParts.length)
+ {
+ return false;
+ }
+ int d = testDomainParts.length - domainParts.length;
+ for (int i = -1; i < domainParts.length; i++)
+ {
+ if (i == -1)
+ {
+ if (testDomainParts[i + d].equals(""))
+ {
+ return false;
+ }
+ }
+ else if (!domainParts[i].equalsIgnoreCase(testDomainParts[i + d]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void checkPermittedDNS(Set permitted, String dns)
+ throws NameConstraintValidatorException
+ {
+ if (permitted == null)
+ {
+ return;
+ }
+
+ Iterator it = permitted.iterator();
+
+ while (it.hasNext())
+ {
+ String str = ((String)it.next());
+
+ // is sub domain
+ if (withinDomain(dns, str) || dns.equalsIgnoreCase(str))
+ {
+ return;
+ }
+ }
+ if (dns.length() == 0 && permitted.size() == 0)
+ {
+ return;
+ }
+ throw new NameConstraintValidatorException(
+ "DNS is not from a permitted subtree.");
+ }
+
+ private void checkExcludedDNS(Set excluded, String dns)
+ throws NameConstraintValidatorException
+ {
+ if (excluded.isEmpty())
+ {
+ return;
+ }
+
+ Iterator it = excluded.iterator();
+
+ while (it.hasNext())
+ {
+ String str = ((String)it.next());
+
+ // is sub domain or the same
+ if (withinDomain(dns, str) || dns.equalsIgnoreCase(str))
+ {
+ throw new NameConstraintValidatorException(
+ "DNS is from an excluded subtree.");
+ }
+ }
+ }
+
+ /**
+ * The common part of <code>email1</code> and <code>email2</code> is
+ * added to the union <code>union</code>. If <code>email1</code> and
+ * <code>email2</code> have nothing in common they are added both.
+ *
+ * @param email1 Email address constraint 1.
+ * @param email2 Email address constraint 2.
+ * @param union The union.
+ */
+ private void unionEmail(String email1, String email2, Set union)
+ {
+ // email1 is a particular address
+ if (email1.indexOf('@') != -1)
+ {
+ String _sub = email1.substring(email1.indexOf('@') + 1);
+ // both are a particular mailbox
+ if (email2.indexOf('@') != -1)
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(_sub, email2))
+ {
+ union.add(email2);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (_sub.equalsIgnoreCase(email2))
+ {
+ union.add(email2);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ }
+ // email1 specifies a domain
+ else if (email1.startsWith("."))
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email1.indexOf('@') + 1);
+ if (withinDomain(_sub, email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2)
+ || email1.equalsIgnoreCase(email2))
+ {
+ union.add(email2);
+ }
+ else if (withinDomain(email2, email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ else
+ {
+ if (withinDomain(email2, email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ }
+ // email specifies a host
+ else
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email1.indexOf('@') + 1);
+ if (_sub.equalsIgnoreCase(email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2))
+ {
+ union.add(email2);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ }
+ }
+
+ private void unionURI(String email1, String email2, Set union)
+ {
+ // email1 is a particular address
+ if (email1.indexOf('@') != -1)
+ {
+ String _sub = email1.substring(email1.indexOf('@') + 1);
+ // both are a particular mailbox
+ if (email2.indexOf('@') != -1)
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(_sub, email2))
+ {
+ union.add(email2);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (_sub.equalsIgnoreCase(email2))
+ {
+ union.add(email2);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ }
+ // email1 specifies a domain
+ else if (email1.startsWith("."))
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email1.indexOf('@') + 1);
+ if (withinDomain(_sub, email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2)
+ || email1.equalsIgnoreCase(email2))
+ {
+ union.add(email2);
+ }
+ else if (withinDomain(email2, email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ else
+ {
+ if (withinDomain(email2, email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ }
+ // email specifies a host
+ else
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email1.indexOf('@') + 1);
+ if (_sub.equalsIgnoreCase(email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2))
+ {
+ union.add(email2);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ }
+ }
+
+ private Set intersectDNS(Set permitted, Set dnss)
+ {
+ Set intersect = new HashSet();
+ for (Iterator it = dnss.iterator(); it.hasNext();)
+ {
+ String dns = extractNameAsString(((GeneralSubtree)it.next())
+ .getBase());
+ if (permitted == null)
+ {
+ if (dns != null)
+ {
+ intersect.add(dns);
+ }
+ }
+ else
+ {
+ Iterator _iter = permitted.iterator();
+ while (_iter.hasNext())
+ {
+ String _permitted = (String)_iter.next();
+
+ if (withinDomain(_permitted, dns))
+ {
+ intersect.add(_permitted);
+ }
+ else if (withinDomain(dns, _permitted))
+ {
+ intersect.add(dns);
+ }
+ }
+ }
+ }
+
+ return intersect;
+ }
+
+ private Set unionDNS(Set excluded, String dns)
+ {
+ if (excluded.isEmpty())
+ {
+ if (dns == null)
+ {
+ return excluded;
+ }
+ excluded.add(dns);
+
+ return excluded;
+ }
+ else
+ {
+ Set union = new HashSet();
+
+ Iterator _iter = excluded.iterator();
+ while (_iter.hasNext())
+ {
+ String _permitted = (String)_iter.next();
+
+ if (withinDomain(_permitted, dns))
+ {
+ union.add(dns);
+ }
+ else if (withinDomain(dns, _permitted))
+ {
+ union.add(_permitted);
+ }
+ else
+ {
+ union.add(_permitted);
+ union.add(dns);
+ }
+ }
+
+ return union;
+ }
+ }
+
+ /**
+ * The most restricting part from <code>email1</code> and
+ * <code>email2</code> is added to the intersection <code>intersect</code>.
+ *
+ * @param email1 Email address constraint 1.
+ * @param email2 Email address constraint 2.
+ * @param intersect The intersection.
+ */
+ private void intersectEmail(String email1, String email2, Set intersect)
+ {
+ // email1 is a particular address
+ if (email1.indexOf('@') != -1)
+ {
+ String _sub = email1.substring(email1.indexOf('@') + 1);
+ // both are a particular mailbox
+ if (email2.indexOf('@') != -1)
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(_sub, email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (_sub.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ }
+ // email specifies a domain
+ else if (email1.startsWith("."))
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email1.indexOf('@') + 1);
+ if (withinDomain(_sub, email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2)
+ || email1.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ else if (withinDomain(email2, email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ else
+ {
+ if (withinDomain(email2, email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ }
+ // email1 specifies a host
+ else
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email2.indexOf('@') + 1);
+ if (_sub.equalsIgnoreCase(email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ }
+ }
+
+ private void checkExcludedURI(Set excluded, String uri)
+ throws NameConstraintValidatorException
+ {
+ if (excluded.isEmpty())
+ {
+ return;
+ }
+
+ Iterator it = excluded.iterator();
+
+ while (it.hasNext())
+ {
+ String str = ((String)it.next());
+
+ if (isUriConstrained(uri, str))
+ {
+ throw new NameConstraintValidatorException(
+ "URI is from an excluded subtree.");
+ }
+ }
+ }
+
+ private Set intersectURI(Set permitted, Set uris)
+ {
+ Set intersect = new HashSet();
+ for (Iterator it = uris.iterator(); it.hasNext();)
+ {
+ String uri = extractNameAsString(((GeneralSubtree)it.next())
+ .getBase());
+ if (permitted == null)
+ {
+ if (uri != null)
+ {
+ intersect.add(uri);
+ }
+ }
+ else
+ {
+ Iterator _iter = permitted.iterator();
+ while (_iter.hasNext())
+ {
+ String _permitted = (String)_iter.next();
+ intersectURI(_permitted, uri, intersect);
+ }
+ }
+ }
+ return intersect;
+ }
+
+ private Set unionURI(Set excluded, String uri)
+ {
+ if (excluded.isEmpty())
+ {
+ if (uri == null)
+ {
+ return excluded;
+ }
+ excluded.add(uri);
+
+ return excluded;
+ }
+ else
+ {
+ Set union = new HashSet();
+
+ Iterator _iter = excluded.iterator();
+ while (_iter.hasNext())
+ {
+ String _excluded = (String)_iter.next();
+
+ unionURI(_excluded, uri, union);
+ }
+
+ return union;
+ }
+ }
+
+ private void intersectURI(String email1, String email2, Set intersect)
+ {
+ // email1 is a particular address
+ if (email1.indexOf('@') != -1)
+ {
+ String _sub = email1.substring(email1.indexOf('@') + 1);
+ // both are a particular mailbox
+ if (email2.indexOf('@') != -1)
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(_sub, email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (_sub.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ }
+ // email specifies a domain
+ else if (email1.startsWith("."))
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email1.indexOf('@') + 1);
+ if (withinDomain(_sub, email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2)
+ || email1.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ else if (withinDomain(email2, email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ else
+ {
+ if (withinDomain(email2, email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ }
+ // email1 specifies a host
+ else
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email2.indexOf('@') + 1);
+ if (_sub.equalsIgnoreCase(email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ }
+ }
+
+ private void checkPermittedURI(Set permitted, String uri)
+ throws NameConstraintValidatorException
+ {
+ if (permitted == null)
+ {
+ return;
+ }
+
+ Iterator it = permitted.iterator();
+
+ while (it.hasNext())
+ {
+ String str = ((String)it.next());
+
+ if (isUriConstrained(uri, str))
+ {
+ return;
+ }
+ }
+ if (uri.length() == 0 && permitted.size() == 0)
+ {
+ return;
+ }
+ throw new NameConstraintValidatorException(
+ "URI is not from a permitted subtree.");
+ }
+
+ private boolean isUriConstrained(String uri, String constraint)
+ {
+ String host = extractHostFromURL(uri);
+ // a host
+ if (!constraint.startsWith("."))
+ {
+ if (host.equalsIgnoreCase(constraint))
+ {
+ return true;
+ }
+ }
+
+ // in sub domain or domain
+ else if (withinDomain(host, constraint))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private static String extractHostFromURL(String url)
+ {
+ // see RFC 1738
+ // remove ':' after protocol, e.g. http:
+ String sub = url.substring(url.indexOf(':') + 1);
+ // extract host from Common Internet Scheme Syntax, e.g. http://
+ if (sub.indexOf("//") != -1)
+ {
+ sub = sub.substring(sub.indexOf("//") + 2);
+ }
+ // first remove port, e.g. http://test.com:21
+ if (sub.lastIndexOf(':') != -1)
+ {
+ sub = sub.substring(0, sub.lastIndexOf(':'));
+ }
+ // remove user and password, e.g. http://john:password@test.com
+ sub = sub.substring(sub.indexOf(':') + 1);
+ sub = sub.substring(sub.indexOf('@') + 1);
+ // remove local parts, e.g. http://test.com/bla
+ if (sub.indexOf('/') != -1)
+ {
+ sub = sub.substring(0, sub.indexOf('/'));
+ }
+ return sub;
+ }
+
+ private String extractNameAsString(GeneralName name)
+ {
+ return DERIA5String.getInstance(name.getName()).getString();
+ }
+
+ /**
+ * Returns the maximum IP address.
+ *
+ * @param ip1 The first IP address.
+ * @param ip2 The second IP address.
+ * @return The maximum IP address.
+ */
+ private static byte[] max(byte[] ip1, byte[] ip2)
+ {
+ for (int i = 0; i < ip1.length; i++)
+ {
+ if ((ip1[i] & 0xFFFF) > (ip2[i] & 0xFFFF))
+ {
+ return ip1;
+ }
+ }
+ return ip2;
+ }
+
+ /**
+ * Returns the minimum IP address.
+ *
+ * @param ip1 The first IP address.
+ * @param ip2 The second IP address.
+ * @return The minimum IP address.
+ */
+ private static byte[] min(byte[] ip1, byte[] ip2)
+ {
+ for (int i = 0; i < ip1.length; i++)
+ {
+ if ((ip1[i] & 0xFFFF) < (ip2[i] & 0xFFFF))
+ {
+ return ip1;
+ }
+ }
+ return ip2;
+ }
+
+ /**
+ * Compares IP address <code>ip1</code> with <code>ip2</code>. If ip1
+ * is equal to ip2 0 is returned. If ip1 is bigger 1 is returned, -1
+ * otherwise.
+ *
+ * @param ip1 The first IP address.
+ * @param ip2 The second IP address.
+ * @return 0 if ip1 is equal to ip2, 1 if ip1 is bigger, -1 otherwise.
+ */
+ private static int compareTo(byte[] ip1, byte[] ip2)
+ {
+ if (Arrays.areEqual(ip1, ip2))
+ {
+ return 0;
+ }
+ if (Arrays.areEqual(max(ip1, ip2), ip1))
+ {
+ return 1;
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the logical OR of the IP addresses <code>ip1</code> and
+ * <code>ip2</code>.
+ *
+ * @param ip1 The first IP address.
+ * @param ip2 The second IP address.
+ * @return The OR of <code>ip1</code> and <code>ip2</code>.
+ */
+ private static byte[] or(byte[] ip1, byte[] ip2)
+ {
+ byte[] temp = new byte[ip1.length];
+ for (int i = 0; i < ip1.length; i++)
+ {
+ temp[i] = (byte)(ip1[i] | ip2[i]);
+ }
+ return temp;
+ }
+
+ private int hashCollection(Collection coll)
+ {
+ if (coll == null)
+ {
+ return 0;
+ }
+ int hash = 0;
+ Iterator it1 = coll.iterator();
+ while (it1.hasNext())
+ {
+ Object o = it1.next();
+ if (o instanceof byte[])
+ {
+ hash += Arrays.hashCode((byte[])o);
+ }
+ else
+ {
+ hash += o.hashCode();
+ }
+ }
+ return hash;
+ }
+
+ private boolean collectionsAreEqual(Collection coll1, Collection coll2)
+ {
+ if (coll1 == coll2)
+ {
+ return true;
+ }
+ if (coll1 == null || coll2 == null)
+ {
+ return false;
+ }
+ if (coll1.size() != coll2.size())
+ {
+ return false;
+ }
+ Iterator it1 = coll1.iterator();
+
+ while (it1.hasNext())
+ {
+ Object a = it1.next();
+ Iterator it2 = coll2.iterator();
+ boolean found = false;
+ while (it2.hasNext())
+ {
+ Object b = it2.next();
+ if (equals(a, b))
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean equals(Object o1, Object o2)
+ {
+ if (o1 == o2)
+ {
+ return true;
+ }
+ if (o1 == null || o2 == null)
+ {
+ return false;
+ }
+ if (o1 instanceof byte[] && o2 instanceof byte[])
+ {
+ return Arrays.areEqual((byte[])o1, (byte[])o2);
+ }
+ else
+ {
+ return o1.equals(o2);
+ }
+ }
+
+ /**
+ * Stringifies an IPv4 or v6 address with subnet mask.
+ *
+ * @param ip The IP with subnet mask.
+ * @return The stringified IP address.
+ */
+ private String stringifyIP(byte[] ip)
+ {
+ StringBuilder temp = new StringBuilder();
+ for (int i = 0; i < ip.length / 2; i++)
+ {
+ if (temp.length() > 0)
+ {
+ temp.append(".");
+ }
+ temp.append(Integer.toString(ip[i] & 0x00FF));
+ }
+
+ temp.append("/");
+ boolean first = true;
+ for (int i = ip.length / 2; i < ip.length; i++)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ temp.append(".");
+ }
+ temp.append(Integer.toString(ip[i] & 0x00FF));
+ }
+
+ return temp.toString();
+ }
+
+ private String stringifyIPCollection(Set ips)
+ {
+ StringBuilder temp = new StringBuilder();
+ temp.append("[");
+ for (Iterator it = ips.iterator(); it.hasNext();)
+ {
+ if (temp.length() > 1)
+ {
+ temp.append(",");
+ }
+ temp.append(stringifyIP((byte[])it.next()));
+ }
+ temp.append("]");
+ return temp.toString();
+ }
+
+ private String stringifyOtherNameCollection(Set otherNames)
+ {
+ StringBuilder temp = new StringBuilder();
+ temp.append("[");
+ for (Iterator it = otherNames.iterator(); it.hasNext();)
+ {
+ if (temp.length() > 1)
+ {
+ temp.append(",");
+ }
+ OtherName name = OtherName.getInstance(it.next());
+ temp.append(name.getTypeID().getId());
+ temp.append(":");
+ try
+ {
+ temp.append(Hex.toHexString(name.getValue().toASN1Primitive().getEncoded()));
+ }
+ catch (IOException e)
+ {
+ temp.append(e.toString());
+ }
+ }
+ temp.append("]");
+ return temp.toString();
+ }
+
+ private final void addLine(StringBuilder sb, String str)
+ {
+ sb.append(str).append(Strings.lineSeparator());
+ }
+
+ public String toString()
+ {
+ StringBuilder temp = new StringBuilder();
+
+ addLine(temp, "permitted:");
+ if (permittedSubtreesDN != null)
+ {
+ addLine(temp, "DN:");
+ addLine(temp, permittedSubtreesDN.toString());
+ }
+ if (permittedSubtreesDNS != null)
+ {
+ addLine(temp, "DNS:");
+ addLine(temp, permittedSubtreesDNS.toString());
+ }
+ if (permittedSubtreesEmail != null)
+ {
+ addLine(temp, "Email:");
+ addLine(temp, permittedSubtreesEmail.toString());
+ }
+ if (permittedSubtreesURI != null)
+ {
+ addLine(temp, "URI:");
+ addLine(temp, permittedSubtreesURI.toString());
+ }
+ if (permittedSubtreesIP != null)
+ {
+ addLine(temp, "IP:");
+ addLine(temp, stringifyIPCollection(permittedSubtreesIP));
+ }
+ if (permittedSubtreesOtherName != null)
+ {
+ addLine(temp, "OtherName:");
+ addLine(temp, stringifyOtherNameCollection(permittedSubtreesOtherName));
+ }
+ addLine(temp, "excluded:");
+ if (!excludedSubtreesDN.isEmpty())
+ {
+ addLine(temp, "DN:");
+ addLine(temp, excludedSubtreesDN.toString());
+ }
+ if (!excludedSubtreesDNS.isEmpty())
+ {
+ addLine(temp, "DNS:");
+ addLine(temp, excludedSubtreesDNS.toString());
+ }
+ if (!excludedSubtreesEmail.isEmpty())
+ {
+ addLine(temp, "Email:");
+ addLine(temp, excludedSubtreesEmail.toString());
+ }
+ if (!excludedSubtreesURI.isEmpty())
+ {
+ addLine(temp, "URI:");
+ addLine(temp, excludedSubtreesURI.toString());
+ }
+ if (!excludedSubtreesIP.isEmpty())
+ {
+ addLine(temp, "IP:");
+ addLine(temp, stringifyIPCollection(excludedSubtreesIP));
+ }
+ if (!excludedSubtreesOtherName.isEmpty())
+ {
+ addLine(temp, "OtherName:");
+ addLine(temp, stringifyOtherNameCollection(excludedSubtreesOtherName));
+ }
+ return temp.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyConstraints.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyConstraints.java
new file mode 100644
index 00000000..f7224438
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyConstraints.java
@@ -0,0 +1,108 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * PKIX RFC 5280
+ * <pre>
+ * id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
+ *
+ * PolicyConstraints ::= SEQUENCE {
+ * requireExplicitPolicy [0] SkipCerts OPTIONAL,
+ * inhibitPolicyMapping [1] SkipCerts OPTIONAL }
+ *
+ * SkipCerts ::= INTEGER (0..MAX)
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PolicyConstraints
+ extends ASN1Object
+{
+ private BigInteger requireExplicitPolicyMapping;
+ private BigInteger inhibitPolicyMapping;
+
+ public PolicyConstraints(BigInteger requireExplicitPolicyMapping, BigInteger inhibitPolicyMapping)
+ {
+ this.requireExplicitPolicyMapping = requireExplicitPolicyMapping;
+ this.inhibitPolicyMapping = inhibitPolicyMapping;
+ }
+
+ private PolicyConstraints(ASN1Sequence seq)
+ {
+ for (int i = 0; i != seq.size(); i++)
+ {
+ ASN1TaggedObject to = ASN1TaggedObject.getInstance(seq.getObjectAt(i));
+
+ if (to.getTagNo() == 0)
+ {
+ requireExplicitPolicyMapping = ASN1Integer.getInstance(to, false).getValue();
+ }
+ else if (to.getTagNo() == 1)
+ {
+ inhibitPolicyMapping = ASN1Integer.getInstance(to, false).getValue();
+ }
+ else
+ {
+ throw new IllegalArgumentException("Unknown tag encountered.");
+ }
+ }
+ }
+
+ public static PolicyConstraints getInstance(
+ Object obj)
+ {
+ if (obj instanceof PolicyConstraints)
+ {
+ return (PolicyConstraints)obj;
+ }
+
+ if (obj != null)
+ {
+ return new PolicyConstraints(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static PolicyConstraints fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.policyConstraints));
+ }
+
+ public BigInteger getRequireExplicitPolicyMapping()
+ {
+ return requireExplicitPolicyMapping;
+ }
+
+ public BigInteger getInhibitPolicyMapping()
+ {
+ return inhibitPolicyMapping;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ if (requireExplicitPolicyMapping != null)
+ {
+ v.add(new DERTaggedObject(false,0, new ASN1Integer(requireExplicitPolicyMapping)));
+ }
+
+ if (inhibitPolicyMapping != null)
+ {
+ v.add(new DERTaggedObject(false, 1, new ASN1Integer(inhibitPolicyMapping)));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyInformation.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyInformation.java
new file mode 100644
index 00000000..6ef7537f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyInformation.java
@@ -0,0 +1,120 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PolicyInformation
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier policyIdentifier;
+ private ASN1Sequence policyQualifiers;
+
+ private PolicyInformation(
+ ASN1Sequence seq)
+ {
+ if (seq.size() < 1 || seq.size() > 2)
+ {
+ throw new IllegalArgumentException("Bad sequence size: "
+ + seq.size());
+ }
+
+ policyIdentifier = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+
+ if (seq.size() > 1)
+ {
+ policyQualifiers = ASN1Sequence.getInstance(seq.getObjectAt(1));
+ }
+ }
+
+ public PolicyInformation(
+ ASN1ObjectIdentifier policyIdentifier)
+ {
+ this.policyIdentifier = policyIdentifier;
+ }
+
+ public PolicyInformation(
+ ASN1ObjectIdentifier policyIdentifier,
+ ASN1Sequence policyQualifiers)
+ {
+ this.policyIdentifier = policyIdentifier;
+ this.policyQualifiers = policyQualifiers;
+ }
+
+ public static PolicyInformation getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof PolicyInformation)
+ {
+ return (PolicyInformation)obj;
+ }
+
+ return new PolicyInformation(ASN1Sequence.getInstance(obj));
+ }
+
+ public ASN1ObjectIdentifier getPolicyIdentifier()
+ {
+ return policyIdentifier;
+ }
+
+ public ASN1Sequence getPolicyQualifiers()
+ {
+ return policyQualifiers;
+ }
+
+ /*
+ * <pre>
+ * PolicyInformation ::= SEQUENCE {
+ * policyIdentifier CertPolicyId,
+ * policyQualifiers SEQUENCE SIZE (1..MAX) OF
+ * PolicyQualifierInfo OPTIONAL }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(policyIdentifier);
+
+ if (policyQualifiers != null)
+ {
+ v.add(policyQualifiers);
+ }
+
+ return new DERSequence(v);
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("Policy information: ");
+ sb.append(policyIdentifier);
+
+ if (policyQualifiers != null)
+ {
+ StringBuffer p = new StringBuffer();
+ for (int i = 0; i < policyQualifiers.size(); i++)
+ {
+ if (p.length() != 0)
+ {
+ p.append(", ");
+ }
+ p.append(PolicyQualifierInfo.getInstance(policyQualifiers.getObjectAt(i)));
+ }
+
+ sb.append("[");
+ sb.append(p);
+ sb.append("]");
+ }
+
+ return sb.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierId.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierId.java
new file mode 100644
index 00000000..e9561446
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierId.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * PolicyQualifierId, used in the CertificatePolicies
+ * X509V3 extension.
+ *
+ * <pre>
+ * id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
+ * id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
+ * id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
+ * PolicyQualifierId ::=
+ * OBJECT IDENTIFIER (id-qt-cps | id-qt-unotice)
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PolicyQualifierId extends ASN1ObjectIdentifier
+{
+ private static final String id_qt = "1.3.6.1.5.5.7.2";
+
+ private PolicyQualifierId(String id)
+ {
+ super(id);
+ }
+
+ public static final PolicyQualifierId id_qt_cps =
+ new PolicyQualifierId(id_qt + ".1");
+ public static final PolicyQualifierId id_qt_unotice =
+ new PolicyQualifierId(id_qt + ".2");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
new file mode 100644
index 00000000..8b3fda34
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
@@ -0,0 +1,119 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERIA5String;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * Policy qualifiers, used in the X509V3 CertificatePolicies
+ * extension.
+ *
+ * <pre>
+ * PolicyQualifierInfo ::= SEQUENCE {
+ * policyQualifierId PolicyQualifierId,
+ * qualifier ANY DEFINED BY policyQualifierId }
+ *
+ * PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PolicyQualifierInfo
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier policyQualifierId;
+ private ASN1Encodable qualifier;
+
+ /**
+ * Creates a new <code>PolicyQualifierInfo</code> instance.
+ *
+ * @param policyQualifierId a <code>PolicyQualifierId</code> value
+ * @param qualifier the qualifier, defined by the above field.
+ */
+ public PolicyQualifierInfo(
+ ASN1ObjectIdentifier policyQualifierId,
+ ASN1Encodable qualifier)
+ {
+ this.policyQualifierId = policyQualifierId;
+ this.qualifier = qualifier;
+ }
+
+ /**
+ * Creates a new <code>PolicyQualifierInfo</code> containing a
+ * cPSuri qualifier.
+ *
+ * @param cps the CPS (certification practice statement) uri as a
+ * <code>String</code>.
+ */
+ public PolicyQualifierInfo(
+ String cps)
+ {
+ policyQualifierId = PolicyQualifierId.id_qt_cps;
+ qualifier = new DERIA5String (cps);
+ }
+
+ /**
+ * Creates a new <code>PolicyQualifierInfo</code> instance.
+ *
+ * @param as <code>PolicyQualifierInfo</code> X509 structure
+ * encoded as an ASN1Sequence.
+ * @deprecated use PolicyQualifierInfo.getInstance()
+ */
+ public PolicyQualifierInfo(
+ ASN1Sequence as)
+ {
+ if (as.size() != 2)
+ {
+ throw new IllegalArgumentException("Bad sequence size: "
+ + as.size());
+ }
+
+ policyQualifierId = ASN1ObjectIdentifier.getInstance(as.getObjectAt(0));
+ qualifier = as.getObjectAt(1);
+ }
+
+ public static PolicyQualifierInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof PolicyQualifierInfo)
+ {
+ return (PolicyQualifierInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new PolicyQualifierInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+
+ public ASN1ObjectIdentifier getPolicyQualifierId()
+ {
+ return policyQualifierId;
+ }
+
+ public ASN1Encodable getQualifier()
+ {
+ return qualifier;
+ }
+
+ /**
+ * Returns a DER-encodable representation of this instance.
+ *
+ * @return a <code>ASN1Primitive</code> value
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector dev = new ASN1EncodableVector(2);
+ dev.add(policyQualifierId);
+ dev.add(qualifier);
+
+ return new DERSequence(dev);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java
new file mode 100644
index 00000000..d7df4554
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java
@@ -0,0 +1,100 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @deprecated use org.bouncycastle.asn1.pkcs.RSAPublicKey
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RSAPublicKeyStructure
+ extends ASN1Object
+{
+ private BigInteger modulus;
+ private BigInteger publicExponent;
+
+ public static RSAPublicKeyStructure getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static RSAPublicKeyStructure getInstance(
+ Object obj)
+ {
+ if(obj == null || obj instanceof RSAPublicKeyStructure)
+ {
+ return (RSAPublicKeyStructure)obj;
+ }
+
+ if(obj instanceof ASN1Sequence)
+ {
+ return new RSAPublicKeyStructure((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("Invalid RSAPublicKeyStructure: " + obj.getClass().getName());
+ }
+
+ public RSAPublicKeyStructure(
+ BigInteger modulus,
+ BigInteger publicExponent)
+ {
+ this.modulus = modulus;
+ this.publicExponent = publicExponent;
+ }
+
+ public RSAPublicKeyStructure(
+ ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("Bad sequence size: "
+ + seq.size());
+ }
+
+ Enumeration e = seq.getObjects();
+
+ modulus = ASN1Integer.getInstance(e.nextElement()).getPositiveValue();
+ publicExponent = ASN1Integer.getInstance(e.nextElement()).getPositiveValue();
+ }
+
+ public BigInteger getModulus()
+ {
+ return modulus;
+ }
+
+ public BigInteger getPublicExponent()
+ {
+ return publicExponent;
+ }
+
+ /**
+ * This outputs the key in PKCS1v2 format.
+ * <pre>
+ * RSAPublicKey ::= SEQUENCE {
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER, -- e
+ * }
+ * </pre>
+ * <p>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(new ASN1Integer(getModulus()));
+ v.add(new ASN1Integer(getPublicExponent()));
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ReasonFlags.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ReasonFlags.java
new file mode 100644
index 00000000..ecb4416b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ReasonFlags.java
@@ -0,0 +1,87 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+
+/**
+ * The ReasonFlags object.
+ * <pre>
+ * ReasonFlags ::= BIT STRING {
+ * unused (0),
+ * keyCompromise (1),
+ * cACompromise (2),
+ * affiliationChanged (3),
+ * superseded (4),
+ * cessationOfOperation (5),
+ * certificateHold (6),
+ * privilegeWithdrawn (7),
+ * aACompromise (8) }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ReasonFlags
+ extends DERBitString
+{
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int UNUSED = (1 << 7);
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int KEY_COMPROMISE = (1 << 6);
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int CA_COMPROMISE = (1 << 5);
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int AFFILIATION_CHANGED = (1 << 4);
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int SUPERSEDED = (1 << 3);
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int CESSATION_OF_OPERATION = (1 << 2);
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int CERTIFICATE_HOLD = (1 << 1);
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int PRIVILEGE_WITHDRAWN = (1 << 0);
+ /**
+ * @deprecated use lower case version
+ */
+ public static final int AA_COMPROMISE = (1 << 15);
+
+ public static final int unused = (1 << 7);
+ public static final int keyCompromise = (1 << 6);
+ public static final int cACompromise = (1 << 5);
+ public static final int affiliationChanged = (1 << 4);
+ public static final int superseded = (1 << 3);
+ public static final int cessationOfOperation = (1 << 2);
+ public static final int certificateHold = (1 << 1);
+ public static final int privilegeWithdrawn = (1 << 0);
+ public static final int aACompromise = (1 << 15);
+
+ /**
+ * @param reasons - the bitwise OR of the Key Reason flags giving the
+ * allowed uses for the key.
+ */
+ public ReasonFlags(
+ int reasons)
+ {
+ super(getBytes(reasons), getPadBits(reasons));
+ }
+
+ public ReasonFlags(
+ DERBitString reasons)
+ {
+ super(reasons.getBytes(), reasons.getPadBits());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java
new file mode 100644
index 00000000..ca1d7b0a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java
@@ -0,0 +1,71 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * The SubjectKeyIdentifier object.
+ * <pre>
+ * SubjectKeyIdentifier::= OCTET STRING
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SubjectKeyIdentifier
+ extends ASN1Object
+{
+ private byte[] keyidentifier;
+
+ public static SubjectKeyIdentifier getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1OctetString.getInstance(obj, explicit));
+ }
+
+ public static SubjectKeyIdentifier getInstance(
+ Object obj)
+ {
+ if (obj instanceof SubjectKeyIdentifier)
+ {
+ return (SubjectKeyIdentifier)obj;
+ }
+ else if (obj != null)
+ {
+ return new SubjectKeyIdentifier(ASN1OctetString.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public static SubjectKeyIdentifier fromExtensions(Extensions extensions)
+ {
+ return getInstance(Extensions.getExtensionParsedValue(extensions, Extension.subjectKeyIdentifier));
+ }
+
+ public SubjectKeyIdentifier(
+ byte[] keyid)
+ {
+ this.keyidentifier = Arrays.clone(keyid);
+ }
+
+ protected SubjectKeyIdentifier(
+ ASN1OctetString keyid)
+ {
+ this(keyid.getOctets());
+ }
+
+ public byte[] getKeyIdentifier()
+ {
+ return Arrays.clone(keyidentifier);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new DEROctetString(getKeyIdentifier());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
new file mode 100644
index 00000000..d26ac7b5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
@@ -0,0 +1,156 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * The object that contains the public key stored in a certificate.
+ * <p>
+ * The getEncoded() method in the public keys in the JCE produces a DER
+ * encoded one of these.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SubjectPublicKeyInfo
+ extends ASN1Object
+{
+ private AlgorithmIdentifier algId;
+ private DERBitString keyData;
+
+ public static SubjectPublicKeyInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static SubjectPublicKeyInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof SubjectPublicKeyInfo)
+ {
+ return (SubjectPublicKeyInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new SubjectPublicKeyInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public SubjectPublicKeyInfo(
+ AlgorithmIdentifier algId,
+ ASN1Encodable publicKey)
+ throws IOException
+ {
+ this.keyData = new DERBitString(publicKey);
+ this.algId = algId;
+ }
+
+ public SubjectPublicKeyInfo(
+ AlgorithmIdentifier algId,
+ byte[] publicKey)
+ {
+ this.keyData = new DERBitString(publicKey);
+ this.algId = algId;
+ }
+
+ /**
+ @deprecated use SubjectPublicKeyInfo.getInstance()
+ */
+ public SubjectPublicKeyInfo(
+ ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("Bad sequence size: "
+ + seq.size());
+ }
+
+ Enumeration e = seq.getObjects();
+
+ this.algId = AlgorithmIdentifier.getInstance(e.nextElement());
+ this.keyData = DERBitString.getInstance(e.nextElement());
+ }
+
+ public AlgorithmIdentifier getAlgorithm()
+ {
+ return algId;
+ }
+
+ /**
+ * @deprecated use getAlgorithm()
+ * @return alg ID.
+ */
+ public AlgorithmIdentifier getAlgorithmId()
+ {
+ return algId;
+ }
+
+ /**
+ * for when the public key is an encoded object - if the bitstring
+ * can't be decoded this routine throws an IOException.
+ *
+ * @exception IOException - if the bit string doesn't represent a DER
+ * encoded object.
+ * @return the public key as an ASN.1 primitive.
+ */
+ public ASN1Primitive parsePublicKey()
+ throws IOException
+ {
+ return ASN1Primitive.fromByteArray(keyData.getOctets());
+ }
+
+ /**
+ * for when the public key is an encoded object - if the bitstring
+ * can't be decoded this routine throws an IOException.
+ *
+ * @exception IOException - if the bit string doesn't represent a DER
+ * encoded object.
+ * @deprecated use parsePublicKey
+ * @return the public key as an ASN.1 primitive.
+ */
+ public ASN1Primitive getPublicKey()
+ throws IOException
+ {
+ return ASN1Primitive.fromByteArray(keyData.getOctets());
+ }
+
+ /**
+ * for when the public key is raw bits.
+ *
+ * @return the public key as the raw bit string...
+ */
+ public DERBitString getPublicKeyData()
+ {
+ return keyData;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * SubjectPublicKeyInfo ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier,
+ * publicKey BIT STRING }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(algId);
+ v.add(keyData);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertList.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertList.java
new file mode 100644
index 00000000..49e763fc
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertList.java
@@ -0,0 +1,315 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.ASN1UTCTime;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+
+/**
+ * PKIX RFC-2459 - TBSCertList object.
+ * <pre>
+ * TBSCertList ::= SEQUENCE {
+ * version Version OPTIONAL,
+ * -- if present, shall be v2
+ * signature AlgorithmIdentifier,
+ * issuer Name,
+ * thisUpdate Time,
+ * nextUpdate Time OPTIONAL,
+ * revokedCertificates SEQUENCE OF SEQUENCE {
+ * userCertificate CertificateSerialNumber,
+ * revocationDate Time,
+ * crlEntryExtensions Extensions OPTIONAL
+ * -- if present, shall be v2
+ * } OPTIONAL,
+ * crlExtensions [0] EXPLICIT Extensions OPTIONAL
+ * -- if present, shall be v2
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TBSCertList
+ extends ASN1Object
+{
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class CRLEntry
+ extends ASN1Object
+ {
+ ASN1Sequence seq;
+
+ Extensions crlEntryExtensions;
+
+ private CRLEntry(
+ ASN1Sequence seq)
+ {
+ if (seq.size() < 2 || seq.size() > 3)
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+
+ this.seq = seq;
+ }
+
+ public static CRLEntry getInstance(Object o)
+ {
+ if (o instanceof CRLEntry)
+ {
+ return ((CRLEntry)o);
+ }
+ else if (o != null)
+ {
+ return new CRLEntry(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public ASN1Integer getUserCertificate()
+ {
+ return ASN1Integer.getInstance(seq.getObjectAt(0));
+ }
+
+ public Time getRevocationDate()
+ {
+ return Time.getInstance(seq.getObjectAt(1));
+ }
+
+ public Extensions getExtensions()
+ {
+ if (crlEntryExtensions == null && seq.size() == 3)
+ {
+ crlEntryExtensions = Extensions.getInstance(seq.getObjectAt(2));
+ }
+
+ return crlEntryExtensions;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return seq;
+ }
+
+ public boolean hasExtensions()
+ {
+ return seq.size() == 3;
+ }
+ }
+
+ private class RevokedCertificatesEnumeration
+ implements Enumeration
+ {
+ private final Enumeration en;
+
+ RevokedCertificatesEnumeration(Enumeration en)
+ {
+ this.en = en;
+ }
+
+ public boolean hasMoreElements()
+ {
+ return en.hasMoreElements();
+ }
+
+ public Object nextElement()
+ {
+ return CRLEntry.getInstance(en.nextElement());
+ }
+ }
+
+ private class EmptyEnumeration
+ implements Enumeration
+ {
+ public boolean hasMoreElements()
+ {
+ return false;
+ }
+
+ public Object nextElement()
+ {
+ throw new NoSuchElementException("Empty Enumeration");
+ }
+ }
+
+ ASN1Integer version;
+ AlgorithmIdentifier signature;
+ X500Name issuer;
+ Time thisUpdate;
+ Time nextUpdate;
+ ASN1Sequence revokedCertificates;
+ Extensions crlExtensions;
+
+ public static TBSCertList getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static TBSCertList getInstance(
+ Object obj)
+ {
+ if (obj instanceof TBSCertList)
+ {
+ return (TBSCertList)obj;
+ }
+ else if (obj != null)
+ {
+ return new TBSCertList(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public TBSCertList(
+ ASN1Sequence seq)
+ {
+ if (seq.size() < 3 || seq.size() > 7)
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+
+ int seqPos = 0;
+
+ if (seq.getObjectAt(seqPos) instanceof ASN1Integer)
+ {
+ version = ASN1Integer.getInstance(seq.getObjectAt(seqPos++));
+ }
+ else
+ {
+ version = null; // version is optional
+ }
+
+ signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqPos++));
+ issuer = X500Name.getInstance(seq.getObjectAt(seqPos++));
+ thisUpdate = Time.getInstance(seq.getObjectAt(seqPos++));
+
+ if (seqPos < seq.size()
+ && (seq.getObjectAt(seqPos) instanceof ASN1UTCTime
+ || seq.getObjectAt(seqPos) instanceof ASN1GeneralizedTime
+ || seq.getObjectAt(seqPos) instanceof Time))
+ {
+ nextUpdate = Time.getInstance(seq.getObjectAt(seqPos++));
+ }
+
+ if (seqPos < seq.size()
+ && !(seq.getObjectAt(seqPos) instanceof ASN1TaggedObject))
+ {
+ revokedCertificates = ASN1Sequence.getInstance(seq.getObjectAt(seqPos++));
+ }
+
+ if (seqPos < seq.size()
+ && seq.getObjectAt(seqPos) instanceof ASN1TaggedObject)
+ {
+ crlExtensions = Extensions.getInstance(ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(seqPos), true));
+ }
+ }
+
+ public int getVersionNumber()
+ {
+ if (version == null)
+ {
+ return 1;
+ }
+ return version.intValueExact() + 1;
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public AlgorithmIdentifier getSignature()
+ {
+ return signature;
+ }
+
+ public X500Name getIssuer()
+ {
+ return issuer;
+ }
+
+ public Time getThisUpdate()
+ {
+ return thisUpdate;
+ }
+
+ public Time getNextUpdate()
+ {
+ return nextUpdate;
+ }
+
+ public CRLEntry[] getRevokedCertificates()
+ {
+ if (revokedCertificates == null)
+ {
+ return new CRLEntry[0];
+ }
+
+ CRLEntry[] entries = new CRLEntry[revokedCertificates.size()];
+
+ for (int i = 0; i < entries.length; i++)
+ {
+ entries[i] = CRLEntry.getInstance(revokedCertificates.getObjectAt(i));
+ }
+
+ return entries;
+ }
+
+ public Enumeration getRevokedCertificateEnumeration()
+ {
+ if (revokedCertificates == null)
+ {
+ return new EmptyEnumeration();
+ }
+
+ return new RevokedCertificatesEnumeration(revokedCertificates.getObjects());
+ }
+
+ public Extensions getExtensions()
+ {
+ return crlExtensions;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(7);
+
+ if (version != null)
+ {
+ v.add(version);
+ }
+ v.add(signature);
+ v.add(issuer);
+
+ v.add(thisUpdate);
+ if (nextUpdate != null)
+ {
+ v.add(nextUpdate);
+ }
+
+ // Add CRLEntries if they exist
+ if (revokedCertificates != null)
+ {
+ v.add(revokedCertificates);
+ }
+
+ if (crlExtensions != null)
+ {
+ v.add(new DERTaggedObject(0, crlExtensions));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificate.java
new file mode 100644
index 00000000..74e28279
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificate.java
@@ -0,0 +1,293 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+import com.android.internal.org.bouncycastle.util.Properties;
+
+/**
+ * The TBSCertificate object.
+ * <pre>
+ * TBSCertificate ::= SEQUENCE {
+ * version [ 0 ] Version DEFAULT v1(0),
+ * serialNumber CertificateSerialNumber,
+ * signature AlgorithmIdentifier,
+ * issuer Name,
+ * validity Validity,
+ * subject Name,
+ * subjectPublicKeyInfo SubjectPublicKeyInfo,
+ * issuerUniqueID [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
+ * subjectUniqueID [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
+ * extensions [ 3 ] Extensions OPTIONAL
+ * }
+ * </pre>
+ * <p>
+ * Note: issuerUniqueID and subjectUniqueID are both deprecated by the IETF. This class
+ * will parse them, but you really shouldn't be creating new ones.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TBSCertificate
+ extends ASN1Object
+{
+ ASN1Sequence seq;
+
+ ASN1Integer version;
+ ASN1Integer serialNumber;
+ AlgorithmIdentifier signature;
+ X500Name issuer;
+ Time startDate, endDate;
+ X500Name subject;
+ SubjectPublicKeyInfo subjectPublicKeyInfo;
+ DERBitString issuerUniqueId;
+ DERBitString subjectUniqueId;
+ Extensions extensions;
+
+ public static TBSCertificate getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static TBSCertificate getInstance(
+ Object obj)
+ {
+ if (obj instanceof TBSCertificate)
+ {
+ return (TBSCertificate)obj;
+ }
+ else if (obj != null)
+ {
+ return new TBSCertificate(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ private TBSCertificate(
+ ASN1Sequence seq)
+ {
+ int seqStart = 0;
+
+ this.seq = seq;
+
+ //
+ // some certficates don't include a version number - we assume v1
+ //
+ if (seq.getObjectAt(0) instanceof ASN1TaggedObject)
+ {
+ version = ASN1Integer.getInstance((ASN1TaggedObject)seq.getObjectAt(0), true);
+ }
+ else
+ {
+ seqStart = -1; // field 0 is missing!
+ version = new ASN1Integer(0);
+ }
+
+ boolean isV1 = false;
+ boolean isV2 = false;
+
+ if (version.hasValue(BigInteger.valueOf(0)))
+ {
+ isV1 = true;
+ }
+ else if (version.hasValue(BigInteger.valueOf(1)))
+ {
+ isV2 = true;
+ }
+ else if (!version.hasValue(BigInteger.valueOf(2)))
+ {
+ throw new IllegalArgumentException("version number not recognised");
+ }
+
+ serialNumber = ASN1Integer.getInstance(seq.getObjectAt(seqStart + 1));
+
+ signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqStart + 2));
+ issuer = X500Name.getInstance(seq.getObjectAt(seqStart + 3));
+
+ //
+ // before and after dates
+ //
+ ASN1Sequence dates = (ASN1Sequence)seq.getObjectAt(seqStart + 4);
+
+ startDate = Time.getInstance(dates.getObjectAt(0));
+ endDate = Time.getInstance(dates.getObjectAt(1));
+
+ subject = X500Name.getInstance(seq.getObjectAt(seqStart + 5));
+
+ //
+ // public key info.
+ //
+ subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(seq.getObjectAt(seqStart + 6));
+
+ int extras = seq.size() - (seqStart + 6) - 1;
+ if (extras != 0 && isV1)
+ {
+ throw new IllegalArgumentException("version 1 certificate contains extra data");
+ }
+
+ while (extras > 0)
+ {
+ ASN1TaggedObject extra = (ASN1TaggedObject)seq.getObjectAt(seqStart + 6 + extras);
+
+ switch (extra.getTagNo())
+ {
+ case 1:
+ issuerUniqueId = DERBitString.getInstance(extra, false);
+ break;
+ case 2:
+ subjectUniqueId = DERBitString.getInstance(extra, false);
+ break;
+ case 3:
+ if (isV2)
+ {
+ throw new IllegalArgumentException("version 2 certificate cannot contain extensions");
+ }
+ extensions = Extensions.getInstance(ASN1Sequence.getInstance(extra, true));
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown tag encountered in structure: " + extra.getTagNo());
+ }
+ extras--;
+ }
+ }
+
+ public int getVersionNumber()
+ {
+ return version.intValueExact() + 1;
+ }
+
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
+ public ASN1Integer getSerialNumber()
+ {
+ return serialNumber;
+ }
+
+ public AlgorithmIdentifier getSignature()
+ {
+ return signature;
+ }
+
+ public X500Name getIssuer()
+ {
+ return issuer;
+ }
+
+ public Time getStartDate()
+ {
+ return startDate;
+ }
+
+ public Time getEndDate()
+ {
+ return endDate;
+ }
+
+ public X500Name getSubject()
+ {
+ return subject;
+ }
+
+ public SubjectPublicKeyInfo getSubjectPublicKeyInfo()
+ {
+ return subjectPublicKeyInfo;
+ }
+
+ public DERBitString getIssuerUniqueId()
+ {
+ return issuerUniqueId;
+ }
+
+ public DERBitString getSubjectUniqueId()
+ {
+ return subjectUniqueId;
+ }
+
+ public Extensions getExtensions()
+ {
+ return extensions;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ if (Properties.getPropertyValue("com.android.internal.org.bouncycastle.x509.allow_non-der_tbscert") != null)
+ {
+ if (Properties.isOverrideSet("com.android.internal.org.bouncycastle.x509.allow_non-der_tbscert"))
+ {
+ return seq;
+ }
+ }
+ else
+ {
+ return seq;
+ }
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ // DEFAULT Zero
+ if (!version.hasValue(BigIntegers.ZERO))
+ {
+ v.add(new DERTaggedObject(true, 0, version));
+ }
+
+ v.add(serialNumber);
+ v.add(signature);
+ v.add(issuer);
+
+ //
+ // before and after dates
+ //
+ {
+ ASN1EncodableVector validity = new ASN1EncodableVector(2);
+ validity.add(startDate);
+ validity.add(endDate);
+
+ v.add(new DERSequence(validity));
+ }
+
+ if (subject != null)
+ {
+ v.add(subject);
+ }
+ else
+ {
+ v.add(new DERSequence());
+ }
+
+ v.add(subjectPublicKeyInfo);
+
+ // Note: implicit tag
+ if (issuerUniqueId != null)
+ {
+ v.add(new DERTaggedObject(false, 1, issuerUniqueId));
+ }
+
+ // Note: implicit tag
+ if (subjectUniqueId != null)
+ {
+ v.add(new DERTaggedObject(false, 2, subjectUniqueId));
+ }
+
+ if (extensions != null)
+ {
+ v.add(new DERTaggedObject(true, 3, extensions));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificateStructure.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
new file mode 100644
index 00000000..5ae69dff
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
@@ -0,0 +1,196 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+
+/**
+ * The TBSCertificate object.
+ * <pre>
+ * TBSCertificate ::= SEQUENCE {
+ * version [ 0 ] Version DEFAULT v1(0),
+ * serialNumber CertificateSerialNumber,
+ * signature AlgorithmIdentifier,
+ * issuer Name,
+ * validity Validity,
+ * subject Name,
+ * subjectPublicKeyInfo SubjectPublicKeyInfo,
+ * issuerUniqueID [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
+ * subjectUniqueID [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
+ * extensions [ 3 ] Extensions OPTIONAL
+ * }
+ * </pre>
+ * <p>
+ * Note: issuerUniqueID and subjectUniqueID are both deprecated by the IETF. This class
+ * will parse them, but you really shouldn't be creating new ones.
+ * @deprecated use TBSCertificate
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TBSCertificateStructure
+ extends ASN1Object
+ implements X509ObjectIdentifiers, PKCSObjectIdentifiers
+{
+ ASN1Sequence seq;
+
+ ASN1Integer version;
+ ASN1Integer serialNumber;
+ AlgorithmIdentifier signature;
+ X500Name issuer;
+ Time startDate, endDate;
+ X500Name subject;
+ SubjectPublicKeyInfo subjectPublicKeyInfo;
+ DERBitString issuerUniqueId;
+ DERBitString subjectUniqueId;
+ X509Extensions extensions;
+
+ public static TBSCertificateStructure getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static TBSCertificateStructure getInstance(
+ Object obj)
+ {
+ if (obj instanceof TBSCertificateStructure)
+ {
+ return (TBSCertificateStructure)obj;
+ }
+ else if (obj != null)
+ {
+ return new TBSCertificateStructure(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public TBSCertificateStructure(
+ ASN1Sequence seq)
+ {
+ int seqStart = 0;
+
+ this.seq = seq;
+
+ //
+ // some certficates don't include a version number - we assume v1
+ //
+ if (seq.getObjectAt(0) instanceof ASN1TaggedObject)
+ {
+ version = ASN1Integer.getInstance((ASN1TaggedObject)seq.getObjectAt(0), true);
+ }
+ else
+ {
+ seqStart = -1; // field 0 is missing!
+ version = new ASN1Integer(0);
+ }
+
+ serialNumber = ASN1Integer.getInstance(seq.getObjectAt(seqStart + 1));
+
+ signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqStart + 2));
+ issuer = X500Name.getInstance(seq.getObjectAt(seqStart + 3));
+
+ //
+ // before and after dates
+ //
+ ASN1Sequence dates = (ASN1Sequence)seq.getObjectAt(seqStart + 4);
+
+ startDate = Time.getInstance(dates.getObjectAt(0));
+ endDate = Time.getInstance(dates.getObjectAt(1));
+
+ subject = X500Name.getInstance(seq.getObjectAt(seqStart + 5));
+
+ //
+ // public key info.
+ //
+ subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(seq.getObjectAt(seqStart + 6));
+
+ for (int extras = seq.size() - (seqStart + 6) - 1; extras > 0; extras--)
+ {
+ ASN1TaggedObject extra = ASN1TaggedObject.getInstance(seq.getObjectAt(seqStart + 6 + extras));
+
+ switch (extra.getTagNo())
+ {
+ case 1:
+ issuerUniqueId = DERBitString.getInstance(extra, false);
+ break;
+ case 2:
+ subjectUniqueId = DERBitString.getInstance(extra, false);
+ break;
+ case 3:
+ extensions = X509Extensions.getInstance(extra);
+ }
+ }
+ }
+
+ public int getVersion()
+ {
+ return version.intValueExact() + 1;
+ }
+
+ public ASN1Integer getVersionNumber()
+ {
+ return version;
+ }
+
+ public ASN1Integer getSerialNumber()
+ {
+ return serialNumber;
+ }
+
+ public AlgorithmIdentifier getSignature()
+ {
+ return signature;
+ }
+
+ public X500Name getIssuer()
+ {
+ return issuer;
+ }
+
+ public Time getStartDate()
+ {
+ return startDate;
+ }
+
+ public Time getEndDate()
+ {
+ return endDate;
+ }
+
+ public X500Name getSubject()
+ {
+ return subject;
+ }
+
+ public SubjectPublicKeyInfo getSubjectPublicKeyInfo()
+ {
+ return subjectPublicKeyInfo;
+ }
+
+ public DERBitString getIssuerUniqueId()
+ {
+ return issuerUniqueId;
+ }
+
+ public DERBitString getSubjectUniqueId()
+ {
+ return subjectUniqueId;
+ }
+
+ public X509Extensions getExtensions()
+ {
+ return extensions;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return seq;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Time.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Time.java
new file mode 100644
index 00000000..eb987139
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Time.java
@@ -0,0 +1,181 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+// Android-added: Localization support
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.SimpleTimeZone;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.ASN1UTCTime;
+import com.android.internal.org.bouncycastle.asn1.DERGeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.DERUTCTime;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Time
+ extends ASN1Object
+ implements ASN1Choice
+{
+ ASN1Primitive time;
+
+ public static Time getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject()); // must be explicitly tagged
+ }
+
+ public Time(
+ ASN1Primitive time)
+ {
+ if (!(time instanceof ASN1UTCTime)
+ && !(time instanceof ASN1GeneralizedTime))
+ {
+ throw new IllegalArgumentException("unknown object passed to Time");
+ }
+
+ this.time = time;
+ }
+
+ /**
+ * Creates a time object from a given date - if the date is between 1950
+ * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
+ * is used.
+ *
+ * @param time a date object representing the time of interest.
+ */
+ public Time(
+ Date time)
+ {
+ SimpleTimeZone tz = new SimpleTimeZone(0, "Z");
+ // Android-changed: Use localized version
+ // SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss");
+ SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
+
+ dateF.setTimeZone(tz);
+
+ String d = dateF.format(time) + "Z";
+ int year = Integer.parseInt(d.substring(0, 4));
+
+ if (year < 1950 || year > 2049)
+ {
+ this.time = new DERGeneralizedTime(d);
+ }
+ else
+ {
+ this.time = new DERUTCTime(d.substring(2));
+ }
+ }
+
+ /**
+ * Creates a time object from a given date and locale - if the date is between 1950
+ * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
+ * is used. You may need to use this constructor if the default locale
+ * doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations.
+ *
+ * @param time a date object representing the time of interest.
+ * @param locale an appropriate Locale for producing an ASN.1 GeneralizedTime value.
+ */
+ public Time(
+ Date time,
+ Locale locale)
+ {
+ SimpleTimeZone tz = new SimpleTimeZone(0, "Z");
+ // BEGIN Android-changed: Use localized version
+ // SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss", locale);
+ SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
+ dateF.setCalendar(Calendar.getInstance(locale));
+ // END android-changed
+
+ dateF.setTimeZone(tz);
+
+ String d = dateF.format(time) + "Z";
+ int year = Integer.parseInt(d.substring(0, 4));
+
+ if (year < 1950 || year > 2049)
+ {
+ this.time = new DERGeneralizedTime(d);
+ }
+ else
+ {
+ this.time = new DERUTCTime(d.substring(2));
+ }
+ }
+
+ public static Time getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof Time)
+ {
+ return (Time)obj;
+ }
+ else if (obj instanceof ASN1UTCTime)
+ {
+ return new Time((ASN1UTCTime)obj);
+ }
+ else if (obj instanceof ASN1GeneralizedTime)
+ {
+ return new Time((ASN1GeneralizedTime)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
+ }
+
+ public String getTime()
+ {
+ if (time instanceof ASN1UTCTime)
+ {
+ return ((ASN1UTCTime)time).getAdjustedTime();
+ }
+ else
+ {
+ return ((ASN1GeneralizedTime)time).getTime();
+ }
+ }
+
+ public Date getDate()
+ {
+ try
+ {
+ if (time instanceof ASN1UTCTime)
+ {
+ return ((ASN1UTCTime)time).getAdjustedDate();
+ }
+ else
+ {
+ return ((ASN1GeneralizedTime)time).getDate();
+ }
+ }
+ catch (ParseException e)
+ { // this should never happen
+ throw new IllegalStateException("invalid date string: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * Time ::= CHOICE {
+ * utcTime UTCTime,
+ * generalTime GeneralizedTime }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return time;
+ }
+
+ public String toString()
+ {
+ return getTime();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java
new file mode 100644
index 00000000..85f7bed0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java
@@ -0,0 +1,147 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1UTCTime;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+
+/**
+ * Generator for Version 1 TBSCertificateStructures.
+ * <pre>
+ * TBSCertificate ::= SEQUENCE {
+ * version [ 0 ] Version DEFAULT v1(0),
+ * serialNumber CertificateSerialNumber,
+ * signature AlgorithmIdentifier,
+ * issuer Name,
+ * validity Validity,
+ * subject Name,
+ * subjectPublicKeyInfo SubjectPublicKeyInfo,
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ *
+ */
+public class V1TBSCertificateGenerator
+{
+ DERTaggedObject version = new DERTaggedObject(true, 0, new ASN1Integer(0));
+
+ ASN1Integer serialNumber;
+ AlgorithmIdentifier signature;
+ X500Name issuer;
+ Time startDate, endDate;
+ X500Name subject;
+ SubjectPublicKeyInfo subjectPublicKeyInfo;
+
+ public V1TBSCertificateGenerator()
+ {
+ }
+
+ public void setSerialNumber(
+ ASN1Integer serialNumber)
+ {
+ this.serialNumber = serialNumber;
+ }
+
+ public void setSignature(
+ AlgorithmIdentifier signature)
+ {
+ this.signature = signature;
+ }
+
+ /**
+ * @deprecated use X500Name method
+ */
+ public void setIssuer(
+ X509Name issuer)
+ {
+ this.issuer = X500Name.getInstance(issuer.toASN1Primitive());
+ }
+
+ public void setIssuer(
+ X500Name issuer)
+ {
+ this.issuer = issuer;
+ }
+
+ public void setStartDate(
+ Time startDate)
+ {
+ this.startDate = startDate;
+ }
+
+ public void setStartDate(
+ ASN1UTCTime startDate)
+ {
+ this.startDate = new Time(startDate);
+ }
+
+ public void setEndDate(
+ Time endDate)
+ {
+ this.endDate = endDate;
+ }
+
+ public void setEndDate(
+ ASN1UTCTime endDate)
+ {
+ this.endDate = new Time(endDate);
+ }
+
+ /**
+ * @deprecated use X500Name method
+ */
+ public void setSubject(
+ X509Name subject)
+ {
+ this.subject = X500Name.getInstance(subject.toASN1Primitive());
+ }
+
+ public void setSubject(
+ X500Name subject)
+ {
+ this.subject = subject;
+ }
+
+ public void setSubjectPublicKeyInfo(
+ SubjectPublicKeyInfo pubKeyInfo)
+ {
+ this.subjectPublicKeyInfo = pubKeyInfo;
+ }
+
+ public TBSCertificate generateTBSCertificate()
+ {
+ if ((serialNumber == null) || (signature == null)
+ || (issuer == null) || (startDate == null) || (endDate == null)
+ || (subject == null) || (subjectPublicKeyInfo == null))
+ {
+ throw new IllegalStateException("not all mandatory fields set in V1 TBScertificate generator");
+ }
+
+ ASN1EncodableVector seq = new ASN1EncodableVector(6);
+
+ // seq.add(version); - not required as default value.
+ seq.add(serialNumber);
+ seq.add(signature);
+ seq.add(issuer);
+
+ //
+ // before and after dates
+ //
+ {
+ ASN1EncodableVector validity = new ASN1EncodableVector(2);
+ validity.add(startDate);
+ validity.add(endDate);
+
+ seq.add(new DERSequence(validity));
+ }
+
+ seq.add(subject);
+
+ seq.add(subjectPublicKeyInfo);
+
+ return TBSCertificate.getInstance(new DERSequence(seq));
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V2Form.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V2Form.java
new file mode 100644
index 00000000..110b9302
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V2Form.java
@@ -0,0 +1,161 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class V2Form
+ extends ASN1Object
+{
+ GeneralNames issuerName;
+ IssuerSerial baseCertificateID;
+ ObjectDigestInfo objectDigestInfo;
+
+ public static V2Form getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static V2Form getInstance(
+ Object obj)
+ {
+ if (obj instanceof V2Form)
+ {
+ return (V2Form)obj;
+ }
+ else if (obj != null)
+ {
+ return new V2Form(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public V2Form(
+ GeneralNames issuerName)
+ {
+ this(issuerName, null, null);
+ }
+
+ public V2Form(
+ GeneralNames issuerName,
+ IssuerSerial baseCertificateID)
+ {
+ this(issuerName, baseCertificateID, null);
+ }
+
+ public V2Form(
+ GeneralNames issuerName,
+ ObjectDigestInfo objectDigestInfo)
+ {
+ this(issuerName, null, objectDigestInfo);
+ }
+
+ public V2Form(
+ GeneralNames issuerName,
+ IssuerSerial baseCertificateID,
+ ObjectDigestInfo objectDigestInfo)
+ {
+ this.issuerName = issuerName;
+ this.baseCertificateID = baseCertificateID;
+ this.objectDigestInfo = objectDigestInfo;
+ }
+
+ /**
+ * @deprecated use getInstance().
+ */
+ public V2Form(
+ ASN1Sequence seq)
+ {
+ if (seq.size() > 3)
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+
+ int index = 0;
+
+ if (!(seq.getObjectAt(0) instanceof ASN1TaggedObject))
+ {
+ index++;
+ this.issuerName = GeneralNames.getInstance(seq.getObjectAt(0));
+ }
+
+ for (int i = index; i != seq.size(); i++)
+ {
+ ASN1TaggedObject o = ASN1TaggedObject.getInstance(seq.getObjectAt(i));
+ if (o.getTagNo() == 0)
+ {
+ baseCertificateID = IssuerSerial.getInstance(o, false);
+ }
+ else if (o.getTagNo() == 1)
+ {
+ objectDigestInfo = ObjectDigestInfo.getInstance(o, false);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Bad tag number: "
+ + o.getTagNo());
+ }
+ }
+ }
+
+ public GeneralNames getIssuerName()
+ {
+ return issuerName;
+ }
+
+ public IssuerSerial getBaseCertificateID()
+ {
+ return baseCertificateID;
+ }
+
+ public ObjectDigestInfo getObjectDigestInfo()
+ {
+ return objectDigestInfo;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * V2Form ::= SEQUENCE {
+ * issuerName GeneralNames OPTIONAL,
+ * baseCertificateID [0] IssuerSerial OPTIONAL,
+ * objectDigestInfo [1] ObjectDigestInfo OPTIONAL
+ * -- issuerName MUST be present in this profile
+ * -- baseCertificateID and objectDigestInfo MUST NOT
+ * -- be present in this profile
+ * }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ if (issuerName != null)
+ {
+ v.add(issuerName);
+ }
+
+ if (baseCertificateID != null)
+ {
+ v.add(new DERTaggedObject(false, 0, baseCertificateID));
+ }
+
+ if (objectDigestInfo != null)
+ {
+ v.add(new DERTaggedObject(false, 1, objectDigestInfo));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
new file mode 100644
index 00000000..2123bdcb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
@@ -0,0 +1,215 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1UTCTime;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+
+/**
+ * Generator for Version 3 TBSCertificateStructures.
+ * <pre>
+ * TBSCertificate ::= SEQUENCE {
+ * version [ 0 ] Version DEFAULT v1(0),
+ * serialNumber CertificateSerialNumber,
+ * signature AlgorithmIdentifier,
+ * issuer Name,
+ * validity Validity,
+ * subject Name,
+ * subjectPublicKeyInfo SubjectPublicKeyInfo,
+ * issuerUniqueID [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
+ * subjectUniqueID [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
+ * extensions [ 3 ] Extensions OPTIONAL
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ *
+ */
+public class V3TBSCertificateGenerator
+{
+ DERTaggedObject version = new DERTaggedObject(true, 0, new ASN1Integer(2));
+
+ ASN1Integer serialNumber;
+ AlgorithmIdentifier signature;
+ X500Name issuer;
+ Time startDate, endDate;
+ X500Name subject;
+ SubjectPublicKeyInfo subjectPublicKeyInfo;
+ Extensions extensions;
+
+ private boolean altNamePresentAndCritical;
+ private DERBitString issuerUniqueID;
+ private DERBitString subjectUniqueID;
+
+ public V3TBSCertificateGenerator()
+ {
+ }
+
+ public void setSerialNumber(
+ ASN1Integer serialNumber)
+ {
+ this.serialNumber = serialNumber;
+ }
+
+ public void setSignature(
+ AlgorithmIdentifier signature)
+ {
+ this.signature = signature;
+ }
+
+ /**
+ * @deprecated use X500Name method
+ */
+ public void setIssuer(
+ X509Name issuer)
+ {
+ this.issuer = X500Name.getInstance(issuer);
+ }
+
+ public void setIssuer(
+ X500Name issuer)
+ {
+ this.issuer = issuer;
+ }
+
+ public void setStartDate(
+ ASN1UTCTime startDate)
+ {
+ this.startDate = new Time(startDate);
+ }
+
+ public void setStartDate(
+ Time startDate)
+ {
+ this.startDate = startDate;
+ }
+
+ public void setEndDate(
+ ASN1UTCTime endDate)
+ {
+ this.endDate = new Time(endDate);
+ }
+
+ public void setEndDate(
+ Time endDate)
+ {
+ this.endDate = endDate;
+ }
+
+ /**
+ * @deprecated use X500Name method
+ */
+ public void setSubject(
+ X509Name subject)
+ {
+ this.subject = X500Name.getInstance(subject.toASN1Primitive());
+ }
+
+ public void setSubject(
+ X500Name subject)
+ {
+ this.subject = subject;
+ }
+
+ public void setIssuerUniqueID(
+ DERBitString uniqueID)
+ {
+ this.issuerUniqueID = uniqueID;
+ }
+
+ public void setSubjectUniqueID(
+ DERBitString uniqueID)
+ {
+ this.subjectUniqueID = uniqueID;
+ }
+
+ public void setSubjectPublicKeyInfo(
+ SubjectPublicKeyInfo pubKeyInfo)
+ {
+ this.subjectPublicKeyInfo = pubKeyInfo;
+ }
+
+ /**
+ * @deprecated use method taking Extensions
+ * @param extensions
+ */
+ public void setExtensions(
+ X509Extensions extensions)
+ {
+ setExtensions(Extensions.getInstance(extensions));
+ }
+
+ public void setExtensions(
+ Extensions extensions)
+ {
+ this.extensions = extensions;
+ if (extensions != null)
+ {
+ Extension altName = extensions.getExtension(Extension.subjectAlternativeName);
+
+ if (altName != null && altName.isCritical())
+ {
+ altNamePresentAndCritical = true;
+ }
+ }
+ }
+
+ public TBSCertificate generateTBSCertificate()
+ {
+ if ((serialNumber == null) || (signature == null)
+ || (issuer == null) || (startDate == null) || (endDate == null)
+ || (subject == null && !altNamePresentAndCritical) || (subjectPublicKeyInfo == null))
+ {
+ throw new IllegalStateException("not all mandatory fields set in V3 TBScertificate generator");
+ }
+
+ ASN1EncodableVector v = new ASN1EncodableVector(10);
+
+ v.add(version);
+ v.add(serialNumber);
+ v.add(signature);
+ v.add(issuer);
+
+ //
+ // before and after dates
+ //
+ {
+ ASN1EncodableVector validity = new ASN1EncodableVector(2);
+ validity.add(startDate);
+ validity.add(endDate);
+
+ v.add(new DERSequence(validity));
+ }
+
+ if (subject != null)
+ {
+ v.add(subject);
+ }
+ else
+ {
+ v.add(new DERSequence());
+ }
+
+ v.add(subjectPublicKeyInfo);
+
+ if (issuerUniqueID != null)
+ {
+ v.add(new DERTaggedObject(false, 1, issuerUniqueID));
+ }
+
+ if (subjectUniqueID != null)
+ {
+ v.add(new DERTaggedObject(false, 2, subjectUniqueID));
+ }
+
+ if (extensions != null)
+ {
+ v.add(new DERTaggedObject(true, 3, extensions));
+ }
+
+ return TBSCertificate.getInstance(new DERSequence(v));
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509CertificateStructure.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509CertificateStructure.java
new file mode 100644
index 00000000..34afe366
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509CertificateStructure.java
@@ -0,0 +1,131 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+
+/**
+ * an X509Certificate structure.
+ * <pre>
+ * Certificate ::= SEQUENCE {
+ * tbsCertificate TBSCertificate,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING
+ * }
+ * </pre>
+ * @deprecated use org.bouncycastle.asn1.x509.Certificate
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509CertificateStructure
+ extends ASN1Object
+ implements X509ObjectIdentifiers, PKCSObjectIdentifiers
+{
+ ASN1Sequence seq;
+ TBSCertificateStructure tbsCert;
+ AlgorithmIdentifier sigAlgId;
+ DERBitString sig;
+
+ public static X509CertificateStructure getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static X509CertificateStructure getInstance(
+ Object obj)
+ {
+ if (obj instanceof X509CertificateStructure)
+ {
+ return (X509CertificateStructure)obj;
+ }
+ else if (obj != null)
+ {
+ return new X509CertificateStructure(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public X509CertificateStructure(
+ ASN1Sequence seq)
+ {
+ this.seq = seq;
+
+ //
+ // correct x509 certficate
+ //
+ if (seq.size() == 3)
+ {
+ tbsCert = TBSCertificateStructure.getInstance(seq.getObjectAt(0));
+ sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
+
+ sig = DERBitString.getInstance(seq.getObjectAt(2));
+ }
+ else
+ {
+ throw new IllegalArgumentException("sequence wrong size for a certificate");
+ }
+ }
+
+ public TBSCertificateStructure getTBSCertificate()
+ {
+ return tbsCert;
+ }
+
+ public int getVersion()
+ {
+ return tbsCert.getVersion();
+ }
+
+ public ASN1Integer getSerialNumber()
+ {
+ return tbsCert.getSerialNumber();
+ }
+
+ public X500Name getIssuer()
+ {
+ return tbsCert.getIssuer();
+ }
+
+ public Time getStartDate()
+ {
+ return tbsCert.getStartDate();
+ }
+
+ public Time getEndDate()
+ {
+ return tbsCert.getEndDate();
+ }
+
+ public X500Name getSubject()
+ {
+ return tbsCert.getSubject();
+ }
+
+ public SubjectPublicKeyInfo getSubjectPublicKeyInfo()
+ {
+ return tbsCert.getSubjectPublicKeyInfo();
+ }
+
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return sigAlgId;
+ }
+
+ public DERBitString getSignature()
+ {
+ return sig;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return seq;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java
new file mode 100644
index 00000000..582ebdd3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509DefaultEntryConverter.java
@@ -0,0 +1,67 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERGeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.DERIA5String;
+import com.android.internal.org.bouncycastle.asn1.DERPrintableString;
+import com.android.internal.org.bouncycastle.asn1.DERUTF8String;
+
+/**
+ * The default converter for X509 DN entries when going from their
+ * string value to ASN.1 strings.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509DefaultEntryConverter
+ extends X509NameEntryConverter
+{
+ /**
+ * Apply default coversion for the given value depending on the oid
+ * and the character range of the value.
+ *
+ * @param oid the object identifier for the DN entry
+ * @param value the value associated with it
+ * @return the ASN.1 equivalent for the string value.
+ */
+ public ASN1Primitive getConvertedValue(
+ ASN1ObjectIdentifier oid,
+ String value)
+ {
+ if (value.length() != 0 && value.charAt(0) == '#')
+ {
+ try
+ {
+ return convertHexEncoded(value, 1);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("can't recode value for oid " + oid.getId());
+ }
+ }
+ else
+ {
+ if (value.length() != 0 && value.charAt(0) == '\\')
+ {
+ value = value.substring(1);
+ }
+ if (oid.equals(X509Name.EmailAddress) || oid.equals(X509Name.DC))
+ {
+ return new DERIA5String(value);
+ }
+ else if (oid.equals(X509Name.DATE_OF_BIRTH)) // accept time string as well as # (for compatibility)
+ {
+ return new DERGeneralizedTime(value);
+ }
+ else if (oid.equals(X509Name.C) || oid.equals(X509Name.SN) || oid.equals(X509Name.DN_QUALIFIER)
+ || oid.equals(X509Name.TELEPHONE_NUMBER))
+ {
+ return new DERPrintableString(value);
+ }
+ }
+
+ return new DERUTF8String(value);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extension.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extension.java
new file mode 100644
index 00000000..8bdf57b4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extension.java
@@ -0,0 +1,251 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Boolean;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * an object for the elements in the X.509 V3 extension block.
+ * @deprecated use Extension
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509Extension
+{
+ /**
+ * Subject Directory Attributes
+ */
+ public static final ASN1ObjectIdentifier subjectDirectoryAttributes = new ASN1ObjectIdentifier("2.5.29.9");
+
+ /**
+ * Subject Key Identifier
+ */
+ public static final ASN1ObjectIdentifier subjectKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.14");
+
+ /**
+ * Key Usage
+ */
+ public static final ASN1ObjectIdentifier keyUsage = new ASN1ObjectIdentifier("2.5.29.15");
+
+ /**
+ * Private Key Usage Period
+ */
+ public static final ASN1ObjectIdentifier privateKeyUsagePeriod = new ASN1ObjectIdentifier("2.5.29.16");
+
+ /**
+ * Subject Alternative Name
+ */
+ public static final ASN1ObjectIdentifier subjectAlternativeName = new ASN1ObjectIdentifier("2.5.29.17");
+
+ /**
+ * Issuer Alternative Name
+ */
+ public static final ASN1ObjectIdentifier issuerAlternativeName = new ASN1ObjectIdentifier("2.5.29.18");
+
+ /**
+ * Basic Constraints
+ */
+ public static final ASN1ObjectIdentifier basicConstraints = new ASN1ObjectIdentifier("2.5.29.19");
+
+ /**
+ * CRL Number
+ */
+ public static final ASN1ObjectIdentifier cRLNumber = new ASN1ObjectIdentifier("2.5.29.20");
+
+ /**
+ * Reason code
+ */
+ public static final ASN1ObjectIdentifier reasonCode = new ASN1ObjectIdentifier("2.5.29.21");
+
+ /**
+ * Hold Instruction Code
+ */
+ public static final ASN1ObjectIdentifier instructionCode = new ASN1ObjectIdentifier("2.5.29.23");
+
+ /**
+ * Invalidity Date
+ */
+ public static final ASN1ObjectIdentifier invalidityDate = new ASN1ObjectIdentifier("2.5.29.24");
+
+ /**
+ * Delta CRL indicator
+ */
+ public static final ASN1ObjectIdentifier deltaCRLIndicator = new ASN1ObjectIdentifier("2.5.29.27");
+
+ /**
+ * Issuing Distribution Point
+ */
+ public static final ASN1ObjectIdentifier issuingDistributionPoint = new ASN1ObjectIdentifier("2.5.29.28");
+
+ /**
+ * Certificate Issuer
+ */
+ public static final ASN1ObjectIdentifier certificateIssuer = new ASN1ObjectIdentifier("2.5.29.29");
+
+ /**
+ * Name Constraints
+ */
+ public static final ASN1ObjectIdentifier nameConstraints = new ASN1ObjectIdentifier("2.5.29.30");
+
+ /**
+ * CRL Distribution Points
+ */
+ public static final ASN1ObjectIdentifier cRLDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31");
+
+ /**
+ * Certificate Policies
+ */
+ public static final ASN1ObjectIdentifier certificatePolicies = new ASN1ObjectIdentifier("2.5.29.32");
+
+ /**
+ * Policy Mappings
+ */
+ public static final ASN1ObjectIdentifier policyMappings = new ASN1ObjectIdentifier("2.5.29.33");
+
+ /**
+ * Authority Key Identifier
+ */
+ public static final ASN1ObjectIdentifier authorityKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.35");
+
+ /**
+ * Policy Constraints
+ */
+ public static final ASN1ObjectIdentifier policyConstraints = new ASN1ObjectIdentifier("2.5.29.36");
+
+ /**
+ * Extended Key Usage
+ */
+ public static final ASN1ObjectIdentifier extendedKeyUsage = new ASN1ObjectIdentifier("2.5.29.37");
+
+ /**
+ * Freshest CRL
+ */
+ public static final ASN1ObjectIdentifier freshestCRL = new ASN1ObjectIdentifier("2.5.29.46");
+
+ /**
+ * Inhibit Any Policy
+ */
+ public static final ASN1ObjectIdentifier inhibitAnyPolicy = new ASN1ObjectIdentifier("2.5.29.54");
+
+ /**
+ * Authority Info Access
+ */
+ public static final ASN1ObjectIdentifier authorityInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.1");
+
+ /**
+ * Subject Info Access
+ */
+ public static final ASN1ObjectIdentifier subjectInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.11");
+
+ /**
+ * Logo Type
+ */
+ public static final ASN1ObjectIdentifier logoType = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.12");
+
+ /**
+ * BiometricInfo
+ */
+ public static final ASN1ObjectIdentifier biometricInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.2");
+
+ /**
+ * QCStatements
+ */
+ public static final ASN1ObjectIdentifier qCStatements = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.3");
+
+ /**
+ * Audit identity extension in attribute certificates.
+ */
+ public static final ASN1ObjectIdentifier auditIdentity = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.4");
+
+ /**
+ * NoRevAvail extension in attribute certificates.
+ */
+ public static final ASN1ObjectIdentifier noRevAvail = new ASN1ObjectIdentifier("2.5.29.56");
+
+ /**
+ * TargetInformation extension in attribute certificates.
+ */
+ public static final ASN1ObjectIdentifier targetInformation = new ASN1ObjectIdentifier("2.5.29.55");
+
+ boolean critical;
+ ASN1OctetString value;
+
+ public X509Extension(
+ ASN1Boolean critical,
+ ASN1OctetString value)
+ {
+ this.critical = critical.isTrue();
+ this.value = value;
+ }
+
+ public X509Extension(
+ boolean critical,
+ ASN1OctetString value)
+ {
+ this.critical = critical;
+ this.value = value;
+ }
+
+ public boolean isCritical()
+ {
+ return critical;
+ }
+
+ public ASN1OctetString getValue()
+ {
+ return value;
+ }
+
+ public ASN1Encodable getParsedValue()
+ {
+ return convertValueToObject(this);
+ }
+
+ public int hashCode()
+ {
+ if (this.isCritical())
+ {
+ return this.getValue().hashCode();
+ }
+
+ return ~this.getValue().hashCode();
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof X509Extension))
+ {
+ return false;
+ }
+
+ X509Extension other = (X509Extension)o;
+
+ return other.getValue().equals(this.getValue())
+ && (other.isCritical() == this.isCritical());
+ }
+
+ /**
+ * Convert the value of the passed in extension to an object
+ * @param ext the extension to parse
+ * @return the object the value string contains
+ * @exception IllegalArgumentException if conversion is not possible
+ */
+ public static ASN1Primitive convertValueToObject(
+ X509Extension ext)
+ throws IllegalArgumentException
+ {
+ try
+ {
+ return ASN1Primitive.fromByteArray(ext.getValue().getOctets());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("can't convert extension: " + e);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extensions.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extensions.java
new file mode 100644
index 00000000..2f3fbefd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extensions.java
@@ -0,0 +1,480 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Boolean;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @deprecated use {@link Extensions}
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509Extensions
+ extends ASN1Object
+{
+ /**
+ * Subject Directory Attributes
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier SubjectDirectoryAttributes = new ASN1ObjectIdentifier("2.5.29.9");
+
+ /**
+ * Subject Key Identifier
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier SubjectKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.14");
+
+ /**
+ * Key Usage
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier KeyUsage = new ASN1ObjectIdentifier("2.5.29.15");
+
+ /**
+ * Private Key Usage Period
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier PrivateKeyUsagePeriod = new ASN1ObjectIdentifier("2.5.29.16");
+
+ /**
+ * Subject Alternative Name
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier SubjectAlternativeName = new ASN1ObjectIdentifier("2.5.29.17");
+
+ /**
+ * Issuer Alternative Name
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier IssuerAlternativeName = new ASN1ObjectIdentifier("2.5.29.18");
+
+ /**
+ * Basic Constraints
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier BasicConstraints = new ASN1ObjectIdentifier("2.5.29.19");
+
+ /**
+ * CRL Number
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier CRLNumber = new ASN1ObjectIdentifier("2.5.29.20");
+
+ /**
+ * Reason code
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier ReasonCode = new ASN1ObjectIdentifier("2.5.29.21");
+
+ /**
+ * Hold Instruction Code
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier InstructionCode = new ASN1ObjectIdentifier("2.5.29.23");
+
+ /**
+ * Invalidity Date
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier InvalidityDate = new ASN1ObjectIdentifier("2.5.29.24");
+
+ /**
+ * Delta CRL indicator
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier DeltaCRLIndicator = new ASN1ObjectIdentifier("2.5.29.27");
+
+ /**
+ * Issuing Distribution Point
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier IssuingDistributionPoint = new ASN1ObjectIdentifier("2.5.29.28");
+
+ /**
+ * Certificate Issuer
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier CertificateIssuer = new ASN1ObjectIdentifier("2.5.29.29");
+
+ /**
+ * Name Constraints
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier NameConstraints = new ASN1ObjectIdentifier("2.5.29.30");
+
+ /**
+ * CRL Distribution Points
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier CRLDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31");
+
+ /**
+ * Certificate Policies
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier CertificatePolicies = new ASN1ObjectIdentifier("2.5.29.32");
+
+ /**
+ * Policy Mappings
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier PolicyMappings = new ASN1ObjectIdentifier("2.5.29.33");
+
+ /**
+ * Authority Key Identifier
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier AuthorityKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.35");
+
+ /**
+ * Policy Constraints
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier PolicyConstraints = new ASN1ObjectIdentifier("2.5.29.36");
+
+ /**
+ * Extended Key Usage
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier ExtendedKeyUsage = new ASN1ObjectIdentifier("2.5.29.37");
+
+ /**
+ * Freshest CRL
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier FreshestCRL = new ASN1ObjectIdentifier("2.5.29.46");
+
+ /**
+ * Inhibit Any Policy
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier InhibitAnyPolicy = new ASN1ObjectIdentifier("2.5.29.54");
+
+ /**
+ * Authority Info Access
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier AuthorityInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.1");
+
+ /**
+ * Subject Info Access
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier SubjectInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.11");
+
+ /**
+ * Logo Type
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier LogoType = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.12");
+
+ /**
+ * BiometricInfo
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier BiometricInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.2");
+
+ /**
+ * QCStatements
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier QCStatements = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.3");
+
+ /**
+ * Audit identity extension in attribute certificates.
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier AuditIdentity = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.4");
+
+ /**
+ * NoRevAvail extension in attribute certificates.
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier NoRevAvail = new ASN1ObjectIdentifier("2.5.29.56");
+
+ /**
+ * TargetInformation extension in attribute certificates.
+ * @deprecated use X509Extension value.
+ */
+ public static final ASN1ObjectIdentifier TargetInformation = new ASN1ObjectIdentifier("2.5.29.55");
+
+ private Hashtable extensions = new Hashtable();
+ private Vector ordering = new Vector();
+
+ public static X509Extensions getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static X509Extensions getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof X509Extensions)
+ {
+ return (X509Extensions)obj;
+ }
+
+ if (obj instanceof ASN1Sequence)
+ {
+ return new X509Extensions((ASN1Sequence)obj);
+ }
+
+ if (obj instanceof Extensions)
+ {
+ return new X509Extensions((ASN1Sequence)((Extensions)obj).toASN1Primitive());
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ return getInstance(((ASN1TaggedObject)obj).getObject());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * Constructor from ASN1Sequence.
+ *
+ * the extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString)
+ */
+ public X509Extensions(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ ASN1Sequence s = ASN1Sequence.getInstance(e.nextElement());
+
+ if (s.size() == 3)
+ {
+ extensions.put(s.getObjectAt(0), new X509Extension(ASN1Boolean.getInstance(s.getObjectAt(1)), ASN1OctetString.getInstance(s.getObjectAt(2))));
+ }
+ else if (s.size() == 2)
+ {
+ extensions.put(s.getObjectAt(0), new X509Extension(false, ASN1OctetString.getInstance(s.getObjectAt(1))));
+ }
+ else
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + s.size());
+ }
+
+ ordering.addElement(s.getObjectAt(0));
+ }
+ }
+
+ /**
+ * constructor from a table of extensions.
+ * <p>
+ * it's is assumed the table contains OID/String pairs.
+ */
+ public X509Extensions(
+ Hashtable extensions)
+ {
+ this(null, extensions);
+ }
+
+ /**
+ * Constructor from a table of extensions with ordering.
+ * <p>
+ * It's is assumed the table contains OID/String pairs.
+ * @deprecated use Extensions
+ */
+ public X509Extensions(
+ Vector ordering,
+ Hashtable extensions)
+ {
+ Enumeration e;
+
+ if (ordering == null)
+ {
+ e = extensions.keys();
+ }
+ else
+ {
+ e = ordering.elements();
+ }
+
+ while (e.hasMoreElements())
+ {
+ this.ordering.addElement(ASN1ObjectIdentifier.getInstance(e.nextElement()));
+ }
+
+ e = this.ordering.elements();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(e.nextElement());
+ X509Extension ext = (X509Extension)extensions.get(oid);
+
+ this.extensions.put(oid, ext);
+ }
+ }
+
+ /**
+ * Constructor from two vectors
+ *
+ * @param objectIDs a vector of the object identifiers.
+ * @param values a vector of the extension values.
+ * @deprecated use Extensions
+ */
+ public X509Extensions(
+ Vector objectIDs,
+ Vector values)
+ {
+ Enumeration e = objectIDs.elements();
+
+ while (e.hasMoreElements())
+ {
+ this.ordering.addElement(e.nextElement());
+ }
+
+ int count = 0;
+
+ e = this.ordering.elements();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ X509Extension ext = (X509Extension)values.elementAt(count);
+
+ this.extensions.put(oid, ext);
+ count++;
+ }
+ }
+
+ /**
+ * return an Enumeration of the extension field's object ids.
+ */
+ public Enumeration oids()
+ {
+ return ordering.elements();
+ }
+
+ /**
+ * return the extension represented by the object identifier
+ * passed in.
+ *
+ * @return the extension if it's present, null otherwise.
+ */
+ public X509Extension getExtension(
+ ASN1ObjectIdentifier oid)
+ {
+ return (X509Extension)extensions.get(oid);
+ }
+
+ /**
+ * <pre>
+ * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ *
+ * Extension ::= SEQUENCE {
+ * extnId EXTENSION.&amp;id ({ExtensionSet}),
+ * critical BOOLEAN DEFAULT FALSE,
+ * extnValue OCTET STRING }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector vec = new ASN1EncodableVector(ordering.size());
+
+ Enumeration e = ordering.elements();
+ while (e.hasMoreElements())
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ X509Extension ext = (X509Extension)extensions.get(oid);
+
+ v.add(oid);
+
+ if (ext.isCritical())
+ {
+ v.add(ASN1Boolean.TRUE);
+ }
+
+ v.add(ext.getValue());
+
+ vec.add(new DERSequence(v));
+ }
+
+ return new DERSequence(vec);
+ }
+
+ public boolean equivalent(
+ X509Extensions other)
+ {
+ if (extensions.size() != other.extensions.size())
+ {
+ return false;
+ }
+
+ Enumeration e1 = extensions.keys();
+
+ while (e1.hasMoreElements())
+ {
+ Object key = e1.nextElement();
+
+ if (!extensions.get(key).equals(other.extensions.get(key)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public ASN1ObjectIdentifier[] getExtensionOIDs()
+ {
+ return toOidArray(ordering);
+ }
+
+ public ASN1ObjectIdentifier[] getNonCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(false);
+ }
+
+ public ASN1ObjectIdentifier[] getCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(true);
+ }
+
+ private ASN1ObjectIdentifier[] getExtensionOIDs(boolean isCritical)
+ {
+ Vector oidVec = new Vector();
+
+ for (int i = 0; i != ordering.size(); i++)
+ {
+ Object oid = ordering.elementAt(i);
+
+ if (((X509Extension)extensions.get(oid)).isCritical() == isCritical)
+ {
+ oidVec.addElement(oid);
+ }
+ }
+
+ return toOidArray(oidVec);
+ }
+
+ private ASN1ObjectIdentifier[] toOidArray(Vector oidVec)
+ {
+ ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[oidVec.size()];
+
+ for (int i = 0; i != oids.length; i++)
+ {
+ oids[i] = (ASN1ObjectIdentifier)oidVec.elementAt(i);
+ }
+ return oids;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ExtensionsGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ExtensionsGenerator.java
new file mode 100644
index 00000000..04aa1420
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ExtensionsGenerator.java
@@ -0,0 +1,96 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Vector;
+
+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.DEROctetString;
+
+/**
+ * Generator for X.509 extensions
+ * @deprecated use org.bouncycastle.asn1.x509.ExtensionsGenerator
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509ExtensionsGenerator
+{
+ private Hashtable extensions = new Hashtable();
+ private Vector extOrdering = new Vector();
+
+ /**
+ * Reset the generator
+ */
+ public void reset()
+ {
+ extensions = new Hashtable();
+ extOrdering = new Vector();
+ }
+
+ /**
+ * Add an extension with the given oid and the passed in value to be included
+ * in the OCTET STRING associated with the extension.
+ *
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the ASN.1 object to be included in the extension.
+ */
+ public void addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ ASN1Encodable value)
+ {
+ try
+ {
+ this.addExtension(oid, critical, value.toASN1Primitive().getEncoded(ASN1Encoding.DER));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("error encoding value: " + e);
+ }
+ }
+
+ /**
+ * Add an extension with the given oid and the passed in byte array to be wrapped in the
+ * OCTET STRING associated with the extension.
+ *
+ * @param oid OID for the extension.
+ * @param critical true if critical, false otherwise.
+ * @param value the byte array to be wrapped.
+ */
+ public void addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ byte[] value)
+ {
+ if (extensions.containsKey(oid))
+ {
+ throw new IllegalArgumentException("extension " + oid + " already added");
+ }
+
+ extOrdering.addElement(oid);
+ extensions.put(oid, new X509Extension(critical, new DEROctetString(value)));
+ }
+
+ /**
+ * Return true if there are no extension present in this generator.
+ *
+ * @return true if empty, false otherwise
+ */
+ public boolean isEmpty()
+ {
+ return extOrdering.isEmpty();
+ }
+
+ /**
+ * Generate an X509Extensions object based on the current state of the generator.
+ *
+ * @return an X09Extensions object.
+ */
+ public X509Extensions generate()
+ {
+ return new X509Extensions(extOrdering, extensions);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Name.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Name.java
new file mode 100644
index 00000000..90652395
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Name.java
@@ -0,0 +1,1383 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1String;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERSet;
+import com.android.internal.org.bouncycastle.asn1.DERUniversalString;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * <pre>
+ * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+ *
+ * RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
+ *
+ * AttributeTypeAndValue ::= SEQUENCE {
+ * type OBJECT IDENTIFIER,
+ * value ANY }
+ * </pre>
+ * @deprecated use org.bouncycastle.asn1.x500.X500Name.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509Name
+ extends ASN1Object
+{
+ /**
+ * country code - StringType(SIZE(2))
+ * @deprecated use a X500NameStyle
+ */
+ public static final ASN1ObjectIdentifier C = new ASN1ObjectIdentifier("2.5.4.6");
+
+ /**
+ * organization - StringType(SIZE(1..64))
+ * @deprecated use a X500NameStyle
+ */
+ public static final ASN1ObjectIdentifier O = new ASN1ObjectIdentifier("2.5.4.10");
+
+ /**
+ * organizational unit name - StringType(SIZE(1..64))
+ * @deprecated use a X500NameStyle
+ */
+ public static final ASN1ObjectIdentifier OU = new ASN1ObjectIdentifier("2.5.4.11");
+
+ /**
+ * Title
+ * @deprecated use a X500NameStyle
+ */
+ public static final ASN1ObjectIdentifier T = new ASN1ObjectIdentifier("2.5.4.12");
+
+ /**
+ * common name - StringType(SIZE(1..64))
+ * @deprecated use a X500NameStyle
+ */
+ public static final ASN1ObjectIdentifier CN = new ASN1ObjectIdentifier("2.5.4.3");
+
+ /**
+ * device serial number name - StringType(SIZE(1..64))
+ */
+ public static final ASN1ObjectIdentifier SN = new ASN1ObjectIdentifier("2.5.4.5");
+
+ /**
+ * street - StringType(SIZE(1..64))
+ */
+ public static final ASN1ObjectIdentifier STREET = new ASN1ObjectIdentifier("2.5.4.9");
+
+ /**
+ * device serial number name - StringType(SIZE(1..64))
+ */
+ public static final ASN1ObjectIdentifier SERIALNUMBER = SN;
+
+ /**
+ * locality name - StringType(SIZE(1..64))
+ */
+ public static final ASN1ObjectIdentifier L = new ASN1ObjectIdentifier("2.5.4.7");
+
+ /**
+ * state, or province name - StringType(SIZE(1..64))
+ */
+ public static final ASN1ObjectIdentifier ST = new ASN1ObjectIdentifier("2.5.4.8");
+
+ /**
+ * Naming attributes of type X520name
+ */
+ public static final ASN1ObjectIdentifier SURNAME = new ASN1ObjectIdentifier("2.5.4.4");
+ public static final ASN1ObjectIdentifier GIVENNAME = new ASN1ObjectIdentifier("2.5.4.42");
+ public static final ASN1ObjectIdentifier INITIALS = new ASN1ObjectIdentifier("2.5.4.43");
+ public static final ASN1ObjectIdentifier GENERATION = new ASN1ObjectIdentifier("2.5.4.44");
+ public static final ASN1ObjectIdentifier UNIQUE_IDENTIFIER = new ASN1ObjectIdentifier("2.5.4.45");
+
+ /**
+ * businessCategory - DirectoryString(SIZE(1..128)
+ */
+ public static final ASN1ObjectIdentifier BUSINESS_CATEGORY = new ASN1ObjectIdentifier(
+ "2.5.4.15");
+
+ /**
+ * postalCode - DirectoryString(SIZE(1..40)
+ */
+ public static final ASN1ObjectIdentifier POSTAL_CODE = new ASN1ObjectIdentifier(
+ "2.5.4.17");
+
+ /**
+ * dnQualifier - DirectoryString(SIZE(1..64)
+ */
+ public static final ASN1ObjectIdentifier DN_QUALIFIER = new ASN1ObjectIdentifier(
+ "2.5.4.46");
+
+ /**
+ * RFC 3039 Pseudonym - DirectoryString(SIZE(1..64)
+ */
+ public static final ASN1ObjectIdentifier PSEUDONYM = new ASN1ObjectIdentifier(
+ "2.5.4.65");
+
+
+ /**
+ * RFC 3039 DateOfBirth - GeneralizedTime - YYYYMMDD000000Z
+ */
+ public static final ASN1ObjectIdentifier DATE_OF_BIRTH = new ASN1ObjectIdentifier(
+ "1.3.6.1.5.5.7.9.1");
+
+ /**
+ * RFC 3039 PlaceOfBirth - DirectoryString(SIZE(1..128)
+ */
+ public static final ASN1ObjectIdentifier PLACE_OF_BIRTH = new ASN1ObjectIdentifier(
+ "1.3.6.1.5.5.7.9.2");
+
+ /**
+ * RFC 3039 Gender - PrintableString (SIZE(1)) -- "M", "F", "m" or "f"
+ */
+ public static final ASN1ObjectIdentifier GENDER = new ASN1ObjectIdentifier(
+ "1.3.6.1.5.5.7.9.3");
+
+ /**
+ * RFC 3039 CountryOfCitizenship - PrintableString (SIZE (2)) -- ISO 3166
+ * codes only
+ */
+ public static final ASN1ObjectIdentifier COUNTRY_OF_CITIZENSHIP = new ASN1ObjectIdentifier(
+ "1.3.6.1.5.5.7.9.4");
+
+ /**
+ * RFC 3039 CountryOfResidence - PrintableString (SIZE (2)) -- ISO 3166
+ * codes only
+ */
+ public static final ASN1ObjectIdentifier COUNTRY_OF_RESIDENCE = new ASN1ObjectIdentifier(
+ "1.3.6.1.5.5.7.9.5");
+
+
+ /**
+ * ISIS-MTT NameAtBirth - DirectoryString(SIZE(1..64)
+ */
+ public static final ASN1ObjectIdentifier NAME_AT_BIRTH = new ASN1ObjectIdentifier("1.3.36.8.3.14");
+
+ /**
+ * RFC 3039 PostalAddress - SEQUENCE SIZE (1..6) OF
+ * DirectoryString(SIZE(1..30))
+ */
+ public static final ASN1ObjectIdentifier POSTAL_ADDRESS = new ASN1ObjectIdentifier("2.5.4.16");
+
+ /**
+ * RFC 2256 dmdName
+ */
+ public static final ASN1ObjectIdentifier DMD_NAME = new ASN1ObjectIdentifier("2.5.4.54");
+
+ /**
+ * id-at-telephoneNumber
+ */
+ public static final ASN1ObjectIdentifier TELEPHONE_NUMBER = X509ObjectIdentifiers.id_at_telephoneNumber;
+
+ /**
+ * id-at-name
+ */
+ public static final ASN1ObjectIdentifier NAME = X509ObjectIdentifiers.id_at_name;
+
+ /**
+ * Email address (RSA PKCS#9 extension) - IA5String.
+ * <p>Note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here.
+ * @deprecated use a X500NameStyle
+ */
+ public static final ASN1ObjectIdentifier EmailAddress = PKCSObjectIdentifiers.pkcs_9_at_emailAddress;
+
+ /**
+ * more from PKCS#9
+ */
+ public static final ASN1ObjectIdentifier UnstructuredName = PKCSObjectIdentifiers.pkcs_9_at_unstructuredName;
+ public static final ASN1ObjectIdentifier UnstructuredAddress = PKCSObjectIdentifiers.pkcs_9_at_unstructuredAddress;
+
+ /**
+ * email address in Verisign certificates
+ */
+ public static final ASN1ObjectIdentifier E = EmailAddress;
+
+ /*
+ * others...
+ */
+ public static final ASN1ObjectIdentifier DC = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.25");
+
+ /**
+ * LDAP User id.
+ */
+ public static final ASN1ObjectIdentifier UID = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1");
+
+ /**
+ * determines whether or not strings should be processed and printed
+ * from back to front.
+ */
+ public static boolean DefaultReverse = false;
+
+ /**
+ * default look up table translating OID values into their common symbols following
+ * the convention in RFC 2253 with a few extras
+ */
+ public static final Hashtable DefaultSymbols = new Hashtable();
+
+ /**
+ * look up table translating OID values into their common symbols following the convention in RFC 2253
+ *
+ */
+ public static final Hashtable RFC2253Symbols = new Hashtable();
+
+ /**
+ * look up table translating OID values into their common symbols following the convention in RFC 1779
+ *
+ */
+ public static final Hashtable RFC1779Symbols = new Hashtable();
+
+ /**
+ * look up table translating common symbols into their OIDS.
+ */
+ public static final Hashtable DefaultLookUp = new Hashtable();
+
+ /**
+ * look up table translating OID values into their common symbols
+ * @deprecated use DefaultSymbols
+ */
+ public static final Hashtable OIDLookUp = DefaultSymbols;
+
+ /**
+ * look up table translating string values into their OIDS -
+ * @deprecated use DefaultLookUp
+ */
+ public static final Hashtable SymbolLookUp = DefaultLookUp;
+
+ // BEGIN Android-changed: Use Boolean class constants instead of Boolean constructor
+ private static final Boolean TRUE = Boolean.TRUE;
+ private static final Boolean FALSE = Boolean.FALSE;
+ // END Android-changed: Use Boolean class constants instead of Boolean constructor
+
+ static
+ {
+ DefaultSymbols.put(C, "C");
+ DefaultSymbols.put(O, "O");
+ DefaultSymbols.put(T, "T");
+ DefaultSymbols.put(OU, "OU");
+ DefaultSymbols.put(CN, "CN");
+ DefaultSymbols.put(L, "L");
+ DefaultSymbols.put(ST, "ST");
+ DefaultSymbols.put(SN, "SERIALNUMBER");
+ DefaultSymbols.put(EmailAddress, "E");
+ DefaultSymbols.put(DC, "DC");
+ DefaultSymbols.put(UID, "UID");
+ DefaultSymbols.put(STREET, "STREET");
+ DefaultSymbols.put(SURNAME, "SURNAME");
+ DefaultSymbols.put(GIVENNAME, "GIVENNAME");
+ DefaultSymbols.put(INITIALS, "INITIALS");
+ DefaultSymbols.put(GENERATION, "GENERATION");
+ DefaultSymbols.put(UnstructuredAddress, "unstructuredAddress");
+ DefaultSymbols.put(UnstructuredName, "unstructuredName");
+ DefaultSymbols.put(UNIQUE_IDENTIFIER, "UniqueIdentifier");
+ DefaultSymbols.put(DN_QUALIFIER, "DN");
+ DefaultSymbols.put(PSEUDONYM, "Pseudonym");
+ DefaultSymbols.put(POSTAL_ADDRESS, "PostalAddress");
+ DefaultSymbols.put(NAME_AT_BIRTH, "NameAtBirth");
+ DefaultSymbols.put(COUNTRY_OF_CITIZENSHIP, "CountryOfCitizenship");
+ DefaultSymbols.put(COUNTRY_OF_RESIDENCE, "CountryOfResidence");
+ DefaultSymbols.put(GENDER, "Gender");
+ DefaultSymbols.put(PLACE_OF_BIRTH, "PlaceOfBirth");
+ DefaultSymbols.put(DATE_OF_BIRTH, "DateOfBirth");
+ DefaultSymbols.put(POSTAL_CODE, "PostalCode");
+ DefaultSymbols.put(BUSINESS_CATEGORY, "BusinessCategory");
+ DefaultSymbols.put(TELEPHONE_NUMBER, "TelephoneNumber");
+ DefaultSymbols.put(NAME, "Name");
+
+ RFC2253Symbols.put(C, "C");
+ RFC2253Symbols.put(O, "O");
+ RFC2253Symbols.put(OU, "OU");
+ RFC2253Symbols.put(CN, "CN");
+ RFC2253Symbols.put(L, "L");
+ RFC2253Symbols.put(ST, "ST");
+ RFC2253Symbols.put(STREET, "STREET");
+ RFC2253Symbols.put(DC, "DC");
+ RFC2253Symbols.put(UID, "UID");
+
+ RFC1779Symbols.put(C, "C");
+ RFC1779Symbols.put(O, "O");
+ RFC1779Symbols.put(OU, "OU");
+ RFC1779Symbols.put(CN, "CN");
+ RFC1779Symbols.put(L, "L");
+ RFC1779Symbols.put(ST, "ST");
+ RFC1779Symbols.put(STREET, "STREET");
+
+ DefaultLookUp.put("c", C);
+ DefaultLookUp.put("o", O);
+ DefaultLookUp.put("t", T);
+ DefaultLookUp.put("ou", OU);
+ DefaultLookUp.put("cn", CN);
+ DefaultLookUp.put("l", L);
+ DefaultLookUp.put("st", ST);
+ DefaultLookUp.put("sn", SN);
+ DefaultLookUp.put("serialnumber", SN);
+ DefaultLookUp.put("street", STREET);
+ DefaultLookUp.put("emailaddress", E);
+ DefaultLookUp.put("dc", DC);
+ DefaultLookUp.put("e", E);
+ DefaultLookUp.put("uid", UID);
+ DefaultLookUp.put("surname", SURNAME);
+ DefaultLookUp.put("givenname", GIVENNAME);
+ DefaultLookUp.put("initials", INITIALS);
+ DefaultLookUp.put("generation", GENERATION);
+ DefaultLookUp.put("unstructuredaddress", UnstructuredAddress);
+ DefaultLookUp.put("unstructuredname", UnstructuredName);
+ DefaultLookUp.put("uniqueidentifier", UNIQUE_IDENTIFIER);
+ DefaultLookUp.put("dn", DN_QUALIFIER);
+ DefaultLookUp.put("pseudonym", PSEUDONYM);
+ DefaultLookUp.put("postaladdress", POSTAL_ADDRESS);
+ DefaultLookUp.put("nameofbirth", NAME_AT_BIRTH);
+ DefaultLookUp.put("countryofcitizenship", COUNTRY_OF_CITIZENSHIP);
+ DefaultLookUp.put("countryofresidence", COUNTRY_OF_RESIDENCE);
+ DefaultLookUp.put("gender", GENDER);
+ DefaultLookUp.put("placeofbirth", PLACE_OF_BIRTH);
+ DefaultLookUp.put("dateofbirth", DATE_OF_BIRTH);
+ DefaultLookUp.put("postalcode", POSTAL_CODE);
+ DefaultLookUp.put("businesscategory", BUSINESS_CATEGORY);
+ DefaultLookUp.put("telephonenumber", TELEPHONE_NUMBER);
+ DefaultLookUp.put("name", NAME);
+ }
+
+ private X509NameEntryConverter converter = null;
+ private Vector ordering = new Vector();
+ private Vector values = new Vector();
+ private Vector added = new Vector();
+
+ private ASN1Sequence seq;
+
+ private boolean isHashCodeCalculated;
+ private int hashCodeValue;
+
+ /**
+ * Return a X509Name based on the passed in tagged object.
+ *
+ * @param obj tag object holding name.
+ * @param explicit true if explicitly tagged false otherwise.
+ * @return the X509Name
+ */
+ public static X509Name getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static X509Name getInstance(
+ Object obj)
+ {
+ if (obj instanceof X509Name)
+ {
+ return (X509Name)obj;
+ }
+ else if (obj instanceof X500Name)
+ {
+ return new X509Name(ASN1Sequence.getInstance(((X500Name)obj).toASN1Primitive()));
+ }
+ else if (obj != null)
+ {
+ return new X509Name(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ protected X509Name()
+ {
+ // constructure use by new X500 Name class
+ }
+ /**
+ * Constructor from ASN1Sequence
+ *
+ * the principal will be a list of constructed sets, each containing an (OID, String) pair.
+ * @deprecated use X500Name.getInstance()
+ */
+ public X509Name(
+ ASN1Sequence seq)
+ {
+ this.seq = seq;
+
+ Enumeration e = seq.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ ASN1Set set = ASN1Set.getInstance(((ASN1Encodable)e.nextElement()).toASN1Primitive());
+
+ for (int i = 0; i < set.size(); i++)
+ {
+ ASN1Sequence s = ASN1Sequence.getInstance(set.getObjectAt(i).toASN1Primitive());
+
+ if (s.size() != 2)
+ {
+ throw new IllegalArgumentException("badly sized pair");
+ }
+
+ ordering.addElement(ASN1ObjectIdentifier.getInstance(s.getObjectAt(0)));
+
+ ASN1Encodable value = s.getObjectAt(1);
+ if (value instanceof ASN1String && !(value instanceof DERUniversalString))
+ {
+ String v = ((ASN1String)value).getString();
+ if (v.length() > 0 && v.charAt(0) == '#')
+ {
+ values.addElement("\\" + v);
+ }
+ else
+ {
+ values.addElement(v);
+ }
+ }
+ else
+ {
+ try
+ {
+ values.addElement("#" + bytesToString(Hex.encode(value.toASN1Primitive().getEncoded(ASN1Encoding.DER))));
+ }
+ catch (IOException e1)
+ {
+ throw new IllegalArgumentException("cannot encode value");
+ }
+ }
+ added.addElement((i != 0) ? TRUE : FALSE); // to allow earlier JDK compatibility
+ }
+ }
+ }
+
+ /**
+ * constructor from a table of attributes.
+ * <p>
+ * it's is assumed the table contains OID/String pairs, and the contents
+ * of the table are copied into an internal table as part of the
+ * construction process.
+ * <p>
+ * <b>Note:</b> if the name you are trying to generate should be
+ * following a specific ordering, you should use the constructor
+ * with the ordering specified below.
+ * @deprecated use an ordered constructor! The hashtable ordering is rarely correct
+ */
+ public X509Name(
+ Hashtable attributes)
+ {
+ this(null, attributes);
+ }
+
+ /**
+ * Constructor from a table of attributes with ordering.
+ * <p>
+ * it's is assumed the table contains OID/String pairs, and the contents
+ * of the table are copied into an internal table as part of the
+ * construction process. The ordering vector should contain the OIDs
+ * in the order they are meant to be encoded or printed in toString.
+ */
+ public X509Name(
+ Vector ordering,
+ Hashtable attributes)
+ {
+ this(ordering, attributes, new X509DefaultEntryConverter());
+ }
+
+ /**
+ * Constructor from a table of attributes with ordering.
+ * <p>
+ * it's is assumed the table contains OID/String pairs, and the contents
+ * of the table are copied into an internal table as part of the
+ * construction process. The ordering vector should contain the OIDs
+ * in the order they are meant to be encoded or printed in toString.
+ * <p>
+ * The passed in converter will be used to convert the strings into their
+ * ASN.1 counterparts.
+ * @deprecated use X500Name, X500NameBuilder
+ */
+ public X509Name(
+ Vector ordering,
+ Hashtable attributes,
+ X509NameEntryConverter converter)
+ {
+ this.converter = converter;
+
+ if (ordering != null)
+ {
+ for (int i = 0; i != ordering.size(); i++)
+ {
+ this.ordering.addElement(ordering.elementAt(i));
+ this.added.addElement(FALSE);
+ }
+ }
+ else
+ {
+ Enumeration e = attributes.keys();
+
+ while (e.hasMoreElements())
+ {
+ this.ordering.addElement(e.nextElement());
+ this.added.addElement(FALSE);
+ }
+ }
+
+ for (int i = 0; i != this.ordering.size(); i++)
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)this.ordering.elementAt(i);
+
+ if (attributes.get(oid) == null)
+ {
+ throw new IllegalArgumentException("No attribute for object id - " + oid.getId() + " - passed to distinguished name");
+ }
+
+ this.values.addElement(attributes.get(oid)); // copy the hash table
+ }
+ }
+
+ /**
+ * Takes two vectors one of the oids and the other of the values.
+ * @deprecated use X500Name, X500NameBuilder
+ */
+ public X509Name(
+ Vector oids,
+ Vector values)
+ {
+ this(oids, values, new X509DefaultEntryConverter());
+ }
+
+ /**
+ * Takes two vectors one of the oids and the other of the values.
+ * <p>
+ * The passed in converter will be used to convert the strings into their
+ * ASN.1 counterparts.
+ * @deprecated use X500Name, X500NameBuilder
+ */
+ public X509Name(
+ Vector oids,
+ Vector values,
+ X509NameEntryConverter converter)
+ {
+ this.converter = converter;
+
+ if (oids.size() != values.size())
+ {
+ throw new IllegalArgumentException("oids vector must be same length as values.");
+ }
+
+ for (int i = 0; i < oids.size(); i++)
+ {
+ this.ordering.addElement(oids.elementAt(i));
+ this.values.addElement(values.elementAt(i));
+ this.added.addElement(FALSE);
+ }
+ }
+
+// private Boolean isEncoded(String s)
+// {
+// if (s.charAt(0) == '#')
+// {
+// return TRUE;
+// }
+//
+// return FALSE;
+// }
+
+ /**
+ * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
+ * some such, converting it into an ordered set of name attributes.
+ * @deprecated use X500Name, X500NameBuilder
+ */
+ public X509Name(
+ String dirName)
+ {
+ this(DefaultReverse, DefaultLookUp, dirName);
+ }
+
+ /**
+ * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
+ * some such, converting it into an ordered set of name attributes with each
+ * string value being converted to its associated ASN.1 type using the passed
+ * in converter.
+ * @deprecated use X500Name, X500NameBuilder
+ */
+ public X509Name(
+ String dirName,
+ X509NameEntryConverter converter)
+ {
+ this(DefaultReverse, DefaultLookUp, dirName, converter);
+ }
+
+ /**
+ * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
+ * some such, converting it into an ordered set of name attributes. If reverse
+ * is true, create the encoded version of the sequence starting from the
+ * last element in the string.
+ * @deprecated use X500Name, X500NameBuilder
+ */
+ public X509Name(
+ boolean reverse,
+ String dirName)
+ {
+ this(reverse, DefaultLookUp, dirName);
+ }
+
+ /**
+ * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
+ * some such, converting it into an ordered set of name attributes with each
+ * string value being converted to its associated ASN.1 type using the passed
+ * in converter. If reverse is true the ASN.1 sequence representing the DN will
+ * be built by starting at the end of the string, rather than the start.
+ * @deprecated use X500Name, X500NameBuilder
+ */
+ public X509Name(
+ boolean reverse,
+ String dirName,
+ X509NameEntryConverter converter)
+ {
+ this(reverse, DefaultLookUp, dirName, converter);
+ }
+
+ /**
+ * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
+ * some such, converting it into an ordered set of name attributes. lookUp
+ * should provide a table of lookups, indexed by lowercase only strings and
+ * yielding a ASN1ObjectIdentifier, other than that OID. and numeric oids
+ * will be processed automatically.
+ * <br>
+ * If reverse is true, create the encoded version of the sequence
+ * starting from the last element in the string.
+ * @param reverse true if we should start scanning from the end (RFC 2553).
+ * @param lookUp table of names and their oids.
+ * @param dirName the X.500 string to be parsed.
+ * @deprecated use X500Name, X500NameBuilder
+ */
+ public X509Name(
+ boolean reverse,
+ Hashtable lookUp,
+ String dirName)
+ {
+ this(reverse, lookUp, dirName, new X509DefaultEntryConverter());
+ }
+
+ private ASN1ObjectIdentifier decodeOID(
+ String name,
+ Hashtable lookUp)
+ {
+ name = name.trim();
+ if (Strings.toUpperCase(name).startsWith("OID."))
+ {
+ return new ASN1ObjectIdentifier(name.substring(4));
+ }
+ else if (name.charAt(0) >= '0' && name.charAt(0) <= '9')
+ {
+ return new ASN1ObjectIdentifier(name);
+ }
+
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)lookUp.get(Strings.toLowerCase(name));
+ if (oid == null)
+ {
+ throw new IllegalArgumentException("Unknown object id - " + name + " - passed to distinguished name");
+ }
+
+ return oid;
+ }
+
+ private String unescape(String elt)
+ {
+ if (elt.length() == 0 || (elt.indexOf('\\') < 0 && elt.indexOf('"') < 0))
+ {
+ return elt.trim();
+ }
+
+ char[] elts = elt.toCharArray();
+ boolean escaped = false;
+ boolean quoted = false;
+ StringBuffer buf = new StringBuffer(elt.length());
+ int start = 0;
+
+ // if it's an escaped hash string and not an actual encoding in string form
+ // we need to leave it escaped.
+ if (elts[0] == '\\')
+ {
+ if (elts[1] == '#')
+ {
+ start = 2;
+ buf.append("\\#");
+ }
+ }
+
+ boolean nonWhiteSpaceEncountered = false;
+ int lastEscaped = 0;
+
+ for (int i = start; i != elts.length; i++)
+ {
+ char c = elts[i];
+
+ if (c != ' ')
+ {
+ nonWhiteSpaceEncountered = true;
+ }
+
+ if (c == '"')
+ {
+ if (!escaped)
+ {
+ quoted = !quoted;
+ }
+ else
+ {
+ buf.append(c);
+ }
+ escaped = false;
+ }
+ else if (c == '\\' && !(escaped || quoted))
+ {
+ escaped = true;
+ lastEscaped = buf.length();
+ }
+ else
+ {
+ if (c == ' ' && !escaped && !nonWhiteSpaceEncountered)
+ {
+ continue;
+ }
+ buf.append(c);
+ escaped = false;
+ }
+ }
+
+ if (buf.length() > 0)
+ {
+ while (buf.charAt(buf.length() - 1) == ' ' && lastEscaped != (buf.length() - 1))
+ {
+ buf.setLength(buf.length() - 1);
+ }
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
+ * some such, converting it into an ordered set of name attributes. lookUp
+ * should provide a table of lookups, indexed by lowercase only strings and
+ * yielding a ASN1ObjectIdentifier, other than that OID. and numeric oids
+ * will be processed automatically. The passed in converter is used to convert the
+ * string values to the right of each equals sign to their ASN.1 counterparts.
+ * <br>
+ * @param reverse true if we should start scanning from the end, false otherwise.
+ * @param lookUp table of names and oids.
+ * @param dirName the string dirName
+ * @param converter the converter to convert string values into their ASN.1 equivalents
+ */
+ public X509Name(
+ boolean reverse,
+ Hashtable lookUp,
+ String dirName,
+ X509NameEntryConverter converter)
+ {
+ this.converter = converter;
+ X509NameTokenizer nTok = new X509NameTokenizer(dirName);
+
+ while (nTok.hasMoreTokens())
+ {
+ String token = nTok.nextToken();
+
+ if (token.indexOf('+') > 0)
+ {
+ X509NameTokenizer pTok = new X509NameTokenizer(token, '+');
+
+ addEntry(lookUp, pTok.nextToken(), FALSE);
+
+ while (pTok.hasMoreTokens())
+ {
+ addEntry(lookUp, pTok.nextToken(), TRUE);
+ }
+ }
+ else
+ {
+ addEntry(lookUp, token, FALSE);
+ }
+ }
+
+ if (reverse)
+ {
+ Vector o = new Vector();
+ Vector v = new Vector();
+ Vector a = new Vector();
+
+ int count = 1;
+
+ for (int i = 0; i < this.ordering.size(); i++)
+ {
+ if (((Boolean)this.added.elementAt(i)).booleanValue())
+ {
+ o.insertElementAt(this.ordering.elementAt(i), count);
+ v.insertElementAt(this.values.elementAt(i), count);
+ a.insertElementAt(this.added.elementAt(i), count);
+ count++;
+ }
+ else
+ {
+ o.insertElementAt(this.ordering.elementAt(i), 0);
+ v.insertElementAt(this.values.elementAt(i), 0);
+ a.insertElementAt(this.added.elementAt(i), 0);
+ count = 1;
+ }
+ }
+
+ this.ordering = o;
+ this.values = v;
+ this.added = a;
+ }
+ }
+
+ private void addEntry(Hashtable lookUp, String token, Boolean isAdded)
+ {
+ X509NameTokenizer vTok;
+ String name;
+ String value;ASN1ObjectIdentifier oid;
+ vTok = new X509NameTokenizer(token, '=');
+
+ name = vTok.nextToken();
+
+ if (!vTok.hasMoreTokens())
+ {
+ throw new IllegalArgumentException("badly formatted directory string");
+ }
+
+ value = vTok.nextToken();
+
+ oid = decodeOID(name, lookUp);
+
+ this.ordering.addElement(oid);
+ this.values.addElement(unescape(value));
+ this.added.addElement(isAdded);
+ }
+
+ /**
+ * return a vector of the oids in the name, in the order they were found.
+ */
+ public Vector getOIDs()
+ {
+ Vector v = new Vector();
+
+ for (int i = 0; i != ordering.size(); i++)
+ {
+ v.addElement(ordering.elementAt(i));
+ }
+
+ return v;
+ }
+
+ /**
+ * return a vector of the values found in the name, in the order they
+ * were found.
+ */
+ public Vector getValues()
+ {
+ Vector v = new Vector();
+
+ for (int i = 0; i != values.size(); i++)
+ {
+ v.addElement(values.elementAt(i));
+ }
+
+ return v;
+ }
+
+ /**
+ * return a vector of the values found in the name, in the order they
+ * were found, with the DN label corresponding to passed in oid.
+ */
+ public Vector getValues(
+ ASN1ObjectIdentifier oid)
+ {
+ Vector v = new Vector();
+
+ for (int i = 0; i != values.size(); i++)
+ {
+ if (ordering.elementAt(i).equals(oid))
+ {
+ String val = (String)values.elementAt(i);
+
+ if (val.length() > 2 && val.charAt(0) == '\\' && val.charAt(1) == '#')
+ {
+ v.addElement(val.substring(1));
+ }
+ else
+ {
+ v.addElement(val);
+ }
+ }
+ }
+
+ return v;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ if (seq == null)
+ {
+ ASN1EncodableVector vec = new ASN1EncodableVector();
+ ASN1EncodableVector sVec = new ASN1EncodableVector();
+ ASN1ObjectIdentifier lstOid = null;
+
+ for (int i = 0; i != ordering.size(); i++)
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)ordering.elementAt(i);
+
+ v.add(oid);
+
+ String str = (String)values.elementAt(i);
+
+ v.add(converter.getConvertedValue(oid, str));
+
+ if (lstOid == null
+ || ((Boolean)this.added.elementAt(i)).booleanValue())
+ {
+ sVec.add(new DERSequence(v));
+ }
+ else
+ {
+ vec.add(new DERSet(sVec));
+
+ sVec = new ASN1EncodableVector();
+ sVec.add(new DERSequence(v));
+ }
+
+ lstOid = oid;
+ }
+
+ vec.add(new DERSet(sVec));
+
+ seq = new DERSequence(vec);
+ }
+
+ return seq;
+ }
+
+ /**
+ * @param inOrder if true the order of both X509 names must be the same,
+ * as well as the values associated with each element.
+ */
+ public boolean equals(Object obj, boolean inOrder)
+ {
+ if (!inOrder)
+ {
+ return this.equals(obj);
+ }
+
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (!(obj instanceof X509Name || obj instanceof ASN1Sequence))
+ {
+ return false;
+ }
+
+ ASN1Primitive derO = ((ASN1Encodable)obj).toASN1Primitive();
+
+ if (this.toASN1Primitive().equals(derO))
+ {
+ return true;
+ }
+
+ X509Name other;
+
+ try
+ {
+ other = X509Name.getInstance(obj);
+ }
+ catch (IllegalArgumentException e)
+ {
+ return false;
+ }
+
+ int orderingSize = ordering.size();
+
+ if (orderingSize != other.ordering.size())
+ {
+ return false;
+ }
+
+ for (int i = 0; i < orderingSize; i++)
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)ordering.elementAt(i);
+ ASN1ObjectIdentifier oOid = (ASN1ObjectIdentifier)other.ordering.elementAt(i);
+
+ if (oid.equals(oOid))
+ {
+ String value = (String)values.elementAt(i);
+ String oValue = (String)other.values.elementAt(i);
+
+ if (!equivalentStrings(value, oValue))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ if (isHashCodeCalculated)
+ {
+ return hashCodeValue;
+ }
+
+ isHashCodeCalculated = true;
+
+ // this needs to be order independent, like equals
+ for (int i = 0; i != ordering.size(); i += 1)
+ {
+ String value = (String)values.elementAt(i);
+
+ value = canonicalize(value);
+ value = stripInternalSpaces(value);
+
+ hashCodeValue ^= ordering.elementAt(i).hashCode();
+ hashCodeValue ^= value.hashCode();
+ }
+
+ return hashCodeValue;
+ }
+
+ /**
+ * test for equality - note: case is ignored.
+ */
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (!(obj instanceof X509Name || obj instanceof ASN1Sequence))
+ {
+ return false;
+ }
+
+ ASN1Primitive derO = ((ASN1Encodable)obj).toASN1Primitive();
+
+ if (this.toASN1Primitive().equals(derO))
+ {
+ return true;
+ }
+
+ X509Name other;
+
+ try
+ {
+ other = X509Name.getInstance(obj);
+ }
+ catch (IllegalArgumentException e)
+ {
+ return false;
+ }
+
+ int orderingSize = ordering.size();
+
+ if (orderingSize != other.ordering.size())
+ {
+ return false;
+ }
+
+ boolean[] indexes = new boolean[orderingSize];
+ int start, end, delta;
+
+ if (ordering.elementAt(0).equals(other.ordering.elementAt(0))) // guess forward
+ {
+ start = 0;
+ end = orderingSize;
+ delta = 1;
+ }
+ else // guess reversed - most common problem
+ {
+ start = orderingSize - 1;
+ end = -1;
+ delta = -1;
+ }
+
+ for (int i = start; i != end; i += delta)
+ {
+ boolean found = false;
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)ordering.elementAt(i);
+ String value = (String)values.elementAt(i);
+
+ for (int j = 0; j < orderingSize; j++)
+ {
+ if (indexes[j])
+ {
+ continue;
+ }
+
+ ASN1ObjectIdentifier oOid = (ASN1ObjectIdentifier)other.ordering.elementAt(j);
+
+ if (oid.equals(oOid))
+ {
+ String oValue = (String)other.values.elementAt(j);
+
+ if (equivalentStrings(value, oValue))
+ {
+ indexes[j] = true;
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private boolean equivalentStrings(String s1, String s2)
+ {
+ String value = canonicalize(s1);
+ String oValue = canonicalize(s2);
+
+ if (!value.equals(oValue))
+ {
+ value = stripInternalSpaces(value);
+ oValue = stripInternalSpaces(oValue);
+
+ if (!value.equals(oValue))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private String canonicalize(String s)
+ {
+ String value = Strings.toLowerCase(s.trim());
+
+ if (value.length() > 0 && value.charAt(0) == '#')
+ {
+ ASN1Primitive obj = decodeObject(value);
+
+ if (obj instanceof ASN1String)
+ {
+ value = Strings.toLowerCase(((ASN1String)obj).getString().trim());
+ }
+ }
+
+ return value;
+ }
+
+ private ASN1Primitive decodeObject(String oValue)
+ {
+ try
+ {
+ return ASN1Primitive.fromByteArray(Hex.decodeStrict(oValue, 1, oValue.length() - 1));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unknown encoding in name: " + e);
+ }
+ }
+
+ private String stripInternalSpaces(
+ String str)
+ {
+ StringBuffer res = new StringBuffer();
+
+ if (str.length() != 0)
+ {
+ char c1 = str.charAt(0);
+
+ res.append(c1);
+
+ for (int k = 1; k < str.length(); k++)
+ {
+ char c2 = str.charAt(k);
+ if (!(c1 == ' ' && c2 == ' '))
+ {
+ res.append(c2);
+ }
+ c1 = c2;
+ }
+ }
+
+ return res.toString();
+ }
+
+ private void appendValue(
+ StringBuffer buf,
+ Hashtable oidSymbols,
+ ASN1ObjectIdentifier oid,
+ String value)
+ {
+ String sym = (String)oidSymbols.get(oid);
+
+ if (sym != null)
+ {
+ buf.append(sym);
+ }
+ else
+ {
+ buf.append(oid.getId());
+ }
+
+ buf.append('=');
+
+ int start = buf.length();
+ buf.append(value);
+ int end = buf.length();
+
+ if (value.length() >= 2 && value.charAt(0) == '\\' && value.charAt(1) == '#')
+ {
+ start += 2;
+ }
+
+ while (start < end && buf.charAt(start) == ' ')
+ {
+ buf.insert(start, "\\");
+ start += 2;
+ ++end;
+ }
+
+ while (--end > start && buf.charAt(end) == ' ')
+ {
+ buf.insert(end, '\\');
+ }
+
+ while (start <= end)
+ {
+ switch (buf.charAt(start))
+ {
+ case ',':
+ case '"':
+ case '\\':
+ case '+':
+ case '=':
+ case '<':
+ case '>':
+ case ';':
+ buf.insert(start, "\\");
+ start += 2;
+ ++end;
+ break;
+ default:
+ ++start;
+ break;
+ }
+ }
+ }
+
+ /**
+ * convert the structure to a string - if reverse is true the
+ * oids and values are listed out starting with the last element
+ * in the sequence (ala RFC 2253), otherwise the string will begin
+ * with the first element of the structure. If no string definition
+ * for the oid is found in oidSymbols the string value of the oid is
+ * added. Two standard symbol tables are provided DefaultSymbols, and
+ * RFC2253Symbols as part of this class.
+ *
+ * @param reverse if true start at the end of the sequence and work back.
+ * @param oidSymbols look up table strings for oids.
+ */
+ public String toString(
+ boolean reverse,
+ Hashtable oidSymbols)
+ {
+ StringBuffer buf = new StringBuffer();
+ Vector components = new Vector();
+ boolean first = true;
+
+ StringBuffer ava = null;
+
+ for (int i = 0; i < ordering.size(); i++)
+ {
+ if (((Boolean)added.elementAt(i)).booleanValue())
+ {
+ ava.append('+');
+ appendValue(ava, oidSymbols,
+ (ASN1ObjectIdentifier)ordering.elementAt(i),
+ (String)values.elementAt(i));
+ }
+ else
+ {
+ ava = new StringBuffer();
+ appendValue(ava, oidSymbols,
+ (ASN1ObjectIdentifier)ordering.elementAt(i),
+ (String)values.elementAt(i));
+ components.addElement(ava);
+ }
+ }
+
+ if (reverse)
+ {
+ for (int i = components.size() - 1; i >= 0; i--)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ buf.append(',');
+ }
+
+ buf.append(components.elementAt(i).toString());
+ }
+ }
+ else
+ {
+ for (int i = 0; i < components.size(); i++)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ buf.append(',');
+ }
+
+ buf.append(components.elementAt(i).toString());
+ }
+ }
+
+ return buf.toString();
+ }
+
+ private String bytesToString(
+ byte[] data)
+ {
+ char[] cs = new char[data.length];
+
+ for (int i = 0; i != cs.length; i++)
+ {
+ cs[i] = (char)(data[i] & 0xff);
+ }
+
+ return new String(cs);
+ }
+
+ public String toString()
+ {
+ return toString(DefaultReverse, DefaultSymbols);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameEntryConverter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
new file mode 100644
index 00000000..9329e674
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
@@ -0,0 +1,88 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERPrintableString;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * It turns out that the number of standard ways the fields in a DN should be
+ * encoded into their ASN.1 counterparts is rapidly approaching the
+ * number of machines on the internet. By default the X509Name class
+ * will produce UTF8Strings in line with the current recommendations (RFC 3280).
+ * <p>
+ * An example of an encoder look like below:
+ * <pre>
+ * public class X509DirEntryConverter
+ * extends X509NameEntryConverter
+ * {
+ * public ASN1Primitive getConvertedValue(
+ * ASN1ObjectIdentifier oid,
+ * String value)
+ * {
+ * if (str.length() != 0 &amp;&amp; str.charAt(0) == '#')
+ * {
+ * return convertHexEncoded(str, 1);
+ * }
+ * if (oid.equals(EmailAddress))
+ * {
+ * return new DERIA5String(str);
+ * }
+ * else if (canBePrintable(str))
+ * {
+ * return new DERPrintableString(str);
+ * }
+ * else if (canBeUTF8(str))
+ * {
+ * return new DERUTF8String(str);
+ * }
+ * else
+ * {
+ * return new DERBMPString(str);
+ * }
+ * }
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class X509NameEntryConverter
+{
+ /**
+ * Convert an inline encoded hex string rendition of an ASN.1
+ * object back into its corresponding ASN.1 object.
+ *
+ * @param str the hex encoded object
+ * @param off the index at which the encoding starts
+ * @return the decoded object
+ */
+ protected ASN1Primitive convertHexEncoded(
+ String str,
+ int off)
+ throws IOException
+ {
+ return ASN1Primitive.fromByteArray(Hex.decodeStrict(str, off, str.length() - off));
+ }
+
+ /**
+ * return true if the passed in String can be represented without
+ * loss as a PrintableString, false otherwise.
+ */
+ protected boolean canBePrintable(
+ String str)
+ {
+ return DERPrintableString.isPrintableString(str);
+ }
+
+ /**
+ * Convert the passed in String value into the appropriate ASN.1
+ * encoded object.
+ *
+ * @param oid the oid associated with the value in the DN.
+ * @param value the value of the particular DN component.
+ * @return the ASN.1 equivalent for the value.
+ */
+ public abstract ASN1Primitive getConvertedValue(ASN1ObjectIdentifier oid, String value);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameTokenizer.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameTokenizer.java
new file mode 100644
index 00000000..6f9a61e3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameTokenizer.java
@@ -0,0 +1,106 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+/**
+ * class for breaking up an X500 Name into it's component tokens, ala
+ * java.util.StringTokenizer. We need this class as some of the
+ * lightweight Java environment don't support classes like
+ * StringTokenizer.
+ * @deprecated use X500NameTokenizer
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509NameTokenizer
+{
+ private String value;
+ private int index;
+ private char separator;
+ private StringBuffer buf = new StringBuffer();
+
+ public X509NameTokenizer(
+ String oid)
+ {
+ this(oid, ',');
+ }
+
+ public X509NameTokenizer(
+ String oid,
+ char separator)
+ {
+ this.value = oid;
+ this.index = -1;
+ this.separator = separator;
+ }
+
+ public boolean hasMoreTokens()
+ {
+ return (index != value.length());
+ }
+
+ public String nextToken()
+ {
+ if (index == value.length())
+ {
+ return null;
+ }
+
+ int end = index + 1;
+ boolean quoted = false;
+ boolean escaped = false;
+
+ buf.setLength(0);
+
+ while (end != value.length())
+ {
+ char c = value.charAt(end);
+
+ if (c == '"')
+ {
+ if (!escaped)
+ {
+ quoted = !quoted;
+ }
+ buf.append(c);
+ escaped = false;
+ }
+ else
+ {
+ if (escaped || quoted)
+ {
+ buf.append(c);
+ escaped = false;
+ }
+ else if (c == '\\')
+ {
+ buf.append(c);
+ escaped = true;
+ }
+ else if (c == separator)
+ {
+ break;
+ }
+ else
+ {
+ // BEGIN Android-added: Unknown reason
+ // This was previously marked with the comment "copied from a newer version
+ // of BouncyCastle", but I couldn't find any evidence that it ever was included
+ // in any version of BC
+ if (c == '#' && buf.charAt(buf.length() - 1) == '=')
+ {
+ buf.append('\\');
+ }
+ else if (c == '+' && separator != '+')
+ {
+ buf.append('\\');
+ }
+ // END Android-added: Unknown reason
+ buf.append(c);
+ }
+ }
+ end++;
+ }
+
+ index = end;
+
+ return buf.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
new file mode 100644
index 00000000..89e8a562
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
@@ -0,0 +1,114 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface X509ObjectIdentifiers
+{
+ /** Subject RDN components: commonName = 2.5.4.3 */
+ static final ASN1ObjectIdentifier commonName = new ASN1ObjectIdentifier("2.5.4.3").intern();
+ /** Subject RDN components: countryName = 2.5.4.6 */
+ static final ASN1ObjectIdentifier countryName = new ASN1ObjectIdentifier("2.5.4.6").intern();
+ /** Subject RDN components: localityName = 2.5.4.7 */
+ static final ASN1ObjectIdentifier localityName = new ASN1ObjectIdentifier("2.5.4.7").intern();
+ /** Subject RDN components: stateOrProvinceName = 2.5.4.8 */
+ static final ASN1ObjectIdentifier stateOrProvinceName = new ASN1ObjectIdentifier("2.5.4.8").intern();
+ /** Subject RDN components: organization = 2.5.4.10 */
+ static final ASN1ObjectIdentifier organization = new ASN1ObjectIdentifier("2.5.4.10").intern();
+ /** Subject RDN components: organizationalUnitName = 2.5.4.11 */
+ static final ASN1ObjectIdentifier organizationalUnitName = new ASN1ObjectIdentifier("2.5.4.11").intern();
+
+ /** Subject RDN components: telephone_number = 2.5.4.20 */
+ static final ASN1ObjectIdentifier id_at_telephoneNumber = new ASN1ObjectIdentifier("2.5.4.20").intern();
+ /** Subject RDN components: name = 2.5.4.41 */
+ static final ASN1ObjectIdentifier id_at_name = new ASN1ObjectIdentifier("2.5.4.41").intern();
+
+ static final ASN1ObjectIdentifier id_at_organizationIdentifier = new ASN1ObjectIdentifier("2.5.4.97").intern();
+
+ /**
+ * id-SHA1 OBJECT IDENTIFIER ::=
+ * {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 }
+ * <p>
+ * OID: 1.3.14.3.2.27
+ */
+ static final ASN1ObjectIdentifier id_SHA1 = new ASN1ObjectIdentifier("1.3.14.3.2.26").intern();
+
+ /**
+ * ripemd160 OBJECT IDENTIFIER ::=
+ * {iso(1) identified-organization(3) TeleTrust(36) algorithm(3) hashAlgorithm(2) RIPEMD-160(1)}
+ * <p>
+ * OID: 1.3.36.3.2.1
+ */
+ static final ASN1ObjectIdentifier ripemd160 = new ASN1ObjectIdentifier("1.3.36.3.2.1").intern();
+
+ /**
+ * ripemd160WithRSAEncryption OBJECT IDENTIFIER ::=
+ * {iso(1) identified-organization(3) TeleTrust(36) algorithm(3) signatureAlgorithm(3) rsaSignature(1) rsaSignatureWithripemd160(2) }
+ * <p>
+ * OID: 1.3.36.3.3.1.2
+ */
+ static final ASN1ObjectIdentifier ripemd160WithRSAEncryption = new ASN1ObjectIdentifier("1.3.36.3.3.1.2").intern();
+
+
+ /** OID: 2.5.8.1.1 */
+ static final ASN1ObjectIdentifier id_ea_rsa = new ASN1ObjectIdentifier("2.5.8.1.1").intern();
+
+ /** id-pkix OID: 1.3.6.1.5.5.7
+ */
+ static final ASN1ObjectIdentifier id_pkix = new ASN1ObjectIdentifier("1.3.6.1.5.5.7");
+
+ /**
+ * id-RSASSA-PSS-SHAKE128 OBJECT IDENTIFIER ::= { iso(1)
+ * identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) algorithms(6) 30 }
+ */
+ static final ASN1ObjectIdentifier id_rsassa_pss_shake128 = id_pkix.branch("6.30");
+
+ /**
+ * id-RSASSA-PSS-SHAKE256 OBJECT IDENTIFIER ::= { iso(1)
+ * identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) algorithms(6) 31 }
+ */
+ static final ASN1ObjectIdentifier id_rsassa_pss_shake256 = id_pkix.branch("6.31");
+
+ /**
+ * id-ecdsa-with-shake128 OBJECT IDENTIFIER ::= { iso(1)
+ * identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) algorithms(6) 32 }
+ */
+ static final ASN1ObjectIdentifier id_ecdsa_with_shake128 = id_pkix.branch("6.32");
+
+ /**
+ * id-ecdsa-with-shake256 OBJECT IDENTIFIER ::= { iso(1)
+ * identified-organization(3) dod(6) internet(1)
+ * security(5) mechanisms(5) pkix(7) algorithms(6) 33 }
+ */
+ static final ASN1ObjectIdentifier id_ecdsa_with_shake256 = id_pkix.branch("6.33");
+
+ /**
+ * private internet extensions; OID = 1.3.6.1.5.5.7.1
+ */
+ static final ASN1ObjectIdentifier id_pe = id_pkix.branch("1");
+
+ /**
+ * ISO ARC for standard certificate and CRL extensions
+ * <p>
+ * OID: 2.5.29
+ */
+ static final ASN1ObjectIdentifier id_ce = new ASN1ObjectIdentifier("2.5.29");
+
+ /** id-pkix OID: 1.3.6.1.5.5.7.48 */
+ static final ASN1ObjectIdentifier id_ad = id_pkix.branch("48");
+ /** id-ad-caIssuers OID: 1.3.6.1.5.5.7.48.2 */
+ static final ASN1ObjectIdentifier id_ad_caIssuers = id_ad.branch("2").intern();
+ /** id-ad-ocsp OID: 1.3.6.1.5.5.7.48.1 */
+ static final ASN1ObjectIdentifier id_ad_ocsp = id_ad.branch("1").intern();
+
+ /** OID for ocsp uri in AuthorityInformationAccess extension */
+ static final ASN1ObjectIdentifier ocspAccessMethod = id_ad_ocsp;
+ /** OID for crl uri in AuthorityInformationAccess extension */
+ static final ASN1ObjectIdentifier crlAccessMethod = id_ad_caIssuers;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHDomainParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHDomainParameters.java
new file mode 100644
index 00000000..6206a0d9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHDomainParameters.java
@@ -0,0 +1,168 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @deprecated use DomainParameters
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHDomainParameters
+ extends ASN1Object
+{
+ private ASN1Integer p, g, q, j;
+ private DHValidationParms validationParms;
+
+ public static DHDomainParameters getInstance(ASN1TaggedObject obj, boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static DHDomainParameters getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof DHDomainParameters)
+ {
+ return (DHDomainParameters)obj;
+ }
+
+ if (obj instanceof ASN1Sequence)
+ {
+ return new DHDomainParameters((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("Invalid DHDomainParameters: "
+ + obj.getClass().getName());
+ }
+
+ public DHDomainParameters(BigInteger p, BigInteger g, BigInteger q, BigInteger j,
+ DHValidationParms validationParms)
+ {
+ if (p == null)
+ {
+ throw new IllegalArgumentException("'p' cannot be null");
+ }
+ if (g == null)
+ {
+ throw new IllegalArgumentException("'g' cannot be null");
+ }
+ if (q == null)
+ {
+ throw new IllegalArgumentException("'q' cannot be null");
+ }
+
+ this.p = new ASN1Integer(p);
+ this.g = new ASN1Integer(g);
+ this.q = new ASN1Integer(q);
+ this.j = new ASN1Integer(j);
+ this.validationParms = validationParms;
+ }
+
+ public DHDomainParameters(ASN1Integer p, ASN1Integer g, ASN1Integer q, ASN1Integer j,
+ DHValidationParms validationParms)
+ {
+ if (p == null)
+ {
+ throw new IllegalArgumentException("'p' cannot be null");
+ }
+ if (g == null)
+ {
+ throw new IllegalArgumentException("'g' cannot be null");
+ }
+ if (q == null)
+ {
+ throw new IllegalArgumentException("'q' cannot be null");
+ }
+
+ this.p = p;
+ this.g = g;
+ this.q = q;
+ this.j = j;
+ this.validationParms = validationParms;
+ }
+
+ private DHDomainParameters(ASN1Sequence seq)
+ {
+ if (seq.size() < 3 || seq.size() > 5)
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+
+ Enumeration e = seq.getObjects();
+ this.p = ASN1Integer.getInstance(e.nextElement());
+ this.g = ASN1Integer.getInstance(e.nextElement());
+ this.q = ASN1Integer.getInstance(e.nextElement());
+
+ ASN1Encodable next = getNext(e);
+
+ if (next != null && next instanceof ASN1Integer)
+ {
+ this.j = ASN1Integer.getInstance(next);
+ next = getNext(e);
+ }
+
+ if (next != null)
+ {
+ this.validationParms = DHValidationParms.getInstance(next.toASN1Primitive());
+ }
+ }
+
+ private static ASN1Encodable getNext(Enumeration e)
+ {
+ return e.hasMoreElements() ? (ASN1Encodable)e.nextElement() : null;
+ }
+
+ public ASN1Integer getP()
+ {
+ return this.p;
+ }
+
+ public ASN1Integer getG()
+ {
+ return this.g;
+ }
+
+ public ASN1Integer getQ()
+ {
+ return this.q;
+ }
+
+ public ASN1Integer getJ()
+ {
+ return this.j;
+ }
+
+ public DHValidationParms getValidationParms()
+ {
+ return this.validationParms;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
+ v.add(this.p);
+ v.add(this.g);
+ v.add(this.q);
+
+ if (this.j != null)
+ {
+ v.add(this.j);
+ }
+
+ if (this.validationParms != null)
+ {
+ v.add(this.validationParms);
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHPublicKey.java
new file mode 100644
index 00000000..a3f50535
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHPublicKey.java
@@ -0,0 +1,100 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+
+/**
+ * X9.42 definition of a DHPublicKey
+ * <pre>
+ * DHPublicKey ::= INTEGER
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHPublicKey
+ extends ASN1Object
+{
+ private ASN1Integer y;
+
+ /**
+ * Return a DHPublicKey from the passed in tagged object.
+ *
+ * @param obj a tagged object.
+ * @param explicit true if the contents of the object is explictly tagged, false otherwise.
+ * @return a DHPublicKey
+ */
+ public static DHPublicKey getInstance(ASN1TaggedObject obj, boolean explicit)
+ {
+ return getInstance(ASN1Integer.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return a DHPublicKey from the passed in object.
+ *
+ * @param obj an object for conversion or a byte[].
+ * @return a DHPublicKey
+ */
+ public static DHPublicKey getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof DHPublicKey)
+ {
+ return (DHPublicKey)obj;
+ }
+
+ if (obj instanceof ASN1Integer)
+ {
+ return new DHPublicKey((ASN1Integer)obj);
+ }
+
+ throw new IllegalArgumentException("Invalid DHPublicKey: " + obj.getClass().getName());
+ }
+
+ private DHPublicKey(ASN1Integer y)
+ {
+ if (y == null)
+ {
+ throw new IllegalArgumentException("'y' cannot be null");
+ }
+
+ this.y = y;
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param y the public value Y.
+ */
+ public DHPublicKey(BigInteger y)
+ {
+ if (y == null)
+ {
+ throw new IllegalArgumentException("'y' cannot be null");
+ }
+
+ this.y = new ASN1Integer(y);
+ }
+
+ /**
+ * Return the public value Y for the key.
+ *
+ * @return the Y value.
+ */
+ public BigInteger getY()
+ {
+ return this.y.getPositiveValue();
+ }
+
+ /**
+ * Return an ASN.1 primitive representation of this object.
+ *
+ * @return an ASN1Integer.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return this.y;
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHValidationParms.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHValidationParms.java
new file mode 100644
index 00000000..a2d4c8a5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHValidationParms.java
@@ -0,0 +1,84 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * @deprecated use ValidationParams
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHValidationParms extends ASN1Object
+{
+ private DERBitString seed;
+ private ASN1Integer pgenCounter;
+
+ public static DHValidationParms getInstance(ASN1TaggedObject obj, boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static DHValidationParms getInstance(Object obj)
+ {
+ if (obj instanceof DHValidationParms)
+ {
+ return (DHValidationParms)obj;
+ }
+ else if (obj != null)
+ {
+ return new DHValidationParms(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public DHValidationParms(DERBitString seed, ASN1Integer pgenCounter)
+ {
+ if (seed == null)
+ {
+ throw new IllegalArgumentException("'seed' cannot be null");
+ }
+ if (pgenCounter == null)
+ {
+ throw new IllegalArgumentException("'pgenCounter' cannot be null");
+ }
+
+ this.seed = seed;
+ this.pgenCounter = pgenCounter;
+ }
+
+ private DHValidationParms(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+
+ this.seed = DERBitString.getInstance(seq.getObjectAt(0));
+ this.pgenCounter = ASN1Integer.getInstance(seq.getObjectAt(1));
+ }
+
+ public DERBitString getSeed()
+ {
+ return this.seed;
+ }
+
+ public ASN1Integer getPgenCounter()
+ {
+ return this.pgenCounter;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+ v.add(this.seed);
+ v.add(this.pgenCounter);
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DomainParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DomainParameters.java
new file mode 100644
index 00000000..672a4460
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DomainParameters.java
@@ -0,0 +1,225 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * X9.44 Diffie-Hellman domain parameters.
+ * <pre>
+ * DomainParameters ::= SEQUENCE {
+ * p INTEGER, -- odd prime, p=jq +1
+ * g INTEGER, -- generator, g
+ * q INTEGER, -- factor of p-1
+ * j INTEGER OPTIONAL, -- subgroup factor, j &gt;= 2
+ * validationParams ValidationParams OPTIONAL
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DomainParameters
+ extends ASN1Object
+{
+ private final ASN1Integer p, g, q, j;
+ private final ValidationParams validationParams;
+
+ /**
+ * Return a DomainParameters object from the passed in tagged object.
+ *
+ * @param obj a tagged object.
+ * @param explicit true if the contents of the object is explictly tagged, false otherwise.
+ * @return a DomainParameters
+ */
+ public static DomainParameters getInstance(ASN1TaggedObject obj, boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return a DomainParameters object from the passed in object.
+ *
+ * @param obj an object for conversion or a byte[].
+ * @return a DomainParameters
+ */
+ public static DomainParameters getInstance(Object obj)
+ {
+ if (obj instanceof DomainParameters)
+ {
+ return (DomainParameters)obj;
+ }
+ else if (obj != null)
+ {
+ return new DomainParameters(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * Base constructor - the full domain parameter set.
+ *
+ * @param p the prime p defining the Galois field.
+ * @param g the generator of the multiplicative subgroup of order g.
+ * @param q specifies the prime factor of p - 1
+ * @param j optionally specifies the value that satisfies the equation p = jq+1
+ * @param validationParams parameters for validating these domain parameters.
+ */
+ public DomainParameters(BigInteger p, BigInteger g, BigInteger q, BigInteger j,
+ ValidationParams validationParams)
+ {
+ if (p == null)
+ {
+ throw new IllegalArgumentException("'p' cannot be null");
+ }
+ if (g == null)
+ {
+ throw new IllegalArgumentException("'g' cannot be null");
+ }
+ if (q == null)
+ {
+ throw new IllegalArgumentException("'q' cannot be null");
+ }
+
+ this.p = new ASN1Integer(p);
+ this.g = new ASN1Integer(g);
+ this.q = new ASN1Integer(q);
+
+ if (j != null)
+ {
+ this.j = new ASN1Integer(j);
+ }
+ else
+ {
+ this.j = null;
+ }
+ this.validationParams = validationParams;
+ }
+
+ private DomainParameters(ASN1Sequence seq)
+ {
+ if (seq.size() < 3 || seq.size() > 5)
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+
+ Enumeration e = seq.getObjects();
+ this.p = ASN1Integer.getInstance(e.nextElement());
+ this.g = ASN1Integer.getInstance(e.nextElement());
+ this.q = ASN1Integer.getInstance(e.nextElement());
+
+ ASN1Encodable next = getNext(e);
+
+ if (next != null && next instanceof ASN1Integer)
+ {
+ this.j = ASN1Integer.getInstance(next);
+ next = getNext(e);
+ }
+ else
+ {
+ this.j = null;
+ }
+
+ if (next != null)
+ {
+ this.validationParams = ValidationParams.getInstance(next.toASN1Primitive());
+ }
+ else
+ {
+ this.validationParams = null;
+ }
+ }
+
+ private static ASN1Encodable getNext(Enumeration e)
+ {
+ return e.hasMoreElements() ? (ASN1Encodable)e.nextElement() : null;
+ }
+
+ /**
+ * Return the prime p defining the Galois field.
+ *
+ * @return the prime p.
+ */
+ public BigInteger getP()
+ {
+ return this.p.getPositiveValue();
+ }
+
+ /**
+ * Return the generator of the multiplicative subgroup of order g.
+ *
+ * @return the generator g.
+ */
+ public BigInteger getG()
+ {
+ return this.g.getPositiveValue();
+ }
+
+ /**
+ * Return q, the prime factor of p - 1
+ *
+ * @return q value
+ */
+ public BigInteger getQ()
+ {
+ return this.q.getPositiveValue();
+ }
+
+ /**
+ * Return the value that satisfies the equation p = jq+1 (if present).
+ *
+ * @return j value or null.
+ */
+ public BigInteger getJ()
+ {
+ if (this.j == null)
+ {
+ return null;
+ }
+
+ return this.j.getPositiveValue();
+ }
+
+ /**
+ * Return the validation parameters for this set (if present).
+ *
+ * @return validation parameters, or null if absent.
+ */
+ public ValidationParams getValidationParams()
+ {
+ return this.validationParams;
+ }
+
+ /**
+ * Return an ASN.1 primitive representation of this object.
+ *
+ * @return a DERSequence containing the parameter values.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
+ v.add(this.p);
+ v.add(this.g);
+ v.add(this.q);
+
+ if (this.j != null)
+ {
+ v.add(this.j);
+ }
+
+ if (this.validationParams != null)
+ {
+ v.add(this.validationParams);
+ }
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ECNamedCurveTable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
new file mode 100644
index 00000000..08ada94e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
@@ -0,0 +1,258 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+// Android-removed: Unsupported curves
+// import org.bouncycastle.asn1.anssi.ANSSINamedCurves;
+// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
+// import org.bouncycastle.asn1.gm.GMNamedCurves;
+// import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.nist.NISTNamedCurves;
+import com.android.internal.org.bouncycastle.asn1.sec.SECNamedCurves;
+// Android-removed: Unsupported curves
+// import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
+import com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves;
+
+/**
+ * A general class that reads all X9.62 style EC curve tables.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECNamedCurveTable
+{
+ /**
+ * return a X9ECParameters object representing the passed in named
+ * curve. The routine returns null if the curve is not present.
+ *
+ * @param name the name of the curve requested
+ * @return an X9ECParameters object or null if the curve is not available.
+ */
+ public static X9ECParameters getByName(
+ String name)
+ {
+ X9ECParameters ecP = X962NamedCurves.getByName(name);
+
+ if (ecP == null)
+ {
+ ecP = SECNamedCurves.getByName(name);
+ }
+
+ if (ecP == null)
+ {
+ ecP = NISTNamedCurves.getByName(name);
+ }
+
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ if (ecP == null)
+ {
+ ecP = TeleTrusTNamedCurves.getByName(name);
+ }
+
+ if (ecP == null)
+ {
+ ecP = ANSSINamedCurves.getByName(name);
+ }
+
+ if (ecP == null)
+ {
+ ecP = ECGOST3410NamedCurves.getByNameX9(name);
+ }
+
+ if (ecP == null)
+ {
+ ecP = GMNamedCurves.getByName(name);
+ }
+ */
+ // END Android-removed: Unsupported curves
+
+ return ecP;
+ }
+
+ /**
+ * return the object identifier signified by the passed in name. Null
+ * if there is no object identifier associated with name.
+ *
+ * @return the object identifier associated with name, if present.
+ */
+ public static ASN1ObjectIdentifier getOID(
+ String name)
+ {
+ ASN1ObjectIdentifier oid = X962NamedCurves.getOID(name);
+
+ if (oid == null)
+ {
+ oid = SECNamedCurves.getOID(name);
+ }
+
+ if (oid == null)
+ {
+ oid = NISTNamedCurves.getOID(name);
+ }
+
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ if (oid == null)
+ {
+ oid = TeleTrusTNamedCurves.getOID(name);
+ }
+
+ if (oid == null)
+ {
+ oid = ANSSINamedCurves.getOID(name);
+ }
+
+ if (oid == null)
+ {
+ oid = ECGOST3410NamedCurves.getOID(name);
+ }
+
+ if (oid == null)
+ {
+ oid = GMNamedCurves.getOID(name);
+ }
+
+ if (oid == null && name.equals("curve25519"))
+ {
+ oid = CryptlibObjectIdentifiers.curvey25519;
+ }
+ */
+ // END Android-removed: Unsupported curves
+
+ return oid;
+ }
+
+ /**
+ * return a X9ECParameters object representing the passed in named
+ * curve.
+ *
+ * @param oid the object id of the curve requested
+ * @return a standard name for the curve.
+ */
+ public static String getName(
+ ASN1ObjectIdentifier oid)
+ {
+ String name = X962NamedCurves.getName(oid);
+
+ if (name == null)
+ {
+ name = SECNamedCurves.getName(oid);
+ }
+
+ if (name == null)
+ {
+ name = NISTNamedCurves.getName(oid);
+ }
+
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ if (name == null)
+ {
+ name = TeleTrusTNamedCurves.getName(oid);
+ }
+
+ if (name == null)
+ {
+ name = ANSSINamedCurves.getName(oid);
+ }
+
+ if (name == null)
+ {
+ name = ECGOST3410NamedCurves.getName(oid);
+ }
+
+ if (name == null)
+ {
+ name = GMNamedCurves.getName(oid);
+ }
+
+ if (name == null)
+ {
+ name = CustomNamedCurves.getName(oid);
+ }
+ */
+ // END Android-removed: Unsupported curves
+
+ return name;
+ }
+
+ /**
+ * return a X9ECParameters object representing the passed in named
+ * curve.
+ *
+ * @param oid the object id of the curve requested
+ * @return an X9ECParameters object or null if the curve is not available.
+ */
+ public static X9ECParameters getByOID(
+ ASN1ObjectIdentifier oid)
+ {
+ X9ECParameters ecP = X962NamedCurves.getByOID(oid);
+
+ if (ecP == null)
+ {
+ ecP = SECNamedCurves.getByOID(oid);
+ }
+
+ // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup
+
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ if (ecP == null)
+ {
+ ecP = TeleTrusTNamedCurves.getByOID(oid);
+ }
+
+ if (ecP == null)
+ {
+ ecP = ANSSINamedCurves.getByOID(oid);
+ }
+
+ if (ecP == null)
+ {
+ ecP = ECGOST3410NamedCurves.getByOIDX9(oid);
+ }
+
+ if (ecP == null)
+ {
+ ecP = GMNamedCurves.getByOID(oid);
+ }
+ */
+ // END Android-removed: Unsupported curves
+
+ return ecP;
+ }
+
+ /**
+ * return an enumeration of the names of the available curves.
+ *
+ * @return an enumeration of the names of the available curves.
+ */
+ public static Enumeration getNames()
+ {
+ Vector v = new Vector();
+
+ addEnumeration(v, X962NamedCurves.getNames());
+ addEnumeration(v, SECNamedCurves.getNames());
+ addEnumeration(v, NISTNamedCurves.getNames());
+ // BEGIN Android-removed: Unsupported curves
+ // addEnumeration(v, TeleTrusTNamedCurves.getNames());
+ // addEnumeration(v, ANSSINamedCurves.getNames());
+ // addEnumeration(v, ECGOST3410NamedCurves.getNames());
+ // addEnumeration(v, GMNamedCurves.getNames());
+ // END Android-removed: Unsupported curves
+
+ return v.elements();
+ }
+
+ private static void addEnumeration(
+ Vector v,
+ Enumeration e)
+ {
+ while (e.hasMoreElements())
+ {
+ v.addElement(e.nextElement());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ValidationParams.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ValidationParams.java
new file mode 100644
index 00000000..0e2329c8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ValidationParams.java
@@ -0,0 +1,104 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * Diffie-Hellman domain validation parameters.
+ * <pre>
+ * ValidationParams ::= SEQUENCE {
+ * seed BIT STRING,
+ * pgenCounter INTEGER
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ValidationParams
+ extends ASN1Object
+{
+ private DERBitString seed;
+ private ASN1Integer pgenCounter;
+
+ public static ValidationParams getInstance(ASN1TaggedObject obj, boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static ValidationParams getInstance(Object obj)
+ {
+ if (obj instanceof ValidationParams)
+ {
+ return (ValidationParams)obj;
+ }
+ else if (obj != null)
+ {
+ return new ValidationParams(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ValidationParams(byte[] seed, int pgenCounter)
+ {
+ if (seed == null)
+ {
+ throw new IllegalArgumentException("'seed' cannot be null");
+ }
+
+ this.seed = new DERBitString(seed);
+ this.pgenCounter = new ASN1Integer(pgenCounter);
+ }
+
+ public ValidationParams(DERBitString seed, ASN1Integer pgenCounter)
+ {
+ if (seed == null)
+ {
+ throw new IllegalArgumentException("'seed' cannot be null");
+ }
+ if (pgenCounter == null)
+ {
+ throw new IllegalArgumentException("'pgenCounter' cannot be null");
+ }
+
+ this.seed = seed;
+ this.pgenCounter = pgenCounter;
+ }
+
+ private ValidationParams(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+
+ this.seed = DERBitString.getInstance(seq.getObjectAt(0));
+ this.pgenCounter = ASN1Integer.getInstance(seq.getObjectAt(1));
+ }
+
+ public byte[] getSeed()
+ {
+ return this.seed.getBytes();
+ }
+
+ public BigInteger getPgenCounter()
+ {
+ return this.pgenCounter.getPositiveValue();
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+ v.add(this.seed);
+ v.add(this.pgenCounter);
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962NamedCurves.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962NamedCurves.java
new file mode 100644
index 00000000..7b82cc0c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962NamedCurves.java
@@ -0,0 +1,617 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.WNafUtil;
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+
+/**
+ * Table of the current named curves defined in X.962 EC-DSA.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X962NamedCurves
+{
+ private static X9ECPoint configureBasepoint(ECCurve curve, String encoding)
+ {
+ X9ECPoint G = new X9ECPoint(curve, Hex.decodeStrict(encoding));
+ WNafUtil.configureBasepoint(G.getPoint());
+ return G;
+ }
+
+ private static ECCurve configureCurve(ECCurve curve)
+ {
+ return curve;
+ }
+
+ private static BigInteger fromHex(String hex)
+ {
+ return new BigInteger(1, Hex.decodeStrict(hex));
+ }
+
+ static X9ECParametersHolder prime192v1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("ffffffffffffffffffffffff99def836146bc9b1b4d22831");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(
+ fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
+ fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
+ fromHex("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("3045AE6FC8422f64ED579528D38120EAE12196D5"));
+ }
+ };
+
+ static X9ECParametersHolder prime192v2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("fffffffffffffffffffffffe5fb1a724dc80418648d8dd31");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(
+ fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
+ fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
+ fromHex("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("31a92ee2029fd10d901b113e990710f0d21ac6b6"));
+ }
+ };
+
+ static X9ECParametersHolder prime192v3 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("ffffffffffffffffffffffff7a62d031c83f4294f640ec13");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(
+ fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
+ fromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
+ fromHex("22123dc2395a05caa7423daeccc94760a7d462256bd56916"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "027d29778100c65a1da1783716588dce2b8b4aee8e228f1896");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("c469684435deb378c4b65ca9591e2a5763059a2e"));
+ }
+ };
+
+ static X9ECParametersHolder prime239v1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(
+ new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
+ fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
+ fromHex("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("e43bb460f0b80cc0c0b075798e948060f8321b7d"));
+ }
+ };
+
+ static X9ECParametersHolder prime239v2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(
+ new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
+ fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
+ fromHex("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("e8b4011604095303ca3b8099982be09fcb9ae616"));
+ }
+ };
+
+ static X9ECParametersHolder prime239v3 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(
+ new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
+ fromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
+ fromHex("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("7d7374168ffe3471b60a857686a19475d3bfa2ff"));
+ }
+ };
+
+ static X9ECParametersHolder prime256v1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551");
+ BigInteger h = BigInteger.valueOf(1);
+
+ ECCurve curve = configureCurve(new ECCurve.Fp(
+ new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951"),
+ fromHex("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc"),
+ fromHex("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("c49d360886e704936a6678e1139d26b7819f7e90"));
+ }
+ };
+
+ /*
+ * F2m Curves
+ */
+ static X9ECParametersHolder c2pnb163v1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("0400000000000000000001E60FC8821CC74DAEAFC1");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 163,
+ 1, 2, 8,
+ fromHex("072546B5435234A422E0789675F432C89435DE5242"),
+ fromHex("00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0307AF69989546103D79329FCC3D74880F33BBE803CB");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("D2C0FB15760860DEF1EEF4D696E6768756151754"));
+ }
+ };
+
+ static X9ECParametersHolder c2pnb163v2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 163,
+ 1, 2, 8,
+ fromHex("0108B39E77C4B108BED981ED0E890E117C511CF072"),
+ fromHex("0667ACEB38AF4E488C407433FFAE4F1C811638DF20"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "030024266E4EB5106D0A964D92C4860E2671DB9B6CC5");
+
+ return new X9ECParameters(curve, G, n, h);
+ }
+ };
+
+ static X9ECParametersHolder c2pnb163v3 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 163,
+ 1, 2, 8,
+ fromHex("07A526C63D3E25A256A007699F5447E32AE456B50E"),
+ fromHex("03F7061798EB99E238FD6F1BF95B48FEEB4854252B"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB");
+
+ return new X9ECParameters(curve, G, n, h);
+ }
+ };
+
+ static X9ECParametersHolder c2pnb176w1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("010092537397ECA4F6145799D62B0A19CE06FE26AD");
+ BigInteger h = BigInteger.valueOf(0xFF6E);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 176,
+ 1, 2, 43,
+ fromHex("E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B"),
+ fromHex("5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "038D16C2866798B600F9F08BB4A8E860F3298CE04A5798");
+
+ return new X9ECParameters(curve, G, n, h);
+ }
+ };
+
+ static X9ECParametersHolder c2tnb191v1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("40000000000000000000000004A20E90C39067C893BBB9A5");
+ BigInteger h = BigInteger.valueOf(2);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 191,
+ 9,
+ fromHex("2866537B676752636A68F56554E12640276B649EF7526267"),
+ fromHex("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D");
+
+ return new X9ECParameters(curve, G, n, h, Hex.decodeStrict("4E13CA542744D696E67687561517552F279A8C84"));
+ }
+ };
+
+ static X9ECParametersHolder c2tnb191v2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("20000000000000000000000050508CB89F652824E06B8173");
+ BigInteger h = BigInteger.valueOf(4);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 191,
+ 9,
+ fromHex("401028774D7777C7B7666D1366EA432071274F89FF01E718"),
+ fromHex("0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10");
+
+ return new X9ECParameters(curve, G, n, h);
+ }
+ };
+
+ static X9ECParametersHolder c2tnb191v3 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("155555555555555555555555610C0B196812BFB6288A3EA3");
+ BigInteger h = BigInteger.valueOf(6);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 191,
+ 9,
+ fromHex("6C01074756099122221056911C77D77E77A777E7E7E77FCB"),
+ fromHex("71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "03375D4CE24FDE434489DE8746E71786015009E66E38A926DD");
+
+ return new X9ECParameters(curve, G, n, h);
+ }
+ };
+
+ static X9ECParametersHolder c2pnb208w1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("0101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D");
+ BigInteger h = BigInteger.valueOf(0xFE48);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 208,
+ 1, 2, 83,
+ BigInteger.valueOf(0),
+ fromHex("C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A");
+
+ return new X9ECParameters(curve, G, n, h);
+ }
+ };
+
+ static X9ECParametersHolder c2tnb239v1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447");
+ BigInteger h = BigInteger.valueOf(4);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 239,
+ 36,
+ fromHex("32010857077C5431123A46B808906756F543423E8D27877578125778AC76"),
+ fromHex("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D");
+
+ return new X9ECParameters(curve, G, n, h);
+ }
+ };
+
+ static X9ECParametersHolder c2tnb239v2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("1555555555555555555555555555553C6F2885259C31E3FCDF154624522D");
+ BigInteger h = BigInteger.valueOf(6);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 239,
+ 36,
+ fromHex("4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F"),
+ fromHex("5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205");
+
+ return new X9ECParameters(curve, G, n, h);
+ }
+ };
+
+ static X9ECParametersHolder c2tnb239v3 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF");
+ BigInteger h = BigInteger.valueOf(10);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 239,
+ 36,
+ fromHex("01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F"),
+ fromHex("6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92");
+
+ return new X9ECParameters(curve, G, n, h);
+ }
+ };
+
+ static X9ECParametersHolder c2pnb272w1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("0100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521");
+ BigInteger h = BigInteger.valueOf(0xFF06);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 272,
+ 1, 3, 56,
+ fromHex("91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20"),
+ fromHex("7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D");
+
+ return new X9ECParameters(curve, G, n, h);
+ }
+ };
+
+ static X9ECParametersHolder c2pnb304w1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("0101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D");
+ BigInteger h = BigInteger.valueOf(0xFE2E);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 304,
+ 1, 2, 11,
+ fromHex("FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681"),
+ fromHex("BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614");
+
+ return new X9ECParameters(curve, G, n, h);
+ }
+ };
+
+ static X9ECParametersHolder c2tnb359v1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B");
+ BigInteger h = BigInteger.valueOf(0x4C);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 359,
+ 68,
+ fromHex("5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557"),
+ fromHex("2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097");
+
+ return new X9ECParameters(curve, G, n, h);
+ }
+ };
+
+ static X9ECParametersHolder c2pnb368w1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967");
+ BigInteger h = BigInteger.valueOf(0xFF70);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 368,
+ 1, 2, 85,
+ fromHex("E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D"),
+ fromHex("FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F");
+
+ return new X9ECParameters(curve, G, n, h);
+ }
+ };
+
+ static X9ECParametersHolder c2tnb431r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ BigInteger n = fromHex("0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91");
+ BigInteger h = BigInteger.valueOf(0x2760);
+
+ ECCurve curve = configureCurve(new ECCurve.F2m(
+ 431,
+ 120,
+ fromHex("1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F"),
+ fromHex("10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618"),
+ n, h));
+
+ X9ECPoint G = configureBasepoint(curve,
+ "02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7");
+
+ return new X9ECParameters(curve, G, n, h);
+ }
+ };
+
+
+ static final Hashtable objIds = new Hashtable();
+ static final Hashtable curves = new Hashtable();
+ static final Hashtable names = new Hashtable();
+
+ static void defineCurve(String name, ASN1ObjectIdentifier oid, X9ECParametersHolder holder)
+ {
+ objIds.put(name, oid);
+ names.put(oid, name);
+ curves.put(oid, holder);
+ }
+
+ static
+ {
+ defineCurve("prime192v1", X9ObjectIdentifiers.prime192v1, prime192v1);
+ defineCurve("prime192v2", X9ObjectIdentifiers.prime192v2, prime192v2);
+ defineCurve("prime192v3", X9ObjectIdentifiers.prime192v3, prime192v3);
+ defineCurve("prime239v1", X9ObjectIdentifiers.prime239v1, prime239v1);
+ defineCurve("prime239v2", X9ObjectIdentifiers.prime239v2, prime239v2);
+ defineCurve("prime239v3", X9ObjectIdentifiers.prime239v3, prime239v3);
+ defineCurve("prime256v1", X9ObjectIdentifiers.prime256v1, prime256v1);
+ defineCurve("c2pnb163v1", X9ObjectIdentifiers.c2pnb163v1, c2pnb163v1);
+ defineCurve("c2pnb163v2", X9ObjectIdentifiers.c2pnb163v2, c2pnb163v2);
+ defineCurve("c2pnb163v3", X9ObjectIdentifiers.c2pnb163v3, c2pnb163v3);
+ defineCurve("c2pnb176w1", X9ObjectIdentifiers.c2pnb176w1, c2pnb176w1);
+ defineCurve("c2tnb191v1", X9ObjectIdentifiers.c2tnb191v1, c2tnb191v1);
+ defineCurve("c2tnb191v2", X9ObjectIdentifiers.c2tnb191v2, c2tnb191v2);
+ defineCurve("c2tnb191v3", X9ObjectIdentifiers.c2tnb191v3, c2tnb191v3);
+ defineCurve("c2pnb208w1", X9ObjectIdentifiers.c2pnb208w1, c2pnb208w1);
+ defineCurve("c2tnb239v1", X9ObjectIdentifiers.c2tnb239v1, c2tnb239v1);
+ defineCurve("c2tnb239v2", X9ObjectIdentifiers.c2tnb239v2, c2tnb239v2);
+ defineCurve("c2tnb239v3", X9ObjectIdentifiers.c2tnb239v3, c2tnb239v3);
+ defineCurve("c2pnb272w1", X9ObjectIdentifiers.c2pnb272w1, c2pnb272w1);
+ defineCurve("c2pnb304w1", X9ObjectIdentifiers.c2pnb304w1, c2pnb304w1);
+ defineCurve("c2tnb359v1", X9ObjectIdentifiers.c2tnb359v1, c2tnb359v1);
+ defineCurve("c2pnb368w1", X9ObjectIdentifiers.c2pnb368w1, c2pnb368w1);
+ defineCurve("c2tnb431r1", X9ObjectIdentifiers.c2tnb431r1, c2tnb431r1);
+ }
+
+ public static X9ECParameters getByName(
+ String name)
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name));
+
+ if (oid != null)
+ {
+ return getByOID(oid);
+ }
+
+ return null;
+ }
+
+ /**
+ * return the X9ECParameters object for the named curve represented by
+ * the passed in object identifier. Null if the curve isn't present.
+ *
+ * @param oid an object identifier representing a named curve, if present.
+ */
+ public static X9ECParameters getByOID(
+ ASN1ObjectIdentifier oid)
+ {
+ X9ECParametersHolder holder = (X9ECParametersHolder)curves.get(oid);
+
+ if (holder != null)
+ {
+ return holder.getParameters();
+ }
+
+ return null;
+ }
+
+ /**
+ * return the object identifier signified by the passed in name. Null
+ * if there is no object identifier associated with name.
+ *
+ * @return the object identifier associated with name, if present.
+ */
+ public static ASN1ObjectIdentifier getOID(
+ String name)
+ {
+ return (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name));
+ }
+
+ /**
+ * return the named curve name represented by the given object identifier.
+ */
+ public static String getName(
+ ASN1ObjectIdentifier oid)
+ {
+ return (String)names.get(oid);
+ }
+
+ /**
+ * returns an enumeration containing the name strings for curves
+ * contained in this structure.
+ */
+ public static Enumeration getNames()
+ {
+ return objIds.keys();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962Parameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962Parameters.java
new file mode 100644
index 00000000..07808324
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962Parameters.java
@@ -0,0 +1,108 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Null;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+
+/**
+ * The Parameters ASN.1 CHOICE from X9.62.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X962Parameters
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private ASN1Primitive params = null;
+
+ public static X962Parameters getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof X962Parameters)
+ {
+ return (X962Parameters)obj;
+ }
+
+ if (obj instanceof ASN1Primitive)
+ {
+ return new X962Parameters((ASN1Primitive)obj);
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return new X962Parameters(ASN1Primitive.fromByteArray((byte[])obj));
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("unable to parse encoded data: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance()");
+ }
+
+ public static X962Parameters getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject()); // must be explicitly tagged
+ }
+
+ public X962Parameters(
+ X9ECParameters ecParameters)
+ {
+ this.params = ecParameters.toASN1Primitive();
+ }
+
+ public X962Parameters(
+ ASN1ObjectIdentifier namedCurve)
+ {
+ this.params = namedCurve;
+ }
+
+ public X962Parameters(
+ ASN1Null obj)
+ {
+ this.params = obj;
+ }
+
+ private X962Parameters(ASN1Primitive obj)
+ {
+ this.params = obj;
+ }
+
+ public boolean isNamedCurve()
+ {
+ return (params instanceof ASN1ObjectIdentifier);
+ }
+
+ public boolean isImplicitlyCA()
+ {
+ return (params instanceof ASN1Null);
+ }
+
+ public ASN1Primitive getParameters()
+ {
+ return params;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * Parameters ::= CHOICE {
+ * ecParameters ECParameters,
+ * namedCurve CURVES.&amp;id({CurveNames}),
+ * implicitlyCA NULL
+ * }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return params;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9Curve.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9Curve.java
new file mode 100644
index 00000000..bef641a2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9Curve.java
@@ -0,0 +1,162 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.math.ec.ECAlgorithms;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * ASN.1 def for Elliptic-Curve Curve structure. See
+ * X9.62, for further details.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X9Curve
+ extends ASN1Object
+ implements X9ObjectIdentifiers
+{
+ private ECCurve curve;
+ private byte[] seed;
+ private ASN1ObjectIdentifier fieldIdentifier = null;
+
+ public X9Curve(
+ ECCurve curve)
+ {
+ this(curve, null);
+ }
+
+ public X9Curve(
+ ECCurve curve,
+ byte[] seed)
+ {
+ this.curve = curve;
+ this.seed = Arrays.clone(seed);
+ setFieldIdentifier();
+ }
+
+ public X9Curve(
+ X9FieldID fieldID,
+ BigInteger order,
+ BigInteger cofactor,
+ ASN1Sequence seq)
+ {
+ fieldIdentifier = fieldID.getIdentifier();
+ if (fieldIdentifier.equals(prime_field))
+ {
+ BigInteger p = ((ASN1Integer)fieldID.getParameters()).getValue();
+ BigInteger A = new BigInteger(1, ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets());
+ BigInteger B = new BigInteger(1, ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets());
+ curve = new ECCurve.Fp(p, A, B, order, cofactor);
+ }
+ else if (fieldIdentifier.equals(characteristic_two_field))
+ {
+ // Characteristic two field
+ ASN1Sequence parameters = ASN1Sequence.getInstance(fieldID.getParameters());
+ int m = ((ASN1Integer)parameters.getObjectAt(0)).intValueExact();
+ ASN1ObjectIdentifier representation = (ASN1ObjectIdentifier)parameters.getObjectAt(1);
+
+ int k1 = 0;
+ int k2 = 0;
+ int k3 = 0;
+
+ if (representation.equals(tpBasis))
+ {
+ // Trinomial basis representation
+ k1 = ASN1Integer.getInstance(parameters.getObjectAt(2)).intValueExact();
+ }
+ else if (representation.equals(ppBasis))
+ {
+ // Pentanomial basis representation
+ ASN1Sequence pentanomial = ASN1Sequence.getInstance(parameters.getObjectAt(2));
+ k1 = ASN1Integer.getInstance(pentanomial.getObjectAt(0)).intValueExact();
+ k2 = ASN1Integer.getInstance(pentanomial.getObjectAt(1)).intValueExact();
+ k3 = ASN1Integer.getInstance(pentanomial.getObjectAt(2)).intValueExact();
+ }
+ else
+ {
+ throw new IllegalArgumentException("This type of EC basis is not implemented");
+ }
+ BigInteger A = new BigInteger(1, ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets());
+ BigInteger B = new BigInteger(1, ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets());
+ curve = new ECCurve.F2m(m, k1, k2, k3, A, B, order, cofactor);
+ }
+ else
+ {
+ throw new IllegalArgumentException("This type of ECCurve is not implemented");
+ }
+
+ if (seq.size() == 3)
+ {
+ seed = ((DERBitString)seq.getObjectAt(2)).getBytes();
+ }
+ }
+
+ private void setFieldIdentifier()
+ {
+ if (ECAlgorithms.isFpCurve(curve))
+ {
+ fieldIdentifier = prime_field;
+ }
+ else if (ECAlgorithms.isF2mCurve(curve))
+ {
+ fieldIdentifier = characteristic_two_field;
+ }
+ else
+ {
+ throw new IllegalArgumentException("This type of ECCurve is not implemented");
+ }
+ }
+
+ public ECCurve getCurve()
+ {
+ return curve;
+ }
+
+ public byte[] getSeed()
+ {
+ return Arrays.clone(seed);
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * Curve ::= SEQUENCE {
+ * a FieldElement,
+ * b FieldElement,
+ * seed BIT STRING OPTIONAL
+ * }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
+
+ if (fieldIdentifier.equals(prime_field))
+ {
+ v.add(new X9FieldElement(curve.getA()).toASN1Primitive());
+ v.add(new X9FieldElement(curve.getB()).toASN1Primitive());
+ }
+ else if (fieldIdentifier.equals(characteristic_two_field))
+ {
+ v.add(new X9FieldElement(curve.getA()).toASN1Primitive());
+ v.add(new X9FieldElement(curve.getB()).toASN1Primitive());
+ }
+
+ if (seed != null)
+ {
+ v.add(new DERBitString(seed));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParameters.java
new file mode 100644
index 00000000..58ca88b9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParameters.java
@@ -0,0 +1,234 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.math.ec.ECAlgorithms;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.field.PolynomialExtensionField;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * ASN.1 def for Elliptic-Curve ECParameters structure. See
+ * X9.62, for further details.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X9ECParameters
+ extends ASN1Object
+ implements X9ObjectIdentifiers
+{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+
+ private X9FieldID fieldID;
+ private ECCurve curve;
+ private X9ECPoint g;
+ private BigInteger n;
+ private BigInteger h;
+ private byte[] seed;
+
+ private X9ECParameters(
+ ASN1Sequence seq)
+ {
+ if (!(seq.getObjectAt(0) instanceof ASN1Integer)
+ || !((ASN1Integer)seq.getObjectAt(0)).hasValue(ONE))
+ {
+ throw new IllegalArgumentException("bad version in X9ECParameters");
+ }
+
+ this.n = ((ASN1Integer)seq.getObjectAt(4)).getValue();
+
+ if (seq.size() == 6)
+ {
+ this.h = ((ASN1Integer)seq.getObjectAt(5)).getValue();
+ }
+
+ X9Curve x9c = new X9Curve(
+ X9FieldID.getInstance(seq.getObjectAt(1)), n, h,
+ ASN1Sequence.getInstance(seq.getObjectAt(2)));
+
+ this.curve = x9c.getCurve();
+ Object p = seq.getObjectAt(3);
+
+ if (p instanceof X9ECPoint)
+ {
+ this.g = (X9ECPoint)p;
+ }
+ else
+ {
+ this.g = new X9ECPoint(curve, (ASN1OctetString)p);
+ }
+
+ this.seed = x9c.getSeed();
+ }
+
+ public static X9ECParameters getInstance(Object obj)
+ {
+ if (obj instanceof X9ECParameters)
+ {
+ return (X9ECParameters)obj;
+ }
+
+ if (obj != null)
+ {
+ return new X9ECParameters(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public X9ECParameters(
+ ECCurve curve,
+ X9ECPoint g,
+ BigInteger n)
+ {
+ this(curve, g, n, null, null);
+ }
+
+ public X9ECParameters(
+ ECCurve curve,
+ X9ECPoint g,
+ BigInteger n,
+ BigInteger h)
+ {
+ this(curve, g, n, h, null);
+ }
+
+ public X9ECParameters(
+ ECCurve curve,
+ X9ECPoint g,
+ BigInteger n,
+ BigInteger h,
+ byte[] seed)
+ {
+ this.curve = curve;
+ this.g = g;
+ this.n = n;
+ this.h = h;
+ this.seed = Arrays.clone(seed);
+
+ if (ECAlgorithms.isFpCurve(curve))
+ {
+ this.fieldID = new X9FieldID(curve.getField().getCharacteristic());
+ }
+ else if (ECAlgorithms.isF2mCurve(curve))
+ {
+ PolynomialExtensionField field = (PolynomialExtensionField)curve.getField();
+ int[] exponents = field.getMinimalPolynomial().getExponentsPresent();
+ if (exponents.length == 3)
+ {
+ this.fieldID = new X9FieldID(exponents[2], exponents[1]);
+ }
+ else if (exponents.length == 5)
+ {
+ this.fieldID = new X9FieldID(exponents[4], exponents[1], exponents[2], exponents[3]);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Only trinomial and pentomial curves are supported");
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("'curve' is of an unsupported type");
+ }
+ }
+
+ public ECCurve getCurve()
+ {
+ return curve;
+ }
+
+ public ECPoint getG()
+ {
+ return g.getPoint();
+ }
+
+ public BigInteger getN()
+ {
+ return n;
+ }
+
+ public BigInteger getH()
+ {
+ return h;
+ }
+
+ public byte[] getSeed()
+ {
+ return Arrays.clone(seed);
+ }
+
+ public boolean hasSeed()
+ {
+ return null != seed;
+ }
+
+ /**
+ * Return the ASN.1 entry representing the Curve.
+ *
+ * @return the X9Curve for the curve in these parameters.
+ */
+ public X9Curve getCurveEntry()
+ {
+ return new X9Curve(curve, seed);
+ }
+
+ /**
+ * Return the ASN.1 entry representing the FieldID.
+ *
+ * @return the X9FieldID for the FieldID in these parameters.
+ */
+ public X9FieldID getFieldIDEntry()
+ {
+ return fieldID;
+ }
+
+ /**
+ * Return the ASN.1 entry representing the base point G.
+ *
+ * @return the X9ECPoint for the base point in these parameters.
+ */
+ public X9ECPoint getBaseEntry()
+ {
+ return g;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * ECParameters ::= SEQUENCE {
+ * version INTEGER { ecpVer1(1) } (ecpVer1),
+ * fieldID FieldID {{FieldTypes}},
+ * curve X9Curve,
+ * base X9ECPoint,
+ * order INTEGER,
+ * cofactor INTEGER OPTIONAL
+ * }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(6);
+
+ v.add(new ASN1Integer(ONE));
+ v.add(fieldID);
+ v.add(new X9Curve(curve, seed));
+ v.add(g);
+ v.add(new ASN1Integer(n));
+
+ if (h != null)
+ {
+ v.add(new ASN1Integer(h));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParametersHolder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParametersHolder.java
new file mode 100644
index 00000000..4db5dd1e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParametersHolder.java
@@ -0,0 +1,23 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+/**
+ * A holding class that allows for X9ECParameters to be lazily constructed.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class X9ECParametersHolder
+{
+ private X9ECParameters params;
+
+ public synchronized X9ECParameters getParameters()
+ {
+ if (params == null)
+ {
+ params = createParameters();
+ }
+
+ return params;
+ }
+
+ protected abstract X9ECParameters createParameters();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECPoint.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECPoint.java
new file mode 100644
index 00000000..42cf2834
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECPoint.java
@@ -0,0 +1,80 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Class for describing an ECPoint as a DER object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X9ECPoint
+ extends ASN1Object
+{
+ private final ASN1OctetString encoding;
+
+ private ECCurve c;
+ private ECPoint p;
+
+ public X9ECPoint(
+ ECPoint p,
+ boolean compressed)
+ {
+ this.p = p.normalize();
+ this.encoding = new DEROctetString(p.getEncoded(compressed));
+ }
+
+ public X9ECPoint(
+ ECCurve c,
+ byte[] encoding)
+ {
+ this.c = c;
+ this.encoding = new DEROctetString(Arrays.clone(encoding));
+ }
+
+ public X9ECPoint(
+ ECCurve c,
+ ASN1OctetString s)
+ {
+ this(c, s.getOctets());
+ }
+
+ public byte[] getPointEncoding()
+ {
+ return Arrays.clone(encoding.getOctets());
+ }
+
+ public synchronized ECPoint getPoint()
+ {
+ if (p == null)
+ {
+ p = c.decodePoint(encoding.getOctets()).normalize();
+ }
+
+ return p;
+ }
+
+ public boolean isPointCompressed()
+ {
+ byte[] octets = encoding.getOctets();
+ return octets != null && octets.length > 0 && (octets[0] == 2 || octets[0] == 3);
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * ECPoint ::= OCTET STRING
+ * </pre>
+ * <p>
+ * Octet string produced using ECPoint.getEncoded().
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ return encoding;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9FieldElement.java
new file mode 100644
index 00000000..e9124a2e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9FieldElement.java
@@ -0,0 +1,72 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+
+/**
+ * class for processing an FieldElement as a DER object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X9FieldElement
+ extends ASN1Object
+{
+ protected ECFieldElement f;
+
+ private static X9IntegerConverter converter = new X9IntegerConverter();
+
+ public X9FieldElement(ECFieldElement f)
+ {
+ this.f = f;
+ }
+
+ /**
+ * @deprecated Will be removed
+ */
+ public X9FieldElement(BigInteger p, ASN1OctetString s)
+ {
+ this(new ECFieldElement.Fp(p, new BigInteger(1, s.getOctets())));
+ }
+
+ /**
+ * @deprecated Will be removed
+ */
+ public X9FieldElement(int m, int k1, int k2, int k3, ASN1OctetString s)
+ {
+ this(new ECFieldElement.F2m(m, k1, k2, k3, new BigInteger(1, s.getOctets())));
+ }
+
+ public ECFieldElement getValue()
+ {
+ return f;
+ }
+
+ /**
+ * Produce an object suitable for an ASN1OutputStream.
+ * <pre>
+ * FieldElement ::= OCTET STRING
+ * </pre>
+ * <p>
+ * <ol>
+ * <li> if <i>q</i> is an odd prime then the field element is
+ * processed as an Integer and converted to an octet string
+ * according to x 9.62 4.3.1.</li>
+ * <li> if <i>q</i> is 2<sup>m</sup> then the bit string
+ * contained in the field element is converted into an octet
+ * string with the same ordering padded at the front if necessary.
+ * </li>
+ * </ol>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ int byteCount = converter.getByteLength(f);
+ byte[] paddedBigInteger = converter.integerToBytes(f.toBigInteger(), byteCount);
+
+ return new DEROctetString(paddedBigInteger);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9FieldID.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9FieldID.java
new file mode 100644
index 00000000..d28c460d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9FieldID.java
@@ -0,0 +1,150 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * ASN.1 def for Elliptic-Curve Field ID structure. See
+ * X9.62, for further details.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X9FieldID
+ extends ASN1Object
+ implements X9ObjectIdentifiers
+{
+ private ASN1ObjectIdentifier id;
+ private ASN1Primitive parameters;
+
+ /**
+ * Constructor for elliptic curves over prime fields
+ * <code>F<sub>2</sub></code>.
+ * @param primeP The prime <code>p</code> defining the prime field.
+ */
+ public X9FieldID(BigInteger primeP)
+ {
+ this.id = prime_field;
+ this.parameters = new ASN1Integer(primeP);
+ }
+
+ /**
+ * Constructor for elliptic curves over binary fields
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param m The exponent <code>m</code> of
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param k1 The integer <code>k1</code> where <code>x<sup>m</sup> +
+ * x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.
+ */
+ public X9FieldID(int m, int k1)
+ {
+ this(m, k1, 0, 0);
+ }
+
+ /**
+ * Constructor for elliptic curves over binary fields
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param m The exponent <code>m</code> of
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param k1 The integer <code>k1</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.
+ * @param k2 The integer <code>k2</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.
+ * @param k3 The integer <code>k3</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>..
+ */
+ public X9FieldID(int m, int k1, int k2, int k3)
+ {
+ this.id = characteristic_two_field;
+ ASN1EncodableVector fieldIdParams = new ASN1EncodableVector(3);
+ fieldIdParams.add(new ASN1Integer(m));
+
+ if (k2 == 0)
+ {
+ if (k3 != 0)
+ {
+ throw new IllegalArgumentException("inconsistent k values");
+ }
+
+ fieldIdParams.add(tpBasis);
+ fieldIdParams.add(new ASN1Integer(k1));
+ }
+ else
+ {
+ if (k2 <= k1 || k3 <= k2)
+ {
+ throw new IllegalArgumentException("inconsistent k values");
+ }
+
+ fieldIdParams.add(ppBasis);
+ ASN1EncodableVector pentanomialParams = new ASN1EncodableVector(3);
+ pentanomialParams.add(new ASN1Integer(k1));
+ pentanomialParams.add(new ASN1Integer(k2));
+ pentanomialParams.add(new ASN1Integer(k3));
+ fieldIdParams.add(new DERSequence(pentanomialParams));
+ }
+
+ this.parameters = new DERSequence(fieldIdParams);
+ }
+
+ private X9FieldID(
+ ASN1Sequence seq)
+ {
+ this.id = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+ this.parameters = seq.getObjectAt(1).toASN1Primitive();
+ }
+
+ public static X9FieldID getInstance(Object obj)
+ {
+ if (obj instanceof X9FieldID)
+ {
+ return (X9FieldID)obj;
+ }
+
+ if (obj != null)
+ {
+ return new X9FieldID(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ASN1ObjectIdentifier getIdentifier()
+ {
+ return id;
+ }
+
+ public ASN1Primitive getParameters()
+ {
+ return parameters;
+ }
+
+ /**
+ * Produce a DER encoding of the following structure.
+ * <pre>
+ * FieldID ::= SEQUENCE {
+ * fieldType FIELD-ID.&amp;id({IOSet}),
+ * parameters FIELD-ID.&amp;Type({IOSet}{&#64;fieldType})
+ * }
+ * </pre>
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
+
+ v.add(this.id);
+ v.add(this.parameters);
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9IntegerConverter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9IntegerConverter.java
new file mode 100644
index 00000000..b3e78570
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9IntegerConverter.java
@@ -0,0 +1,72 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+
+/**
+ * A class which converts integers to byte arrays, allowing padding and calculations
+ * to be done according the the filed size of the curve or field element involved.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X9IntegerConverter
+{
+ /**
+ * Return the curve's field size in bytes.
+ *
+ * @param c the curve of interest.
+ * @return the field size in bytes (rounded up).
+ */
+ public int getByteLength(
+ ECCurve c)
+ {
+ return (c.getFieldSize() + 7) / 8;
+ }
+
+ /**
+ * Return the field element's field size in bytes.
+ *
+ * @param fe the field element of interest.
+ * @return the field size in bytes (rounded up).
+ */
+ public int getByteLength(
+ ECFieldElement fe)
+ {
+ return (fe.getFieldSize() + 7) / 8;
+ }
+
+ /**
+ * Convert an integer to a byte array, ensuring it is exactly qLength long.
+ *
+ * @param s the integer to be converted.
+ * @param qLength the length
+ * @return the resulting byte array.
+ */
+ public byte[] integerToBytes(
+ BigInteger s,
+ int qLength)
+ {
+ byte[] bytes = s.toByteArray();
+
+ if (qLength < bytes.length)
+ {
+ byte[] tmp = new byte[qLength];
+
+ System.arraycopy(bytes, bytes.length - tmp.length, tmp, 0, tmp.length);
+
+ return tmp;
+ }
+ else if (qLength > bytes.length)
+ {
+ byte[] tmp = new byte[qLength];
+
+ System.arraycopy(bytes, 0, tmp, tmp.length - bytes.length, bytes.length);
+
+ return tmp;
+ }
+
+ return bytes;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java
new file mode 100644
index 00000000..903465b9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java
@@ -0,0 +1,226 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.asn1.x9;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ *
+ * Object identifiers for the various X9 standards.
+ * <pre>
+ * ansi-X9-62 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ * us(840) ansi-x962(10045) }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface X9ObjectIdentifiers
+{
+ /** Base OID: 1.2.840.10045 */
+ ASN1ObjectIdentifier ansi_X9_62 = new ASN1ObjectIdentifier("1.2.840.10045");
+
+ /** OID: 1.2.840.10045.1 */
+ ASN1ObjectIdentifier id_fieldType = ansi_X9_62.branch("1");
+
+ /** OID: 1.2.840.10045.1.1 */
+ ASN1ObjectIdentifier prime_field = id_fieldType.branch("1");
+
+ /** OID: 1.2.840.10045.1.2 */
+ ASN1ObjectIdentifier characteristic_two_field = id_fieldType.branch("2");
+
+ /** OID: 1.2.840.10045.1.2.3.1 */
+ ASN1ObjectIdentifier gnBasis = characteristic_two_field.branch("3.1");
+
+ /** OID: 1.2.840.10045.1.2.3.2 */
+ ASN1ObjectIdentifier tpBasis = characteristic_two_field.branch("3.2");
+
+ /** OID: 1.2.840.10045.1.2.3.3 */
+ ASN1ObjectIdentifier ppBasis = characteristic_two_field.branch("3.3");
+
+ /** OID: 1.2.840.10045.4 */
+ ASN1ObjectIdentifier id_ecSigType = ansi_X9_62.branch("4");
+
+ /** OID: 1.2.840.10045.4.1 */
+ ASN1ObjectIdentifier ecdsa_with_SHA1 = id_ecSigType.branch("1");
+
+ /** OID: 1.2.840.10045.2 */
+ ASN1ObjectIdentifier id_publicKeyType = ansi_X9_62.branch("2");
+
+ /** OID: 1.2.840.10045.2.1 */
+ ASN1ObjectIdentifier id_ecPublicKey = id_publicKeyType.branch("1");
+
+ /** OID: 1.2.840.10045.4.3 */
+ ASN1ObjectIdentifier ecdsa_with_SHA2 = id_ecSigType.branch("3");
+
+ /** OID: 1.2.840.10045.4.3.1 */
+ ASN1ObjectIdentifier ecdsa_with_SHA224 = ecdsa_with_SHA2.branch("1");
+
+ /** OID: 1.2.840.10045.4.3.2 */
+ ASN1ObjectIdentifier ecdsa_with_SHA256 = ecdsa_with_SHA2.branch("2");
+
+ /** OID: 1.2.840.10045.4.3.3 */
+ ASN1ObjectIdentifier ecdsa_with_SHA384 = ecdsa_with_SHA2.branch("3");
+
+ /** OID: 1.2.840.10045.4.3.4 */
+ ASN1ObjectIdentifier ecdsa_with_SHA512 = ecdsa_with_SHA2.branch("4");
+
+ /**
+ * Named curves base
+ * <p>
+ * OID: 1.2.840.10045.3
+ */
+ ASN1ObjectIdentifier ellipticCurve = ansi_X9_62.branch("3");
+
+ /**
+ * Two Curves
+ * <p>
+ * OID: 1.2.840.10045.3.0
+ */
+ ASN1ObjectIdentifier cTwoCurve = ellipticCurve.branch("0");
+
+ /** Two Curve c2pnb163v1, OID: 1.2.840.10045.3.0.1 */
+ ASN1ObjectIdentifier c2pnb163v1 = cTwoCurve.branch("1");
+ /** Two Curve c2pnb163v2, OID: 1.2.840.10045.3.0.2 */
+ ASN1ObjectIdentifier c2pnb163v2 = cTwoCurve.branch("2");
+ /** Two Curve c2pnb163v3, OID: 1.2.840.10045.3.0.3 */
+ ASN1ObjectIdentifier c2pnb163v3 = cTwoCurve.branch("3");
+ /** Two Curve c2pnb176w1, OID: 1.2.840.10045.3.0.4 */
+ ASN1ObjectIdentifier c2pnb176w1 = cTwoCurve.branch("4");
+ /** Two Curve c2tnb191v1, OID: 1.2.840.10045.3.0.5 */
+ ASN1ObjectIdentifier c2tnb191v1 = cTwoCurve.branch("5");
+ /** Two Curve c2tnb191v2, OID: 1.2.840.10045.3.0.6 */
+ ASN1ObjectIdentifier c2tnb191v2 = cTwoCurve.branch("6");
+ /** Two Curve c2tnb191v3, OID: 1.2.840.10045.3.0.7 */
+ ASN1ObjectIdentifier c2tnb191v3 = cTwoCurve.branch("7");
+ /** Two Curve c2onb191v4, OID: 1.2.840.10045.3.0.8 */
+ ASN1ObjectIdentifier c2onb191v4 = cTwoCurve.branch("8");
+ /** Two Curve c2onb191v5, OID: 1.2.840.10045.3.0.9 */
+ ASN1ObjectIdentifier c2onb191v5 = cTwoCurve.branch("9");
+ /** Two Curve c2pnb208w1, OID: 1.2.840.10045.3.0.10 */
+ ASN1ObjectIdentifier c2pnb208w1 = cTwoCurve.branch("10");
+ /** Two Curve c2tnb239v1, OID: 1.2.840.10045.3.0.11 */
+ ASN1ObjectIdentifier c2tnb239v1 = cTwoCurve.branch("11");
+ /** Two Curve c2tnb239v2, OID: 1.2.840.10045.3.0.12 */
+ ASN1ObjectIdentifier c2tnb239v2 = cTwoCurve.branch("12");
+ /** Two Curve c2tnb239v3, OID: 1.2.840.10045.3.0.13 */
+ ASN1ObjectIdentifier c2tnb239v3 = cTwoCurve.branch("13");
+ /** Two Curve c2onb239v4, OID: 1.2.840.10045.3.0.14 */
+ ASN1ObjectIdentifier c2onb239v4 = cTwoCurve.branch("14");
+ /** Two Curve c2onb239v5, OID: 1.2.840.10045.3.0.15 */
+ ASN1ObjectIdentifier c2onb239v5 = cTwoCurve.branch("15");
+ /** Two Curve c2pnb272w1, OID: 1.2.840.10045.3.0.16 */
+ ASN1ObjectIdentifier c2pnb272w1 = cTwoCurve.branch("16");
+ /** Two Curve c2pnb304w1, OID: 1.2.840.10045.3.0.17 */
+ ASN1ObjectIdentifier c2pnb304w1 = cTwoCurve.branch("17");
+ /** Two Curve c2tnb359v1, OID: 1.2.840.10045.3.0.18 */
+ ASN1ObjectIdentifier c2tnb359v1 = cTwoCurve.branch("18");
+ /** Two Curve c2pnb368w1, OID: 1.2.840.10045.3.0.19 */
+ ASN1ObjectIdentifier c2pnb368w1 = cTwoCurve.branch("19");
+ /** Two Curve c2tnb431r1, OID: 1.2.840.10045.3.0.20 */
+ ASN1ObjectIdentifier c2tnb431r1 = cTwoCurve.branch("20");
+
+ /**
+ * Prime Curves
+ * <p>
+ * OID: 1.2.840.10045.3.1
+ */
+ ASN1ObjectIdentifier primeCurve = ellipticCurve.branch("1");
+
+ /** Prime Curve prime192v1, OID: 1.2.840.10045.3.1.1 */
+ ASN1ObjectIdentifier prime192v1 = primeCurve.branch("1");
+ /** Prime Curve prime192v2, OID: 1.2.840.10045.3.1.2 */
+ ASN1ObjectIdentifier prime192v2 = primeCurve.branch("2");
+ /** Prime Curve prime192v3, OID: 1.2.840.10045.3.1.3 */
+ ASN1ObjectIdentifier prime192v3 = primeCurve.branch("3");
+ /** Prime Curve prime239v1, OID: 1.2.840.10045.3.1.4 */
+ ASN1ObjectIdentifier prime239v1 = primeCurve.branch("4");
+ /** Prime Curve prime239v2, OID: 1.2.840.10045.3.1.5 */
+ ASN1ObjectIdentifier prime239v2 = primeCurve.branch("5");
+ /** Prime Curve prime239v3, OID: 1.2.840.10045.3.1.6 */
+ ASN1ObjectIdentifier prime239v3 = primeCurve.branch("6");
+ /** Prime Curve prime256v1, OID: 1.2.840.10045.3.1.7 */
+ ASN1ObjectIdentifier prime256v1 = primeCurve.branch("7");
+
+ /**
+ * DSA
+ * <pre>
+ * dsapublicnumber OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ * us(840) ansi-x957(10040) number-type(4) 1 }
+ * </pre>
+ * Base OID: 1.2.840.10040.4.1
+ */
+ ASN1ObjectIdentifier id_dsa = new ASN1ObjectIdentifier("1.2.840.10040.4.1");
+
+ /**
+ * <pre>
+ * id-dsa-with-sha1 OBJECT IDENTIFIER ::= {
+ * iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3 }
+ * </pre>
+ * OID: 1.2.840.10040.4.3
+ */
+ ASN1ObjectIdentifier id_dsa_with_sha1 = new ASN1ObjectIdentifier("1.2.840.10040.4.3");
+
+ /**
+ * X9.63 - Signature Specification
+ * <p>
+ * Base OID: 1.3.133.16.840.63.0
+ */
+ ASN1ObjectIdentifier x9_63_scheme = new ASN1ObjectIdentifier("1.3.133.16.840.63.0");
+ /** OID: 1.3.133.16.840.63.0.2 */
+ ASN1ObjectIdentifier dhSinglePass_stdDH_sha1kdf_scheme = x9_63_scheme.branch("2");
+ /** OID: 1.3.133.16.840.63.0.3 */
+ ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha1kdf_scheme = x9_63_scheme.branch("3");
+ /** OID: 1.3.133.16.840.63.0.16 */
+ ASN1ObjectIdentifier mqvSinglePass_sha1kdf_scheme = x9_63_scheme.branch("16");
+
+ /**
+ * X9.42
+ */
+
+ ASN1ObjectIdentifier ansi_X9_42 = new ASN1ObjectIdentifier("1.2.840.10046");
+
+ /**
+ * Diffie-Hellman
+ * <pre>
+ * dhpublicnumber OBJECT IDENTIFIER ::= {
+ * iso(1) member-body(2) us(840) ansi-x942(10046) number-type(2) 1
+ * }
+ * </pre>
+ * OID: 1.2.840.10046.2.1
+ */
+ ASN1ObjectIdentifier dhpublicnumber = ansi_X9_42.branch("2.1");
+
+ /** X9.42 schemas base OID: 1.2.840.10046.3 */
+ ASN1ObjectIdentifier x9_42_schemes = ansi_X9_42.branch("3");
+ /** X9.42 dhStatic OID: 1.2.840.10046.3.1 */
+ ASN1ObjectIdentifier dhStatic = x9_42_schemes.branch("1");
+ /** X9.42 dhEphem OID: 1.2.840.10046.3.2 */
+ ASN1ObjectIdentifier dhEphem = x9_42_schemes.branch("2");
+ /** X9.42 dhOneFlow OID: 1.2.840.10046.3.3 */
+ ASN1ObjectIdentifier dhOneFlow = x9_42_schemes.branch("3");
+ /** X9.42 dhHybrid1 OID: 1.2.840.10046.3.4 */
+ ASN1ObjectIdentifier dhHybrid1 = x9_42_schemes.branch("4");
+ /** X9.42 dhHybrid2 OID: 1.2.840.10046.3.5 */
+ ASN1ObjectIdentifier dhHybrid2 = x9_42_schemes.branch("5");
+ /** X9.42 dhHybridOneFlow OID: 1.2.840.10046.3.6 */
+ ASN1ObjectIdentifier dhHybridOneFlow = x9_42_schemes.branch("6");
+ /** X9.42 MQV2 OID: 1.2.840.10046.3.7 */
+ ASN1ObjectIdentifier mqv2 = x9_42_schemes.branch("7");
+ /** X9.42 MQV1 OID: 1.2.840.10046.3.8 */
+ ASN1ObjectIdentifier mqv1 = x9_42_schemes.branch("8");
+
+ /**
+ * X9.44
+ * <pre>
+ * x9-44 OID ::= {
+ * iso(1) identified-organization(3) tc68(133) country(16) x9(840)
+ * x9Standards(9) x9-44(44)
+ * }
+ * </pre>
+ */
+
+ ASN1ObjectIdentifier x9_44 = new ASN1ObjectIdentifier("1.3.133.16.840.9.44");
+
+ ASN1ObjectIdentifier x9_44_components = x9_44.branch("1");
+
+ ASN1ObjectIdentifier id_kdf_kdf2 = x9_44_components.branch("1");
+ ASN1ObjectIdentifier id_kdf_kdf3 = x9_44_components.branch("2");
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AsymmetricBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AsymmetricBlockCipher.java
new file mode 100644
index 00000000..511e48c0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AsymmetricBlockCipher.java
@@ -0,0 +1,47 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+
+/**
+ * base interface that a public/private key block cipher needs
+ * to conform to.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface AsymmetricBlockCipher
+{
+ /**
+ * initialise the cipher.
+ *
+ * @param forEncryption if true the cipher is initialised for
+ * encryption, if false for decryption.
+ * @param param the key and other data required by the cipher.
+ */
+ public void init(boolean forEncryption, CipherParameters param);
+
+ /**
+ * returns the largest size an input block can be.
+ *
+ * @return maximum size for an input block.
+ */
+ public int getInputBlockSize();
+
+ /**
+ * returns the maximum size of the block produced by this cipher.
+ *
+ * @return maximum size of the output block produced by the cipher.
+ */
+ public int getOutputBlockSize();
+
+ /**
+ * process the block of len bytes stored in in from offset inOff.
+ *
+ * @param in the input data
+ * @param inOff offset into the in array where the data starts
+ * @param len the length of the block to be processed.
+ * @return the resulting byte array of the encryption/decryption process.
+ * @exception InvalidCipherTextException data decrypts improperly.
+ * @exception DataLengthException the input data is too large for the cipher.
+ */
+ public byte[] processBlock(byte[] in, int inOff, int len)
+ throws InvalidCipherTextException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AsymmetricCipherKeyPair.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AsymmetricCipherKeyPair.java
new file mode 100644
index 00000000..7bd42eaf
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AsymmetricCipherKeyPair.java
@@ -0,0 +1,63 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+
+/**
+ * a holding class for public/private parameter pairs.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AsymmetricCipherKeyPair
+{
+ private AsymmetricKeyParameter publicParam;
+ private AsymmetricKeyParameter privateParam;
+
+ /**
+ * basic constructor.
+ *
+ * @param publicParam a public key parameters object.
+ * @param privateParam the corresponding private key parameters.
+ */
+ public AsymmetricCipherKeyPair(
+ AsymmetricKeyParameter publicParam,
+ AsymmetricKeyParameter privateParam)
+ {
+ this.publicParam = publicParam;
+ this.privateParam = privateParam;
+ }
+
+ /**
+ * basic constructor.
+ *
+ * @param publicParam a public key parameters object.
+ * @param privateParam the corresponding private key parameters.
+ * @deprecated use AsymmetricKeyParameter
+ */
+ public AsymmetricCipherKeyPair(
+ CipherParameters publicParam,
+ CipherParameters privateParam)
+ {
+ this.publicParam = (AsymmetricKeyParameter)publicParam;
+ this.privateParam = (AsymmetricKeyParameter)privateParam;
+ }
+
+ /**
+ * return the public key parameters.
+ *
+ * @return the public key parameters.
+ */
+ public AsymmetricKeyParameter getPublic()
+ {
+ return publicParam;
+ }
+
+ /**
+ * return the private key parameters.
+ *
+ * @return the private key parameters.
+ */
+ public AsymmetricKeyParameter getPrivate()
+ {
+ return privateParam;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AsymmetricCipherKeyPairGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AsymmetricCipherKeyPairGenerator.java
new file mode 100644
index 00000000..c7d272b2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/AsymmetricCipherKeyPairGenerator.java
@@ -0,0 +1,24 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * interface that a public/private key pair generator should conform to.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface AsymmetricCipherKeyPairGenerator
+{
+ /**
+ * intialise the key pair generator.
+ *
+ * @param param the parameters the key pair is to be initialised with.
+ */
+ public void init(KeyGenerationParameters param);
+
+ /**
+ * return an AsymmetricCipherKeyPair containing the generated keys.
+ *
+ * @return an AsymmetricCipherKeyPair containing the generated keys.
+ */
+ public AsymmetricCipherKeyPair generateKeyPair();
+}
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BasicAgreement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BasicAgreement.java
new file mode 100644
index 00000000..fcf23828
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BasicAgreement.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+import java.math.BigInteger;
+
+/**
+ * The basic interface that basic Diffie-Hellman implementations
+ * conforms to.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface BasicAgreement
+{
+ /**
+ * initialise the agreement engine.
+ */
+ void init(CipherParameters param);
+
+ /**
+ * return the field size for the agreement algorithm in bytes.
+ */
+ int getFieldSize();
+
+ /**
+ * given a public key from a given party calculate the next
+ * message in the agreement sequence.
+ */
+ BigInteger calculateAgreement(CipherParameters pubKey);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BlockCipher.java
new file mode 100644
index 00000000..9fbfe10d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BlockCipher.java
@@ -0,0 +1,58 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+
+/**
+ * Block cipher engines are expected to conform to this interface.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface BlockCipher
+{
+ /**
+ * Initialise the cipher.
+ *
+ * @param forEncryption if true the cipher is initialised for
+ * encryption, if false for decryption.
+ * @param params the key and other data required by the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(boolean forEncryption, CipherParameters params)
+ throws IllegalArgumentException;
+
+ /**
+ * Return the name of the algorithm the cipher implements.
+ *
+ * @return the name of the algorithm the cipher implements.
+ */
+ public String getAlgorithmName();
+
+ /**
+ * Return the block size for this cipher (in bytes).
+ *
+ * @return the block size for this cipher in bytes.
+ */
+ public int getBlockSize();
+
+ /**
+ * Process one block of input from the array in and write it to
+ * the out array.
+ *
+ * @param in the array containing the input data.
+ * @param inOff offset into the in array the data starts at.
+ * @param out the array the output data will be copied into.
+ * @param outOff the offset into the out array the output will start at.
+ * @exception DataLengthException if there isn't enough data in in, or
+ * space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ * @return the number of bytes processed and produced.
+ */
+ public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
+ throws DataLengthException, IllegalStateException;
+
+ /**
+ * Reset the cipher. After resetting the cipher is in the same state
+ * as it was after the last init (if there was one).
+ */
+ public void reset();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BufferedBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BufferedBlockCipher.java
new file mode 100644
index 00000000..f9e8c6c7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/BufferedBlockCipher.java
@@ -0,0 +1,322 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+
+/**
+ * A wrapper class that allows block ciphers to be used to process data in
+ * a piecemeal fashion. The BufferedBlockCipher outputs a block only when the
+ * buffer is full and more data is being added, or on a doFinal.
+ * <p>
+ * Note: in the case where the underlying cipher is either a CFB cipher or an
+ * OFB one the last block may not be a multiple of the block size.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BufferedBlockCipher
+{
+ protected byte[] buf;
+ protected int bufOff;
+
+ protected boolean forEncryption;
+ protected BlockCipher cipher;
+
+ protected boolean partialBlockOkay;
+ protected boolean pgpCFB;
+
+ /**
+ * constructor for subclasses
+ */
+ protected BufferedBlockCipher()
+ {
+ }
+
+ /**
+ * Create a buffered block cipher without padding.
+ *
+ * @param cipher the underlying block cipher this buffering object wraps.
+ */
+ public BufferedBlockCipher(
+ BlockCipher cipher)
+ {
+ this.cipher = cipher;
+
+ buf = new byte[cipher.getBlockSize()];
+ bufOff = 0;
+
+ //
+ // check if we can handle partial blocks on doFinal.
+ //
+ String name = cipher.getAlgorithmName();
+ int idx = name.indexOf('/') + 1;
+
+ pgpCFB = (idx > 0 && name.startsWith("PGP", idx));
+
+ if (pgpCFB || cipher instanceof StreamCipher)
+ {
+ partialBlockOkay = true;
+ }
+ else
+ {
+ partialBlockOkay = (idx > 0 && (name.startsWith("OpenPGP", idx)));
+ }
+ }
+
+ /**
+ * return the cipher this object wraps.
+ *
+ * @return the cipher this object wraps.
+ */
+ public BlockCipher getUnderlyingCipher()
+ {
+ return cipher;
+ }
+
+ /**
+ * initialise the cipher.
+ *
+ * @param forEncryption if true the cipher is initialised for
+ * encryption, if false for decryption.
+ * @param params the key and other data required by the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean forEncryption,
+ CipherParameters params)
+ throws IllegalArgumentException
+ {
+ this.forEncryption = forEncryption;
+
+ reset();
+
+ cipher.init(forEncryption, params);
+ }
+
+ /**
+ * return the blocksize for the underlying cipher.
+ *
+ * @return the blocksize for the underlying cipher.
+ */
+ public int getBlockSize()
+ {
+ return cipher.getBlockSize();
+ }
+
+ /**
+ * return the size of the output buffer required for an update
+ * an input of len bytes.
+ *
+ * @param len the length of the input.
+ * @return the space required to accommodate a call to update
+ * with len bytes of input.
+ */
+ public int getUpdateOutputSize(
+ int len)
+ {
+ int total = len + bufOff;
+ int leftOver;
+
+ if (pgpCFB)
+ {
+ if (forEncryption)
+ {
+ leftOver = total % buf.length - (cipher.getBlockSize() + 2);
+ }
+ else
+ {
+ leftOver = total % buf.length;
+ }
+ }
+ else
+ {
+ leftOver = total % buf.length;
+ }
+
+ return total - leftOver;
+ }
+
+ /**
+ * return the size of the output buffer required for an update plus a
+ * doFinal with an input of 'length' bytes.
+ *
+ * @param length the length of the input.
+ * @return the space required to accommodate a call to update and doFinal
+ * with 'length' bytes of input.
+ */
+ public int getOutputSize(
+ int length)
+ {
+ // Note: Can assume partialBlockOkay is true for purposes of this calculation
+ return length + bufOff;
+ }
+
+ /**
+ * process a single byte, producing an output block if necessary.
+ *
+ * @param in the input byte.
+ * @param out the space for any output that might be produced.
+ * @param outOff the offset from which the output will be copied.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there isn't enough space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ */
+ public int processByte(
+ byte in,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ int resultLen = 0;
+
+ buf[bufOff++] = in;
+
+ if (bufOff == buf.length)
+ {
+ resultLen = cipher.processBlock(buf, 0, out, outOff);
+ bufOff = 0;
+ }
+
+ return resultLen;
+ }
+
+ /**
+ * process an array of bytes, producing output if necessary.
+ *
+ * @param in the input byte array.
+ * @param inOff the offset at which the input data starts.
+ * @param len the number of bytes to be copied out of the input array.
+ * @param out the space for any output that might be produced.
+ * @param outOff the offset from which the output will be copied.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there isn't enough space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ */
+ public int processBytes(
+ byte[] in,
+ int inOff,
+ int len,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ if (len < 0)
+ {
+ throw new IllegalArgumentException("Can't have a negative input length!");
+ }
+
+ int blockSize = getBlockSize();
+ int length = getUpdateOutputSize(len);
+
+ if (length > 0)
+ {
+ if ((outOff + length) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ }
+
+ int resultLen = 0;
+ int gapLen = buf.length - bufOff;
+
+ if (len > gapLen)
+ {
+ System.arraycopy(in, inOff, buf, bufOff, gapLen);
+
+ resultLen += cipher.processBlock(buf, 0, out, outOff);
+
+ bufOff = 0;
+ len -= gapLen;
+ inOff += gapLen;
+
+ while (len > buf.length)
+ {
+ resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen);
+
+ len -= blockSize;
+ inOff += blockSize;
+ }
+ }
+
+ System.arraycopy(in, inOff, buf, bufOff, len);
+
+ bufOff += len;
+
+ if (bufOff == buf.length)
+ {
+ resultLen += cipher.processBlock(buf, 0, out, outOff + resultLen);
+ bufOff = 0;
+ }
+
+ return resultLen;
+ }
+
+ /**
+ * Process the last block in the buffer.
+ *
+ * @param out the array the block currently being held is copied into.
+ * @param outOff the offset at which the copying starts.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there is insufficient space in out for
+ * the output, or the input is not block size aligned and should be.
+ * @exception IllegalStateException if the underlying cipher is not
+ * initialised.
+ * @exception InvalidCipherTextException if padding is expected and not found.
+ * @exception DataLengthException if the input is not block size
+ * aligned.
+ */
+ public int doFinal(
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException, InvalidCipherTextException
+ {
+ try
+ {
+ int resultLen = 0;
+
+ if (outOff + bufOff > out.length)
+ {
+ throw new OutputLengthException("output buffer too short for doFinal()");
+ }
+
+ if (bufOff != 0)
+ {
+ if (!partialBlockOkay)
+ {
+ throw new DataLengthException("data not block size aligned");
+ }
+
+ cipher.processBlock(buf, 0, buf, 0);
+ resultLen = bufOff;
+ bufOff = 0;
+ System.arraycopy(buf, 0, out, outOff, resultLen);
+ }
+
+ return resultLen;
+ }
+ finally
+ {
+ reset();
+ }
+ }
+
+ /**
+ * Reset the buffer and cipher. After resetting the object is in the same
+ * state as it was after the last init (if there was one).
+ */
+ public void reset()
+ {
+ //
+ // clean the buffer.
+ //
+ for (int i = 0; i < buf.length; i++)
+ {
+ buf[i] = 0;
+ }
+
+ bufOff = 0;
+
+ //
+ // reset the underlying cipher.
+ //
+ cipher.reset();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CipherKeyGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CipherKeyGenerator.java
new file mode 100644
index 00000000..2b26db69
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CipherKeyGenerator.java
@@ -0,0 +1,40 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+import java.security.SecureRandom;
+
+/**
+ * The base class for symmetric, or secret, cipher key generators.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CipherKeyGenerator
+{
+ protected SecureRandom random;
+ protected int strength;
+
+ /**
+ * initialise the key generator.
+ *
+ * @param param the parameters to be used for key generation
+ */
+ public void init(
+ KeyGenerationParameters param)
+ {
+ this.random = param.getRandom();
+ this.strength = (param.getStrength() + 7) / 8;
+ }
+
+ /**
+ * generate a secret key.
+ *
+ * @return a byte array containing the key value.
+ */
+ public byte[] generateKey()
+ {
+ byte[] key = new byte[strength];
+
+ random.nextBytes(key);
+
+ return key;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CipherParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CipherParameters.java
new file mode 100644
index 00000000..20658e2a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CipherParameters.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * all parameter classes implement this.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CipherParameters
+{
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoException.java
new file mode 100644
index 00000000..af6bf045
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoException.java
@@ -0,0 +1,50 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * the foundation class for the hard exceptions thrown by the crypto packages.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CryptoException
+ extends Exception
+{
+ private Throwable cause;
+
+ /**
+ * base constructor.
+ */
+ public CryptoException()
+ {
+ }
+
+ /**
+ * create a CryptoException with the given message.
+ *
+ * @param message the message to be carried with the exception.
+ */
+ public CryptoException(
+ String message)
+ {
+ super(message);
+ }
+
+ /**
+ * Create a CryptoException with the given message and underlying cause.
+ *
+ * @param message message describing exception.
+ * @param cause the throwable that was the underlying cause.
+ */
+ public CryptoException(
+ String message,
+ Throwable cause)
+ {
+ super(message);
+
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesPermission.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesPermission.java
new file mode 100644
index 00000000..6c1f44a8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesPermission.java
@@ -0,0 +1,83 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+import java.security.Permission;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Permissions that need to be configured if a SecurityManager is used.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CryptoServicesPermission
+ extends Permission
+{
+ /**
+ * Enable the setting of global configuration properties. This permission implies THREAD_LOCAL_CONFIG
+ */
+ public static final String GLOBAL_CONFIG = "globalConfig";
+
+ /**
+ * Enable the setting of thread local configuration properties.
+ */
+ public static final String THREAD_LOCAL_CONFIG = "threadLocalConfig";
+
+ /**
+ * Enable the setting of the default SecureRandom.
+ */
+ public static final String DEFAULT_RANDOM = "defaultRandomConfig";
+
+ private final Set<String> actions = new HashSet<String>();
+
+ public CryptoServicesPermission(String name)
+ {
+ super(name);
+
+ this.actions.add(name);
+ }
+
+ public boolean implies(Permission permission)
+ {
+ if (permission instanceof CryptoServicesPermission)
+ {
+ CryptoServicesPermission other = (CryptoServicesPermission)permission;
+
+ if (this.getName().equals(other.getName()))
+ {
+ return true;
+ }
+
+ if (this.actions.containsAll(other.actions))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof CryptoServicesPermission)
+ {
+ CryptoServicesPermission other = (CryptoServicesPermission)obj;
+
+ if (this.actions.equals(other.actions))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public int hashCode()
+ {
+ return actions.hashCode();
+ }
+
+ public String getActions()
+ {
+ return actions.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesRegistrar.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesRegistrar.java
new file mode 100644
index 00000000..7a337ce8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesRegistrar.java
@@ -0,0 +1,447 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+import java.math.BigInteger;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PrivilegedAction;
+import java.security.SecureRandom;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHValidationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAValidationParameters;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * Basic registrar class for providing defaults for cryptography services in this module.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class CryptoServicesRegistrar
+{
+ private static final Permission CanSetDefaultProperty = new CryptoServicesPermission(CryptoServicesPermission.GLOBAL_CONFIG);
+ private static final Permission CanSetThreadProperty = new CryptoServicesPermission(CryptoServicesPermission.THREAD_LOCAL_CONFIG);
+ private static final Permission CanSetDefaultRandom = new CryptoServicesPermission(CryptoServicesPermission.DEFAULT_RANDOM);
+
+ private static final ThreadLocal<Map<String, Object[]>> threadProperties = new ThreadLocal<Map<String, Object[]>>();
+ private static final Map<String, Object[]> globalProperties = Collections.synchronizedMap(new HashMap<String, Object[]>());
+
+ private static final Object cacheLock = new Object();
+ private static SecureRandom defaultSecureRandom;
+
+ static
+ {
+ // default domain parameters for DSA and Diffie-Hellman
+
+ DSAParameters def512Params = new DSAParameters(
+ new BigInteger("fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e17", 16),
+ new BigInteger("962eddcc369cba8ebb260ee6b6a126d9346e38c5", 16),
+ new BigInteger("678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4", 16),
+ new DSAValidationParameters(Hex.decodeStrict("b869c82b35d70e1b1ff91b28e37a62ecdc34409b"), 123));
+
+ DSAParameters def768Params = new DSAParameters(
+ new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5" +
+ "d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a" +
+ "22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45" +
+ "ee3688c11a8c56ab127a3daf", 16),
+ new BigInteger("9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511", 16),
+ new BigInteger("30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7" +
+ "a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d366844577" +
+ "1f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a" +
+ "7064f316933a346d3f529252", 16),
+ new DSAValidationParameters(Hex.decodeStrict("77d0f8c4dad15eb8c4f2f8d6726cefd96d5bb399"), 263));
+
+ DSAParameters def1024Params = new DSAParameters(
+ new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80" +
+ "b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b" +
+ "801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c6" +
+ "1bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675" +
+ "f3ae2b61d72aeff22203199dd14801c7", 16),
+ new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16),
+ new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b" +
+ "3d0782675159578ebad4594fe67107108180b449167123e84c281613" +
+ "b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f" +
+ "0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06" +
+ "928b665e807b552564014c3bfecf492a", 16),
+ new DSAValidationParameters(Hex.decodeStrict("8d5155894229d5e689ee01e6018a237e2cae64cd"), 92));
+
+ DSAParameters def2048Params = new DSAParameters(
+ new BigInteger("95475cf5d93e596c3fcd1d902add02f427f5f3c7210313bb45fb4d5b" +
+ "b2e5fe1cbd678cd4bbdd84c9836be1f31c0777725aeb6c2fc38b85f4" +
+ "8076fa76bcd8146cc89a6fb2f706dd719898c2083dc8d896f84062e2" +
+ "c9c94d137b054a8d8096adb8d51952398eeca852a0af12df83e475aa" +
+ "65d4ec0c38a9560d5661186ff98b9fc9eb60eee8b030376b236bc73b" +
+ "e3acdbd74fd61c1d2475fa3077b8f080467881ff7e1ca56fee066d79" +
+ "506ade51edbb5443a563927dbc4ba520086746175c8885925ebc64c6" +
+ "147906773496990cb714ec667304e261faee33b3cbdf008e0c3fa906" +
+ "50d97d3909c9275bf4ac86ffcb3d03e6dfc8ada5934242dd6d3bcca2" +
+ "a406cb0b", 16),
+ new BigInteger("f8183668ba5fc5bb06b5981e6d8b795d30b8978d43ca0ec572e37e09939a9773", 16),
+ new BigInteger("42debb9da5b3d88cc956e08787ec3f3a09bba5f48b889a74aaf53174" +
+ "aa0fbe7e3c5b8fcd7a53bef563b0e98560328960a9517f4014d3325f" +
+ "c7962bf1e049370d76d1314a76137e792f3f0db859d095e4a5b93202" +
+ "4f079ecf2ef09c797452b0770e1350782ed57ddf794979dcef23cb96" +
+ "f183061965c4ebc93c9c71c56b925955a75f94cccf1449ac43d586d0" +
+ "beee43251b0b2287349d68de0d144403f13e802f4146d882e057af19" +
+ "b6f6275c6676c8fa0e3ca2713a3257fd1b27d0639f695e347d8d1cf9" +
+ "ac819a26ca9b04cb0eb9b7b035988d15bbac65212a55239cfc7e58fa" +
+ "e38d7250ab9991ffbc97134025fe8ce04c4399ad96569be91a546f49" +
+ "78693c7a", 16),
+ new DSAValidationParameters(Hex.decodeStrict("b0b4417601b59cbc9d8ac8f935cadaec4f5fbb2f23785609ae466748d9b5a536"), 497));
+
+ localSetGlobalProperty(Property.DSA_DEFAULT_PARAMS, def512Params, def768Params, def1024Params, def2048Params);
+ localSetGlobalProperty(Property.DH_DEFAULT_PARAMS, toDH(def512Params), toDH(def768Params), toDH(def1024Params), toDH(def2048Params));
+ }
+
+ private CryptoServicesRegistrar()
+ {
+
+ }
+
+ /**
+ * Return the default source of randomness.
+ *
+ * @return the default SecureRandom
+ */
+ public static SecureRandom getSecureRandom()
+ {
+ synchronized (cacheLock)
+ {
+ if (null != defaultSecureRandom)
+ {
+ return defaultSecureRandom;
+ }
+ }
+
+ SecureRandom tmp = new SecureRandom();
+
+ synchronized (cacheLock)
+ {
+ if (null == defaultSecureRandom)
+ {
+ defaultSecureRandom = tmp;
+ }
+
+ return defaultSecureRandom;
+ }
+ }
+
+ /**
+ * Return either the passed-in SecureRandom, or if it is null, then the default source of randomness.
+ *
+ * @param secureRandom the SecureRandom to use if it is not null.
+ * @return the SecureRandom parameter if it is not null, or else the default SecureRandom
+ */
+ public static SecureRandom getSecureRandom(SecureRandom secureRandom)
+ {
+ return null == secureRandom ? getSecureRandom() : secureRandom;
+ }
+
+ /**
+ * Set a default secure random to be used where none is otherwise provided.
+ *
+ * @param secureRandom the SecureRandom to use as the default.
+ */
+ public static void setSecureRandom(SecureRandom secureRandom)
+ {
+ checkPermission(CanSetDefaultRandom);
+
+ synchronized (cacheLock)
+ {
+ defaultSecureRandom = secureRandom;
+ }
+ }
+
+ /**
+ * Return the default value for a particular property if one exists. The look up is done on the thread's local
+ * configuration first and then on the global configuration in no local configuration exists.
+ *
+ * @param property the property to look up.
+ * @param <T> the type to be returned
+ * @return null if the property is not set, the default value otherwise,
+ */
+ public static <T> T getProperty(Property property)
+ {
+ Object[] values = lookupProperty(property);
+
+ if (values != null)
+ {
+ return (T)values[0];
+ }
+
+ return null;
+ }
+
+ private static Object[] lookupProperty(Property property)
+ {
+ Map<String, Object[]> properties = threadProperties.get();
+ Object[] values;
+
+ if (properties == null || !properties.containsKey(property.name))
+ {
+ values = globalProperties.get(property.name);
+ }
+ else
+ {
+ values = properties.get(property.name);
+ }
+ return values;
+ }
+
+ /**
+ * Return an array representing the current values for a sized property such as DH_DEFAULT_PARAMS or
+ * DSA_DEFAULT_PARAMS.
+ *
+ * @param property the name of the property to look up.
+ * @param <T> the base type of the array to be returned.
+ * @return null if the property is not set, an array of the current values otherwise.
+ */
+ public static <T> T[] getSizedProperty(Property property)
+ {
+ Object[] values = lookupProperty(property);
+
+ if (values == null)
+ {
+ return null;
+ }
+
+ return (T[])values.clone();
+ }
+
+ /**
+ * Return the value for a specific size for a sized property such as DH_DEFAULT_PARAMS or
+ * DSA_DEFAULT_PARAMS.
+ *
+ * @param property the name of the property to look up.
+ * @param size the size (in bits) of the defining value in the property type.
+ * @param <T> the type of the value to be returned.
+ * @return the current value for the size, null if there is no value set,
+ */
+ public static <T> T getSizedProperty(Property property, int size)
+ {
+ Object[] values = lookupProperty(property);
+
+ if (values == null)
+ {
+ return null;
+ }
+
+ if (property.type.isAssignableFrom(DHParameters.class))
+ {
+ for (int i = 0; i != values.length; i++)
+ {
+ DHParameters params = (DHParameters)values[i];
+
+ if (params.getP().bitLength() == size)
+ {
+ return (T)params;
+ }
+ }
+ }
+ else if (property.type.isAssignableFrom(DSAParameters.class))
+ {
+ for (int i = 0; i != values.length; i++)
+ {
+ DSAParameters params = (DSAParameters)values[i];
+
+ if (params.getP().bitLength() == size)
+ {
+ return (T)params;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Set the value of the the passed in property on the current thread only. More than
+ * one value can be passed in for a sized property. If more than one value is provided the
+ * first value in the argument list becomes the default value.
+ *
+ * @param property the name of the property to set.
+ * @param propertyValue the values to assign to the property.
+ * @param <T> the base type of the property value.
+ */
+ public static <T> void setThreadProperty(Property property, T... propertyValue)
+ {
+ checkPermission(CanSetThreadProperty);
+
+ if (!property.type.isAssignableFrom(propertyValue[0].getClass()))
+ {
+ throw new IllegalArgumentException("Bad property value passed");
+ }
+
+ localSetThread(property, propertyValue.clone());
+ }
+
+ /**
+ * Set the value of the the passed in property globally in the JVM. More than
+ * one value can be passed in for a sized property. If more than one value is provided the
+ * first value in the argument list becomes the default value.
+ *
+ * @param property the name of the property to set.
+ * @param propertyValue the values to assign to the property.
+ * @param <T> the base type of the property value.
+ */
+ public static <T> void setGlobalProperty(Property property, T... propertyValue)
+ {
+ checkPermission(CanSetDefaultProperty);
+
+ localSetGlobalProperty(property, propertyValue.clone());
+ }
+
+ private static <T> void localSetThread(Property property, T[] propertyValue)
+ {
+ Map<String, Object[]> properties = threadProperties.get();
+
+ if (properties == null)
+ {
+ properties = new HashMap<String, Object[]>();
+ threadProperties.set(properties);
+ }
+
+ properties.put(property.name, propertyValue);
+ }
+
+ private static <T> void localSetGlobalProperty(Property property, T... propertyValue)
+ {
+ if (!property.type.isAssignableFrom(propertyValue[0].getClass()))
+ {
+ throw new IllegalArgumentException("Bad property value passed");
+ }
+
+ // set the property for the current thread as well to avoid mass confusion
+ localSetThread(property, propertyValue);
+
+ globalProperties.put(property.name, propertyValue);
+ }
+
+ /**
+ * Clear the global value for the passed in property.
+ *
+ * @param property the property to be cleared.
+ * @param <T> the base type of the property value
+ * @return an array of T if a value was previously set, null otherwise.
+ */
+ public static <T> T[] clearGlobalProperty(Property property)
+ {
+ checkPermission(CanSetDefaultProperty);
+
+ // clear the property for the current thread as well to avoid confusion
+ localClearThreadProperty(property);
+
+ return (T[])globalProperties.remove(property.name);
+ }
+
+ /**
+ * Clear the thread local value for the passed in property.
+ *
+ * @param property the property to be cleared.
+ * @param <T> the base type of the property value
+ * @return an array of T if a value was previously set, null otherwise.
+ */
+ public static <T> T[] clearThreadProperty(Property property)
+ {
+ checkPermission(CanSetThreadProperty);
+
+ return (T[])localClearThreadProperty(property);
+ }
+
+ private static Object[] localClearThreadProperty(Property property)
+ {
+ Map<String, Object[]> properties = threadProperties.get();
+
+ if (properties == null)
+ {
+ properties = new HashMap<String, Object[]>();
+ threadProperties.set(properties);
+ }
+
+ return properties.remove(property.name);
+ }
+
+ private static void checkPermission(final Permission permission)
+ {
+ final SecurityManager securityManager = System.getSecurityManager();
+
+ if (securityManager != null)
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ securityManager.checkPermission(permission);
+
+ return null;
+ }
+ });
+ }
+ }
+
+ private static DHParameters toDH(DSAParameters dsaParams)
+ {
+ int pSize = dsaParams.getP().bitLength();
+ int m = chooseLowerBound(pSize);
+ return new DHParameters(dsaParams.getP(), dsaParams.getG(), dsaParams.getQ(), m, 0, null,
+ new DHValidationParameters(dsaParams.getValidationParameters().getSeed(), dsaParams.getValidationParameters().getCounter()));
+ }
+
+ // based on lower limit of at least 2^{2 * bits_of_security}
+ private static int chooseLowerBound(int pSize)
+ {
+ int m = 160;
+ if (pSize > 1024)
+ {
+ if (pSize <= 2048)
+ {
+ m = 224;
+ }
+ else if (pSize <= 3072)
+ {
+ m = 256;
+ }
+ else if (pSize <= 7680)
+ {
+ m = 384;
+ }
+ else
+ {
+ m = 512;
+ }
+ }
+ return m;
+ }
+
+ /**
+ * Available properties that can be set.
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static final class Property
+ {
+ /**
+ * The parameters to be used for processing implicitlyCA X9.62 parameters
+ */
+ public static final Property EC_IMPLICITLY_CA = new Property("ecImplicitlyCA", X9ECParameters.class);
+ /**
+ * The default parameters for a particular size of Diffie-Hellman key.This is a sized property.
+ */
+ public static final Property DH_DEFAULT_PARAMS= new Property("dhDefaultParams", DHParameters.class);
+ /**
+ * The default parameters for a particular size of DSA key. This is a sized property.
+ */
+ public static final Property DSA_DEFAULT_PARAMS= new Property("dsaDefaultParams", DSAParameters.class);
+ private final String name;
+ private final Class type;
+
+ private Property(String name, Class type)
+ {
+ this.name = name;
+ this.type = type;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DSA.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DSA.java
new file mode 100644
index 00000000..2d836c7d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DSA.java
@@ -0,0 +1,38 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+import java.math.BigInteger;
+
+/**
+ * interface for classes implementing algorithms modeled similar to the Digital Signature Alorithm.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface DSA
+{
+ /**
+ * initialise the signer for signature generation or signature
+ * verification.
+ *
+ * @param forSigning true if we are generating a signature, false
+ * otherwise.
+ * @param param key parameters for signature generation.
+ */
+ public void init(boolean forSigning, CipherParameters param);
+
+ /**
+ * sign the passed in message (usually the output of a hash function).
+ *
+ * @param message the message to be signed.
+ * @return two big integers representing the r and s values respectively.
+ */
+ public BigInteger[] generateSignature(byte[] message);
+
+ /**
+ * verify the message message against the signature values r and s.
+ *
+ * @param message the message that was supposed to have been signed.
+ * @param r the r signature value.
+ * @param s the s signature value.
+ */
+ public boolean verifySignature(byte[] message, BigInteger r, BigInteger s);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DSAExt.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DSAExt.java
new file mode 100644
index 00000000..c69a3f83
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DSAExt.java
@@ -0,0 +1,18 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+import java.math.BigInteger;
+
+/**
+ * An "extended" interface for classes implementing DSA-style algorithms, that provides access to
+ * the group order.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface DSAExt
+ extends DSA
+{
+ /**
+ * Get the order of the group that the r, s values in signatures belong to.
+ */
+ public BigInteger getOrder();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DataLengthException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DataLengthException.java
new file mode 100644
index 00000000..a23947da
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DataLengthException.java
@@ -0,0 +1,31 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * this exception is thrown if a buffer that is meant to have output
+ * copied into it turns out to be too short, or if we've been given
+ * insufficient input. In general this exception will get thrown rather
+ * than an ArrayOutOfBounds exception.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DataLengthException
+ extends RuntimeCryptoException
+{
+ /**
+ * base constructor.
+ */
+ public DataLengthException()
+ {
+ }
+
+ /**
+ * create a DataLengthException with the given message.
+ *
+ * @param message the message to be carried with the exception.
+ */
+ public DataLengthException(
+ String message)
+ {
+ super(message);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DerivationFunction.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DerivationFunction.java
new file mode 100644
index 00000000..3e30b929
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DerivationFunction.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * base interface for general purpose byte derivation functions.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface DerivationFunction
+{
+ public void init(DerivationParameters param);
+
+ public int generateBytes(byte[] out, int outOff, int len)
+ throws DataLengthException, IllegalArgumentException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DerivationParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DerivationParameters.java
new file mode 100644
index 00000000..41101598
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/DerivationParameters.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * Parameters for key/byte stream derivation classes
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface DerivationParameters
+{
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Digest.java
new file mode 100644
index 00000000..a73ca810
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Digest.java
@@ -0,0 +1,53 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * interface that a message digest conforms to.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Digest
+{
+ /**
+ * return the algorithm name
+ *
+ * @return the algorithm name
+ */
+ public String getAlgorithmName();
+
+ /**
+ * return the size, in bytes, of the digest produced by this message digest.
+ *
+ * @return the size, in bytes, of the digest produced by this message digest.
+ */
+ public int getDigestSize();
+
+ /**
+ * update the message digest with a single byte.
+ *
+ * @param in the input byte to be entered.
+ */
+ public void update(byte in);
+
+ /**
+ * update the message digest with a block of bytes.
+ *
+ * @param in the byte array containing the data.
+ * @param inOff the offset into the byte array where the data starts.
+ * @param len the length of the data.
+ */
+ public void update(byte[] in, int inOff, int len);
+
+ /**
+ * close the digest, producing the final digest value. The doFinal
+ * call leaves the digest reset.
+ *
+ * @param out the array the digest is to be copied into.
+ * @param outOff the offset into the out array the digest is to start at.
+ */
+ public int doFinal(byte[] out, int outOff);
+
+ /**
+ * reset the digest back to it's initial state.
+ */
+ public void reset();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/ExtendedDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/ExtendedDigest.java
new file mode 100644
index 00000000..75db8652
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/ExtendedDigest.java
@@ -0,0 +1,17 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ExtendedDigest
+ extends Digest
+{
+ /**
+ * Return the size in bytes of the internal buffer the digest applies it's compression
+ * function to.
+ *
+ * @return byte length of the digests internal buffer.
+ */
+ public int getByteLength();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/InvalidCipherTextException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/InvalidCipherTextException.java
new file mode 100644
index 00000000..05ebfe54
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/InvalidCipherTextException.java
@@ -0,0 +1,42 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * this exception is thrown whenever we find something we don't expect in a
+ * message.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class InvalidCipherTextException
+ extends CryptoException
+{
+ /**
+ * base constructor.
+ */
+ public InvalidCipherTextException()
+ {
+ }
+
+ /**
+ * create a InvalidCipherTextException with the given message.
+ *
+ * @param message the message to be carried with the exception.
+ */
+ public InvalidCipherTextException(
+ String message)
+ {
+ super(message);
+ }
+
+ /**
+ * create a InvalidCipherTextException with the given message.
+ *
+ * @param message the message to be carried with the exception.
+ * @param cause the root cause of the exception.
+ */
+ public InvalidCipherTextException(
+ String message,
+ Throwable cause)
+ {
+ super(message, cause);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/KeyGenerationParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/KeyGenerationParameters.java
new file mode 100644
index 00000000..7da35273
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/KeyGenerationParameters.java
@@ -0,0 +1,50 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+import java.security.SecureRandom;
+
+/**
+ * The base class for parameters to key generators.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyGenerationParameters
+{
+ private SecureRandom random;
+ private int strength;
+
+ /**
+ * initialise the generator with a source of randomness
+ * and a strength (in bits).
+ *
+ * @param random the random byte source.
+ * @param strength the size, in bits, of the keys we want to produce.
+ */
+ public KeyGenerationParameters(
+ SecureRandom random,
+ int strength)
+ {
+ this.random = CryptoServicesRegistrar.getSecureRandom(random);
+ this.strength = strength;
+ }
+
+ /**
+ * return the random source associated with this
+ * generator.
+ *
+ * @return the generators random source.
+ */
+ public SecureRandom getRandom()
+ {
+ return random;
+ }
+
+ /**
+ * return the bit strength for keys produced by this generator,
+ *
+ * @return the strength of the keys this generator produces (in bits).
+ */
+ public int getStrength()
+ {
+ return strength;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Mac.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Mac.java
new file mode 100644
index 00000000..e7ec29dd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Mac.java
@@ -0,0 +1,73 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+
+/**
+ * The base interface for implementations of message authentication codes (MACs).
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Mac
+{
+ /**
+ * Initialise the MAC.
+ *
+ * @param params the key and other data required by the MAC.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(CipherParameters params)
+ throws IllegalArgumentException;
+
+ /**
+ * Return the name of the algorithm the MAC implements.
+ *
+ * @return the name of the algorithm the MAC implements.
+ */
+ public String getAlgorithmName();
+
+ /**
+ * Return the block size for this MAC (in bytes).
+ *
+ * @return the block size for this MAC in bytes.
+ */
+ public int getMacSize();
+
+ /**
+ * add a single byte to the mac for processing.
+ *
+ * @param in the byte to be processed.
+ * @exception IllegalStateException if the MAC is not initialised.
+ */
+ public void update(byte in)
+ throws IllegalStateException;
+
+ /**
+ * @param in the array containing the input.
+ * @param inOff the index in the array the data begins at.
+ * @param len the length of the input starting at inOff.
+ * @exception IllegalStateException if the MAC is not initialised.
+ * @exception DataLengthException if there isn't enough data in in.
+ */
+ public void update(byte[] in, int inOff, int len)
+ throws DataLengthException, IllegalStateException;
+
+ /**
+ * Compute the final stage of the MAC writing the output to the out
+ * parameter.
+ * <p>
+ * doFinal leaves the MAC in the same state it was after the last init.
+ *
+ * @param out the array the MAC is to be output to.
+ * @param outOff the offset into the out buffer the output is to start at.
+ * @exception DataLengthException if there isn't enough space in out.
+ * @exception IllegalStateException if the MAC is not initialised.
+ */
+ public int doFinal(byte[] out, int outOff)
+ throws DataLengthException, IllegalStateException;
+
+ /**
+ * Reset the MAC. At the end of resetting the MAC should be in the
+ * in the same state it was after the last init (if there was one).
+ */
+ public void reset();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/OutputLengthException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/OutputLengthException.java
new file mode 100644
index 00000000..c87bd1e9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/OutputLengthException.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OutputLengthException
+ extends DataLengthException
+{
+ public OutputLengthException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/PBEParametersGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/PBEParametersGenerator.java
new file mode 100644
index 00000000..8ac380f0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/PBEParametersGenerator.java
@@ -0,0 +1,173 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * super class for all Password Based Encryption (PBE) parameter generator classes.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class PBEParametersGenerator
+{
+ protected byte[] password;
+ protected byte[] salt;
+ protected int iterationCount;
+
+ /**
+ * base constructor.
+ */
+ protected PBEParametersGenerator()
+ {
+ }
+
+ /**
+ * initialise the PBE generator.
+ *
+ * @param password the password converted into bytes (see below).
+ * @param salt the salt to be mixed with the password.
+ * @param iterationCount the number of iterations the "mixing" function
+ * is to be applied for.
+ */
+ public void init(
+ byte[] password,
+ byte[] salt,
+ int iterationCount)
+ {
+ this.password = password;
+ this.salt = salt;
+ this.iterationCount = iterationCount;
+ }
+
+ /**
+ * return the password byte array.
+ *
+ * @return the password byte array.
+ */
+ public byte[] getPassword()
+ {
+ return password;
+ }
+
+ /**
+ * return the salt byte array.
+ *
+ * @return the salt byte array.
+ */
+ public byte[] getSalt()
+ {
+ return salt;
+ }
+
+ /**
+ * return the iteration count.
+ *
+ * @return the iteration count.
+ */
+ public int getIterationCount()
+ {
+ return iterationCount;
+ }
+
+ /**
+ * generate derived parameters for a key of length keySize.
+ *
+ * @param keySize the length, in bits, of the key required.
+ * @return a parameters object representing a key.
+ */
+ public abstract CipherParameters generateDerivedParameters(int keySize);
+
+ /**
+ * generate derived parameters for a key of length keySize, and
+ * an initialisation vector (IV) of length ivSize.
+ *
+ * @param keySize the length, in bits, of the key required.
+ * @param ivSize the length, in bits, of the iv required.
+ * @return a parameters object representing a key and an IV.
+ */
+ public abstract CipherParameters generateDerivedParameters(int keySize, int ivSize);
+
+ /**
+ * generate derived parameters for a key of length keySize, specifically
+ * for use with a MAC.
+ *
+ * @param keySize the length, in bits, of the key required.
+ * @return a parameters object representing a key.
+ */
+ public abstract CipherParameters generateDerivedMacParameters(int keySize);
+
+ /**
+ * converts a password to a byte array according to the scheme in
+ * PKCS5 (ascii, no padding)
+ *
+ * @param password a character array representing the password.
+ * @return a byte array representing the password.
+ */
+ public static byte[] PKCS5PasswordToBytes(
+ char[] password)
+ {
+ if (password != null)
+ {
+ byte[] bytes = new byte[password.length];
+
+ for (int i = 0; i != bytes.length; i++)
+ {
+ bytes[i] = (byte)password[i];
+ }
+
+ return bytes;
+ }
+ else
+ {
+ return new byte[0];
+ }
+ }
+
+ /**
+ * converts a password to a byte array according to the scheme in
+ * PKCS5 (UTF-8, no padding)
+ *
+ * @param password a character array representing the password.
+ * @return a byte array representing the password.
+ */
+ public static byte[] PKCS5PasswordToUTF8Bytes(
+ char[] password)
+ {
+ if (password != null)
+ {
+ return Strings.toUTF8ByteArray(password);
+ }
+ else
+ {
+ return new byte[0];
+ }
+ }
+
+ /**
+ * converts a password to a byte array according to the scheme in
+ * PKCS12 (unicode, big endian, 2 zero pad bytes at the end).
+ *
+ * @param password a character array representing the password.
+ * @return a byte array representing the password.
+ */
+ public static byte[] PKCS12PasswordToBytes(
+ char[] password)
+ {
+ if (password != null && password.length > 0)
+ {
+ // +1 for extra 2 pad bytes.
+ byte[] bytes = new byte[(password.length + 1) * 2];
+
+ for (int i = 0; i != password.length; i ++)
+ {
+ bytes[i * 2] = (byte)(password[i] >>> 8);
+ bytes[i * 2 + 1] = (byte)password[i];
+ }
+
+ return bytes;
+ }
+ else
+ {
+ return new byte[0];
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/RawAgreement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/RawAgreement.java
new file mode 100644
index 00000000..19ee2677
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/RawAgreement.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface RawAgreement
+{
+ void init(CipherParameters parameters);
+
+ int getAgreementSize();
+
+ void calculateAgreement(CipherParameters publicKey, byte[] buf, int off);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/RuntimeCryptoException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/RuntimeCryptoException.java
new file mode 100644
index 00000000..44122cb7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/RuntimeCryptoException.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * the foundation class for the exceptions thrown by the crypto packages.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RuntimeCryptoException
+ extends RuntimeException
+{
+ /**
+ * base constructor.
+ */
+ public RuntimeCryptoException()
+ {
+ }
+
+ /**
+ * create a RuntimeCryptoException with the given message.
+ *
+ * @param message the message to be carried with the exception.
+ */
+ public RuntimeCryptoException(
+ String message)
+ {
+ super(message);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Signer.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Signer.java
new file mode 100644
index 00000000..3cecaa47
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Signer.java
@@ -0,0 +1,45 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * Generic signer interface for hash based and message recovery signers.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Signer
+{
+ /**
+ * Initialise the signer for signing or verification.
+ *
+ * @param forSigning true if for signing, false otherwise
+ * @param param necessary parameters.
+ */
+ public void init(boolean forSigning, CipherParameters param);
+
+ /**
+ * update the internal digest with the byte b
+ */
+ public void update(byte b);
+
+ /**
+ * update the internal digest with the byte array in
+ */
+ public void update(byte[] in, int off, int len);
+
+ /**
+ * generate a signature for the message we've been loaded with using
+ * the key we were initialised with.
+ */
+ public byte[] generateSignature()
+ throws CryptoException, DataLengthException;
+
+ /**
+ * return true if the internal state represents the signature described
+ * in the passed in array.
+ */
+ public boolean verifySignature(byte[] signature);
+
+ /**
+ * reset the internal state
+ */
+ public void reset();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SignerWithRecovery.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SignerWithRecovery.java
new file mode 100644
index 00000000..d211afe9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SignerWithRecovery.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * Signer with message recovery.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface SignerWithRecovery
+ extends Signer
+{
+ /**
+ * Returns true if the signer has recovered the full message as
+ * part of signature verification.
+ *
+ * @return true if full message recovered.
+ */
+ public boolean hasFullMessage();
+
+ /**
+ * Returns a reference to what message was recovered (if any).
+ *
+ * @return full/partial message, null if nothing.
+ */
+ public byte[] getRecoveredMessage();
+
+ /**
+ * Perform an update with the recovered message before adding any other data. This must
+ * be the first update method called, and calling it will result in the signer assuming
+ * that further calls to update will include message content past what is recoverable.
+ *
+ * @param signature the signature that we are in the process of verifying.
+ * @throws IllegalStateException
+ */
+ public void updateWithRecoveredMessage(byte[] signature)
+ throws InvalidCipherTextException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SkippingCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SkippingCipher.java
new file mode 100644
index 00000000..709041e6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SkippingCipher.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * Ciphers producing a key stream which can be reset to particular points in the stream implement this.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface SkippingCipher
+{
+ /**
+ * Skip numberOfBytes forwards, or backwards.
+ *
+ * @param numberOfBytes the number of bytes to skip (positive forward, negative backwards).
+ * @return the number of bytes actually skipped.
+ * @throws java.lang.IllegalArgumentException if numberOfBytes is an invalid value.
+ */
+ long skip(long numberOfBytes);
+
+ /**
+ * Reset the cipher and then skip forward to a given position.
+ *
+ * @param position the number of bytes in to set the cipher state to.
+ * @return the byte position moved to.
+ */
+ long seekTo(long position);
+
+ /**
+ * Return the current "position" of the cipher
+ *
+ * @return the current byte position.
+ */
+ long getPosition();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SkippingStreamCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SkippingStreamCipher.java
new file mode 100644
index 00000000..ee3e3357
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/SkippingStreamCipher.java
@@ -0,0 +1,11 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * General interface for a stream cipher that supports skipping.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface SkippingStreamCipher
+ extends StreamCipher, SkippingCipher
+{
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StagedAgreement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StagedAgreement.java
new file mode 100644
index 00000000..35fd64d5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StagedAgreement.java
@@ -0,0 +1,13 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface StagedAgreement
+ extends BasicAgreement
+{
+ AsymmetricKeyParameter calculateStage(CipherParameters pubKey);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StreamBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StreamBlockCipher.java
new file mode 100644
index 00000000..b52b224e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StreamBlockCipher.java
@@ -0,0 +1,59 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * A parent class for block cipher modes that do not require block aligned data to be processed, but can function in
+ * a streaming mode.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class StreamBlockCipher
+ implements BlockCipher, StreamCipher
+{
+ private final BlockCipher cipher;
+
+ protected StreamBlockCipher(BlockCipher cipher)
+ {
+ this.cipher = cipher;
+ }
+
+ /**
+ * return the underlying block cipher that we are wrapping.
+ *
+ * @return the underlying block cipher that we are wrapping.
+ */
+ public BlockCipher getUnderlyingCipher()
+ {
+ return cipher;
+ }
+
+ public final byte returnByte(byte in)
+ {
+ return calculateByte(in);
+ }
+
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException
+ {
+ if (inOff + len > in.length)
+ {
+ throw new DataLengthException("input buffer too small");
+ }
+ if (outOff + len > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ int inStart = inOff;
+ int inEnd = inOff + len;
+ int outStart = outOff;
+
+ while (inStart < inEnd)
+ {
+ out[outStart++] = calculateByte(in[inStart++]);
+ }
+
+ return len;
+ }
+
+ protected abstract byte calculateByte(byte b);
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StreamCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StreamCipher.java
new file mode 100644
index 00000000..0564bbb8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/StreamCipher.java
@@ -0,0 +1,56 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * the interface stream ciphers conform to.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface StreamCipher
+{
+ /**
+ * Initialise the cipher.
+ *
+ * @param forEncryption if true the cipher is initialised for
+ * encryption, if false for decryption.
+ * @param params the key and other data required by the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(boolean forEncryption, CipherParameters params)
+ throws IllegalArgumentException;
+
+ /**
+ * Return the name of the algorithm the cipher implements.
+ *
+ * @return the name of the algorithm the cipher implements.
+ */
+ public String getAlgorithmName();
+
+ /**
+ * encrypt/decrypt a single byte returning the result.
+ *
+ * @param in the byte to be processed.
+ * @return the result of processing the input byte.
+ */
+ public byte returnByte(byte in);
+
+ /**
+ * process a block of bytes from in putting the result into out.
+ *
+ * @param in the input byte array.
+ * @param inOff the offset into the in array where the data to be processed starts.
+ * @param len the number of bytes to be processed.
+ * @param out the output buffer the processed bytes go into.
+ * @param outOff the offset into the output byte array the processed data starts at.
+ * @return the number of bytes produced - should always be len.
+ * @exception DataLengthException if the output buffer is too small.
+ */
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException;
+
+ /**
+ * reset the cipher. This leaves it in the same state
+ * it was at after the last init (if there was one).
+ */
+ public void reset();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Wrapper.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Wrapper.java
new file mode 100644
index 00000000..1d24270a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/Wrapper.java
@@ -0,0 +1,22 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Wrapper
+{
+ public void init(boolean forWrapping, CipherParameters param);
+
+ /**
+ * Return the name of the algorithm the wrapper implements.
+ *
+ * @return the name of the algorithm the wrapper implements.
+ */
+ public String getAlgorithmName();
+
+ public byte[] wrap(byte[] in, int inOff, int inLen);
+
+ public byte[] unwrap(byte[] in, int inOff, int inLen)
+ throws InvalidCipherTextException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/DHBasicAgreement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/DHBasicAgreement.java
new file mode 100644
index 00000000..718e1059
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/DHBasicAgreement.java
@@ -0,0 +1,89 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.agreement;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.crypto.BasicAgreement;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPublicKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+
+/**
+ * a Diffie-Hellman key agreement class.
+ * <p>
+ * note: This is only the basic algorithm, it doesn't take advantage of
+ * long term public keys if they are available. See the DHAgreement class
+ * for a "better" implementation.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHBasicAgreement
+ implements BasicAgreement
+{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+
+ private DHPrivateKeyParameters key;
+ private DHParameters dhParams;
+
+ public void init(
+ CipherParameters param)
+ {
+ AsymmetricKeyParameter kParam;
+
+ if (param instanceof ParametersWithRandom)
+ {
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
+ kParam = (AsymmetricKeyParameter)rParam.getParameters();
+ }
+ else
+ {
+ kParam = (AsymmetricKeyParameter)param;
+ }
+
+ if (!(kParam instanceof DHPrivateKeyParameters))
+ {
+ throw new IllegalArgumentException("DHEngine expects DHPrivateKeyParameters");
+ }
+
+ this.key = (DHPrivateKeyParameters)kParam;
+ this.dhParams = key.getParameters();
+ }
+
+ public int getFieldSize()
+ {
+ return (key.getParameters().getP().bitLength() + 7) / 8;
+ }
+
+ /**
+ * given a short term public key from a given party calculate the next
+ * message in the agreement sequence.
+ */
+ public BigInteger calculateAgreement(
+ CipherParameters pubKey)
+ {
+ DHPublicKeyParameters pub = (DHPublicKeyParameters)pubKey;
+
+ if (!pub.getParameters().equals(dhParams))
+ {
+ throw new IllegalArgumentException("Diffie-Hellman public key has wrong parameters.");
+ }
+
+ BigInteger p = dhParams.getP();
+
+ BigInteger peerY = pub.getY();
+ if (peerY == null || peerY.compareTo(ONE) <= 0 || peerY.compareTo(p.subtract(ONE)) >= 0)
+ {
+ throw new IllegalArgumentException("Diffie-Hellman public key is weak");
+ }
+
+ BigInteger result = peerY.modPow(key.getX(), p);
+ if (result.equals(ONE))
+ {
+ throw new IllegalStateException("Shared key can't be 1");
+ }
+
+ return result;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java
new file mode 100644
index 00000000..944a9865
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java
@@ -0,0 +1,80 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.agreement;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.crypto.BasicAgreement;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import com.android.internal.org.bouncycastle.math.ec.ECAlgorithms;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+
+/**
+ * P1363 7.2.1 ECSVDP-DH
+ *
+ * ECSVDP-DH is Elliptic Curve Secret Value Derivation Primitive,
+ * Diffie-Hellman version. It is based on the work of [DH76], [Mil86],
+ * and [Kob87]. This primitive derives a shared secret value from one
+ * party's private key and another party's public key, where both have
+ * the same set of EC domain parameters. If two parties correctly
+ * execute this primitive, they will produce the same output. This
+ * primitive can be invoked by a scheme to derive a shared secret key;
+ * specifically, it may be used with the schemes ECKAS-DH1 and
+ * DL/ECKAS-DH2. It assumes that the input keys are valid (see also
+ * Section 7.2.2).
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECDHBasicAgreement
+ implements BasicAgreement
+{
+ private ECPrivateKeyParameters key;
+
+ public void init(
+ CipherParameters key)
+ {
+ this.key = (ECPrivateKeyParameters)key;
+ }
+
+ public int getFieldSize()
+ {
+ return (key.getParameters().getCurve().getFieldSize() + 7) / 8;
+ }
+
+ public BigInteger calculateAgreement(
+ CipherParameters pubKey)
+ {
+ ECPublicKeyParameters pub = (ECPublicKeyParameters)pubKey;
+ ECDomainParameters params = key.getParameters();
+ if (!params.equals(pub.getParameters()))
+ {
+ throw new IllegalStateException("ECDH public key has wrong domain parameters");
+ }
+
+ BigInteger d = key.getD();
+
+ // Always perform calculations on the exact curve specified by our private key's parameters
+ ECPoint Q = ECAlgorithms.cleanPoint(params.getCurve(), pub.getQ());
+ if (Q.isInfinity())
+ {
+ throw new IllegalStateException("Infinity is not a valid public key for ECDH");
+ }
+
+ BigInteger h = params.getH();
+ if (!h.equals(ECConstants.ONE))
+ {
+ d = params.getHInv().multiply(d).mod(params.getN());
+ Q = ECAlgorithms.referenceMultiply(Q, h);
+ }
+
+ ECPoint P = Q.multiply(d).normalize();
+ if (P.isInfinity())
+ {
+ throw new IllegalStateException("Infinity is not a valid agreement value for ECDH");
+ }
+
+ return P.getAffineXCoord().toBigInteger();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactory.java
new file mode 100644
index 00000000..638b9620
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactory.java
@@ -0,0 +1,111 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import java.security.Security;
+import java.util.Locale;
+
+import com.android.internal.org.bouncycastle.crypto.Digest;
+
+/**
+ * Level of indirection to let us select OpenSSLDigest implementations
+ * for libcore but fallback to BouncyCastle ones on the RI.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class AndroidDigestFactory {
+ private static final AndroidDigestFactoryInterface CONSCRYPT;
+ private static final AndroidDigestFactoryInterface BC;
+
+ static {
+ BC = new AndroidDigestFactoryBouncyCastle();
+ if (Security.getProvider("AndroidOpenSSL") != null) {
+ CONSCRYPT = new AndroidDigestFactoryOpenSSL();
+ } else {
+ if (System.getProperty("java.vendor", "").toLowerCase(Locale.US).contains("android")) {
+ throw new AssertionError("Provider AndroidOpenSSL must exist");
+ }
+ CONSCRYPT = null;
+ }
+ }
+
+ public static Digest getMD5() {
+ if (CONSCRYPT != null) {
+ try {
+ return CONSCRYPT.getMD5();
+ } catch (Exception ignored) {
+ }
+ }
+
+ return BC.getMD5();
+ }
+
+ public static Digest getSHA1() {
+ if (CONSCRYPT != null) {
+ try {
+ return CONSCRYPT.getSHA1();
+ } catch (Exception ignored) {
+ }
+ }
+
+ return BC.getSHA1();
+ }
+
+ public static Digest getSHA224() {
+ if (CONSCRYPT != null) {
+ try {
+ return CONSCRYPT.getSHA224();
+ } catch (Exception ignored) {
+ }
+ }
+
+ return BC.getSHA224();
+ }
+
+ public static Digest getSHA256() {
+ if (CONSCRYPT != null) {
+ try {
+ return CONSCRYPT.getSHA256();
+ } catch (Exception ignored) {
+ }
+ }
+
+ return BC.getSHA256();
+ }
+
+ public static Digest getSHA384() {
+ if (CONSCRYPT != null) {
+ try {
+ return CONSCRYPT.getSHA384();
+ } catch (Exception ignored) {
+ }
+ }
+
+ return BC.getSHA384();
+ }
+
+ public static Digest getSHA512() {
+ if (CONSCRYPT != null) {
+ try {
+ return CONSCRYPT.getSHA512();
+ } catch (Exception ignored) {
+ }
+ }
+
+ return BC.getSHA512();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactoryBouncyCastle.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactoryBouncyCastle.java
new file mode 100644
index 00000000..bfbe92c6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactoryBouncyCastle.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import com.android.internal.org.bouncycastle.crypto.Digest;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AndroidDigestFactoryBouncyCastle implements AndroidDigestFactoryInterface {
+ public Digest getMD5() {
+ return new MD5Digest();
+ }
+ public Digest getSHA1() {
+ return new SHA1Digest();
+ }
+ public Digest getSHA224() {
+ return new SHA224Digest();
+ }
+ public Digest getSHA256() {
+ return new SHA256Digest();
+ }
+ public Digest getSHA384() {
+ return new SHA384Digest();
+ }
+ public Digest getSHA512() {
+ return new SHA512Digest();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactoryInterface.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactoryInterface.java
new file mode 100644
index 00000000..cee9ca8d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactoryInterface.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import com.android.internal.org.bouncycastle.crypto.Digest;
+
+interface AndroidDigestFactoryInterface {
+ public Digest getMD5();
+ public Digest getSHA1();
+ public Digest getSHA224();
+ public Digest getSHA256();
+ public Digest getSHA384();
+ public Digest getSHA512();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactoryOpenSSL.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactoryOpenSSL.java
new file mode 100644
index 00000000..1cc3451c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/AndroidDigestFactoryOpenSSL.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import com.android.internal.org.bouncycastle.crypto.Digest;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AndroidDigestFactoryOpenSSL implements AndroidDigestFactoryInterface {
+ public Digest getMD5() {
+ return new OpenSSLDigest.MD5();
+ }
+ public Digest getSHA1() {
+ return new OpenSSLDigest.SHA1();
+ }
+ public Digest getSHA224() {
+ return new OpenSSLDigest.SHA224();
+ }
+ public Digest getSHA256() {
+ return new OpenSSLDigest.SHA256();
+ }
+ public Digest getSHA384() {
+ return new OpenSSLDigest.SHA384();
+ }
+ public Digest getSHA512() {
+ return new OpenSSLDigest.SHA512();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/EncodableDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/EncodableDigest.java
new file mode 100644
index 00000000..9197ba67
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/EncodableDigest.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+/**
+ * Encodable digests allow you to download an encoded copy of their internal state. This is useful for the situation where
+ * you need to generate a signature on an external device and it allows for "sign with last round", so a copy of the
+ * internal state of the digest, plus the last few blocks of the message are all that needs to be sent, rather than the
+ * entire message.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface EncodableDigest
+{
+ /**
+ * Return an encoded byte array for the digest's internal state
+ *
+ * @return an encoding of the digests internal state.
+ */
+ byte[] getEncodedState();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/GeneralDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/GeneralDigest.java
new file mode 100644
index 00000000..75038bd5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/GeneralDigest.java
@@ -0,0 +1,162 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import com.android.internal.org.bouncycastle.crypto.ExtendedDigest;
+import com.android.internal.org.bouncycastle.util.Memoable;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * base implementation of MD4 family style digest as outlined in
+ * "Handbook of Applied Cryptography", pages 344 - 347.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class GeneralDigest
+ implements ExtendedDigest, Memoable
+{
+ private static final int BYTE_LENGTH = 64;
+
+ private final byte[] xBuf = new byte[4];
+ private int xBufOff;
+
+ private long byteCount;
+
+ /**
+ * Standard constructor
+ */
+ protected GeneralDigest()
+ {
+ 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)
+ {
+ copyIn(t);
+ }
+
+ protected GeneralDigest(byte[] encodedState)
+ {
+ System.arraycopy(encodedState, 0, xBuf, 0, xBuf.length);
+ xBufOff = Pack.bigEndianToInt(encodedState, 4);
+ byteCount = Pack.bigEndianToLong(encodedState, 8);
+ }
+
+ 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)
+ {
+ len = Math.max(0, len);
+
+ //
+ // fill the current word
+ //
+ int i = 0;
+ if (xBufOff != 0)
+ {
+ while (i < len)
+ {
+ xBuf[xBufOff++] = in[inOff + i++];
+ if (xBufOff == 4)
+ {
+ processWord(xBuf, 0);
+ xBufOff = 0;
+ break;
+ }
+ }
+ }
+
+ //
+ // process whole words.
+ //
+ int limit = ((len - i) & ~3) + i;
+ for (; i < limit; i += 4)
+ {
+ processWord(in, inOff + i);
+ }
+
+ //
+ // load in the remainder.
+ //
+ while (i < len)
+ {
+ xBuf[xBufOff++] = in[inOff + i++];
+ }
+
+ byteCount += 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 void populateState(byte[] state)
+ {
+ System.arraycopy(xBuf, 0, state, 0, xBufOff);
+ Pack.intToBigEndian(xBufOff, state, 4);
+ Pack.longToBigEndian(byteCount, state, 8);
+ }
+
+ public int getByteLength()
+ {
+ return BYTE_LENGTH;
+ }
+
+ protected abstract void processWord(byte[] in, int inOff);
+
+ protected abstract void processLength(long bitLength);
+
+ protected abstract void processBlock();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/LongDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/LongDigest.java
new file mode 100644
index 00000000..cc7411e7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/LongDigest.java
@@ -0,0 +1,411 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import com.android.internal.org.bouncycastle.crypto.ExtendedDigest;
+import com.android.internal.org.bouncycastle.util.Memoable;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * Base class for SHA-384 and SHA-512.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class LongDigest
+ implements ExtendedDigest, Memoable, EncodableDigest
+{
+ private static final int BYTE_LENGTH = 128;
+
+ private byte[] xBuf = new byte[8];
+ private int xBufOff;
+
+ private long byteCount1;
+ private long byteCount2;
+
+ protected long H1, H2, H3, H4, H5, H6, H7, H8;
+
+ private long[] W = new long[80];
+ private int wOff;
+
+ /**
+ * Constructor for variable length word
+ */
+ protected LongDigest()
+ {
+ xBufOff = 0;
+
+ reset();
+ }
+
+ /**
+ * Copy constructor. We are using copy constructors in place
+ * of the Object.clone() interface as this interface is not
+ * supported by J2ME.
+ */
+ protected LongDigest(LongDigest t)
+ {
+ copyIn(t);
+ }
+
+ protected void copyIn(LongDigest t)
+ {
+ System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length);
+
+ xBufOff = t.xBufOff;
+ byteCount1 = t.byteCount1;
+ byteCount2 = t.byteCount2;
+
+ H1 = t.H1;
+ H2 = t.H2;
+ H3 = t.H3;
+ H4 = t.H4;
+ H5 = t.H5;
+ H6 = t.H6;
+ H7 = t.H7;
+ H8 = t.H8;
+
+ System.arraycopy(t.W, 0, W, 0, t.W.length);
+ wOff = t.wOff;
+ }
+
+ protected void populateState(byte[] state)
+ {
+ System.arraycopy(xBuf, 0, state, 0, xBufOff);
+ Pack.intToBigEndian(xBufOff, state, 8);
+ Pack.longToBigEndian(byteCount1, state, 12);
+ Pack.longToBigEndian(byteCount2, state, 20);
+ Pack.longToBigEndian(H1, state, 28);
+ Pack.longToBigEndian(H2, state, 36);
+ Pack.longToBigEndian(H3, state, 44);
+ Pack.longToBigEndian(H4, state, 52);
+ Pack.longToBigEndian(H5, state, 60);
+ Pack.longToBigEndian(H6, state, 68);
+ Pack.longToBigEndian(H7, state, 76);
+ Pack.longToBigEndian(H8, state, 84);
+
+ Pack.intToBigEndian(wOff, state, 92);
+ for (int i = 0; i < wOff; i++)
+ {
+ Pack.longToBigEndian(W[i], state, 96 + (i * 8));
+ }
+ }
+
+ protected void restoreState(byte[] encodedState)
+ {
+ xBufOff = Pack.bigEndianToInt(encodedState, 8);
+ System.arraycopy(encodedState, 0, xBuf, 0, xBufOff);
+ byteCount1 = Pack.bigEndianToLong(encodedState, 12);
+ byteCount2 = Pack.bigEndianToLong(encodedState, 20);
+
+ H1 = Pack.bigEndianToLong(encodedState, 28);
+ H2 = Pack.bigEndianToLong(encodedState, 36);
+ H3 = Pack.bigEndianToLong(encodedState, 44);
+ H4 = Pack.bigEndianToLong(encodedState, 52);
+ H5 = Pack.bigEndianToLong(encodedState, 60);
+ H6 = Pack.bigEndianToLong(encodedState, 68);
+ H7 = Pack.bigEndianToLong(encodedState, 76);
+ H8 = Pack.bigEndianToLong(encodedState, 84);
+
+ wOff = Pack.bigEndianToInt(encodedState, 92);
+ for (int i = 0; i < wOff; i++)
+ {
+ W[i] = Pack.bigEndianToLong(encodedState, 96 + (i * 8));
+ }
+ }
+
+ protected int getEncodedStateSize()
+ {
+ return 96 + (wOff * 8);
+ }
+
+ public void update(
+ byte in)
+ {
+ xBuf[xBufOff++] = in;
+
+ if (xBufOff == xBuf.length)
+ {
+ processWord(xBuf, 0);
+ xBufOff = 0;
+ }
+
+ byteCount1++;
+ }
+
+ 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;
+ byteCount1 += xBuf.length;
+ }
+
+ //
+ // load in the remainder.
+ //
+ while (len > 0)
+ {
+ update(in[inOff]);
+
+ inOff++;
+ len--;
+ }
+ }
+
+ public void finish()
+ {
+ adjustByteCounts();
+
+ long lowBitLength = byteCount1 << 3;
+ long hiBitLength = byteCount2;
+
+ //
+ // add the pad bytes.
+ //
+ update((byte)128);
+
+ while (xBufOff != 0)
+ {
+ update((byte)0);
+ }
+
+ processLength(lowBitLength, hiBitLength);
+
+ processBlock();
+ }
+
+ public void reset()
+ {
+ byteCount1 = 0;
+ byteCount2 = 0;
+
+ xBufOff = 0;
+ for (int i = 0; i < xBuf.length; i++)
+ {
+ xBuf[i] = 0;
+ }
+
+ wOff = 0;
+ for (int i = 0; i != W.length; i++)
+ {
+ W[i] = 0;
+ }
+ }
+
+ public int getByteLength()
+ {
+ return BYTE_LENGTH;
+ }
+
+ protected void processWord(
+ byte[] in,
+ int inOff)
+ {
+ W[wOff] = Pack.bigEndianToLong(in, inOff);
+
+ if (++wOff == 16)
+ {
+ processBlock();
+ }
+ }
+
+ /**
+ * adjust the byte counts so that byteCount2 represents the
+ * upper long (less 3 bits) word of the byte count.
+ */
+ private void adjustByteCounts()
+ {
+ if (byteCount1 > 0x1fffffffffffffffL)
+ {
+ byteCount2 += (byteCount1 >>> 61);
+ byteCount1 &= 0x1fffffffffffffffL;
+ }
+ }
+
+ protected void processLength(
+ long lowW,
+ long hiW)
+ {
+ if (wOff > 14)
+ {
+ processBlock();
+ }
+
+ W[14] = hiW;
+ W[15] = lowW;
+ }
+
+ protected void processBlock()
+ {
+ adjustByteCounts();
+
+ //
+ // expand 16 word block into 80 word blocks.
+ //
+ for (int t = 16; t <= 79; t++)
+ {
+ W[t] = Sigma1(W[t - 2]) + W[t - 7] + Sigma0(W[t - 15]) + W[t - 16];
+ }
+
+ //
+ // set up working variables.
+ //
+ long a = H1;
+ long b = H2;
+ long c = H3;
+ long d = H4;
+ long e = H5;
+ long f = H6;
+ long g = H7;
+ long h = H8;
+
+ int t = 0;
+ for(int i = 0; i < 10; i ++)
+ {
+ // t = 8 * i
+ h += Sum1(e) + Ch(e, f, g) + K[t] + W[t++];
+ d += h;
+ h += Sum0(a) + Maj(a, b, c);
+
+ // t = 8 * i + 1
+ g += Sum1(d) + Ch(d, e, f) + K[t] + W[t++];
+ c += g;
+ g += Sum0(h) + Maj(h, a, b);
+
+ // t = 8 * i + 2
+ f += Sum1(c) + Ch(c, d, e) + K[t] + W[t++];
+ b += f;
+ f += Sum0(g) + Maj(g, h, a);
+
+ // t = 8 * i + 3
+ e += Sum1(b) + Ch(b, c, d) + K[t] + W[t++];
+ a += e;
+ e += Sum0(f) + Maj(f, g, h);
+
+ // t = 8 * i + 4
+ d += Sum1(a) + Ch(a, b, c) + K[t] + W[t++];
+ h += d;
+ d += Sum0(e) + Maj(e, f, g);
+
+ // t = 8 * i + 5
+ c += Sum1(h) + Ch(h, a, b) + K[t] + W[t++];
+ g += c;
+ c += Sum0(d) + Maj(d, e, f);
+
+ // t = 8 * i + 6
+ b += Sum1(g) + Ch(g, h, a) + K[t] + W[t++];
+ f += b;
+ b += Sum0(c) + Maj(c, d, e);
+
+ // t = 8 * i + 7
+ a += Sum1(f) + Ch(f, g, h) + K[t] + W[t++];
+ e += a;
+ a += Sum0(b) + Maj(b, c, d);
+ }
+
+ H1 += a;
+ H2 += b;
+ H3 += c;
+ H4 += d;
+ H5 += e;
+ H6 += f;
+ H7 += g;
+ H8 += h;
+
+ //
+ // reset the offset and clean out the word buffer.
+ //
+ wOff = 0;
+ for (int i = 0; i < 16; i++)
+ {
+ W[i] = 0;
+ }
+ }
+
+ /* SHA-384 and SHA-512 functions (as for SHA-256 but for longs) */
+ private long Ch(
+ long x,
+ long y,
+ long z)
+ {
+ return ((x & y) ^ ((~x) & z));
+ }
+
+ private long Maj(
+ long x,
+ long y,
+ long z)
+ {
+ return ((x & y) ^ (x & z) ^ (y & z));
+ }
+
+ private long Sum0(
+ long x)
+ {
+ return ((x << 36)|(x >>> 28)) ^ ((x << 30)|(x >>> 34)) ^ ((x << 25)|(x >>> 39));
+ }
+
+ private long Sum1(
+ long x)
+ {
+ return ((x << 50)|(x >>> 14)) ^ ((x << 46)|(x >>> 18)) ^ ((x << 23)|(x >>> 41));
+ }
+
+ private long Sigma0(
+ long x)
+ {
+ return ((x << 63)|(x >>> 1)) ^ ((x << 56)|(x >>> 8)) ^ (x >>> 7);
+ }
+
+ private long Sigma1(
+ long x)
+ {
+ return ((x << 45)|(x >>> 19)) ^ ((x << 3)|(x >>> 61)) ^ (x >>> 6);
+ }
+
+ /* SHA-384 and SHA-512 Constants
+ * (represent the first 64 bits of the fractional parts of the
+ * cube roots of the first sixty-four prime numbers)
+ */
+ static final long K[] = {
+0x428a2f98d728ae22L, 0x7137449123ef65cdL, 0xb5c0fbcfec4d3b2fL, 0xe9b5dba58189dbbcL,
+0x3956c25bf348b538L, 0x59f111f1b605d019L, 0x923f82a4af194f9bL, 0xab1c5ed5da6d8118L,
+0xd807aa98a3030242L, 0x12835b0145706fbeL, 0x243185be4ee4b28cL, 0x550c7dc3d5ffb4e2L,
+0x72be5d74f27b896fL, 0x80deb1fe3b1696b1L, 0x9bdc06a725c71235L, 0xc19bf174cf692694L,
+0xe49b69c19ef14ad2L, 0xefbe4786384f25e3L, 0x0fc19dc68b8cd5b5L, 0x240ca1cc77ac9c65L,
+0x2de92c6f592b0275L, 0x4a7484aa6ea6e483L, 0x5cb0a9dcbd41fbd4L, 0x76f988da831153b5L,
+0x983e5152ee66dfabL, 0xa831c66d2db43210L, 0xb00327c898fb213fL, 0xbf597fc7beef0ee4L,
+0xc6e00bf33da88fc2L, 0xd5a79147930aa725L, 0x06ca6351e003826fL, 0x142929670a0e6e70L,
+0x27b70a8546d22ffcL, 0x2e1b21385c26c926L, 0x4d2c6dfc5ac42aedL, 0x53380d139d95b3dfL,
+0x650a73548baf63deL, 0x766a0abb3c77b2a8L, 0x81c2c92e47edaee6L, 0x92722c851482353bL,
+0xa2bfe8a14cf10364L, 0xa81a664bbc423001L, 0xc24b8b70d0f89791L, 0xc76c51a30654be30L,
+0xd192e819d6ef5218L, 0xd69906245565a910L, 0xf40e35855771202aL, 0x106aa07032bbd1b8L,
+0x19a4c116b8d2d0c8L, 0x1e376c085141ab53L, 0x2748774cdf8eeb99L, 0x34b0bcb5e19b48a8L,
+0x391c0cb3c5c95a63L, 0x4ed8aa4ae3418acbL, 0x5b9cca4f7763e373L, 0x682e6ff3d6b2b8a3L,
+0x748f82ee5defb2fcL, 0x78a5636f43172f60L, 0x84c87814a1f0ab72L, 0x8cc702081a6439ecL,
+0x90befffa23631e28L, 0xa4506cebde82bde9L, 0xbef9a3f7b2c67915L, 0xc67178f2e372532bL,
+0xca273eceea26619cL, 0xd186b8c721c0c207L, 0xeada7dd6cde0eb1eL, 0xf57d4f7fee6ed178L,
+0x06f067aa72176fbaL, 0x0a637dc5a2c898a6L, 0x113f9804bef90daeL, 0x1b710b35131c471bL,
+0x28db77f523047d84L, 0x32caab7b40c72493L, 0x3c9ebe0a15c9bebcL, 0x431d67c49c100d4cL,
+0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL, 0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L
+ };
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD4Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD4Digest.java
new file mode 100644
index 00000000..9b8176d5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD4Digest.java
@@ -0,0 +1,293 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+
+import com.android.internal.org.bouncycastle.util.Memoable;
+
+/**
+ * implementation of MD4 as RFC 1320 by R. Rivest, MIT Laboratory for
+ * Computer Science and RSA Data Security, Inc.
+ * <p>
+ * <b>NOTE</b>: This algorithm is only included for backwards compatability
+ * with legacy applications, it's not secure, don't use it for anything new!
+ * @hide This class is not part of the Android public SDK API
+ */
+public class MD4Digest
+ extends GeneralDigest
+{
+ private static final int DIGEST_LENGTH = 16;
+
+ private int H1, H2, H3, H4; // IV's
+
+ private int[] X = new int[16];
+ private int xOff;
+
+ /**
+ * Standard constructor
+ */
+ public MD4Digest()
+ {
+ reset();
+ }
+
+ /**
+ * Copy constructor. This will copy the state of the provided
+ * message digest.
+ */
+ public MD4Digest(MD4Digest t)
+ {
+ super(t);
+
+ copyIn(t);
+ }
+
+ private void copyIn(MD4Digest t)
+ {
+ super.copyIn(t);
+
+ H1 = t.H1;
+ H2 = t.H2;
+ H3 = t.H3;
+ H4 = t.H4;
+
+ System.arraycopy(t.X, 0, X, 0, t.X.length);
+ xOff = t.xOff;
+ }
+
+ public String getAlgorithmName()
+ {
+ return "MD4";
+ }
+
+ public int getDigestSize()
+ {
+ return DIGEST_LENGTH;
+ }
+
+ protected void processWord(
+ byte[] in,
+ int inOff)
+ {
+ X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8)
+ | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24);
+
+ if (xOff == 16)
+ {
+ processBlock();
+ }
+ }
+
+ protected void processLength(
+ long bitLength)
+ {
+ if (xOff > 14)
+ {
+ processBlock();
+ }
+
+ X[14] = (int)(bitLength & 0xffffffff);
+ X[15] = (int)(bitLength >>> 32);
+ }
+
+ private void unpackWord(
+ int word,
+ byte[] out,
+ int outOff)
+ {
+ out[outOff] = (byte)word;
+ out[outOff + 1] = (byte)(word >>> 8);
+ out[outOff + 2] = (byte)(word >>> 16);
+ out[outOff + 3] = (byte)(word >>> 24);
+ }
+
+ public int doFinal(
+ byte[] out,
+ int outOff)
+ {
+ finish();
+
+ unpackWord(H1, out, outOff);
+ unpackWord(H2, out, outOff + 4);
+ unpackWord(H3, out, outOff + 8);
+ unpackWord(H4, out, outOff + 12);
+
+ reset();
+
+ return DIGEST_LENGTH;
+ }
+
+ /**
+ * reset the chaining variables to the IV values.
+ */
+ public void reset()
+ {
+ super.reset();
+
+ H1 = 0x67452301;
+ H2 = 0xefcdab89;
+ H3 = 0x98badcfe;
+ H4 = 0x10325476;
+
+ xOff = 0;
+
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+
+ //
+ // round 1 left rotates
+ //
+ private static final int S11 = 3;
+ private static final int S12 = 7;
+ private static final int S13 = 11;
+ private static final int S14 = 19;
+
+ //
+ // round 2 left rotates
+ //
+ private static final int S21 = 3;
+ private static final int S22 = 5;
+ private static final int S23 = 9;
+ private static final int S24 = 13;
+
+ //
+ // round 3 left rotates
+ //
+ private static final int S31 = 3;
+ private static final int S32 = 9;
+ private static final int S33 = 11;
+ private static final int S34 = 15;
+
+ /*
+ * rotate int x left n bits.
+ */
+ private int rotateLeft(
+ int x,
+ int n)
+ {
+ return (x << n) | (x >>> (32 - n));
+ }
+
+ /*
+ * F, G, H and I are the basic MD4 functions.
+ */
+ private int F(
+ int u,
+ int v,
+ int w)
+ {
+ return (u & v) | (~u & w);
+ }
+
+ private int G(
+ int u,
+ int v,
+ int w)
+ {
+ return (u & v) | (u & w) | (v & w);
+ }
+
+ private int H(
+ int u,
+ int v,
+ int w)
+ {
+ return u ^ v ^ w;
+ }
+
+ protected void processBlock()
+ {
+ int a = H1;
+ int b = H2;
+ int c = H3;
+ int d = H4;
+
+ //
+ // Round 1 - F cycle, 16 times.
+ //
+ a = rotateLeft(a + F(b, c, d) + X[ 0], S11);
+ d = rotateLeft(d + F(a, b, c) + X[ 1], S12);
+ c = rotateLeft(c + F(d, a, b) + X[ 2], S13);
+ b = rotateLeft(b + F(c, d, a) + X[ 3], S14);
+ a = rotateLeft(a + F(b, c, d) + X[ 4], S11);
+ d = rotateLeft(d + F(a, b, c) + X[ 5], S12);
+ c = rotateLeft(c + F(d, a, b) + X[ 6], S13);
+ b = rotateLeft(b + F(c, d, a) + X[ 7], S14);
+ a = rotateLeft(a + F(b, c, d) + X[ 8], S11);
+ d = rotateLeft(d + F(a, b, c) + X[ 9], S12);
+ c = rotateLeft(c + F(d, a, b) + X[10], S13);
+ b = rotateLeft(b + F(c, d, a) + X[11], S14);
+ a = rotateLeft(a + F(b, c, d) + X[12], S11);
+ d = rotateLeft(d + F(a, b, c) + X[13], S12);
+ c = rotateLeft(c + F(d, a, b) + X[14], S13);
+ b = rotateLeft(b + F(c, d, a) + X[15], S14);
+
+ //
+ // Round 2 - G cycle, 16 times.
+ //
+ a = rotateLeft(a + G(b, c, d) + X[ 0] + 0x5a827999, S21);
+ d = rotateLeft(d + G(a, b, c) + X[ 4] + 0x5a827999, S22);
+ c = rotateLeft(c + G(d, a, b) + X[ 8] + 0x5a827999, S23);
+ b = rotateLeft(b + G(c, d, a) + X[12] + 0x5a827999, S24);
+ a = rotateLeft(a + G(b, c, d) + X[ 1] + 0x5a827999, S21);
+ d = rotateLeft(d + G(a, b, c) + X[ 5] + 0x5a827999, S22);
+ c = rotateLeft(c + G(d, a, b) + X[ 9] + 0x5a827999, S23);
+ b = rotateLeft(b + G(c, d, a) + X[13] + 0x5a827999, S24);
+ a = rotateLeft(a + G(b, c, d) + X[ 2] + 0x5a827999, S21);
+ d = rotateLeft(d + G(a, b, c) + X[ 6] + 0x5a827999, S22);
+ c = rotateLeft(c + G(d, a, b) + X[10] + 0x5a827999, S23);
+ b = rotateLeft(b + G(c, d, a) + X[14] + 0x5a827999, S24);
+ a = rotateLeft(a + G(b, c, d) + X[ 3] + 0x5a827999, S21);
+ d = rotateLeft(d + G(a, b, c) + X[ 7] + 0x5a827999, S22);
+ c = rotateLeft(c + G(d, a, b) + X[11] + 0x5a827999, S23);
+ b = rotateLeft(b + G(c, d, a) + X[15] + 0x5a827999, S24);
+
+ //
+ // Round 3 - H cycle, 16 times.
+ //
+ a = rotateLeft(a + H(b, c, d) + X[ 0] + 0x6ed9eba1, S31);
+ d = rotateLeft(d + H(a, b, c) + X[ 8] + 0x6ed9eba1, S32);
+ c = rotateLeft(c + H(d, a, b) + X[ 4] + 0x6ed9eba1, S33);
+ b = rotateLeft(b + H(c, d, a) + X[12] + 0x6ed9eba1, S34);
+ a = rotateLeft(a + H(b, c, d) + X[ 2] + 0x6ed9eba1, S31);
+ d = rotateLeft(d + H(a, b, c) + X[10] + 0x6ed9eba1, S32);
+ c = rotateLeft(c + H(d, a, b) + X[ 6] + 0x6ed9eba1, S33);
+ b = rotateLeft(b + H(c, d, a) + X[14] + 0x6ed9eba1, S34);
+ a = rotateLeft(a + H(b, c, d) + X[ 1] + 0x6ed9eba1, S31);
+ d = rotateLeft(d + H(a, b, c) + X[ 9] + 0x6ed9eba1, S32);
+ c = rotateLeft(c + H(d, a, b) + X[ 5] + 0x6ed9eba1, S33);
+ b = rotateLeft(b + H(c, d, a) + X[13] + 0x6ed9eba1, S34);
+ a = rotateLeft(a + H(b, c, d) + X[ 3] + 0x6ed9eba1, S31);
+ d = rotateLeft(d + H(a, b, c) + X[11] + 0x6ed9eba1, S32);
+ c = rotateLeft(c + H(d, a, b) + X[ 7] + 0x6ed9eba1, S33);
+ b = rotateLeft(b + H(c, d, a) + X[15] + 0x6ed9eba1, S34);
+
+ H1 += a;
+ H2 += b;
+ H3 += c;
+ H4 += d;
+
+ //
+ // reset the offset and clean out the word buffer.
+ //
+ xOff = 0;
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+
+ public Memoable copy()
+ {
+ return new MD4Digest(this);
+ }
+
+ public void reset(Memoable other)
+ {
+ MD4Digest d = (MD4Digest)other;
+
+ copyIn(d);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD5Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD5Digest.java
new file mode 100644
index 00000000..ba662025
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/MD5Digest.java
@@ -0,0 +1,363 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+
+import com.android.internal.org.bouncycastle.util.Memoable;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class MD5Digest
+ extends GeneralDigest
+ implements EncodableDigest
+{
+ private static final int DIGEST_LENGTH = 16;
+
+ private int H1, H2, H3, H4; // IV's
+
+ private int[] X = new int[16];
+ private int xOff;
+
+ /**
+ * Standard constructor
+ */
+ public MD5Digest()
+ {
+ reset();
+ }
+
+ public MD5Digest(byte[] encodedState)
+ {
+ super(encodedState);
+
+ H1 = Pack.bigEndianToInt(encodedState, 16);
+ H2 = Pack.bigEndianToInt(encodedState, 20);
+ H3 = Pack.bigEndianToInt(encodedState, 24);
+ H4 = Pack.bigEndianToInt(encodedState, 28);
+
+ xOff = Pack.bigEndianToInt(encodedState, 32);
+ for (int i = 0; i != xOff; i++)
+ {
+ X[i] = Pack.bigEndianToInt(encodedState, 36 + (i * 4));
+ }
+ }
+
+ /**
+ * Copy constructor. This will copy the state of the provided
+ * message digest.
+ */
+ public MD5Digest(MD5Digest t)
+ {
+ super(t);
+
+ copyIn(t);
+ }
+
+ private void copyIn(MD5Digest t)
+ {
+ super.copyIn(t);
+
+ H1 = t.H1;
+ H2 = t.H2;
+ H3 = t.H3;
+ H4 = t.H4;
+
+ System.arraycopy(t.X, 0, X, 0, t.X.length);
+ xOff = t.xOff;
+ }
+
+ public String getAlgorithmName()
+ {
+ return "MD5";
+ }
+
+ public int getDigestSize()
+ {
+ return DIGEST_LENGTH;
+ }
+
+ protected void processWord(
+ byte[] in,
+ int inOff)
+ {
+ X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8)
+ | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24);
+
+ if (xOff == 16)
+ {
+ processBlock();
+ }
+ }
+
+ protected void processLength(
+ long bitLength)
+ {
+ if (xOff > 14)
+ {
+ processBlock();
+ }
+
+ X[14] = (int)(bitLength & 0xffffffff);
+ X[15] = (int)(bitLength >>> 32);
+ }
+
+ private void unpackWord(
+ int word,
+ byte[] out,
+ int outOff)
+ {
+ out[outOff] = (byte)word;
+ out[outOff + 1] = (byte)(word >>> 8);
+ out[outOff + 2] = (byte)(word >>> 16);
+ out[outOff + 3] = (byte)(word >>> 24);
+ }
+
+ public int doFinal(
+ byte[] out,
+ int outOff)
+ {
+ finish();
+
+ unpackWord(H1, out, outOff);
+ unpackWord(H2, out, outOff + 4);
+ unpackWord(H3, out, outOff + 8);
+ unpackWord(H4, out, outOff + 12);
+
+ reset();
+
+ return DIGEST_LENGTH;
+ }
+
+ /**
+ * reset the chaining variables to the IV values.
+ */
+ public void reset()
+ {
+ super.reset();
+
+ H1 = 0x67452301;
+ H2 = 0xefcdab89;
+ H3 = 0x98badcfe;
+ H4 = 0x10325476;
+
+ xOff = 0;
+
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+
+ //
+ // round 1 left rotates
+ //
+ private static final int S11 = 7;
+ private static final int S12 = 12;
+ private static final int S13 = 17;
+ private static final int S14 = 22;
+
+ //
+ // round 2 left rotates
+ //
+ private static final int S21 = 5;
+ private static final int S22 = 9;
+ private static final int S23 = 14;
+ private static final int S24 = 20;
+
+ //
+ // round 3 left rotates
+ //
+ private static final int S31 = 4;
+ private static final int S32 = 11;
+ private static final int S33 = 16;
+ private static final int S34 = 23;
+
+ //
+ // round 4 left rotates
+ //
+ private static final int S41 = 6;
+ private static final int S42 = 10;
+ private static final int S43 = 15;
+ private static final int S44 = 21;
+
+ /*
+ * rotate int x left n bits.
+ */
+ private int rotateLeft(
+ int x,
+ int n)
+ {
+ return (x << n) | (x >>> (32 - n));
+ }
+
+ /*
+ * F, G, H and I are the basic MD5 functions.
+ */
+ private int F(
+ int u,
+ int v,
+ int w)
+ {
+ return (u & v) | (~u & w);
+ }
+
+ private int G(
+ int u,
+ int v,
+ int w)
+ {
+ return (u & w) | (v & ~w);
+ }
+
+ private int H(
+ int u,
+ int v,
+ int w)
+ {
+ return u ^ v ^ w;
+ }
+
+ private int K(
+ int u,
+ int v,
+ int w)
+ {
+ return v ^ (u | ~w);
+ }
+
+ protected void processBlock()
+ {
+ int a = H1;
+ int b = H2;
+ int c = H3;
+ int d = H4;
+
+ //
+ // Round 1 - F cycle, 16 times.
+ //
+ a = rotateLeft(a + F(b, c, d) + X[ 0] + 0xd76aa478, S11) + b;
+ d = rotateLeft(d + F(a, b, c) + X[ 1] + 0xe8c7b756, S12) + a;
+ c = rotateLeft(c + F(d, a, b) + X[ 2] + 0x242070db, S13) + d;
+ b = rotateLeft(b + F(c, d, a) + X[ 3] + 0xc1bdceee, S14) + c;
+ a = rotateLeft(a + F(b, c, d) + X[ 4] + 0xf57c0faf, S11) + b;
+ d = rotateLeft(d + F(a, b, c) + X[ 5] + 0x4787c62a, S12) + a;
+ c = rotateLeft(c + F(d, a, b) + X[ 6] + 0xa8304613, S13) + d;
+ b = rotateLeft(b + F(c, d, a) + X[ 7] + 0xfd469501, S14) + c;
+ a = rotateLeft(a + F(b, c, d) + X[ 8] + 0x698098d8, S11) + b;
+ d = rotateLeft(d + F(a, b, c) + X[ 9] + 0x8b44f7af, S12) + a;
+ c = rotateLeft(c + F(d, a, b) + X[10] + 0xffff5bb1, S13) + d;
+ b = rotateLeft(b + F(c, d, a) + X[11] + 0x895cd7be, S14) + c;
+ a = rotateLeft(a + F(b, c, d) + X[12] + 0x6b901122, S11) + b;
+ d = rotateLeft(d + F(a, b, c) + X[13] + 0xfd987193, S12) + a;
+ c = rotateLeft(c + F(d, a, b) + X[14] + 0xa679438e, S13) + d;
+ b = rotateLeft(b + F(c, d, a) + X[15] + 0x49b40821, S14) + c;
+
+ //
+ // Round 2 - G cycle, 16 times.
+ //
+ a = rotateLeft(a + G(b, c, d) + X[ 1] + 0xf61e2562, S21) + b;
+ d = rotateLeft(d + G(a, b, c) + X[ 6] + 0xc040b340, S22) + a;
+ c = rotateLeft(c + G(d, a, b) + X[11] + 0x265e5a51, S23) + d;
+ b = rotateLeft(b + G(c, d, a) + X[ 0] + 0xe9b6c7aa, S24) + c;
+ a = rotateLeft(a + G(b, c, d) + X[ 5] + 0xd62f105d, S21) + b;
+ d = rotateLeft(d + G(a, b, c) + X[10] + 0x02441453, S22) + a;
+ c = rotateLeft(c + G(d, a, b) + X[15] + 0xd8a1e681, S23) + d;
+ b = rotateLeft(b + G(c, d, a) + X[ 4] + 0xe7d3fbc8, S24) + c;
+ a = rotateLeft(a + G(b, c, d) + X[ 9] + 0x21e1cde6, S21) + b;
+ d = rotateLeft(d + G(a, b, c) + X[14] + 0xc33707d6, S22) + a;
+ c = rotateLeft(c + G(d, a, b) + X[ 3] + 0xf4d50d87, S23) + d;
+ b = rotateLeft(b + G(c, d, a) + X[ 8] + 0x455a14ed, S24) + c;
+ a = rotateLeft(a + G(b, c, d) + X[13] + 0xa9e3e905, S21) + b;
+ d = rotateLeft(d + G(a, b, c) + X[ 2] + 0xfcefa3f8, S22) + a;
+ c = rotateLeft(c + G(d, a, b) + X[ 7] + 0x676f02d9, S23) + d;
+ b = rotateLeft(b + G(c, d, a) + X[12] + 0x8d2a4c8a, S24) + c;
+
+ //
+ // Round 3 - H cycle, 16 times.
+ //
+ a = rotateLeft(a + H(b, c, d) + X[ 5] + 0xfffa3942, S31) + b;
+ d = rotateLeft(d + H(a, b, c) + X[ 8] + 0x8771f681, S32) + a;
+ c = rotateLeft(c + H(d, a, b) + X[11] + 0x6d9d6122, S33) + d;
+ b = rotateLeft(b + H(c, d, a) + X[14] + 0xfde5380c, S34) + c;
+ a = rotateLeft(a + H(b, c, d) + X[ 1] + 0xa4beea44, S31) + b;
+ d = rotateLeft(d + H(a, b, c) + X[ 4] + 0x4bdecfa9, S32) + a;
+ c = rotateLeft(c + H(d, a, b) + X[ 7] + 0xf6bb4b60, S33) + d;
+ b = rotateLeft(b + H(c, d, a) + X[10] + 0xbebfbc70, S34) + c;
+ a = rotateLeft(a + H(b, c, d) + X[13] + 0x289b7ec6, S31) + b;
+ d = rotateLeft(d + H(a, b, c) + X[ 0] + 0xeaa127fa, S32) + a;
+ c = rotateLeft(c + H(d, a, b) + X[ 3] + 0xd4ef3085, S33) + d;
+ b = rotateLeft(b + H(c, d, a) + X[ 6] + 0x04881d05, S34) + c;
+ a = rotateLeft(a + H(b, c, d) + X[ 9] + 0xd9d4d039, S31) + b;
+ d = rotateLeft(d + H(a, b, c) + X[12] + 0xe6db99e5, S32) + a;
+ c = rotateLeft(c + H(d, a, b) + X[15] + 0x1fa27cf8, S33) + d;
+ b = rotateLeft(b + H(c, d, a) + X[ 2] + 0xc4ac5665, S34) + c;
+
+ //
+ // Round 4 - K cycle, 16 times.
+ //
+ a = rotateLeft(a + K(b, c, d) + X[ 0] + 0xf4292244, S41) + b;
+ d = rotateLeft(d + K(a, b, c) + X[ 7] + 0x432aff97, S42) + a;
+ c = rotateLeft(c + K(d, a, b) + X[14] + 0xab9423a7, S43) + d;
+ b = rotateLeft(b + K(c, d, a) + X[ 5] + 0xfc93a039, S44) + c;
+ a = rotateLeft(a + K(b, c, d) + X[12] + 0x655b59c3, S41) + b;
+ d = rotateLeft(d + K(a, b, c) + X[ 3] + 0x8f0ccc92, S42) + a;
+ c = rotateLeft(c + K(d, a, b) + X[10] + 0xffeff47d, S43) + d;
+ b = rotateLeft(b + K(c, d, a) + X[ 1] + 0x85845dd1, S44) + c;
+ a = rotateLeft(a + K(b, c, d) + X[ 8] + 0x6fa87e4f, S41) + b;
+ d = rotateLeft(d + K(a, b, c) + X[15] + 0xfe2ce6e0, S42) + a;
+ c = rotateLeft(c + K(d, a, b) + X[ 6] + 0xa3014314, S43) + d;
+ b = rotateLeft(b + K(c, d, a) + X[13] + 0x4e0811a1, S44) + c;
+ a = rotateLeft(a + K(b, c, d) + X[ 4] + 0xf7537e82, S41) + b;
+ d = rotateLeft(d + K(a, b, c) + X[11] + 0xbd3af235, S42) + a;
+ c = rotateLeft(c + K(d, a, b) + X[ 2] + 0x2ad7d2bb, S43) + d;
+ b = rotateLeft(b + K(c, d, a) + X[ 9] + 0xeb86d391, S44) + c;
+
+ H1 += a;
+ H2 += b;
+ H3 += c;
+ H4 += d;
+
+ //
+ // reset the offset and clean out the word buffer.
+ //
+ xOff = 0;
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+
+ public Memoable copy()
+ {
+ return new MD5Digest(this);
+ }
+
+ public void reset(Memoable other)
+ {
+ MD5Digest d = (MD5Digest)other;
+
+ copyIn(d);
+ }
+
+ public byte[] getEncodedState()
+ {
+ byte[] state = new byte[36 + xOff * 4];
+
+ super.populateState(state);
+
+ Pack.intToBigEndian(H1, state, 16);
+ Pack.intToBigEndian(H2, state, 20);
+ Pack.intToBigEndian(H3, state, 24);
+ Pack.intToBigEndian(H4, state, 28);
+ Pack.intToBigEndian(xOff, state, 32);
+
+ for (int i = 0; i != xOff; i++)
+ {
+ Pack.intToBigEndian(X[i], state, 36 + (i * 4));
+ }
+
+ return state;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/NullDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/NullDigest.java
new file mode 100644
index 00000000..5447a046
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/NullDigest.java
@@ -0,0 +1,69 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import java.io.ByteArrayOutputStream;
+
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class NullDigest
+ implements Digest
+{
+ private OpenByteArrayOutputStream bOut = new OpenByteArrayOutputStream();
+
+ public String getAlgorithmName()
+ {
+ return "NULL";
+ }
+
+ public int getDigestSize()
+ {
+ return bOut.size();
+ }
+
+ public void update(byte in)
+ {
+ bOut.write(in);
+ }
+
+ public void update(byte[] in, int inOff, int len)
+ {
+ bOut.write(in, inOff, len);
+ }
+
+ public int doFinal(byte[] out, int outOff)
+ {
+ int size = bOut.size();
+
+ bOut.copy(out, outOff);
+
+ reset();
+
+ return size;
+ }
+
+ public void reset()
+ {
+ bOut.reset();
+ }
+
+ private static class OpenByteArrayOutputStream
+ extends ByteArrayOutputStream
+ {
+ public void reset()
+ {
+ super.reset();
+
+ Arrays.clear(buf);
+ }
+
+ void copy(byte[] out, int outOff)
+ {
+ System.arraycopy(buf, 0, out, outOff, this.size());
+ }
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/OpenSSLDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/OpenSSLDigest.java
new file mode 100644
index 00000000..fe2ff803
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/OpenSSLDigest.java
@@ -0,0 +1,117 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import com.android.internal.org.bouncycastle.crypto.ExtendedDigest;
+import com.android.internal.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi;
+import java.security.DigestException;
+import java.security.MessageDigest;
+
+/**
+ * Implements the BouncyCastle Digest interface using OpenSSL's EVP API. This
+ * must be an ExtendedDigest for {@link BcKeyStoreSpi} to be able to use it.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OpenSSLDigest implements ExtendedDigest {
+ private final MessageDigest delegate;
+
+ private final int byteSize;
+
+ public OpenSSLDigest(String algorithm, int byteSize) {
+ try {
+ delegate = MessageDigest.getInstance(algorithm, "AndroidOpenSSL");
+ this.byteSize = byteSize;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public String getAlgorithmName() {
+ return delegate.getAlgorithm();
+ }
+
+ public int getDigestSize() {
+ return delegate.getDigestLength();
+ }
+
+ public int getByteLength() {
+ return byteSize;
+ }
+
+ public void reset() {
+ delegate.reset();
+ }
+
+ public void update(byte in) {
+ delegate.update(in);
+ }
+
+ public void update(byte[] in, int inOff, int len) {
+ delegate.update(in, inOff, len);
+ }
+
+ public int doFinal(byte[] out, int outOff) {
+ try {
+ return delegate.digest(out, outOff, out.length - outOff);
+ } catch (DigestException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class MD5 extends OpenSSLDigest {
+ public MD5() { super("MD5", 64); }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class SHA1 extends OpenSSLDigest {
+ public SHA1() { super("SHA-1", 64); }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class SHA224 extends OpenSSLDigest {
+ public SHA224() { super("SHA-224", 64); }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class SHA256 extends OpenSSLDigest {
+ public SHA256() { super("SHA-256", 64); }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class SHA384 extends OpenSSLDigest {
+ public SHA384() { super("SHA-384", 128); }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class SHA512 extends OpenSSLDigest {
+ public SHA512() { super("SHA-512", 128); }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA1Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA1Digest.java
new file mode 100644
index 00000000..12f82e51
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA1Digest.java
@@ -0,0 +1,355 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import com.android.internal.org.bouncycastle.util.Memoable;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349.
+ *
+ * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5
+ * is the "endianness" of the word processing!
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SHA1Digest
+ extends GeneralDigest
+ implements EncodableDigest
+{
+ 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();
+ }
+
+ /**
+ * Copy constructor. This will copy the state of the provided
+ * message digest.
+ */
+ public SHA1Digest(SHA1Digest t)
+ {
+ super(t);
+
+ copyIn(t);
+ }
+
+ /**
+ * State constructor - create a digest initialised with the state of a previous one.
+ *
+ * @param encodedState the encoded state from the originating digest.
+ */
+ public SHA1Digest(byte[] encodedState)
+ {
+ super(encodedState);
+
+ H1 = Pack.bigEndianToInt(encodedState, 16);
+ H2 = Pack.bigEndianToInt(encodedState, 20);
+ H3 = Pack.bigEndianToInt(encodedState, 24);
+ H4 = Pack.bigEndianToInt(encodedState, 28);
+ H5 = Pack.bigEndianToInt(encodedState, 32);
+
+ xOff = Pack.bigEndianToInt(encodedState, 36);
+ for (int i = 0; i != xOff; i++)
+ {
+ X[i] = Pack.bigEndianToInt(encodedState, 40 + (i * 4));
+ }
+ }
+
+ private void copyIn(SHA1Digest t)
+ {
+ H1 = t.H1;
+ H2 = t.H2;
+ H3 = t.H3;
+ H4 = t.H4;
+ H5 = t.H5;
+
+ System.arraycopy(t.X, 0, X, 0, t.X.length);
+ xOff = t.xOff;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+ }
+
+ public Memoable copy()
+ {
+ return new SHA1Digest(this);
+ }
+
+ public void reset(Memoable other)
+ {
+ SHA1Digest d = (SHA1Digest)other;
+
+ super.copyIn(d);
+ copyIn(d);
+ }
+
+ public byte[] getEncodedState()
+ {
+ byte[] state = new byte[40 + xOff * 4];
+
+ super.populateState(state);
+
+ Pack.intToBigEndian(H1, state, 16);
+ Pack.intToBigEndian(H2, state, 20);
+ Pack.intToBigEndian(H3, state, 24);
+ Pack.intToBigEndian(H4, state, 28);
+ Pack.intToBigEndian(H5, state, 32);
+ Pack.intToBigEndian(xOff, state, 36);
+
+ for (int i = 0; i != xOff; i++)
+ {
+ Pack.intToBigEndian(X[i], state, 40 + (i * 4));
+ }
+
+ return state;
+ }
+}
+
+
+
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA224Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA224Digest.java
new file mode 100644
index 00000000..8c3f9a45
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA224Digest.java
@@ -0,0 +1,363 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+
+import com.android.internal.org.bouncycastle.util.Memoable;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+
+/**
+ * SHA-224 as described in RFC 3874
+ * <pre>
+ * block word digest
+ * SHA-1 512 32 160
+ * SHA-224 512 32 224
+ * SHA-256 512 32 256
+ * SHA-384 1024 64 384
+ * SHA-512 1024 64 512
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SHA224Digest
+ extends GeneralDigest
+ implements EncodableDigest
+{
+ private static final int DIGEST_LENGTH = 28;
+
+ private int H1, H2, H3, H4, H5, H6, H7, H8;
+
+ private int[] X = new int[64];
+ private int xOff;
+
+ /**
+ * Standard constructor
+ */
+ public SHA224Digest()
+ {
+ reset();
+ }
+
+ /**
+ * Copy constructor. This will copy the state of the provided
+ * message digest.
+ */
+ public SHA224Digest(SHA224Digest t)
+ {
+ super(t);
+
+ doCopy(t);
+ }
+
+ private void doCopy(SHA224Digest t)
+ {
+ super.copyIn(t);
+
+ H1 = t.H1;
+ H2 = t.H2;
+ H3 = t.H3;
+ H4 = t.H4;
+ H5 = t.H5;
+ H6 = t.H6;
+ H7 = t.H7;
+ H8 = t.H8;
+
+ System.arraycopy(t.X, 0, X, 0, t.X.length);
+ xOff = t.xOff;
+ }
+
+ /**
+ * State constructor - create a digest initialised with the state of a previous one.
+ *
+ * @param encodedState the encoded state from the originating digest.
+ */
+ public SHA224Digest(byte[] encodedState)
+ {
+ super(encodedState);
+
+ H1 = Pack.bigEndianToInt(encodedState, 16);
+ H2 = Pack.bigEndianToInt(encodedState, 20);
+ H3 = Pack.bigEndianToInt(encodedState, 24);
+ H4 = Pack.bigEndianToInt(encodedState, 28);
+ H5 = Pack.bigEndianToInt(encodedState, 32);
+ H6 = Pack.bigEndianToInt(encodedState, 36);
+ H7 = Pack.bigEndianToInt(encodedState, 40);
+ H8 = Pack.bigEndianToInt(encodedState, 44);
+
+ xOff = Pack.bigEndianToInt(encodedState, 48);
+ for (int i = 0; i != xOff; i++)
+ {
+ X[i] = Pack.bigEndianToInt(encodedState, 52 + (i * 4));
+ }
+ }
+
+ public String getAlgorithmName()
+ {
+ return "SHA-224";
+ }
+
+ 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);
+ Pack.intToBigEndian(H6, out, outOff + 20);
+ Pack.intToBigEndian(H7, out, outOff + 24);
+
+ reset();
+
+ return DIGEST_LENGTH;
+ }
+
+ /**
+ * reset the chaining variables
+ */
+ public void reset()
+ {
+ super.reset();
+
+ /* SHA-224 initial hash value
+ */
+
+ H1 = 0xc1059ed8;
+ H2 = 0x367cd507;
+ H3 = 0x3070dd17;
+ H4 = 0xf70e5939;
+ H5 = 0xffc00b31;
+ H6 = 0x68581511;
+ H7 = 0x64f98fa7;
+ H8 = 0xbefa4fa4;
+
+ xOff = 0;
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+
+ protected void processBlock()
+ {
+ //
+ // expand 16 word block into 64 word blocks.
+ //
+ for (int t = 16; t <= 63; t++)
+ {
+ X[t] = Theta1(X[t - 2]) + X[t - 7] + Theta0(X[t - 15]) + X[t - 16];
+ }
+
+ //
+ // set up working variables.
+ //
+ int a = H1;
+ int b = H2;
+ int c = H3;
+ int d = H4;
+ int e = H5;
+ int f = H6;
+ int g = H7;
+ int h = H8;
+
+
+ int t = 0;
+ for(int i = 0; i < 8; i ++)
+ {
+ // t = 8 * i
+ h += Sum1(e) + Ch(e, f, g) + K[t] + X[t];
+ d += h;
+ h += Sum0(a) + Maj(a, b, c);
+ ++t;
+
+ // t = 8 * i + 1
+ g += Sum1(d) + Ch(d, e, f) + K[t] + X[t];
+ c += g;
+ g += Sum0(h) + Maj(h, a, b);
+ ++t;
+
+ // t = 8 * i + 2
+ f += Sum1(c) + Ch(c, d, e) + K[t] + X[t];
+ b += f;
+ f += Sum0(g) + Maj(g, h, a);
+ ++t;
+
+ // t = 8 * i + 3
+ e += Sum1(b) + Ch(b, c, d) + K[t] + X[t];
+ a += e;
+ e += Sum0(f) + Maj(f, g, h);
+ ++t;
+
+ // t = 8 * i + 4
+ d += Sum1(a) + Ch(a, b, c) + K[t] + X[t];
+ h += d;
+ d += Sum0(e) + Maj(e, f, g);
+ ++t;
+
+ // t = 8 * i + 5
+ c += Sum1(h) + Ch(h, a, b) + K[t] + X[t];
+ g += c;
+ c += Sum0(d) + Maj(d, e, f);
+ ++t;
+
+ // t = 8 * i + 6
+ b += Sum1(g) + Ch(g, h, a) + K[t] + X[t];
+ f += b;
+ b += Sum0(c) + Maj(c, d, e);
+ ++t;
+
+ // t = 8 * i + 7
+ a += Sum1(f) + Ch(f, g, h) + K[t] + X[t];
+ e += a;
+ a += Sum0(b) + Maj(b, c, d);
+ ++t;
+ }
+
+ H1 += a;
+ H2 += b;
+ H3 += c;
+ H4 += d;
+ H5 += e;
+ H6 += f;
+ H7 += g;
+ H8 += h;
+
+ //
+ // reset the offset and clean out the word buffer.
+ //
+ xOff = 0;
+ for (int i = 0; i < 16; i++)
+ {
+ X[i] = 0;
+ }
+ }
+
+ /* SHA-224 functions */
+ private int Ch(
+ int x,
+ int y,
+ int z)
+ {
+ return ((x & y) ^ ((~x) & z));
+ }
+
+ private int Maj(
+ int x,
+ int y,
+ int z)
+ {
+ return ((x & y) ^ (x & z) ^ (y & z));
+ }
+
+ private int Sum0(
+ int x)
+ {
+ return ((x >>> 2) | (x << 30)) ^ ((x >>> 13) | (x << 19)) ^ ((x >>> 22) | (x << 10));
+ }
+
+ private int Sum1(
+ int x)
+ {
+ return ((x >>> 6) | (x << 26)) ^ ((x >>> 11) | (x << 21)) ^ ((x >>> 25) | (x << 7));
+ }
+
+ private int Theta0(
+ int x)
+ {
+ return ((x >>> 7) | (x << 25)) ^ ((x >>> 18) | (x << 14)) ^ (x >>> 3);
+ }
+
+ private int Theta1(
+ int x)
+ {
+ return ((x >>> 17) | (x << 15)) ^ ((x >>> 19) | (x << 13)) ^ (x >>> 10);
+ }
+
+ /* SHA-224 Constants
+ * (represent the first 32 bits of the fractional parts of the
+ * cube roots of the first sixty-four prime numbers)
+ */
+ static final int K[] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ };
+
+ public Memoable copy()
+ {
+ return new SHA224Digest(this);
+ }
+
+ public void reset(Memoable other)
+ {
+ SHA224Digest d = (SHA224Digest)other;
+
+ doCopy(d);
+ }
+
+ public byte[] getEncodedState()
+ {
+ byte[] state = new byte[52 + xOff * 4];
+
+ super.populateState(state);
+
+ Pack.intToBigEndian(H1, state, 16);
+ Pack.intToBigEndian(H2, state, 20);
+ Pack.intToBigEndian(H3, state, 24);
+ Pack.intToBigEndian(H4, state, 28);
+ Pack.intToBigEndian(H5, state, 32);
+ Pack.intToBigEndian(H6, state, 36);
+ Pack.intToBigEndian(H7, state, 40);
+ Pack.intToBigEndian(H8, state, 44);
+ Pack.intToBigEndian(xOff, state, 48);
+
+ for (int i = 0; i != xOff; i++)
+ {
+ Pack.intToBigEndian(X[i], state, 52 + (i * 4));
+ }
+
+ return state;
+ }
+}
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA256Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA256Digest.java
new file mode 100644
index 00000000..2626336b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA256Digest.java
@@ -0,0 +1,359 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+
+import com.android.internal.org.bouncycastle.util.Memoable;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+
+/**
+ * FIPS 180-2 implementation of SHA-256.
+ *
+ * <pre>
+ * block word digest
+ * SHA-1 512 32 160
+ * SHA-256 512 32 256
+ * SHA-384 1024 64 384
+ * SHA-512 1024 64 512
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SHA256Digest
+ extends GeneralDigest
+ implements EncodableDigest
+{
+ private static final int DIGEST_LENGTH = 32;
+
+ private int H1, H2, H3, H4, H5, H6, H7, H8;
+
+ private int[] X = new int[64];
+ private int xOff;
+
+ /**
+ * Standard constructor
+ */
+ public SHA256Digest()
+ {
+ reset();
+ }
+
+ /**
+ * Copy constructor. This will copy the state of the provided
+ * message digest.
+ */
+ public SHA256Digest(SHA256Digest t)
+ {
+ super(t);
+
+ copyIn(t);
+ }
+
+ private void copyIn(SHA256Digest t)
+ {
+ super.copyIn(t);
+
+ H1 = t.H1;
+ H2 = t.H2;
+ H3 = t.H3;
+ H4 = t.H4;
+ H5 = t.H5;
+ H6 = t.H6;
+ H7 = t.H7;
+ H8 = t.H8;
+
+ System.arraycopy(t.X, 0, X, 0, t.X.length);
+ xOff = t.xOff;
+ }
+
+ /**
+ * State constructor - create a digest initialised with the state of a previous one.
+ *
+ * @param encodedState the encoded state from the originating digest.
+ */
+ public SHA256Digest(byte[] encodedState)
+ {
+ super(encodedState);
+
+ H1 = Pack.bigEndianToInt(encodedState, 16);
+ H2 = Pack.bigEndianToInt(encodedState, 20);
+ H3 = Pack.bigEndianToInt(encodedState, 24);
+ H4 = Pack.bigEndianToInt(encodedState, 28);
+ H5 = Pack.bigEndianToInt(encodedState, 32);
+ H6 = Pack.bigEndianToInt(encodedState, 36);
+ H7 = Pack.bigEndianToInt(encodedState, 40);
+ H8 = Pack.bigEndianToInt(encodedState, 44);
+
+ xOff = Pack.bigEndianToInt(encodedState, 48);
+ for (int i = 0; i != xOff; i++)
+ {
+ X[i] = Pack.bigEndianToInt(encodedState, 52 + (i * 4));
+ }
+ }
+
+
+ public String getAlgorithmName()
+ {
+ return "SHA-256";
+ }
+
+ 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);
+ Pack.intToBigEndian(H6, out, outOff + 20);
+ Pack.intToBigEndian(H7, out, outOff + 24);
+ Pack.intToBigEndian(H8, out, outOff + 28);
+
+ reset();
+
+ return DIGEST_LENGTH;
+ }
+
+ /**
+ * reset the chaining variables
+ */
+ public void reset()
+ {
+ super.reset();
+
+ /* SHA-256 initial hash value
+ * The first 32 bits of the fractional parts of the square roots
+ * of the first eight prime numbers
+ */
+
+ H1 = 0x6a09e667;
+ H2 = 0xbb67ae85;
+ H3 = 0x3c6ef372;
+ H4 = 0xa54ff53a;
+ H5 = 0x510e527f;
+ H6 = 0x9b05688c;
+ H7 = 0x1f83d9ab;
+ H8 = 0x5be0cd19;
+
+ xOff = 0;
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+
+ protected void processBlock()
+ {
+ //
+ // expand 16 word block into 64 word blocks.
+ //
+ for (int t = 16; t <= 63; t++)
+ {
+ X[t] = Theta1(X[t - 2]) + X[t - 7] + Theta0(X[t - 15]) + X[t - 16];
+ }
+
+ //
+ // set up working variables.
+ //
+ int a = H1;
+ int b = H2;
+ int c = H3;
+ int d = H4;
+ int e = H5;
+ int f = H6;
+ int g = H7;
+ int h = H8;
+
+ int t = 0;
+ for(int i = 0; i < 8; i ++)
+ {
+ // t = 8 * i
+ h += Sum1(e) + Ch(e, f, g) + K[t] + X[t];
+ d += h;
+ h += Sum0(a) + Maj(a, b, c);
+ ++t;
+
+ // t = 8 * i + 1
+ g += Sum1(d) + Ch(d, e, f) + K[t] + X[t];
+ c += g;
+ g += Sum0(h) + Maj(h, a, b);
+ ++t;
+
+ // t = 8 * i + 2
+ f += Sum1(c) + Ch(c, d, e) + K[t] + X[t];
+ b += f;
+ f += Sum0(g) + Maj(g, h, a);
+ ++t;
+
+ // t = 8 * i + 3
+ e += Sum1(b) + Ch(b, c, d) + K[t] + X[t];
+ a += e;
+ e += Sum0(f) + Maj(f, g, h);
+ ++t;
+
+ // t = 8 * i + 4
+ d += Sum1(a) + Ch(a, b, c) + K[t] + X[t];
+ h += d;
+ d += Sum0(e) + Maj(e, f, g);
+ ++t;
+
+ // t = 8 * i + 5
+ c += Sum1(h) + Ch(h, a, b) + K[t] + X[t];
+ g += c;
+ c += Sum0(d) + Maj(d, e, f);
+ ++t;
+
+ // t = 8 * i + 6
+ b += Sum1(g) + Ch(g, h, a) + K[t] + X[t];
+ f += b;
+ b += Sum0(c) + Maj(c, d, e);
+ ++t;
+
+ // t = 8 * i + 7
+ a += Sum1(f) + Ch(f, g, h) + K[t] + X[t];
+ e += a;
+ a += Sum0(b) + Maj(b, c, d);
+ ++t;
+ }
+
+ H1 += a;
+ H2 += b;
+ H3 += c;
+ H4 += d;
+ H5 += e;
+ H6 += f;
+ H7 += g;
+ H8 += h;
+
+ //
+ // reset the offset and clean out the word buffer.
+ //
+ xOff = 0;
+ for (int i = 0; i < 16; i++)
+ {
+ X[i] = 0;
+ }
+ }
+
+ /* SHA-256 functions */
+ private static int Ch(int x, int y, int z)
+ {
+ return (x & y) ^ ((~x) & z);
+// return z ^ (x & (y ^ z));
+ }
+
+ private static int Maj(int x, int y, int z)
+ {
+// return (x & y) ^ (x & z) ^ (y & z);
+ return (x & y) | (z & (x ^ y));
+ }
+
+ private static int Sum0(int x)
+ {
+ return ((x >>> 2) | (x << 30)) ^ ((x >>> 13) | (x << 19)) ^ ((x >>> 22) | (x << 10));
+ }
+
+ private static int Sum1(int x)
+ {
+ return ((x >>> 6) | (x << 26)) ^ ((x >>> 11) | (x << 21)) ^ ((x >>> 25) | (x << 7));
+ }
+
+ private static int Theta0(int x)
+ {
+ return ((x >>> 7) | (x << 25)) ^ ((x >>> 18) | (x << 14)) ^ (x >>> 3);
+ }
+
+ private static int Theta1(int x)
+ {
+ return ((x >>> 17) | (x << 15)) ^ ((x >>> 19) | (x << 13)) ^ (x >>> 10);
+ }
+
+ /* SHA-256 Constants
+ * (represent the first 32 bits of the fractional parts of the
+ * cube roots of the first sixty-four prime numbers)
+ */
+ static final int K[] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ };
+
+ public Memoable copy()
+ {
+ return new SHA256Digest(this);
+ }
+
+ public void reset(Memoable other)
+ {
+ SHA256Digest d = (SHA256Digest)other;
+
+ copyIn(d);
+ }
+
+ public byte[] getEncodedState()
+ {
+ byte[] state = new byte[52 + xOff * 4];
+
+ super.populateState(state);
+
+ Pack.intToBigEndian(H1, state, 16);
+ Pack.intToBigEndian(H2, state, 20);
+ Pack.intToBigEndian(H3, state, 24);
+ Pack.intToBigEndian(H4, state, 28);
+ Pack.intToBigEndian(H5, state, 32);
+ Pack.intToBigEndian(H6, state, 36);
+ Pack.intToBigEndian(H7, state, 40);
+ Pack.intToBigEndian(H8, state, 44);
+ Pack.intToBigEndian(xOff, state, 48);
+
+ for (int i = 0; i != xOff; i++)
+ {
+ Pack.intToBigEndian(X[i], state, 52 + (i * 4));
+ }
+
+ return state;
+ }
+}
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA384Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA384Digest.java
new file mode 100644
index 00000000..77a0db37
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA384Digest.java
@@ -0,0 +1,118 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import com.android.internal.org.bouncycastle.util.Memoable;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+
+/**
+ * FIPS 180-2 implementation of SHA-384.
+ *
+ * <pre>
+ * block word digest
+ * SHA-1 512 32 160
+ * SHA-256 512 32 256
+ * SHA-384 1024 64 384
+ * SHA-512 1024 64 512
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SHA384Digest
+ extends LongDigest
+{
+ private static final int DIGEST_LENGTH = 48;
+
+ /**
+ * Standard constructor
+ */
+ public SHA384Digest()
+ {
+ }
+
+ /**
+ * Copy constructor. This will copy the state of the provided
+ * message digest.
+ */
+ public SHA384Digest(SHA384Digest t)
+ {
+ super(t);
+ }
+
+ /**
+ * State constructor - create a digest initialised with the state of a previous one.
+ *
+ * @param encodedState the encoded state from the originating digest.
+ */
+ public SHA384Digest(byte[] encodedState)
+ {
+ restoreState(encodedState);
+ }
+
+ public String getAlgorithmName()
+ {
+ return "SHA-384";
+ }
+
+ public int getDigestSize()
+ {
+ return DIGEST_LENGTH;
+ }
+
+ public int doFinal(
+ byte[] out,
+ int outOff)
+ {
+ finish();
+
+ Pack.longToBigEndian(H1, out, outOff);
+ Pack.longToBigEndian(H2, out, outOff + 8);
+ Pack.longToBigEndian(H3, out, outOff + 16);
+ Pack.longToBigEndian(H4, out, outOff + 24);
+ Pack.longToBigEndian(H5, out, outOff + 32);
+ Pack.longToBigEndian(H6, out, outOff + 40);
+
+ reset();
+
+ return DIGEST_LENGTH;
+ }
+
+ /**
+ * reset the chaining variables
+ */
+ public void reset()
+ {
+ super.reset();
+
+ /* SHA-384 initial hash value
+ * The first 64 bits of the fractional parts of the square roots
+ * of the 9th through 16th prime numbers
+ */
+ H1 = 0xcbbb9d5dc1059ed8l;
+ H2 = 0x629a292a367cd507l;
+ H3 = 0x9159015a3070dd17l;
+ H4 = 0x152fecd8f70e5939l;
+ H5 = 0x67332667ffc00b31l;
+ H6 = 0x8eb44a8768581511l;
+ H7 = 0xdb0c2e0d64f98fa7l;
+ H8 = 0x47b5481dbefa4fa4l;
+ }
+
+ public Memoable copy()
+ {
+ return new SHA384Digest(this);
+ }
+
+ public void reset(Memoable other)
+ {
+ SHA384Digest d = (SHA384Digest)other;
+
+ super.copyIn(d);
+ }
+
+ public byte[] getEncodedState()
+ {
+ byte[] encoded = new byte[getEncodedStateSize()];
+ super.populateState(encoded);
+ return encoded;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA512Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA512Digest.java
new file mode 100644
index 00000000..5a847322
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA512Digest.java
@@ -0,0 +1,121 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+import com.android.internal.org.bouncycastle.util.Memoable;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+
+/**
+ * FIPS 180-2 implementation of SHA-512.
+ *
+ * <pre>
+ * block word digest
+ * SHA-1 512 32 160
+ * SHA-256 512 32 256
+ * SHA-384 1024 64 384
+ * SHA-512 1024 64 512
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SHA512Digest
+ extends LongDigest
+{
+ private static final int DIGEST_LENGTH = 64;
+
+ /**
+ * Standard constructor
+ */
+ public SHA512Digest()
+ {
+ }
+
+ /**
+ * Copy constructor. This will copy the state of the provided
+ * message digest.
+ */
+ public SHA512Digest(SHA512Digest t)
+ {
+ super(t);
+ }
+
+ /**
+ * State constructor - create a digest initialised with the state of a previous one.
+ *
+ * @param encodedState the encoded state from the originating digest.
+ */
+ public SHA512Digest(byte[] encodedState)
+ {
+ restoreState(encodedState);
+ }
+
+ public String getAlgorithmName()
+ {
+ return "SHA-512";
+ }
+
+ public int getDigestSize()
+ {
+ return DIGEST_LENGTH;
+ }
+
+ public int doFinal(
+ byte[] out,
+ int outOff)
+ {
+ finish();
+
+ Pack.longToBigEndian(H1, out, outOff);
+ Pack.longToBigEndian(H2, out, outOff + 8);
+ Pack.longToBigEndian(H3, out, outOff + 16);
+ Pack.longToBigEndian(H4, out, outOff + 24);
+ Pack.longToBigEndian(H5, out, outOff + 32);
+ Pack.longToBigEndian(H6, out, outOff + 40);
+ Pack.longToBigEndian(H7, out, outOff + 48);
+ Pack.longToBigEndian(H8, out, outOff + 56);
+
+ reset();
+
+ return DIGEST_LENGTH;
+ }
+
+ /**
+ * reset the chaining variables
+ */
+ public void reset()
+ {
+ super.reset();
+
+ /* SHA-512 initial hash value
+ * The first 64 bits of the fractional parts of the square roots
+ * of the first eight prime numbers
+ */
+ H1 = 0x6a09e667f3bcc908L;
+ H2 = 0xbb67ae8584caa73bL;
+ H3 = 0x3c6ef372fe94f82bL;
+ H4 = 0xa54ff53a5f1d36f1L;
+ H5 = 0x510e527fade682d1L;
+ H6 = 0x9b05688c2b3e6c1fL;
+ H7 = 0x1f83d9abfb41bd6bL;
+ H8 = 0x5be0cd19137e2179L;
+ }
+
+ public Memoable copy()
+ {
+ return new SHA512Digest(this);
+ }
+
+ public void reset(Memoable other)
+ {
+ SHA512Digest d = (SHA512Digest)other;
+
+ copyIn(d);
+ }
+
+ public byte[] getEncodedState()
+ {
+ byte[] encoded = new byte[getEncodedStateSize()];
+ super.populateState(encoded);
+ return encoded;
+ }
+}
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/XofUtils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/XofUtils.java
new file mode 100644
index 00000000..88c2a4ad
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/XofUtils.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.digests;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class XofUtils
+{
+ public static byte[] leftEncode(long strLen)
+ {
+ byte n = 1;
+
+ long v = strLen;
+ while ((v >>= 8) != 0)
+ {
+ n++;
+ }
+
+ byte[] b = new byte[n + 1];
+
+ b[0] = n;
+
+ for (int i = 1; i <= n; i++)
+ {
+ b[i] = (byte)(strLen >> (8 * (n - i)));
+ }
+
+ return b;
+ }
+
+ public static byte[] rightEncode(long strLen)
+ {
+ byte n = 1;
+
+ long v = strLen;
+ while ((v >>= 8) != 0)
+ {
+ n++;
+ }
+
+ byte[] b = new byte[n + 1];
+
+ b[n] = n;
+
+ for (int i = 0; i < n; i++)
+ {
+ b[i] = (byte)(strLen >> (8 * (n - i - 1)));
+ }
+
+ return b;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/ec/CustomNamedCurves.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/ec/CustomNamedCurves.java
new file mode 100644
index 00000000..d2f0a3a8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/ec/CustomNamedCurves.java
@@ -0,0 +1,792 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.ec;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.gm.GMObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.sec.SECObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParametersHolder;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECPoint;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+// BEGIN android-removed
+// import org.bouncycastle.math.ec.custom.djb.Curve25519;
+// import org.bouncycastle.math.ec.custom.gm.SM2P256V1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecP128R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecP160K1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecP160R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecP160R2Curve;
+// END android-removed
+import com.android.internal.org.bouncycastle.math.ec.WNafUtil;
+import com.android.internal.org.bouncycastle.math.ec.custom.sec.SecP192K1Curve;
+import com.android.internal.org.bouncycastle.math.ec.custom.sec.SecP192R1Curve;
+import com.android.internal.org.bouncycastle.math.ec.custom.sec.SecP224K1Curve;
+import com.android.internal.org.bouncycastle.math.ec.custom.sec.SecP224R1Curve;
+import com.android.internal.org.bouncycastle.math.ec.custom.sec.SecP256K1Curve;
+import com.android.internal.org.bouncycastle.math.ec.custom.sec.SecP256R1Curve;
+import com.android.internal.org.bouncycastle.math.ec.custom.sec.SecP384R1Curve;
+import com.android.internal.org.bouncycastle.math.ec.custom.sec.SecP521R1Curve;
+// BEGIN android-removed
+// import org.bouncycastle.math.ec.custom.sec.SecT113R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT113R2Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT131R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT131R2Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT163K1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT163R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT163R2Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT193R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT193R2Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT233K1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT233R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT239K1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT283K1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT283R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT409K1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT409R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT571K1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT571R1Curve;
+// END android-removed
+import com.android.internal.org.bouncycastle.math.ec.endo.GLVTypeBEndomorphism;
+import com.android.internal.org.bouncycastle.math.ec.endo.GLVTypeBParameters;
+import com.android.internal.org.bouncycastle.math.ec.endo.ScalarSplitParameters;
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CustomNamedCurves
+{
+ private static X9ECPoint configureBasepoint(ECCurve curve, String encoding)
+ {
+ X9ECPoint G = new X9ECPoint(curve, Hex.decodeStrict(encoding));
+ WNafUtil.configureBasepoint(G.getPoint());
+ return G;
+ }
+
+ private static ECCurve configureCurve(ECCurve curve)
+ {
+ return curve;
+ }
+
+ private static ECCurve configureCurveGLV(ECCurve c, GLVTypeBParameters p)
+ {
+ return c.configure().setEndomorphism(new GLVTypeBEndomorphism(c, p)).create();
+ }
+
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ /*
+ * curve25519
+ *
+ static X9ECParametersHolder curve25519 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = configureCurve(new Curve25519());
+
+ /*
+ * NOTE: Curve25519 was specified in Montgomery form. Rewriting in Weierstrass form
+ * involves substitution of variables, so the base-point x coordinate is 9 + (486662 / 3).
+ *
+ * The Curve25519 paper doesn't say which of the two possible y values the base
+ * point has. The choice here is guided by language in the Ed25519 paper.
+ *
+ * (The other possible y value is 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14)
+ *
+ X9ECPoint G = configureBasepoint(curve,
+ "042AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9");
+
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * secp128r1
+ *
+ static X9ECParametersHolder secp128r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("000E0D4D696E6768756151750CC03A4473D03679");
+ ECCurve curve = configureCurve(new SecP128R1Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * secp160k1
+ *
+ static X9ECParametersHolder secp160k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ GLVTypeBParameters glv = new GLVTypeBParameters(
+ new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16),
+ new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16),
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("9162fbe73984472a0a9e", 16),
+ new BigInteger("-96341f1138933bc2f505", 16) },
+ new BigInteger[]{
+ new BigInteger("127971af8721782ecffa3", 16),
+ new BigInteger("9162fbe73984472a0a9e", 16) },
+ new BigInteger("9162fbe73984472a0a9d0590", 16),
+ new BigInteger("96341f1138933bc2f503fd44", 16),
+ 176));
+ ECCurve curve = configureCurveGLV(new SecP160K1Curve(), glv);
+ X9ECPoint G = configureBasepoint(curve,
+ "043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * secp160r1
+ *
+ static X9ECParametersHolder secp160r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("1053CDE42C14D696E67687561517533BF3F83345");
+ ECCurve curve = configureCurve(new SecP160R1Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * secp160r2
+ *
+ static X9ECParametersHolder secp160r2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("B99B99B099B323E02709A4D696E6768756151751");
+ ECCurve curve = configureCurve(new SecP160R2Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+ */
+ // END Android-removed: Unsupported curves
+
+ /*
+ * secp192k1
+ */
+ static X9ECParametersHolder secp192k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ GLVTypeBParameters glv = new GLVTypeBParameters(
+ new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16),
+ new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16),
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("71169be7330b3038edb025f1", 16),
+ new BigInteger("-b3fb3400dec5c4adceb8655c", 16) },
+ new BigInteger[]{
+ new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
+ new BigInteger("71169be7330b3038edb025f1", 16) },
+ new BigInteger("71169be7330b3038edb025f1d0f9", 16),
+ new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
+ 208));
+ ECCurve curve = configureCurveGLV(new SecP192K1Curve(), glv);
+ X9ECPoint G = configureBasepoint(curve,
+ "04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * secp192r1
+ */
+ static X9ECParametersHolder secp192r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5");
+ ECCurve curve = configureCurve(new SecP192R1Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * secp224k1
+ */
+ static X9ECParametersHolder secp224k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ GLVTypeBParameters glv = new GLVTypeBParameters(
+ new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16),
+ new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16),
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
+ new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) },
+ new BigInteger[]{
+ new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) },
+ new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
+ new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
+ 240));
+ ECCurve curve = configureCurveGLV(new SecP224K1Curve(), glv);
+ X9ECPoint G = configureBasepoint(curve,
+ "04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * secp224r1
+ */
+ static X9ECParametersHolder secp224r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
+ ECCurve curve = configureCurve(new SecP224R1Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * secp256k1
+ */
+ static X9ECParametersHolder secp256k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ GLVTypeBParameters glv = new GLVTypeBParameters(
+ new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16),
+ new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16),
+ new ScalarSplitParameters(
+ new BigInteger[]{
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
+ new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) },
+ new BigInteger[]{
+ new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) },
+ new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
+ new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
+ 272));
+ ECCurve curve = configureCurveGLV(new SecP256K1Curve(), glv);
+ X9ECPoint G = configureBasepoint(curve,
+ "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * secp256r1
+ */
+ static X9ECParametersHolder secp256r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("C49D360886E704936A6678E1139D26B7819F7E90");
+ ECCurve curve = configureCurve(new SecP256R1Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * secp384r1
+ */
+ static X9ECParametersHolder secp384r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73");
+ ECCurve curve = configureCurve(new SecP384R1Curve());
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
+ + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * secp521r1
+ */
+ static X9ECParametersHolder secp521r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA");
+ ECCurve curve = configureCurve(new SecP521R1Curve());
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
+ + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ /*
+ * sect113r1
+ *
+ static X9ECParametersHolder sect113r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9");
+ ECCurve curve = configureCurve(new SecT113R1Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect113r2
+ *
+ static X9ECParametersHolder sect113r2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D");
+ ECCurve curve = configureCurve(new SecT113R2Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect131r1
+ *
+ static X9ECParametersHolder sect131r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2");
+ ECCurve curve = configureCurve(new SecT131R1Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect131r2
+ *
+ static X9ECParametersHolder sect131r2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3");
+ ECCurve curve = configureCurve(new SecT131R2Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect163k1
+ *
+ static X9ECParametersHolder sect163k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = configureCurve(new SecT163K1Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect163r1
+ *
+ static X9ECParametersHolder sect163r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C");
+ ECCurve curve = configureCurve(new SecT163R1Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect163r2
+ *
+ static X9ECParametersHolder sect163r2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268");
+ ECCurve curve = configureCurve(new SecT163R2Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect193r1
+ *
+ static X9ECParametersHolder sect193r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("103FAEC74D696E676875615175777FC5B191EF30");
+ ECCurve curve = configureCurve(new SecT193R1Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect193r2
+ *
+ static X9ECParametersHolder sect193r2 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211");
+ ECCurve curve = configureCurve(new SecT193R2Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect233k1
+ *
+ static X9ECParametersHolder sect233k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = configureCurve(new SecT233K1Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect233r1
+ *
+ static X9ECParametersHolder sect233r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
+ ECCurve curve = configureCurve(new SecT233R1Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect239k1
+ *
+ static X9ECParametersHolder sect239k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = configureCurve(new SecT239K1Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect283k1
+ *
+ static X9ECParametersHolder sect283k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = configureCurve(new SecT283K1Curve());
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
+ + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect283r1
+ *
+ static X9ECParametersHolder sect283r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
+ ECCurve curve = configureCurve(new SecT283R1Curve());
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
+ + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect409k1
+ *
+ static X9ECParametersHolder sect409k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = configureCurve(new SecT409K1Curve());
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
+ + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect409r1
+ *
+ static X9ECParametersHolder sect409r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B");
+ ECCurve curve = configureCurve(new SecT409R1Curve());
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
+ + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect571k1
+ *
+ static X9ECParametersHolder sect571k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = configureCurve(new SecT571K1Curve());
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
+ + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sect571r1
+ *
+ static X9ECParametersHolder sect571r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310");
+ ECCurve curve = configureCurve(new SecT571R1Curve());
+ X9ECPoint G = configureBasepoint(curve, "04"
+ + "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
+ + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * sm2p256v1
+ *
+ static X9ECParametersHolder sm2p256v1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = configureCurve(new SM2P256V1Curve());
+ X9ECPoint G = configureBasepoint(curve,
+ "0432C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0");
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+ */
+ // END Android-removed: Unsupported curves
+
+
+ static final Hashtable nameToCurve = new Hashtable();
+ static final Hashtable nameToOID = new Hashtable();
+ static final Hashtable oidToCurve = new Hashtable();
+ static final Hashtable oidToName = new Hashtable();
+ static final Vector names = new Vector();
+
+ static void defineCurve(String name, X9ECParametersHolder holder)
+ {
+ names.addElement(name);
+ name = Strings.toLowerCase(name);
+ nameToCurve.put(name, holder);
+ }
+
+ static void defineCurveWithOID(String name, ASN1ObjectIdentifier oid, X9ECParametersHolder holder)
+ {
+ names.addElement(name);
+ oidToName.put(oid, name);
+ oidToCurve.put(oid, holder);
+ name = Strings.toLowerCase(name);
+ nameToOID.put(name, oid);
+ nameToCurve.put(name, holder);
+ }
+
+ static void defineCurveAlias(String name, ASN1ObjectIdentifier oid)
+ {
+ Object curve = oidToCurve.get(oid);
+ if (curve == null)
+ {
+ throw new IllegalStateException();
+ }
+
+ name = Strings.toLowerCase(name);
+ nameToOID.put(name, oid);
+ nameToCurve.put(name, curve);
+ }
+
+ static
+ {
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ defineCurveWithOID("curve25519", CryptlibObjectIdentifiers.curvey25519, curve25519);
+
+// defineCurveWithOID("secp112r1", SECObjectIdentifiers.secp112r1, secp112r1);
+// defineCurveWithOID("secp112r2", SECObjectIdentifiers.secp112r2, secp112r2);
+ defineCurveWithOID("secp128r1", SECObjectIdentifiers.secp128r1, secp128r1);
+// defineCurveWithOID("secp128r2", SECObjectIdentifiers.secp128r2, secp128r2);
+ defineCurveWithOID("secp160k1", SECObjectIdentifiers.secp160k1, secp160k1);
+ defineCurveWithOID("secp160r1", SECObjectIdentifiers.secp160r1, secp160r1);
+ defineCurveWithOID("secp160r2", SECObjectIdentifiers.secp160r2, secp160r2);
+ */
+ // END Android-removed: Unsupported curves
+ defineCurveWithOID("secp192k1", SECObjectIdentifiers.secp192k1, secp192k1);
+ defineCurveWithOID("secp192r1", SECObjectIdentifiers.secp192r1, secp192r1);
+ defineCurveWithOID("secp224k1", SECObjectIdentifiers.secp224k1, secp224k1);
+ defineCurveWithOID("secp224r1", SECObjectIdentifiers.secp224r1, secp224r1);
+ defineCurveWithOID("secp256k1", SECObjectIdentifiers.secp256k1, secp256k1);
+ defineCurveWithOID("secp256r1", SECObjectIdentifiers.secp256r1, secp256r1);
+ defineCurveWithOID("secp384r1", SECObjectIdentifiers.secp384r1, secp384r1);
+ defineCurveWithOID("secp521r1", SECObjectIdentifiers.secp521r1, secp521r1);
+
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ defineCurveWithOID("sect113r1", SECObjectIdentifiers.sect113r1, sect113r1);
+ defineCurveWithOID("sect113r2", SECObjectIdentifiers.sect113r2, sect113r2);
+ defineCurveWithOID("sect131r1", SECObjectIdentifiers.sect131r1, sect131r1);
+ defineCurveWithOID("sect131r2", SECObjectIdentifiers.sect131r2, sect131r2);
+ defineCurveWithOID("sect163k1", SECObjectIdentifiers.sect163k1, sect163k1);
+ defineCurveWithOID("sect163r1", SECObjectIdentifiers.sect163r1, sect163r1);
+ defineCurveWithOID("sect163r2", SECObjectIdentifiers.sect163r2, sect163r2);
+ defineCurveWithOID("sect193r1", SECObjectIdentifiers.sect193r1, sect193r1);
+ defineCurveWithOID("sect193r2", SECObjectIdentifiers.sect193r2, sect193r2);
+ defineCurveWithOID("sect233k1", SECObjectIdentifiers.sect233k1, sect233k1);
+ defineCurveWithOID("sect233r1", SECObjectIdentifiers.sect233r1, sect233r1);
+ defineCurveWithOID("sect239k1", SECObjectIdentifiers.sect239k1, sect239k1);
+ defineCurveWithOID("sect283k1", SECObjectIdentifiers.sect283k1, sect283k1);
+ defineCurveWithOID("sect283r1", SECObjectIdentifiers.sect283r1, sect283r1);
+ defineCurveWithOID("sect409k1", SECObjectIdentifiers.sect409k1, sect409k1);
+ defineCurveWithOID("sect409r1", SECObjectIdentifiers.sect409r1, sect409r1);
+ defineCurveWithOID("sect571k1", SECObjectIdentifiers.sect571k1, sect571k1);
+ defineCurveWithOID("sect571r1", SECObjectIdentifiers.sect571r1, sect571r1);
+
+ defineCurveWithOID("sm2p256v1", GMObjectIdentifiers.sm2p256v1, sm2p256v1);
+
+ defineCurveAlias("B-163", SECObjectIdentifiers.sect163r2);
+ defineCurveAlias("B-233", SECObjectIdentifiers.sect233r1);
+ defineCurveAlias("B-283", SECObjectIdentifiers.sect283r1);
+ defineCurveAlias("B-409", SECObjectIdentifiers.sect409r1);
+ defineCurveAlias("B-571", SECObjectIdentifiers.sect571r1);
+
+ defineCurveAlias("K-163", SECObjectIdentifiers.sect163k1);
+ defineCurveAlias("K-233", SECObjectIdentifiers.sect233k1);
+ defineCurveAlias("K-283", SECObjectIdentifiers.sect283k1);
+ defineCurveAlias("K-409", SECObjectIdentifiers.sect409k1);
+ defineCurveAlias("K-571", SECObjectIdentifiers.sect571k1);
+ */
+ // END Android-removed: Unsupported curves
+
+ defineCurveAlias("P-192", SECObjectIdentifiers.secp192r1);
+ defineCurveAlias("P-224", SECObjectIdentifiers.secp224r1);
+ defineCurveAlias("P-256", SECObjectIdentifiers.secp256r1);
+ defineCurveAlias("P-384", SECObjectIdentifiers.secp384r1);
+ defineCurveAlias("P-521", SECObjectIdentifiers.secp521r1);
+ }
+
+ public static X9ECParameters getByName(String name)
+ {
+ X9ECParametersHolder holder = (X9ECParametersHolder)nameToCurve.get(Strings.toLowerCase(name));
+ return holder == null ? null : holder.getParameters();
+ }
+
+ /**
+ * return the X9ECParameters object for the named curve represented by the passed in object
+ * identifier. Null if the curve isn't present.
+ *
+ * @param oid
+ * an object identifier representing a named curve, if present.
+ */
+ public static X9ECParameters getByOID(ASN1ObjectIdentifier oid)
+ {
+ X9ECParametersHolder holder = (X9ECParametersHolder)oidToCurve.get(oid);
+ return holder == null ? null : holder.getParameters();
+ }
+
+ /**
+ * return the object identifier signified by the passed in name. Null if there is no object
+ * identifier associated with name.
+ *
+ * @return the object identifier associated with name, if present.
+ */
+ public static ASN1ObjectIdentifier getOID(String name)
+ {
+ return (ASN1ObjectIdentifier)nameToOID.get(Strings.toLowerCase(name));
+ }
+
+ /**
+ * return the named curve name represented by the given object identifier.
+ */
+ public static String getName(ASN1ObjectIdentifier oid)
+ {
+ return (String)oidToName.get(oid);
+ }
+
+ /**
+ * returns an enumeration containing the name strings for curves contained in this structure.
+ */
+ public static Enumeration getNames()
+ {
+ return names.elements();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/OAEPEncoding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/OAEPEncoding.java
new file mode 100644
index 00000000..23fcdd6e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/OAEPEncoding.java
@@ -0,0 +1,366 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.encodings;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.AsymmetricBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+// Android-changed: Use Android digests
+// import org.bouncycastle.crypto.util.DigestFactory;
+import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Optimal Asymmetric Encryption Padding (OAEP) - see PKCS 1 V 2.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OAEPEncoding
+ implements AsymmetricBlockCipher
+{
+ private byte[] defHash;
+ private Digest mgf1Hash;
+
+ private AsymmetricBlockCipher engine;
+ private SecureRandom random;
+ private boolean forEncryption;
+
+ public OAEPEncoding(
+ AsymmetricBlockCipher cipher)
+ {
+ // Android-changed: Use Android digests
+ // this(cipher, DigestFactory.createSHA1(), null);
+ this(cipher, AndroidDigestFactory.getSHA1(), null);
+ }
+
+ public OAEPEncoding(
+ AsymmetricBlockCipher cipher,
+ Digest hash)
+ {
+ this(cipher, hash, null);
+ }
+
+ public OAEPEncoding(
+ AsymmetricBlockCipher cipher,
+ Digest hash,
+ byte[] encodingParams)
+ {
+ this(cipher, hash, hash, encodingParams);
+ }
+
+ public OAEPEncoding(
+ AsymmetricBlockCipher cipher,
+ Digest hash,
+ Digest mgf1Hash,
+ byte[] encodingParams)
+ {
+ this.engine = cipher;
+ this.mgf1Hash = mgf1Hash;
+ this.defHash = new byte[hash.getDigestSize()];
+
+ hash.reset();
+
+ if (encodingParams != null)
+ {
+ hash.update(encodingParams, 0, encodingParams.length);
+ }
+
+ hash.doFinal(defHash, 0);
+ }
+
+ public AsymmetricBlockCipher getUnderlyingCipher()
+ {
+ return engine;
+ }
+
+ public void init(
+ boolean forEncryption,
+ CipherParameters param)
+ {
+ if (param instanceof ParametersWithRandom)
+ {
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
+
+ this.random = rParam.getRandom();
+ }
+ else
+ {
+ this.random = CryptoServicesRegistrar.getSecureRandom();
+ }
+
+ engine.init(forEncryption, param);
+
+ this.forEncryption = forEncryption;
+ }
+
+ public int getInputBlockSize()
+ {
+ int baseBlockSize = engine.getInputBlockSize();
+
+ if (forEncryption)
+ {
+ return baseBlockSize - 1 - 2 * defHash.length;
+ }
+ else
+ {
+ return baseBlockSize;
+ }
+ }
+
+ public int getOutputBlockSize()
+ {
+ int baseBlockSize = engine.getOutputBlockSize();
+
+ if (forEncryption)
+ {
+ return baseBlockSize;
+ }
+ else
+ {
+ return baseBlockSize - 1 - 2 * defHash.length;
+ }
+ }
+
+ public byte[] processBlock(
+ byte[] in,
+ int inOff,
+ int inLen)
+ throws InvalidCipherTextException
+ {
+ if (forEncryption)
+ {
+ return encodeBlock(in, inOff, inLen);
+ }
+ else
+ {
+ return decodeBlock(in, inOff, inLen);
+ }
+ }
+
+ public byte[] encodeBlock(
+ byte[] in,
+ int inOff,
+ int inLen)
+ throws InvalidCipherTextException
+ {
+ if (inLen > getInputBlockSize())
+ {
+ throw new DataLengthException("input data too long");
+ }
+
+ byte[] block = new byte[getInputBlockSize() + 1 + 2 * defHash.length];
+
+ //
+ // copy in the message
+ //
+ System.arraycopy(in, inOff, block, block.length - inLen, inLen);
+
+ //
+ // add sentinel
+ //
+ block[block.length - inLen - 1] = 0x01;
+
+ //
+ // as the block is already zeroed - there's no need to add PS (the >= 0 pad of 0)
+ //
+
+ //
+ // add the hash of the encoding params.
+ //
+ System.arraycopy(defHash, 0, block, defHash.length, defHash.length);
+
+ //
+ // generate the seed.
+ //
+ byte[] seed = new byte[defHash.length];
+
+ random.nextBytes(seed);
+
+ //
+ // mask the message block.
+ //
+ byte[] mask = maskGeneratorFunction1(seed, 0, seed.length, block.length - defHash.length);
+
+ for (int i = defHash.length; i != block.length; i++)
+ {
+ block[i] ^= mask[i - defHash.length];
+ }
+
+ //
+ // add in the seed
+ //
+ System.arraycopy(seed, 0, block, 0, defHash.length);
+
+ //
+ // mask the seed.
+ //
+ mask = maskGeneratorFunction1(
+ block, defHash.length, block.length - defHash.length, defHash.length);
+
+ for (int i = 0; i != defHash.length; i++)
+ {
+ block[i] ^= mask[i];
+ }
+
+ return engine.processBlock(block, 0, block.length);
+ }
+
+ /**
+ * @exception InvalidCipherTextException if the decrypted block turns out to
+ * be badly formatted.
+ */
+ public byte[] decodeBlock(
+ byte[] in,
+ int inOff,
+ int inLen)
+ throws InvalidCipherTextException
+ {
+ byte[] data = engine.processBlock(in, inOff, inLen);
+ byte[] block = new byte[engine.getOutputBlockSize()];
+
+ //
+ // as we may have zeros in our leading bytes for the block we produced
+ // on encryption, we need to make sure our decrypted block comes back
+ // the same size.
+ //
+ boolean wrongData = (block.length < (2 * defHash.length) + 1);
+
+ if (data.length <= block.length)
+ {
+ System.arraycopy(data, 0, block, block.length - data.length, data.length);
+ }
+ else
+ {
+ System.arraycopy(data, 0, block, 0, block.length);
+ wrongData = true;
+ }
+
+ //
+ // unmask the seed.
+ //
+ byte[] mask = maskGeneratorFunction1(
+ block, defHash.length, block.length - defHash.length, defHash.length);
+
+ for (int i = 0; i != defHash.length; i++)
+ {
+ block[i] ^= mask[i];
+ }
+
+ //
+ // unmask the message block.
+ //
+ mask = maskGeneratorFunction1(block, 0, defHash.length, block.length - defHash.length);
+
+ for (int i = defHash.length; i != block.length; i++)
+ {
+ block[i] ^= mask[i - defHash.length];
+ }
+
+ //
+ // check the hash of the encoding params.
+ // long check to try to avoid this been a source of a timing attack.
+ //
+ boolean defHashWrong = false;
+
+ for (int i = 0; i != defHash.length; i++)
+ {
+ if (defHash[i] != block[defHash.length + i])
+ {
+ defHashWrong = true;
+ }
+ }
+
+ //
+ // find the data block
+ //
+ int start = block.length;
+
+ for (int index = 2 * defHash.length; index != block.length; index++)
+ {
+ if (block[index] != 0 & start == block.length)
+ {
+ start = index;
+ }
+ }
+
+ boolean dataStartWrong = (start > (block.length - 1) | block[start] != 1);
+
+ start++;
+
+ if (defHashWrong | wrongData | dataStartWrong)
+ {
+ Arrays.fill(block, (byte)0);
+ throw new InvalidCipherTextException("data wrong");
+ }
+
+ //
+ // extract the data block
+ //
+ byte[] output = new byte[block.length - start];
+
+ System.arraycopy(block, start, output, 0, output.length);
+ Arrays.fill(block, (byte)0);
+
+ return output;
+ }
+
+ /**
+ * int to octet string.
+ */
+ private void ItoOSP(
+ int i,
+ byte[] sp)
+ {
+ sp[0] = (byte)(i >>> 24);
+ sp[1] = (byte)(i >>> 16);
+ sp[2] = (byte)(i >>> 8);
+ sp[3] = (byte)(i >>> 0);
+ }
+
+ /**
+ * mask generator function, as described in PKCS1v2.
+ */
+ private byte[] maskGeneratorFunction1(
+ byte[] Z,
+ int zOff,
+ int zLen,
+ int length)
+ {
+ byte[] mask = new byte[length];
+ byte[] hashBuf = new byte[mgf1Hash.getDigestSize()];
+ byte[] C = new byte[4];
+ int counter = 0;
+
+ mgf1Hash.reset();
+
+ while (counter < (length / hashBuf.length))
+ {
+ ItoOSP(counter, C);
+
+ mgf1Hash.update(Z, zOff, zLen);
+ mgf1Hash.update(C, 0, C.length);
+ mgf1Hash.doFinal(hashBuf, 0);
+
+ System.arraycopy(hashBuf, 0, mask, counter * hashBuf.length, hashBuf.length);
+
+ counter++;
+ }
+
+ if ((counter * hashBuf.length) < length)
+ {
+ ItoOSP(counter, C);
+
+ mgf1Hash.update(Z, zOff, zLen);
+ mgf1Hash.update(C, 0, C.length);
+ mgf1Hash.doFinal(hashBuf, 0);
+
+ System.arraycopy(hashBuf, 0, mask, counter * hashBuf.length, mask.length - (counter * hashBuf.length));
+ }
+
+ return mask;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/PKCS1Encoding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
new file mode 100644
index 00000000..aafbf6ed
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
@@ -0,0 +1,431 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.encodings;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.AsymmetricBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Properties;
+
+/**
+ * this does your basic PKCS 1 v1.5 padding - whether or not you should be using this
+ * depends on your application - see PKCS1 Version 2 for details.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS1Encoding
+ implements AsymmetricBlockCipher
+{
+ /**
+ * @deprecated use NOT_STRICT_LENGTH_ENABLED_PROPERTY
+ */
+ public static final String STRICT_LENGTH_ENABLED_PROPERTY = "com.android.internal.org.bouncycastle.pkcs1.strict";
+
+ /**
+ * some providers fail to include the leading zero in PKCS1 encoded blocks. If you need to
+ * work with one of these set the system property org.bouncycastle.pkcs1.not_strict to true.
+ * <p>
+ * The system property is checked during construction of the encoding object, it is set to
+ * false by default.
+ * </p>
+ */
+ public static final String NOT_STRICT_LENGTH_ENABLED_PROPERTY = "com.android.internal.org.bouncycastle.pkcs1.not_strict";
+
+ private static final int HEADER_LENGTH = 10;
+
+ private SecureRandom random;
+ private AsymmetricBlockCipher engine;
+ private boolean forEncryption;
+ private boolean forPrivateKey;
+ private boolean useStrictLength;
+ private int pLen = -1;
+ private byte[] fallback = null;
+ private byte[] blockBuffer;
+
+ /**
+ * Basic constructor.
+ *
+ * @param cipher
+ */
+ public PKCS1Encoding(
+ AsymmetricBlockCipher cipher)
+ {
+ this.engine = cipher;
+ this.useStrictLength = useStrict();
+ }
+
+ /**
+ * Constructor for decryption with a fixed plaintext length.
+ *
+ * @param cipher The cipher to use for cryptographic operation.
+ * @param pLen Length of the expected plaintext.
+ */
+ public PKCS1Encoding(
+ AsymmetricBlockCipher cipher,
+ int pLen)
+ {
+ this.engine = cipher;
+ this.useStrictLength = useStrict();
+ this.pLen = pLen;
+ }
+
+ /**
+ * Constructor for decryption with a fixed plaintext length and a fallback
+ * value that is returned, if the padding is incorrect.
+ *
+ * @param cipher The cipher to use for cryptographic operation.
+ * @param fallback The fallback value, we don't do an arraycopy here.
+ */
+ public PKCS1Encoding(
+ AsymmetricBlockCipher cipher,
+ byte[] fallback)
+ {
+ this.engine = cipher;
+ this.useStrictLength = useStrict();
+ this.fallback = fallback;
+ this.pLen = fallback.length;
+ }
+
+
+ //
+ // for J2ME compatibility
+ //
+ private boolean useStrict()
+ {
+ if (Properties.isOverrideSetTo(NOT_STRICT_LENGTH_ENABLED_PROPERTY, true))
+ {
+ return false;
+ }
+
+ return !Properties.isOverrideSetTo(STRICT_LENGTH_ENABLED_PROPERTY, false);
+ }
+
+ public AsymmetricBlockCipher getUnderlyingCipher()
+ {
+ return engine;
+ }
+
+ public void init(
+ boolean forEncryption,
+ CipherParameters param)
+ {
+ AsymmetricKeyParameter kParam;
+
+ if (param instanceof ParametersWithRandom)
+ {
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
+
+ this.random = rParam.getRandom();
+ kParam = (AsymmetricKeyParameter)rParam.getParameters();
+ }
+ else
+ {
+ kParam = (AsymmetricKeyParameter)param;
+ if (!kParam.isPrivate() && forEncryption)
+ {
+ this.random = CryptoServicesRegistrar.getSecureRandom();
+ }
+ }
+
+ engine.init(forEncryption, param);
+
+ this.forPrivateKey = kParam.isPrivate();
+ this.forEncryption = forEncryption;
+ this.blockBuffer = new byte[engine.getOutputBlockSize()];
+
+ if (pLen > 0 && fallback == null && random == null)
+ {
+ throw new IllegalArgumentException("encoder requires random");
+ }
+ }
+
+ public int getInputBlockSize()
+ {
+ int baseBlockSize = engine.getInputBlockSize();
+
+ if (forEncryption)
+ {
+ return baseBlockSize - HEADER_LENGTH;
+ }
+ else
+ {
+ return baseBlockSize;
+ }
+ }
+
+ public int getOutputBlockSize()
+ {
+ int baseBlockSize = engine.getOutputBlockSize();
+
+ if (forEncryption)
+ {
+ return baseBlockSize;
+ }
+ else
+ {
+ return baseBlockSize - HEADER_LENGTH;
+ }
+ }
+
+ public byte[] processBlock(
+ byte[] in,
+ int inOff,
+ int inLen)
+ throws InvalidCipherTextException
+ {
+ if (forEncryption)
+ {
+ return encodeBlock(in, inOff, inLen);
+ }
+ else
+ {
+ return decodeBlock(in, inOff, inLen);
+ }
+ }
+
+ private byte[] encodeBlock(
+ byte[] in,
+ int inOff,
+ int inLen)
+ throws InvalidCipherTextException
+ {
+ if (inLen > getInputBlockSize())
+ {
+ throw new IllegalArgumentException("input data too large");
+ }
+
+ byte[] block = new byte[engine.getInputBlockSize()];
+
+ if (forPrivateKey)
+ {
+ block[0] = 0x01; // type code 1
+
+ for (int i = 1; i != block.length - inLen - 1; i++)
+ {
+ block[i] = (byte)0xFF;
+ }
+ }
+ else
+ {
+ random.nextBytes(block); // random fill
+
+ block[0] = 0x02; // type code 2
+
+ //
+ // a zero byte marks the end of the padding, so all
+ // the pad bytes must be non-zero.
+ //
+ for (int i = 1; i != block.length - inLen - 1; i++)
+ {
+ while (block[i] == 0)
+ {
+ block[i] = (byte)random.nextInt();
+ }
+ }
+ }
+
+ block[block.length - inLen - 1] = 0x00; // mark the end of the padding
+ System.arraycopy(in, inOff, block, block.length - inLen, inLen);
+
+ return engine.processBlock(block, 0, block.length);
+ }
+
+ /**
+ * Checks if the argument is a correctly PKCS#1.5 encoded Plaintext
+ * for encryption.
+ *
+ * @param encoded The Plaintext.
+ * @param pLen Expected length of the plaintext.
+ * @return Either 0, if the encoding is correct, or -1, if it is incorrect.
+ */
+ private static int checkPkcs1Encoding(byte[] encoded, int pLen)
+ {
+ int correct = 0;
+ /*
+ * Check if the first two bytes are 0 2
+ */
+ correct |= (encoded[0] ^ 2);
+
+ /*
+ * Now the padding check, check for no 0 byte in the padding
+ */
+ int plen = encoded.length - (
+ pLen /* Length of the PMS */
+ + 1 /* Final 0-byte before PMS */
+ );
+
+ for (int i = 1; i < plen; i++)
+ {
+ int tmp = encoded[i];
+ tmp |= tmp >> 1;
+ tmp |= tmp >> 2;
+ tmp |= tmp >> 4;
+ correct |= (tmp & 1) - 1;
+ }
+
+ /*
+ * Make sure the padding ends with a 0 byte.
+ */
+ correct |= encoded[encoded.length - (pLen + 1)];
+
+ /*
+ * Return 0 or 1, depending on the result.
+ */
+ correct |= correct >> 1;
+ correct |= correct >> 2;
+ correct |= correct >> 4;
+ return ~((correct & 1) - 1);
+ }
+
+
+ /**
+ * Decode PKCS#1.5 encoding, and return a random value if the padding is not correct.
+ *
+ * @param in The encrypted block.
+ * @param inOff Offset in the encrypted block.
+ * @param inLen Length of the encrypted block.
+ * //@param pLen Length of the desired output.
+ * @return The plaintext without padding, or a random value if the padding was incorrect.
+ * @throws InvalidCipherTextException
+ */
+ private byte[] decodeBlockOrRandom(byte[] in, int inOff, int inLen)
+ throws InvalidCipherTextException
+ {
+ if (!forPrivateKey)
+ {
+ throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing");
+ }
+
+ byte[] block = engine.processBlock(in, inOff, inLen);
+ byte[] random;
+ if (this.fallback == null)
+ {
+ random = new byte[this.pLen];
+ this.random.nextBytes(random);
+ }
+ else
+ {
+ random = fallback;
+ }
+
+ byte[] data = (useStrictLength & (block.length != engine.getOutputBlockSize())) ? blockBuffer : block;
+
+ /*
+ * Check the padding.
+ */
+ int correct = PKCS1Encoding.checkPkcs1Encoding(data, this.pLen);
+
+ /*
+ * Now, to a constant time constant memory copy of the decrypted value
+ * or the random value, depending on the validity of the padding.
+ */
+ byte[] result = new byte[this.pLen];
+ for (int i = 0; i < this.pLen; i++)
+ {
+ result[i] = (byte)((data[i + (data.length - pLen)] & (~correct)) | (random[i] & correct));
+ }
+
+ Arrays.fill(data, (byte)0);
+
+ return result;
+ }
+
+ /**
+ * @throws InvalidCipherTextException if the decrypted block is not in PKCS1 format.
+ */
+ private byte[] decodeBlock(
+ byte[] in,
+ int inOff,
+ int inLen)
+ throws InvalidCipherTextException
+ {
+ /*
+ * If the length of the expected plaintext is known, we use a constant-time decryption.
+ * If the decryption fails, we return a random value.
+ */
+ if (this.pLen != -1)
+ {
+ return this.decodeBlockOrRandom(in, inOff, inLen);
+ }
+
+ byte[] block = engine.processBlock(in, inOff, inLen);
+ boolean incorrectLength = (useStrictLength & (block.length != engine.getOutputBlockSize()));
+
+ byte[] data;
+ if (block.length < getOutputBlockSize())
+ {
+ data = blockBuffer;
+ }
+ else
+ {
+ data = block;
+ }
+
+ byte type = data[0];
+
+ boolean badType;
+ if (forPrivateKey)
+ {
+ badType = (type != 2);
+ }
+ else
+ {
+ badType = (type != 1);
+ }
+
+ //
+ // find and extract the message block.
+ //
+ int start = findStart(type, data);
+
+ start++; // data should start at the next byte
+
+ if (badType | start < HEADER_LENGTH)
+ {
+ Arrays.fill(data, (byte)0);
+ throw new InvalidCipherTextException("block incorrect");
+ }
+
+ // if we get this far, it's likely to be a genuine encoding error
+ if (incorrectLength)
+ {
+ Arrays.fill(data, (byte)0);
+ throw new InvalidCipherTextException("block incorrect size");
+ }
+
+ byte[] result = new byte[data.length - start];
+
+ System.arraycopy(data, start, result, 0, result.length);
+
+ return result;
+ }
+
+ private int findStart(byte type, byte[] block)
+ throws InvalidCipherTextException
+ {
+ int start = -1;
+ boolean padErr = false;
+
+ for (int i = 1; i != block.length; i++)
+ {
+ byte pad = block[i];
+
+ if (pad == 0 & start < 0)
+ {
+ start = i;
+ }
+ padErr |= (type == 1 & start < 0 & pad != (byte)0xff);
+ }
+
+ if (padErr)
+ {
+ return -1;
+ }
+
+ return start;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESEngine.java
new file mode 100644
index 00000000..1ad46f64
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESEngine.java
@@ -0,0 +1,630 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * an implementation of the AES (Rijndael), from FIPS-197.
+ * <p>
+ * For further details see: <a href="https://csrc.nist.gov/encryption/aes/">https://csrc.nist.gov/encryption/aes/</a>.
+ *
+ * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at
+ * <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
+ *
+ * There are three levels of tradeoff of speed vs memory
+ * Because java has no preprocessor, they are written as three separate classes from which to choose
+ *
+ * The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption
+ * and 4 for decryption.
+ *
+ * The middle performance version uses only one 256 word table for each, for a total of 2Kbytes,
+ * adding 12 rotate operations per round to compute the values contained in the other tables from
+ * the contents of the first.
+ *
+ * The slowest version uses no static tables at all and computes the values in each round.
+ * <p>
+ * This file contains the middle performance version with 2Kbytes of static tables for round precomputation.
+ * @hide This class is not part of the Android public SDK API
+ *
+ */
+public class AESEngine
+ implements BlockCipher
+{
+ // The S box
+ private static final byte[] S = {
+ (byte)99, (byte)124, (byte)119, (byte)123, (byte)242, (byte)107, (byte)111, (byte)197,
+ (byte)48, (byte)1, (byte)103, (byte)43, (byte)254, (byte)215, (byte)171, (byte)118,
+ (byte)202, (byte)130, (byte)201, (byte)125, (byte)250, (byte)89, (byte)71, (byte)240,
+ (byte)173, (byte)212, (byte)162, (byte)175, (byte)156, (byte)164, (byte)114, (byte)192,
+ (byte)183, (byte)253, (byte)147, (byte)38, (byte)54, (byte)63, (byte)247, (byte)204,
+ (byte)52, (byte)165, (byte)229, (byte)241, (byte)113, (byte)216, (byte)49, (byte)21,
+ (byte)4, (byte)199, (byte)35, (byte)195, (byte)24, (byte)150, (byte)5, (byte)154,
+ (byte)7, (byte)18, (byte)128, (byte)226, (byte)235, (byte)39, (byte)178, (byte)117,
+ (byte)9, (byte)131, (byte)44, (byte)26, (byte)27, (byte)110, (byte)90, (byte)160,
+ (byte)82, (byte)59, (byte)214, (byte)179, (byte)41, (byte)227, (byte)47, (byte)132,
+ (byte)83, (byte)209, (byte)0, (byte)237, (byte)32, (byte)252, (byte)177, (byte)91,
+ (byte)106, (byte)203, (byte)190, (byte)57, (byte)74, (byte)76, (byte)88, (byte)207,
+ (byte)208, (byte)239, (byte)170, (byte)251, (byte)67, (byte)77, (byte)51, (byte)133,
+ (byte)69, (byte)249, (byte)2, (byte)127, (byte)80, (byte)60, (byte)159, (byte)168,
+ (byte)81, (byte)163, (byte)64, (byte)143, (byte)146, (byte)157, (byte)56, (byte)245,
+ (byte)188, (byte)182, (byte)218, (byte)33, (byte)16, (byte)255, (byte)243, (byte)210,
+ (byte)205, (byte)12, (byte)19, (byte)236, (byte)95, (byte)151, (byte)68, (byte)23,
+ (byte)196, (byte)167, (byte)126, (byte)61, (byte)100, (byte)93, (byte)25, (byte)115,
+ (byte)96, (byte)129, (byte)79, (byte)220, (byte)34, (byte)42, (byte)144, (byte)136,
+ (byte)70, (byte)238, (byte)184, (byte)20, (byte)222, (byte)94, (byte)11, (byte)219,
+ (byte)224, (byte)50, (byte)58, (byte)10, (byte)73, (byte)6, (byte)36, (byte)92,
+ (byte)194, (byte)211, (byte)172, (byte)98, (byte)145, (byte)149, (byte)228, (byte)121,
+ (byte)231, (byte)200, (byte)55, (byte)109, (byte)141, (byte)213, (byte)78, (byte)169,
+ (byte)108, (byte)86, (byte)244, (byte)234, (byte)101, (byte)122, (byte)174, (byte)8,
+ (byte)186, (byte)120, (byte)37, (byte)46, (byte)28, (byte)166, (byte)180, (byte)198,
+ (byte)232, (byte)221, (byte)116, (byte)31, (byte)75, (byte)189, (byte)139, (byte)138,
+ (byte)112, (byte)62, (byte)181, (byte)102, (byte)72, (byte)3, (byte)246, (byte)14,
+ (byte)97, (byte)53, (byte)87, (byte)185, (byte)134, (byte)193, (byte)29, (byte)158,
+ (byte)225, (byte)248, (byte)152, (byte)17, (byte)105, (byte)217, (byte)142, (byte)148,
+ (byte)155, (byte)30, (byte)135, (byte)233, (byte)206, (byte)85, (byte)40, (byte)223,
+ (byte)140, (byte)161, (byte)137, (byte)13, (byte)191, (byte)230, (byte)66, (byte)104,
+ (byte)65, (byte)153, (byte)45, (byte)15, (byte)176, (byte)84, (byte)187, (byte)22,
+ };
+
+ // The inverse S-box
+ private static final byte[] Si = {
+ (byte)82, (byte)9, (byte)106, (byte)213, (byte)48, (byte)54, (byte)165, (byte)56,
+ (byte)191, (byte)64, (byte)163, (byte)158, (byte)129, (byte)243, (byte)215, (byte)251,
+ (byte)124, (byte)227, (byte)57, (byte)130, (byte)155, (byte)47, (byte)255, (byte)135,
+ (byte)52, (byte)142, (byte)67, (byte)68, (byte)196, (byte)222, (byte)233, (byte)203,
+ (byte)84, (byte)123, (byte)148, (byte)50, (byte)166, (byte)194, (byte)35, (byte)61,
+ (byte)238, (byte)76, (byte)149, (byte)11, (byte)66, (byte)250, (byte)195, (byte)78,
+ (byte)8, (byte)46, (byte)161, (byte)102, (byte)40, (byte)217, (byte)36, (byte)178,
+ (byte)118, (byte)91, (byte)162, (byte)73, (byte)109, (byte)139, (byte)209, (byte)37,
+ (byte)114, (byte)248, (byte)246, (byte)100, (byte)134, (byte)104, (byte)152, (byte)22,
+ (byte)212, (byte)164, (byte)92, (byte)204, (byte)93, (byte)101, (byte)182, (byte)146,
+ (byte)108, (byte)112, (byte)72, (byte)80, (byte)253, (byte)237, (byte)185, (byte)218,
+ (byte)94, (byte)21, (byte)70, (byte)87, (byte)167, (byte)141, (byte)157, (byte)132,
+ (byte)144, (byte)216, (byte)171, (byte)0, (byte)140, (byte)188, (byte)211, (byte)10,
+ (byte)247, (byte)228, (byte)88, (byte)5, (byte)184, (byte)179, (byte)69, (byte)6,
+ (byte)208, (byte)44, (byte)30, (byte)143, (byte)202, (byte)63, (byte)15, (byte)2,
+ (byte)193, (byte)175, (byte)189, (byte)3, (byte)1, (byte)19, (byte)138, (byte)107,
+ (byte)58, (byte)145, (byte)17, (byte)65, (byte)79, (byte)103, (byte)220, (byte)234,
+ (byte)151, (byte)242, (byte)207, (byte)206, (byte)240, (byte)180, (byte)230, (byte)115,
+ (byte)150, (byte)172, (byte)116, (byte)34, (byte)231, (byte)173, (byte)53, (byte)133,
+ (byte)226, (byte)249, (byte)55, (byte)232, (byte)28, (byte)117, (byte)223, (byte)110,
+ (byte)71, (byte)241, (byte)26, (byte)113, (byte)29, (byte)41, (byte)197, (byte)137,
+ (byte)111, (byte)183, (byte)98, (byte)14, (byte)170, (byte)24, (byte)190, (byte)27,
+ (byte)252, (byte)86, (byte)62, (byte)75, (byte)198, (byte)210, (byte)121, (byte)32,
+ (byte)154, (byte)219, (byte)192, (byte)254, (byte)120, (byte)205, (byte)90, (byte)244,
+ (byte)31, (byte)221, (byte)168, (byte)51, (byte)136, (byte)7, (byte)199, (byte)49,
+ (byte)177, (byte)18, (byte)16, (byte)89, (byte)39, (byte)128, (byte)236, (byte)95,
+ (byte)96, (byte)81, (byte)127, (byte)169, (byte)25, (byte)181, (byte)74, (byte)13,
+ (byte)45, (byte)229, (byte)122, (byte)159, (byte)147, (byte)201, (byte)156, (byte)239,
+ (byte)160, (byte)224, (byte)59, (byte)77, (byte)174, (byte)42, (byte)245, (byte)176,
+ (byte)200, (byte)235, (byte)187, (byte)60, (byte)131, (byte)83, (byte)153, (byte)97,
+ (byte)23, (byte)43, (byte)4, (byte)126, (byte)186, (byte)119, (byte)214, (byte)38,
+ (byte)225, (byte)105, (byte)20, (byte)99, (byte)85, (byte)33, (byte)12, (byte)125,
+ };
+
+ // vector used in calculating key schedule (powers of x in GF(256))
+ private static final int[] rcon = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
+ 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 };
+
+ // precomputation tables of calculations for rounds
+ private static final int[] T0 =
+ {
+ 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff,
+ 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102,
+ 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d,
+ 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa,
+ 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 0xecadad41,
+ 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453,
+ 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d,
+ 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
+ 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2,
+ 0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795,
+ 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a,
+ 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df,
+ 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912,
+ 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc,
+ 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7,
+ 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
+ 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040,
+ 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d,
+ 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0,
+ 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed,
+ 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a,
+ 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78,
+ 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080,
+ 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
+ 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020,
+ 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18,
+ 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488,
+ 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a,
+ 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0,
+ 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54,
+ 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b,
+ 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
+ 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992,
+ 0x0a06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd,
+ 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3,
+ 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda,
+ 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8,
+ 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4,
+ 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a,
+ 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
+ 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96,
+ 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c,
+ 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7,
+ 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969,
+ 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9,
+ 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9,
+ 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715,
+ 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
+ 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65,
+ 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929,
+ 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d,
+ 0x3a16162c};
+
+private static final int[] Tinv0 =
+ {
+ 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b,
+ 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad,
+ 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526,
+ 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d,
+ 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03,
+ 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458,
+ 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899,
+ 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d,
+ 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1,
+ 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f,
+ 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3,
+ 0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3,
+ 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a,
+ 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506,
+ 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05,
+ 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd,
+ 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491,
+ 0x055dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6,
+ 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7,
+ 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000,
+ 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd,
+ 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68,
+ 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793, 0xd296eeb4,
+ 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c,
+ 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e,
+ 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af,
+ 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644,
+ 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8,
+ 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85,
+ 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc,
+ 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411,
+ 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322,
+ 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6,
+ 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0x0d927850,
+ 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e,
+ 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf,
+ 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd,
+ 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa,
+ 0x08cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea,
+ 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235,
+ 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1,
+ 0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43,
+ 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1,
+ 0x7f516546, 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb,
+ 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a,
+ 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7,
+ 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418,
+ 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478,
+ 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16,
+ 0x0c25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08,
+ 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48,
+ 0x4257b8d0};
+
+ private static int shift(int r, int shift)
+ {
+ return (r >>> shift) | (r << -shift);
+ }
+
+ /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
+
+ private static final int m1 = 0x80808080;
+ private static final int m2 = 0x7f7f7f7f;
+ private static final int m3 = 0x0000001b;
+ private static final int m4 = 0xC0C0C0C0;
+ private static final int m5 = 0x3f3f3f3f;
+
+ private static int FFmulX(int x)
+ {
+ return (((x & m2) << 1) ^ (((x & m1) >>> 7) * m3));
+ }
+
+ private static int FFmulX2(int x)
+ {
+ int t0 = (x & m5) << 2;
+ int t1 = (x & m4);
+ t1 ^= (t1 >>> 1);
+ return t0 ^ (t1 >>> 2) ^ (t1 >>> 5);
+ }
+
+ /*
+ The following defines provide alternative definitions of FFmulX that might
+ give improved performance if a fast 32-bit multiply is not available.
+
+ private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); }
+ private static final int m4 = 0x1b1b1b1b;
+ private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); }
+
+ */
+
+ private static int inv_mcol(int x)
+ {
+ int t0, t1;
+ t0 = x;
+ t1 = t0 ^ shift(t0, 8);
+ t0 ^= FFmulX(t1);
+ t1 ^= FFmulX2(t0);
+ t0 ^= t1 ^ shift(t1, 16);
+ return t0;
+ }
+
+ private static int subWord(int x)
+ {
+ return (S[x&255]&255 | ((S[(x>>8)&255]&255)<<8) | ((S[(x>>16)&255]&255)<<16) | S[(x>>24)&255]<<24);
+ }
+
+ /**
+ * Calculate the necessary round keys
+ * The number of calculations depends on key size and block size
+ * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits
+ * This code is written assuming those are the only possible values
+ */
+ private int[][] generateWorkingKey(byte[] key, boolean forEncryption)
+ {
+ int keyLen = key.length;
+ if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0)
+ {
+ throw new IllegalArgumentException("Key length not 128/192/256 bits.");
+ }
+
+ int KC = keyLen >>> 2;
+ ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes
+ int[][] W = new int[ROUNDS+1][4]; // 4 words in a block
+
+ switch (KC)
+ {
+ case 4:
+ {
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
+
+ for (int i = 1; i <= 10; ++i)
+ {
+ int colx = subWord(shift(col3, 8)) ^ rcon[i - 1];
+ col0 ^= colx; W[i][0] = col0;
+ col1 ^= col0; W[i][1] = col1;
+ col2 ^= col1; W[i][2] = col2;
+ col3 ^= col2; W[i][3] = col3;
+ }
+
+ break;
+ }
+ case 6:
+ {
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
+
+ int col4 = Pack.littleEndianToInt(key, 16);
+ int col5 = Pack.littleEndianToInt(key, 20);
+
+ int i = 1, rcon = 1, colx;
+ for (;;)
+ {
+ W[i ][0] = col4;
+ W[i ][1] = col5;
+ colx = subWord(shift(col5, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i ][2] = col0;
+ col1 ^= col0; W[i ][3] = col1;
+
+ col2 ^= col1; W[i + 1][0] = col2;
+ col3 ^= col2; W[i + 1][1] = col3;
+ col4 ^= col3; W[i + 1][2] = col4;
+ col5 ^= col4; W[i + 1][3] = col5;
+
+ colx = subWord(shift(col5, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i + 2][0] = col0;
+ col1 ^= col0; W[i + 2][1] = col1;
+ col2 ^= col1; W[i + 2][2] = col2;
+ col3 ^= col2; W[i + 2][3] = col3;
+
+ if ((i += 3) >= 13)
+ {
+ break;
+ }
+
+ col4 ^= col3;
+ col5 ^= col4;
+ }
+
+ break;
+ }
+ case 8:
+ {
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
+
+ int col4 = Pack.littleEndianToInt(key, 16); W[1][0] = col4;
+ int col5 = Pack.littleEndianToInt(key, 20); W[1][1] = col5;
+ int col6 = Pack.littleEndianToInt(key, 24); W[1][2] = col6;
+ int col7 = Pack.littleEndianToInt(key, 28); W[1][3] = col7;
+
+ int i = 2, rcon = 1, colx;
+ for (;;)
+ {
+ colx = subWord(shift(col7, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i][0] = col0;
+ col1 ^= col0; W[i][1] = col1;
+ col2 ^= col1; W[i][2] = col2;
+ col3 ^= col2; W[i][3] = col3;
+ ++i;
+
+ if (i >= 15)
+ {
+ break;
+ }
+
+ colx = subWord(col3);
+ col4 ^= colx; W[i][0] = col4;
+ col5 ^= col4; W[i][1] = col5;
+ col6 ^= col5; W[i][2] = col6;
+ col7 ^= col6; W[i][3] = col7;
+ ++i;
+ }
+
+ break;
+ }
+ default:
+ {
+ throw new IllegalStateException("Should never get here");
+ }
+ }
+
+ if (!forEncryption)
+ {
+ for (int j = 1; j < ROUNDS; j++)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ W[j][i] = inv_mcol(W[j][i]);
+ }
+ }
+ }
+
+ return W;
+ }
+
+ private int ROUNDS;
+ private int[][] WorkingKey = null;
+ private int C0, C1, C2, C3;
+ private boolean forEncryption;
+
+ private byte[] s;
+
+ private static final int BLOCK_SIZE = 16;
+
+ /**
+ * default constructor - 128 bit block size.
+ */
+ public AESEngine()
+ {
+ }
+
+ /**
+ * initialise an AES cipher.
+ *
+ * @param forEncryption whether or not we are for encryption.
+ * @param params the parameters required to set up the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean forEncryption,
+ CipherParameters params)
+ {
+ if (params instanceof KeyParameter)
+ {
+ WorkingKey = generateWorkingKey(((KeyParameter)params).getKey(), forEncryption);
+ this.forEncryption = forEncryption;
+ if (forEncryption)
+ {
+ s = Arrays.clone(S);
+ }
+ else
+ {
+ s = Arrays.clone(Si);
+ }
+ return;
+ }
+
+ throw new IllegalArgumentException("invalid parameter passed to AES init - " + params.getClass().getName());
+ }
+
+ public String getAlgorithmName()
+ {
+ return "AES";
+ }
+
+ public int getBlockSize()
+ {
+ return BLOCK_SIZE;
+ }
+
+ public int processBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ {
+ if (WorkingKey == null)
+ {
+ throw new IllegalStateException("AES engine not initialised");
+ }
+
+ if ((inOff + (32 / 2)) > in.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+
+ if ((outOff + (32 / 2)) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ if (forEncryption)
+ {
+ unpackBlock(in, inOff);
+ encryptBlock(WorkingKey);
+ packBlock(out, outOff);
+ }
+ else
+ {
+ unpackBlock(in, inOff);
+ decryptBlock(WorkingKey);
+ packBlock(out, outOff);
+ }
+
+ return BLOCK_SIZE;
+ }
+
+ public void reset()
+ {
+ }
+
+ private void unpackBlock(
+ byte[] bytes,
+ int off)
+ {
+ int index = off;
+
+ C0 = (bytes[index++] & 0xff);
+ C0 |= (bytes[index++] & 0xff) << 8;
+ C0 |= (bytes[index++] & 0xff) << 16;
+ C0 |= bytes[index++] << 24;
+
+ C1 = (bytes[index++] & 0xff);
+ C1 |= (bytes[index++] & 0xff) << 8;
+ C1 |= (bytes[index++] & 0xff) << 16;
+ C1 |= bytes[index++] << 24;
+
+ C2 = (bytes[index++] & 0xff);
+ C2 |= (bytes[index++] & 0xff) << 8;
+ C2 |= (bytes[index++] & 0xff) << 16;
+ C2 |= bytes[index++] << 24;
+
+ C3 = (bytes[index++] & 0xff);
+ C3 |= (bytes[index++] & 0xff) << 8;
+ C3 |= (bytes[index++] & 0xff) << 16;
+ C3 |= bytes[index++] << 24;
+ }
+
+ private void packBlock(
+ byte[] bytes,
+ int off)
+ {
+ int index = off;
+
+ bytes[index++] = (byte)C0;
+ bytes[index++] = (byte)(C0 >> 8);
+ bytes[index++] = (byte)(C0 >> 16);
+ bytes[index++] = (byte)(C0 >> 24);
+
+ bytes[index++] = (byte)C1;
+ bytes[index++] = (byte)(C1 >> 8);
+ bytes[index++] = (byte)(C1 >> 16);
+ bytes[index++] = (byte)(C1 >> 24);
+
+ bytes[index++] = (byte)C2;
+ bytes[index++] = (byte)(C2 >> 8);
+ bytes[index++] = (byte)(C2 >> 16);
+ bytes[index++] = (byte)(C2 >> 24);
+
+ bytes[index++] = (byte)C3;
+ bytes[index++] = (byte)(C3 >> 8);
+ bytes[index++] = (byte)(C3 >> 16);
+ bytes[index++] = (byte)(C3 >> 24);
+ }
+
+
+ private void encryptBlock(int[][] KW)
+ {
+ int t0 = this.C0 ^ KW[0][0];
+ int t1 = this.C1 ^ KW[0][1];
+ int t2 = this.C2 ^ KW[0][2];
+
+ int r = 1, r0, r1, r2, r3 = this.C3 ^ KW[0][3];
+ while (r < ROUNDS - 1)
+ {
+ r0 = T0[t0&255] ^ shift(T0[(t1>>8)&255], 24) ^ shift(T0[(t2>>16)&255], 16) ^ shift(T0[(r3>>24)&255], 8) ^ KW[r][0];
+ r1 = T0[t1&255] ^ shift(T0[(t2>>8)&255], 24) ^ shift(T0[(r3>>16)&255], 16) ^ shift(T0[(t0>>24)&255], 8) ^ KW[r][1];
+ r2 = T0[t2&255] ^ shift(T0[(r3>>8)&255], 24) ^ shift(T0[(t0>>16)&255], 16) ^ shift(T0[(t1>>24)&255], 8) ^ KW[r][2];
+ r3 = T0[r3&255] ^ shift(T0[(t0>>8)&255], 24) ^ shift(T0[(t1>>16)&255], 16) ^ shift(T0[(t2>>24)&255], 8) ^ KW[r++][3];
+ t0 = T0[r0&255] ^ shift(T0[(r1>>8)&255], 24) ^ shift(T0[(r2>>16)&255], 16) ^ shift(T0[(r3>>24)&255], 8) ^ KW[r][0];
+ t1 = T0[r1&255] ^ shift(T0[(r2>>8)&255], 24) ^ shift(T0[(r3>>16)&255], 16) ^ shift(T0[(r0>>24)&255], 8) ^ KW[r][1];
+ t2 = T0[r2&255] ^ shift(T0[(r3>>8)&255], 24) ^ shift(T0[(r0>>16)&255], 16) ^ shift(T0[(r1>>24)&255], 8) ^ KW[r][2];
+ r3 = T0[r3&255] ^ shift(T0[(r0>>8)&255], 24) ^ shift(T0[(r1>>16)&255], 16) ^ shift(T0[(r2>>24)&255], 8) ^ KW[r++][3];
+ }
+
+ r0 = T0[t0&255] ^ shift(T0[(t1>>8)&255], 24) ^ shift(T0[(t2>>16)&255], 16) ^ shift(T0[(r3>>24)&255], 8) ^ KW[r][0];
+ r1 = T0[t1&255] ^ shift(T0[(t2>>8)&255], 24) ^ shift(T0[(r3>>16)&255], 16) ^ shift(T0[(t0>>24)&255], 8) ^ KW[r][1];
+ r2 = T0[t2&255] ^ shift(T0[(r3>>8)&255], 24) ^ shift(T0[(t0>>16)&255], 16) ^ shift(T0[(t1>>24)&255], 8) ^ KW[r][2];
+ r3 = T0[r3&255] ^ shift(T0[(t0>>8)&255], 24) ^ shift(T0[(t1>>16)&255], 16) ^ shift(T0[(t2>>24)&255], 8) ^ KW[r++][3];
+
+ // the final round's table is a simple function of S so we don't use a whole other four tables for it
+
+ this.C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[r][0];
+ this.C1 = (s[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[r][1];
+ this.C2 = (s[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2];
+ this.C3 = (s[r3&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3];
+ }
+
+ private void decryptBlock(int[][] KW)
+ {
+ int t0 = this.C0 ^ KW[ROUNDS][0];
+ int t1 = this.C1 ^ KW[ROUNDS][1];
+ int t2 = this.C2 ^ KW[ROUNDS][2];
+
+ int r = ROUNDS - 1, r0, r1, r2, r3 = this.C3 ^ KW[ROUNDS][3];
+ while (r > 1)
+ {
+ r0 = Tinv0[t0&255] ^ shift(Tinv0[(r3>>8)&255], 24) ^ shift(Tinv0[(t2>>16)&255], 16) ^ shift(Tinv0[(t1>>24)&255], 8) ^ KW[r][0];
+ r1 = Tinv0[t1&255] ^ shift(Tinv0[(t0>>8)&255], 24) ^ shift(Tinv0[(r3>>16)&255], 16) ^ shift(Tinv0[(t2>>24)&255], 8) ^ KW[r][1];
+ r2 = Tinv0[t2&255] ^ shift(Tinv0[(t1>>8)&255], 24) ^ shift(Tinv0[(t0>>16)&255], 16) ^ shift(Tinv0[(r3>>24)&255], 8) ^ KW[r][2];
+ r3 = Tinv0[r3&255] ^ shift(Tinv0[(t2>>8)&255], 24) ^ shift(Tinv0[(t1>>16)&255], 16) ^ shift(Tinv0[(t0>>24)&255], 8) ^ KW[r--][3];
+ t0 = Tinv0[r0&255] ^ shift(Tinv0[(r3>>8)&255], 24) ^ shift(Tinv0[(r2>>16)&255], 16) ^ shift(Tinv0[(r1>>24)&255], 8) ^ KW[r][0];
+ t1 = Tinv0[r1&255] ^ shift(Tinv0[(r0>>8)&255], 24) ^ shift(Tinv0[(r3>>16)&255], 16) ^ shift(Tinv0[(r2>>24)&255], 8) ^ KW[r][1];
+ t2 = Tinv0[r2&255] ^ shift(Tinv0[(r1>>8)&255], 24) ^ shift(Tinv0[(r0>>16)&255], 16) ^ shift(Tinv0[(r3>>24)&255], 8) ^ KW[r][2];
+ r3 = Tinv0[r3&255] ^ shift(Tinv0[(r2>>8)&255], 24) ^ shift(Tinv0[(r1>>16)&255], 16) ^ shift(Tinv0[(r0>>24)&255], 8) ^ KW[r--][3];
+ }
+
+ r0 = Tinv0[t0&255] ^ shift(Tinv0[(r3>>8)&255], 24) ^ shift(Tinv0[(t2>>16)&255], 16) ^ shift(Tinv0[(t1>>24)&255], 8) ^ KW[r][0];
+ r1 = Tinv0[t1&255] ^ shift(Tinv0[(t0>>8)&255], 24) ^ shift(Tinv0[(r3>>16)&255], 16) ^ shift(Tinv0[(t2>>24)&255], 8) ^ KW[r][1];
+ r2 = Tinv0[t2&255] ^ shift(Tinv0[(t1>>8)&255], 24) ^ shift(Tinv0[(t0>>16)&255], 16) ^ shift(Tinv0[(r3>>24)&255], 8) ^ KW[r][2];
+ r3 = Tinv0[r3&255] ^ shift(Tinv0[(t2>>8)&255], 24) ^ shift(Tinv0[(t1>>16)&255], 16) ^ shift(Tinv0[(t0>>24)&255], 8) ^ KW[r][3];
+
+ // the final round's table is a simple function of Si so we don't use a whole other four tables for it
+
+ this.C0 = (Si[r0&255]&255) ^ ((s[(r3>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0];
+ this.C1 = (s[r1&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (s[(r2>>24)&255]<<24) ^ KW[0][1];
+ this.C2 = (s[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[0][2];
+ this.C3 = (Si[r3&255]&255) ^ ((s[(r2>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[0][3];
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESFastEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESFastEngine.java
new file mode 100644
index 00000000..71345c14
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESFastEngine.java
@@ -0,0 +1,1011 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * an implementation of the AES (Rijndael), from FIPS-197.
+ * <p>
+ * For further details see: <a href="https://csrc.nist.gov/encryption/aes/">https://csrc.nist.gov/encryption/aes/</a>.
+ *
+ * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at
+ * <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
+ *
+ * There are three levels of tradeoff of speed vs memory
+ * Because java has no preprocessor, they are written as three separate classes from which to choose
+ *
+ * The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption
+ * and 4 for decryption.
+ *
+ * The middle performance version uses only one 256 word table for each, for a total of 2Kbytes,
+ * adding 12 rotate operations per round to compute the values contained in the other tables from
+ * the contents of the first
+ *
+ * The slowest version uses no static tables at all and computes the values in each round
+ * </p>
+ * <p>
+ * This file contains the fast version with 8Kbytes of static tables for round precomputation.
+ * </p>
+ * @deprecated unfortunately this class is has a few side channel issues. In an environment where encryption/decryption may be closely observed it should not be used.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AESFastEngine
+ implements BlockCipher
+{
+ // The S box
+ private static final byte[] S = {
+ (byte)99, (byte)124, (byte)119, (byte)123, (byte)242, (byte)107, (byte)111, (byte)197,
+ (byte)48, (byte)1, (byte)103, (byte)43, (byte)254, (byte)215, (byte)171, (byte)118,
+ (byte)202, (byte)130, (byte)201, (byte)125, (byte)250, (byte)89, (byte)71, (byte)240,
+ (byte)173, (byte)212, (byte)162, (byte)175, (byte)156, (byte)164, (byte)114, (byte)192,
+ (byte)183, (byte)253, (byte)147, (byte)38, (byte)54, (byte)63, (byte)247, (byte)204,
+ (byte)52, (byte)165, (byte)229, (byte)241, (byte)113, (byte)216, (byte)49, (byte)21,
+ (byte)4, (byte)199, (byte)35, (byte)195, (byte)24, (byte)150, (byte)5, (byte)154,
+ (byte)7, (byte)18, (byte)128, (byte)226, (byte)235, (byte)39, (byte)178, (byte)117,
+ (byte)9, (byte)131, (byte)44, (byte)26, (byte)27, (byte)110, (byte)90, (byte)160,
+ (byte)82, (byte)59, (byte)214, (byte)179, (byte)41, (byte)227, (byte)47, (byte)132,
+ (byte)83, (byte)209, (byte)0, (byte)237, (byte)32, (byte)252, (byte)177, (byte)91,
+ (byte)106, (byte)203, (byte)190, (byte)57, (byte)74, (byte)76, (byte)88, (byte)207,
+ (byte)208, (byte)239, (byte)170, (byte)251, (byte)67, (byte)77, (byte)51, (byte)133,
+ (byte)69, (byte)249, (byte)2, (byte)127, (byte)80, (byte)60, (byte)159, (byte)168,
+ (byte)81, (byte)163, (byte)64, (byte)143, (byte)146, (byte)157, (byte)56, (byte)245,
+ (byte)188, (byte)182, (byte)218, (byte)33, (byte)16, (byte)255, (byte)243, (byte)210,
+ (byte)205, (byte)12, (byte)19, (byte)236, (byte)95, (byte)151, (byte)68, (byte)23,
+ (byte)196, (byte)167, (byte)126, (byte)61, (byte)100, (byte)93, (byte)25, (byte)115,
+ (byte)96, (byte)129, (byte)79, (byte)220, (byte)34, (byte)42, (byte)144, (byte)136,
+ (byte)70, (byte)238, (byte)184, (byte)20, (byte)222, (byte)94, (byte)11, (byte)219,
+ (byte)224, (byte)50, (byte)58, (byte)10, (byte)73, (byte)6, (byte)36, (byte)92,
+ (byte)194, (byte)211, (byte)172, (byte)98, (byte)145, (byte)149, (byte)228, (byte)121,
+ (byte)231, (byte)200, (byte)55, (byte)109, (byte)141, (byte)213, (byte)78, (byte)169,
+ (byte)108, (byte)86, (byte)244, (byte)234, (byte)101, (byte)122, (byte)174, (byte)8,
+ (byte)186, (byte)120, (byte)37, (byte)46, (byte)28, (byte)166, (byte)180, (byte)198,
+ (byte)232, (byte)221, (byte)116, (byte)31, (byte)75, (byte)189, (byte)139, (byte)138,
+ (byte)112, (byte)62, (byte)181, (byte)102, (byte)72, (byte)3, (byte)246, (byte)14,
+ (byte)97, (byte)53, (byte)87, (byte)185, (byte)134, (byte)193, (byte)29, (byte)158,
+ (byte)225, (byte)248, (byte)152, (byte)17, (byte)105, (byte)217, (byte)142, (byte)148,
+ (byte)155, (byte)30, (byte)135, (byte)233, (byte)206, (byte)85, (byte)40, (byte)223,
+ (byte)140, (byte)161, (byte)137, (byte)13, (byte)191, (byte)230, (byte)66, (byte)104,
+ (byte)65, (byte)153, (byte)45, (byte)15, (byte)176, (byte)84, (byte)187, (byte)22,
+ };
+
+ // The inverse S-box
+ private static final byte[] Si = {
+ (byte)82, (byte)9, (byte)106, (byte)213, (byte)48, (byte)54, (byte)165, (byte)56,
+ (byte)191, (byte)64, (byte)163, (byte)158, (byte)129, (byte)243, (byte)215, (byte)251,
+ (byte)124, (byte)227, (byte)57, (byte)130, (byte)155, (byte)47, (byte)255, (byte)135,
+ (byte)52, (byte)142, (byte)67, (byte)68, (byte)196, (byte)222, (byte)233, (byte)203,
+ (byte)84, (byte)123, (byte)148, (byte)50, (byte)166, (byte)194, (byte)35, (byte)61,
+ (byte)238, (byte)76, (byte)149, (byte)11, (byte)66, (byte)250, (byte)195, (byte)78,
+ (byte)8, (byte)46, (byte)161, (byte)102, (byte)40, (byte)217, (byte)36, (byte)178,
+ (byte)118, (byte)91, (byte)162, (byte)73, (byte)109, (byte)139, (byte)209, (byte)37,
+ (byte)114, (byte)248, (byte)246, (byte)100, (byte)134, (byte)104, (byte)152, (byte)22,
+ (byte)212, (byte)164, (byte)92, (byte)204, (byte)93, (byte)101, (byte)182, (byte)146,
+ (byte)108, (byte)112, (byte)72, (byte)80, (byte)253, (byte)237, (byte)185, (byte)218,
+ (byte)94, (byte)21, (byte)70, (byte)87, (byte)167, (byte)141, (byte)157, (byte)132,
+ (byte)144, (byte)216, (byte)171, (byte)0, (byte)140, (byte)188, (byte)211, (byte)10,
+ (byte)247, (byte)228, (byte)88, (byte)5, (byte)184, (byte)179, (byte)69, (byte)6,
+ (byte)208, (byte)44, (byte)30, (byte)143, (byte)202, (byte)63, (byte)15, (byte)2,
+ (byte)193, (byte)175, (byte)189, (byte)3, (byte)1, (byte)19, (byte)138, (byte)107,
+ (byte)58, (byte)145, (byte)17, (byte)65, (byte)79, (byte)103, (byte)220, (byte)234,
+ (byte)151, (byte)242, (byte)207, (byte)206, (byte)240, (byte)180, (byte)230, (byte)115,
+ (byte)150, (byte)172, (byte)116, (byte)34, (byte)231, (byte)173, (byte)53, (byte)133,
+ (byte)226, (byte)249, (byte)55, (byte)232, (byte)28, (byte)117, (byte)223, (byte)110,
+ (byte)71, (byte)241, (byte)26, (byte)113, (byte)29, (byte)41, (byte)197, (byte)137,
+ (byte)111, (byte)183, (byte)98, (byte)14, (byte)170, (byte)24, (byte)190, (byte)27,
+ (byte)252, (byte)86, (byte)62, (byte)75, (byte)198, (byte)210, (byte)121, (byte)32,
+ (byte)154, (byte)219, (byte)192, (byte)254, (byte)120, (byte)205, (byte)90, (byte)244,
+ (byte)31, (byte)221, (byte)168, (byte)51, (byte)136, (byte)7, (byte)199, (byte)49,
+ (byte)177, (byte)18, (byte)16, (byte)89, (byte)39, (byte)128, (byte)236, (byte)95,
+ (byte)96, (byte)81, (byte)127, (byte)169, (byte)25, (byte)181, (byte)74, (byte)13,
+ (byte)45, (byte)229, (byte)122, (byte)159, (byte)147, (byte)201, (byte)156, (byte)239,
+ (byte)160, (byte)224, (byte)59, (byte)77, (byte)174, (byte)42, (byte)245, (byte)176,
+ (byte)200, (byte)235, (byte)187, (byte)60, (byte)131, (byte)83, (byte)153, (byte)97,
+ (byte)23, (byte)43, (byte)4, (byte)126, (byte)186, (byte)119, (byte)214, (byte)38,
+ (byte)225, (byte)105, (byte)20, (byte)99, (byte)85, (byte)33, (byte)12, (byte)125,
+ };
+
+ // vector used in calculating key schedule (powers of x in GF(256))
+ private static final int[] rcon = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
+ 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 };
+
+ // precomputation tables of calculations for rounds
+ private static final int[] T =
+ {
+ // T0
+ 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff,
+ 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102,
+ 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d,
+ 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa,
+ 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 0xecadad41,
+ 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453,
+ 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d,
+ 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
+ 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2,
+ 0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795,
+ 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a,
+ 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df,
+ 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912,
+ 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc,
+ 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7,
+ 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
+ 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040,
+ 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d,
+ 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0,
+ 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed,
+ 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a,
+ 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78,
+ 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080,
+ 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
+ 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020,
+ 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18,
+ 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488,
+ 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a,
+ 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0,
+ 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54,
+ 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b,
+ 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
+ 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992,
+ 0x0a06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd,
+ 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3,
+ 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda,
+ 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8,
+ 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4,
+ 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a,
+ 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
+ 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96,
+ 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c,
+ 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7,
+ 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969,
+ 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9,
+ 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9,
+ 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715,
+ 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
+ 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65,
+ 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929,
+ 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d,
+ 0x3a16162c,
+
+ // T1
+ 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d,
+ 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, 0x30306050, 0x01010203,
+ 0x6767cea9, 0x2b2b567d, 0xfefee719, 0xd7d7b562, 0xabab4de6,
+ 0x7676ec9a, 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87,
+ 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, 0xadad41ec,
+ 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7,
+ 0x7272e496, 0xc0c09b5b, 0xb7b775c2, 0xfdfde11c, 0x93933dae,
+ 0x26264c6a, 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f,
+ 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, 0x7171e293,
+ 0xd8d8ab73, 0x31316253, 0x15152a3f, 0x0404080c, 0xc7c79552,
+ 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1, 0x05050a0f,
+ 0x9a9a2fb5, 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d,
+ 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 0x0909121b,
+ 0x83831d9e, 0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2,
+ 0x5a5ab4ee, 0xa0a05bfb, 0x5252a4f6, 0x3b3b764d, 0xd6d6b761,
+ 0xb3b37dce, 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397,
+ 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, 0x20204060,
+ 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, 0x6a6ad4be, 0xcbcb8d46,
+ 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8,
+ 0xcfcf854a, 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16,
+ 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, 0x45458acf,
+ 0xf9f9e910, 0x02020406, 0x7f7ffe81, 0x5050a0f0, 0x3c3c7844,
+ 0x9f9f25ba, 0xa8a84be3, 0x5151a2f3, 0xa3a35dfe, 0x404080c0,
+ 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104,
+ 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030,
+ 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, 0xcdcd814c, 0x0c0c1814,
+ 0x13132635, 0xececc32f, 0x5f5fbee1, 0x979735a2, 0x444488cc,
+ 0x17172e39, 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47,
+ 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, 0x6060c0a0,
+ 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e,
+ 0x90903bab, 0x88880b83, 0x46468cca, 0xeeeec729, 0xb8b86bd3,
+ 0x1414283c, 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76,
+ 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, 0x494992db,
+ 0x06060c0a, 0x2424486c, 0x5c5cb8e4, 0xc2c29f5d, 0xd3d3bd6e,
+ 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, 0xe4e4d337,
+ 0x7979f28b, 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7,
+ 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 0x6c6cd8b4,
+ 0x5656acfa, 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e,
+ 0xaeae47e9, 0x08081018, 0xbaba6fd5, 0x7878f088, 0x25254a6f,
+ 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751,
+ 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, 0x4b4b96dd,
+ 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 0x7070e090, 0x3e3e7c42,
+ 0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x03030605, 0xf6f6f701,
+ 0x0e0e1c12, 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0,
+ 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, 0xe1e1d938,
+ 0xf8f8eb13, 0x98982bb3, 0x11112233, 0x6969d2bb, 0xd9d9a970,
+ 0x8e8e0789, 0x949433a7, 0x9b9b2db6, 0x1e1e3c22, 0x87871592,
+ 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a,
+ 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da,
+ 0xe6e6d731, 0x424284c6, 0x6868d0b8, 0x414182c3, 0x999929b0,
+ 0x2d2d5a77, 0x0f0f1e11, 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6,
+ 0x16162c3a,
+
+ // T2
+ 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2,
+ 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, 0x30605030, 0x01020301,
+ 0x67cea967, 0x2b567d2b, 0xfee719fe, 0xd7b562d7, 0xab4de6ab,
+ 0x76ec9a76, 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d,
+ 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, 0xad41ecad,
+ 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4,
+ 0x72e49672, 0xc09b5bc0, 0xb775c2b7, 0xfde11cfd, 0x933dae93,
+ 0x264c6a26, 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc,
+ 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, 0x71e29371,
+ 0xd8ab73d8, 0x31625331, 0x152a3f15, 0x04080c04, 0xc79552c7,
+ 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196, 0x050a0f05,
+ 0x9a2fb59a, 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2,
+ 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 0x09121b09,
+ 0x831d9e83, 0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e,
+ 0x5ab4ee5a, 0xa05bfba0, 0x52a4f652, 0x3b764d3b, 0xd6b761d6,
+ 0xb37dceb3, 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784,
+ 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, 0x20406020,
+ 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, 0x6ad4be6a, 0xcb8d46cb,
+ 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858,
+ 0xcf854acf, 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb,
+ 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, 0x458acf45,
+ 0xf9e910f9, 0x02040602, 0x7ffe817f, 0x50a0f050, 0x3c78443c,
+ 0x9f25ba9f, 0xa84be3a8, 0x51a2f351, 0xa35dfea3, 0x4080c040,
+ 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5,
+ 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010,
+ 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, 0xcd814ccd, 0x0c18140c,
+ 0x13263513, 0xecc32fec, 0x5fbee15f, 0x9735a297, 0x4488cc44,
+ 0x172e3917, 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d,
+ 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, 0x60c0a060,
+ 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a,
+ 0x903bab90, 0x880b8388, 0x468cca46, 0xeec729ee, 0xb86bd3b8,
+ 0x14283c14, 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db,
+ 0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, 0x4992db49,
+ 0x060c0a06, 0x24486c24, 0x5cb8e45c, 0xc29f5dc2, 0xd3bd6ed3,
+ 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, 0xe4d337e4,
+ 0x79f28b79, 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d,
+ 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 0x6cd8b46c,
+ 0x56acfa56, 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a,
+ 0xae47e9ae, 0x08101808, 0xba6fd5ba, 0x78f08878, 0x254a6f25,
+ 0x2e5c722e, 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6,
+ 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, 0x4b96dd4b,
+ 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 0x70e09070, 0x3e7c423e,
+ 0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x03060503, 0xf6f701f6,
+ 0x0e1c120e, 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9,
+ 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, 0xe1d938e1,
+ 0xf8eb13f8, 0x982bb398, 0x11223311, 0x69d2bb69, 0xd9a970d9,
+ 0x8e07898e, 0x9433a794, 0x9b2db69b, 0x1e3c221e, 0x87159287,
+ 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf,
+ 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf,
+ 0xe6d731e6, 0x4284c642, 0x68d0b868, 0x4182c341, 0x9929b099,
+ 0x2d5a772d, 0x0f1e110f, 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb,
+ 0x162c3a16,
+
+ // T3
+ 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2,
+ 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, 0x60503030, 0x02030101,
+ 0xcea96767, 0x567d2b2b, 0xe719fefe, 0xb562d7d7, 0x4de6abab,
+ 0xec9a7676, 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d,
+ 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, 0x41ecadad,
+ 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4,
+ 0xe4967272, 0x9b5bc0c0, 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393,
+ 0x4c6a2626, 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc,
+ 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, 0xe2937171,
+ 0xab73d8d8, 0x62533131, 0x2a3f1515, 0x080c0404, 0x9552c7c7,
+ 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696, 0x0a0f0505,
+ 0x2fb59a9a, 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2,
+ 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 0x121b0909,
+ 0x1d9e8383, 0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e,
+ 0xb4ee5a5a, 0x5bfba0a0, 0xa4f65252, 0x764d3b3b, 0xb761d6d6,
+ 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484,
+ 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, 0x40602020,
+ 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, 0xd4be6a6a, 0x8d46cbcb,
+ 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858,
+ 0x854acfcf, 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb,
+ 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, 0x8acf4545,
+ 0xe910f9f9, 0x04060202, 0xfe817f7f, 0xa0f05050, 0x78443c3c,
+ 0x25ba9f9f, 0x4be3a8a8, 0xa2f35151, 0x5dfea3a3, 0x80c04040,
+ 0x058a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5,
+ 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010,
+ 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, 0x814ccdcd, 0x18140c0c,
+ 0x26351313, 0xc32fecec, 0xbee15f5f, 0x35a29797, 0x88cc4444,
+ 0x2e391717, 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d,
+ 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, 0xc0a06060,
+ 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a,
+ 0x3bab9090, 0x0b838888, 0x8cca4646, 0xc729eeee, 0x6bd3b8b8,
+ 0x283c1414, 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb,
+ 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, 0x92db4949,
+ 0x0c0a0606, 0x486c2424, 0xb8e45c5c, 0x9f5dc2c2, 0xbd6ed3d3,
+ 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, 0xd337e4e4,
+ 0xf28b7979, 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d,
+ 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 0xd8b46c6c,
+ 0xacfa5656, 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a,
+ 0x47e9aeae, 0x10180808, 0x6fd5baba, 0xf0887878, 0x4a6f2525,
+ 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6,
+ 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, 0x96dd4b4b,
+ 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, 0xe0907070, 0x7c423e3e,
+ 0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x06050303, 0xf701f6f6,
+ 0x1c120e0e, 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9,
+ 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, 0xd938e1e1,
+ 0xeb13f8f8, 0x2bb39898, 0x22331111, 0xd2bb6969, 0xa970d9d9,
+ 0x07898e8e, 0x33a79494, 0x2db69b9b, 0x3c221e1e, 0x15928787,
+ 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf,
+ 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf,
+ 0xd731e6e6, 0x84c64242, 0xd0b86868, 0x82c34141, 0x29b09999,
+ 0x5a772d2d, 0x1e110f0f, 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb,
+ 0x2c3a1616};
+
+ private static final int[] Tinv =
+ {
+ // Tinv0
+ 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b,
+ 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad,
+ 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526,
+ 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d,
+ 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03,
+ 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458,
+ 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899,
+ 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d,
+ 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1,
+ 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f,
+ 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3,
+ 0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3,
+ 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a,
+ 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506,
+ 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05,
+ 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd,
+ 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491,
+ 0x055dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6,
+ 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7,
+ 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000,
+ 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd,
+ 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68,
+ 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793, 0xd296eeb4,
+ 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c,
+ 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e,
+ 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af,
+ 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644,
+ 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8,
+ 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85,
+ 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc,
+ 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411,
+ 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322,
+ 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6,
+ 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0x0d927850,
+ 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e,
+ 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf,
+ 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd,
+ 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa,
+ 0x08cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea,
+ 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235,
+ 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1,
+ 0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43,
+ 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1,
+ 0x7f516546, 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb,
+ 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a,
+ 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7,
+ 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418,
+ 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478,
+ 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16,
+ 0x0c25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08,
+ 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48,
+ 0x4257b8d0,
+
+ // Tinv1
+ 0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, 0x6bab3bcb,
+ 0x459d1ff1, 0x58faacab, 0x03e34b93, 0xfa302055, 0x6d76adf6,
+ 0x76cc8891, 0x4c02f525, 0xd7e54ffc, 0xcb2ac5d7, 0x44352680,
+ 0xa362b58f, 0x5ab1de49, 0x1bba2567, 0x0eea4598, 0xc0fe5de1,
+ 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, 0x5f8f03e7,
+ 0x9c921595, 0x7a6dbfeb, 0x595295da, 0x83bed42d, 0x217458d3,
+ 0x69e04929, 0xc8c98e44, 0x89c2756a, 0x798ef478, 0x3e58996b,
+ 0x71b927dd, 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4,
+ 0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, 0x7764b1e0,
+ 0xae6bbb84, 0xa081fe1c, 0x2b08f994, 0x68487058, 0xfd458f19,
+ 0x6cde9487, 0xf87b52b7, 0xd373ab23, 0x024b72e2, 0x8f1fe357,
+ 0xab55662a, 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x0837d3a5,
+ 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, 0x1ccf8a2b,
+ 0xb479a792, 0xf207f3f0, 0xe2694ea1, 0xf4da65cd, 0xbe0506d5,
+ 0x6234d11f, 0xfea6c48a, 0x532e349d, 0x55f3a2a0, 0xe18a0532,
+ 0xebf6a475, 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51,
+ 0x8a213ef9, 0x06dd963d, 0x053eddae, 0xbde64d46, 0x8d5491b5,
+ 0x5dc47105, 0xd406046f, 0x155060ff, 0xfb981924, 0xe9bdd697,
+ 0x434089cc, 0x9ed96777, 0x42e8b0bd, 0x8b890788, 0x5b19e738,
+ 0xeec879db, 0x0a7ca147, 0x0f427ce9, 0x1e84f8c9, 0x00000000,
+ 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, 0xff0efdfb,
+ 0x38850f56, 0xd5ae3d1e, 0x392d3627, 0xd90f0a64, 0xa65c6821,
+ 0x545b9bd1, 0x2e36243a, 0x670a0cb1, 0xe757930f, 0x96eeb4d2,
+ 0x919b1b9e, 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16,
+ 0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, 0x0d090e0b,
+ 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, 0x19f15785, 0x0775af4c,
+ 0xdd99eebb, 0x607fa3fd, 0x2601f79f, 0xf5725cbc, 0x3b6644c5,
+ 0x7efb5b34, 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863,
+ 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, 0x244a857d,
+ 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, 0x2f9e1d4b, 0x30b2dcf3,
+ 0x52860dec, 0xe3c177d0, 0x16b32b6c, 0xb970a999, 0x489411fa,
+ 0x64e94722, 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef,
+ 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0x0bd49836, 0x81f5a6cf,
+ 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, 0x9d3a2ce4, 0x9278500d,
+ 0xcc5f6a9b, 0x467e5462, 0x138df6c2, 0xb8d890e8, 0xf7392e5e,
+ 0xafc382f5, 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3,
+ 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, 0x7826cd09,
+ 0x18596ef4, 0xb79aec01, 0x9a4f83a8, 0x6e95e665, 0xe6ffaa7e,
+ 0xcfbc2108, 0xe815efe6, 0x9be7bad9, 0x366f4ace, 0x099fead4,
+ 0x7cb029d6, 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0,
+ 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, 0x9804f14a,
+ 0xdaec41f7, 0x50cd7f0e, 0xf691172f, 0xd64d768d, 0xb0ef434d,
+ 0x4daacc54, 0x0496e4df, 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8,
+ 0x5165467f, 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e,
+ 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, 0x61d79a8c,
+ 0x0ca1377a, 0x14f8598e, 0x3c13eb89, 0x27a9ceee, 0xc961b735,
+ 0xe51ce1ed, 0xb1477a3c, 0xdfd29c59, 0x73f2553f, 0xce141879,
+ 0x37c773bf, 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886,
+ 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, 0xc31d1672,
+ 0x25e2bc0c, 0x493c288b, 0x950dff41, 0x01a83971, 0xb30c08de,
+ 0xe4b4d89c, 0xc1566490, 0x84cb7b61, 0xb632d570, 0x5c6c4874,
+ 0x57b8d042,
+
+ // Tinv2
+ 0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, 0xab3bcb6b,
+ 0x9d1ff145, 0xfaacab58, 0xe34b9303, 0x302055fa, 0x76adf66d,
+ 0xcc889176, 0x02f5254c, 0xe54ffcd7, 0x2ac5d7cb, 0x35268044,
+ 0x62b58fa3, 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0,
+ 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, 0x8f03e75f,
+ 0x9215959c, 0x6dbfeb7a, 0x5295da59, 0xbed42d83, 0x7458d321,
+ 0xe0492969, 0xc98e44c8, 0xc2756a89, 0x8ef47879, 0x58996b3e,
+ 0xb927dd71, 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a,
+ 0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, 0x64b1e077,
+ 0x6bbb84ae, 0x81fe1ca0, 0x08f9942b, 0x48705868, 0x458f19fd,
+ 0xde94876c, 0x7b52b7f8, 0x73ab23d3, 0x4b72e202, 0x1fe3578f,
+ 0x55662aab, 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508,
+ 0x2830f287, 0xbf23b2a5, 0x0302ba6a, 0x16ed5c82, 0xcf8a2b1c,
+ 0x79a792b4, 0x07f3f0f2, 0x694ea1e2, 0xda65cdf4, 0x0506d5be,
+ 0x34d11f62, 0xa6c48afe, 0x2e349d53, 0xf3a2a055, 0x8a0532e1,
+ 0xf6a475eb, 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110,
+ 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, 0x5491b58d,
+ 0xc471055d, 0x06046fd4, 0x5060ff15, 0x981924fb, 0xbdd697e9,
+ 0x4089cc43, 0xd967779e, 0xe8b0bd42, 0x8907888b, 0x19e7385b,
+ 0xc879dbee, 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x00000000,
+ 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, 0x0efdfbff,
+ 0x850f5638, 0xae3d1ed5, 0x2d362739, 0x0f0a64d9, 0x5c6821a6,
+ 0x5b9bd154, 0x36243a2e, 0x0a0cb167, 0x57930fe7, 0xeeb4d296,
+ 0x9b1b9e91, 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a,
+ 0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, 0x090e0b0d,
+ 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, 0xf1578519, 0x75af4c07,
+ 0x99eebbdd, 0x7fa3fd60, 0x01f79f26, 0x725cbcf5, 0x6644c53b,
+ 0xfb5b347e, 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1,
+ 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, 0x4a857d24,
+ 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, 0x9e1d4b2f, 0xb2dcf330,
+ 0x860dec52, 0xc177d0e3, 0xb32b6c16, 0x70a999b9, 0x9411fa48,
+ 0xe9472264, 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90,
+ 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, 0xf5a6cf81,
+ 0x7aa528de, 0xb7da268e, 0xad3fa4bf, 0x3a2ce49d, 0x78500d92,
+ 0x5f6a9bcc, 0x7e546246, 0x8df6c213, 0xd890e8b8, 0x392e5ef7,
+ 0xc382f5af, 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312,
+ 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, 0x26cd0978,
+ 0x596ef418, 0x9aec01b7, 0x4f83a89a, 0x95e6656e, 0xffaa7ee6,
+ 0xbc2108cf, 0x15efe6e8, 0xe7bad99b, 0x6f4ace36, 0x9fead409,
+ 0xb029d67c, 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066,
+ 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, 0x04f14a98,
+ 0xec41f7da, 0xcd7f0e50, 0x91172ff6, 0x4d768dd6, 0xef434db0,
+ 0xaacc544d, 0x96e4df04, 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f,
+ 0x65467f51, 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41,
+ 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, 0xd79a8c61,
+ 0xa1377a0c, 0xf8598e14, 0x13eb893c, 0xa9ceee27, 0x61b735c9,
+ 0x1ce1ede5, 0x477a3cb1, 0xd29c59df, 0xf2553f73, 0x141879ce,
+ 0xc773bf37, 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db,
+ 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, 0x1d1672c3,
+ 0xe2bc0c25, 0x3c288b49, 0x0dff4195, 0xa8397101, 0x0c08deb3,
+ 0xb4d89ce4, 0x566490c1, 0xcb7b6184, 0x32d570b6, 0x6c48745c,
+ 0xb8d04257,
+
+ // Tinv3
+ 0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, 0x3bcb6bab,
+ 0x1ff1459d, 0xacab58fa, 0x4b9303e3, 0x2055fa30, 0xadf66d76,
+ 0x889176cc, 0xf5254c02, 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435,
+ 0xb58fa362, 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe,
+ 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, 0x03e75f8f,
+ 0x15959c92, 0xbfeb7a6d, 0x95da5952, 0xd42d83be, 0x58d32174,
+ 0x492969e0, 0x8e44c8c9, 0x756a89c2, 0xf478798e, 0x996b3e58,
+ 0x27dd71b9, 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace,
+ 0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, 0xb1e07764,
+ 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, 0x70586848, 0x8f19fd45,
+ 0x94876cde, 0x52b7f87b, 0xab23d373, 0x72e2024b, 0xe3578f1f,
+ 0x662aab55, 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837,
+ 0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216, 0x8a2b1ccf,
+ 0xa792b479, 0xf3f0f207, 0x4ea1e269, 0x65cdf4da, 0x06d5be05,
+ 0xd11f6234, 0xc48afea6, 0x349d532e, 0xa2a055f3, 0x0532e18a,
+ 0xa475ebf6, 0x0b39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e,
+ 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, 0x91b58d54,
+ 0x71055dc4, 0x046fd406, 0x60ff1550, 0x1924fb98, 0xd697e9bd,
+ 0x89cc4340, 0x67779ed9, 0xb0bd42e8, 0x07888b89, 0xe7385b19,
+ 0x79dbeec8, 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000,
+ 0x09838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, 0xfdfbff0e,
+ 0x0f563885, 0x3d1ed5ae, 0x3627392d, 0x0a64d90f, 0x6821a65c,
+ 0x9bd1545b, 0x243a2e36, 0x0cb1670a, 0x930fe757, 0xb4d296ee,
+ 0x1b9e919b, 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12,
+ 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, 0x0e0b0d09,
+ 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, 0x578519f1, 0xaf4c0775,
+ 0xeebbdd99, 0xa3fd607f, 0xf79f2601, 0x5cbcf572, 0x44c53b66,
+ 0x5b347efb, 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4,
+ 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, 0x857d244a,
+ 0xd2f83dbb, 0xae1132f9, 0xc76da129, 0x1d4b2f9e, 0xdcf330b2,
+ 0x0dec5286, 0x77d0e3c1, 0x2b6c16b3, 0xa999b970, 0x11fa4894,
+ 0x472264e9, 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033,
+ 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, 0xa6cf81f5,
+ 0xa528de7a, 0xda268eb7, 0x3fa4bfad, 0x2ce49d3a, 0x500d9278,
+ 0x6a9bcc5f, 0x5462467e, 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739,
+ 0x82f5afc3, 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225,
+ 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, 0xcd097826,
+ 0x6ef41859, 0xec01b79a, 0x83a89a4f, 0xe6656e95, 0xaa7ee6ff,
+ 0x2108cfbc, 0xefe6e815, 0xbad99be7, 0x4ace366f, 0xead4099f,
+ 0x29d67cb0, 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2,
+ 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, 0xf14a9804,
+ 0x41f7daec, 0x7f0e50cd, 0x172ff691, 0x768dd64d, 0x434db0ef,
+ 0xcc544daa, 0xe4df0496, 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c,
+ 0x467f5165, 0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b,
+ 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, 0x9a8c61d7,
+ 0x377a0ca1, 0x598e14f8, 0xeb893c13, 0xceee27a9, 0xb735c961,
+ 0xe1ede51c, 0x7a3cb147, 0x9c59dfd2, 0x553f73f2, 0x1879ce14,
+ 0x73bf37c7, 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44,
+ 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, 0x1672c31d,
+ 0xbc0c25e2, 0x288b493c, 0xff41950d, 0x397101a8, 0x08deb30c,
+ 0xd89ce4b4, 0x6490c156, 0x7b6184cb, 0xd570b632, 0x48745c6c,
+ 0xd04257b8};
+
+ private static int shift(int r, int shift)
+ {
+ return (r >>> shift) | (r << -shift);
+ }
+
+ /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
+
+ private static final int m1 = 0x80808080;
+ private static final int m2 = 0x7f7f7f7f;
+ private static final int m3 = 0x0000001b;
+ private static final int m4 = 0xC0C0C0C0;
+ private static final int m5 = 0x3f3f3f3f;
+
+ private static int FFmulX(int x)
+ {
+ return (((x & m2) << 1) ^ (((x & m1) >>> 7) * m3));
+ }
+
+ private static int FFmulX2(int x)
+ {
+ int t0 = (x & m5) << 2;
+ int t1 = (x & m4);
+ t1 ^= (t1 >>> 1);
+ return t0 ^ (t1 >>> 2) ^ (t1 >>> 5);
+ }
+
+ /*
+ The following defines provide alternative definitions of FFmulX that might
+ give improved performance if a fast 32-bit multiply is not available.
+
+ private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); }
+ private static final int m4 = 0x1b1b1b1b;
+ private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); }
+
+ */
+
+ private static int inv_mcol(int x)
+ {
+ int t0, t1;
+ t0 = x;
+ t1 = t0 ^ shift(t0, 8);
+ t0 ^= FFmulX(t1);
+ t1 ^= FFmulX2(t0);
+ t0 ^= t1 ^ shift(t1, 16);
+ return t0;
+ }
+
+ private static int subWord(int x)
+ {
+ int i0 = x, i1 = x >>> 8, i2 = x >>> 16, i3 = x >>> 24;
+ i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
+ return i0 | i1 << 8 | i2 << 16 | i3 << 24;
+ }
+
+ /**
+ * Calculate the necessary round keys
+ * The number of calculations depends on key size and block size
+ * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits
+ * This code is written assuming those are the only possible values
+ */
+ private int[][] generateWorkingKey(byte[] key, boolean forEncryption)
+ {
+ int keyLen = key.length;
+ if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0)
+ {
+ throw new IllegalArgumentException("Key length not 128/192/256 bits.");
+ }
+
+ int KC = keyLen >>> 2;
+ ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes
+ int[][] W = new int[ROUNDS+1][4]; // 4 words in a block
+
+ switch (KC)
+ {
+ case 4:
+ {
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
+
+ for (int i = 1; i <= 10; ++i)
+ {
+ int colx = subWord(shift(col3, 8)) ^ rcon[i - 1];
+ col0 ^= colx; W[i][0] = col0;
+ col1 ^= col0; W[i][1] = col1;
+ col2 ^= col1; W[i][2] = col2;
+ col3 ^= col2; W[i][3] = col3;
+ }
+
+ break;
+ }
+ case 6:
+ {
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
+
+ int col4 = Pack.littleEndianToInt(key, 16);
+ int col5 = Pack.littleEndianToInt(key, 20);
+
+ int i = 1, rcon = 1, colx;
+ for (;;)
+ {
+ W[i ][0] = col4;
+ W[i ][1] = col5;
+ colx = subWord(shift(col5, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i ][2] = col0;
+ col1 ^= col0; W[i ][3] = col1;
+
+ col2 ^= col1; W[i + 1][0] = col2;
+ col3 ^= col2; W[i + 1][1] = col3;
+ col4 ^= col3; W[i + 1][2] = col4;
+ col5 ^= col4; W[i + 1][3] = col5;
+
+ colx = subWord(shift(col5, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i + 2][0] = col0;
+ col1 ^= col0; W[i + 2][1] = col1;
+ col2 ^= col1; W[i + 2][2] = col2;
+ col3 ^= col2; W[i + 2][3] = col3;
+
+ if ((i += 3) >= 13)
+ {
+ break;
+ }
+
+ col4 ^= col3;
+ col5 ^= col4;
+ }
+
+ break;
+ }
+ case 8:
+ {
+ int col0 = Pack.littleEndianToInt(key, 0); W[0][0] = col0;
+ int col1 = Pack.littleEndianToInt(key, 4); W[0][1] = col1;
+ int col2 = Pack.littleEndianToInt(key, 8); W[0][2] = col2;
+ int col3 = Pack.littleEndianToInt(key, 12); W[0][3] = col3;
+
+ int col4 = Pack.littleEndianToInt(key, 16); W[1][0] = col4;
+ int col5 = Pack.littleEndianToInt(key, 20); W[1][1] = col5;
+ int col6 = Pack.littleEndianToInt(key, 24); W[1][2] = col6;
+ int col7 = Pack.littleEndianToInt(key, 28); W[1][3] = col7;
+
+ int i = 2, rcon = 1, colx;
+ for (;;)
+ {
+ colx = subWord(shift(col7, 8)) ^ rcon; rcon <<= 1;
+ col0 ^= colx; W[i][0] = col0;
+ col1 ^= col0; W[i][1] = col1;
+ col2 ^= col1; W[i][2] = col2;
+ col3 ^= col2; W[i][3] = col3;
+ ++i;
+
+ if (i >= 15)
+ {
+ break;
+ }
+
+ colx = subWord(col3);
+ col4 ^= colx; W[i][0] = col4;
+ col5 ^= col4; W[i][1] = col5;
+ col6 ^= col5; W[i][2] = col6;
+ col7 ^= col6; W[i][3] = col7;
+ ++i;
+ }
+
+ break;
+ }
+ default:
+ {
+ throw new IllegalStateException("Should never get here");
+ }
+ }
+
+ if (!forEncryption)
+ {
+ for (int j = 1; j < ROUNDS; j++)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ W[j][i] = inv_mcol(W[j][i]);
+ }
+ }
+ }
+
+ return W;
+ }
+
+ private int ROUNDS;
+ private int[][] WorkingKey = null;
+ private int C0, C1, C2, C3;
+ private boolean forEncryption;
+
+ private static final int BLOCK_SIZE = 16;
+
+ /**
+ * default constructor - 128 bit block size.
+ */
+ public AESFastEngine()
+ {
+ }
+
+ /**
+ * initialise an AES cipher.
+ *
+ * @param forEncryption whether or not we are for encryption.
+ * @param params the parameters required to set up the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean forEncryption,
+ CipherParameters params)
+ {
+ if (params instanceof KeyParameter)
+ {
+ WorkingKey = generateWorkingKey(((KeyParameter)params).getKey(), forEncryption);
+ this.forEncryption = forEncryption;
+ return;
+ }
+
+ throw new IllegalArgumentException("invalid parameter passed to AES init - " + params.getClass().getName());
+ }
+
+ public String getAlgorithmName()
+ {
+ return "AES";
+ }
+
+ public int getBlockSize()
+ {
+ return BLOCK_SIZE;
+ }
+
+ public int processBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ {
+ if (WorkingKey == null)
+ {
+ throw new IllegalStateException("AES engine not initialised");
+ }
+
+ if ((inOff + (32 / 2)) > in.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+
+ if ((outOff + (32 / 2)) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ unpackBlock(in, inOff);
+
+ if (forEncryption)
+ {
+ encryptBlock(WorkingKey);
+ }
+ else
+ {
+ decryptBlock(WorkingKey);
+ }
+
+ packBlock(out, outOff);
+
+ return BLOCK_SIZE;
+ }
+
+ public void reset()
+ {
+ }
+
+ private void unpackBlock(byte[] bytes, int off)
+ {
+ this.C0 = Pack.littleEndianToInt(bytes, off);
+ this.C1 = Pack.littleEndianToInt(bytes, off + 4);
+ this.C2 = Pack.littleEndianToInt(bytes, off + 8);
+ this.C3 = Pack.littleEndianToInt(bytes, off + 12);
+ }
+
+ private void packBlock(byte[] bytes, int off)
+ {
+ Pack.intToLittleEndian(this.C0, bytes, off);
+ Pack.intToLittleEndian(this.C1, bytes, off + 4);
+ Pack.intToLittleEndian(this.C2, bytes, off + 8);
+ Pack.intToLittleEndian(this.C3, bytes, off + 12);
+ }
+
+ private void encryptBlock(int[][] KW)
+ {
+ int t0 = this.C0 ^ KW[0][0];
+ int t1 = this.C1 ^ KW[0][1];
+ int t2 = this.C2 ^ KW[0][2];
+
+ /*
+ * Fast engine has precomputed rotr(T0, 8/16/24) tables T1/T2/T3.
+ *
+ * Placing all precomputes in one array requires offsets additions for 8/16/24 rotations but
+ * avoids additional array range checks on 3 more arrays (which on HotSpot are more
+ * expensive than the offset additions).
+ */
+ int r = 1, r0, r1, r2, r3 = this.C3 ^ KW[0][3];
+ int i0, i1, i2, i3;
+
+ while (r < ROUNDS - 1)
+ {
+ i0 = t0; i1 = t1 >>> 8; i2 = t2 >>> 16; i3 = r3 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r0 = T[i0] ^ T[256 + i1] ^ T[512 + i2] ^ T[768 + i3] ^ KW[r][0];
+
+ i0 = t1; i1 = t2 >>> 8; i2 = r3 >>> 16; i3 = t0 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r1 = T[i0] ^ T[256 + i1] ^ T[512 + i2] ^ T[768 + i3] ^ KW[r][1];
+
+ i0 = t2; i1 = r3 >>> 8; i2 = t0 >>> 16; i3 = t1 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r2 = T[i0] ^ T[256 + i1] ^ T[512 + i2] ^ T[768 + i3] ^ KW[r][2];
+
+ i0 = r3; i1 = t0 >>> 8; i2 = t1 >>> 16; i3 = t2 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r3 = T[i0] ^ T[256 + i1] ^ T[512 + i2] ^ T[768 + i3] ^ KW[r++][3];
+
+ i0 = r0; i1 = r1 >>> 8; i2 = r2 >>> 16; i3 = r3 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ t0 = T[i0] ^ T[256 + i1] ^ T[512 + i2] ^ T[768 + i3] ^ KW[r][0];
+
+ i0 = r1; i1 = r2 >>> 8; i2 = r3 >>> 16; i3 = r0 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ t1 = T[i0] ^ T[256 + i1] ^ T[512 + i2] ^ T[768 + i3] ^ KW[r][1];
+
+ i0 = r2; i1 = r3 >>> 8; i2 = r0 >>> 16; i3 = r1 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ t2 = T[i0] ^ T[256 + i1] ^ T[512 + i2] ^ T[768 + i3] ^ KW[r][2];
+
+ i0 = r3; i1 = r0 >>> 8; i2 = r1 >>> 16; i3 = r2 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r3 = T[i0] ^ T[256 + i1] ^ T[512 + i2] ^ T[768 + i3] ^ KW[r++][3];
+ }
+
+ i0 = t0; i1 = t1 >>> 8; i2 = t2 >>> 16; i3 = r3 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r0 = T[i0] ^ T[256 + i1] ^ T[512 + i2] ^ T[768 + i3] ^ KW[r][0];
+
+ i0 = t1; i1 = t2 >>> 8; i2 = r3 >>> 16; i3 = t0 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r1 = T[i0] ^ T[256 + i1] ^ T[512 + i2] ^ T[768 + i3] ^ KW[r][1];
+
+ i0 = t2; i1 = r3 >>> 8; i2 = t0 >>> 16; i3 = t1 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r2 = T[i0] ^ T[256 + i1] ^ T[512 + i2] ^ T[768 + i3] ^ KW[r][2];
+
+ i0 = r3; i1 = t0 >>> 8; i2 = t1 >>> 16; i3 = t2 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r3 = T[i0] ^ T[256 + i1] ^ T[512 + i2] ^ T[768 + i3] ^ KW[r++][3];
+
+ // the final round's table is a simple function of S so we don't use a whole other four tables for it
+
+ i0 = r0; i1 = r1 >>> 8; i2 = r2 >>> 16; i3 = r3 >>> 24;
+ i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
+ this.C0 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][0];
+
+ i0 = r1; i1 = r2 >>> 8; i2 = r3 >>> 16; i3 = r0 >>> 24;
+ i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
+ this.C1 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][1];
+
+ i0 = r2; i1 = r3 >>> 8; i2 = r0 >>> 16; i3 = r1 >>> 24;
+ i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
+ this.C2 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][2];
+
+ i0 = r3; i1 = r0 >>> 8; i2 = r1 >>> 16; i3 = r2 >>> 24;
+ i0 = S[i0 & 255] & 255; i1 = S[i1 & 255] & 255; i2 = S[i2 & 255] & 255; i3 = S[i3 & 255] & 255;
+ this.C3 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[r][3];
+ }
+
+ private void decryptBlock(int[][] KW)
+ {
+ int t0 = this.C0 ^ KW[ROUNDS][0];
+ int t1 = this.C1 ^ KW[ROUNDS][1];
+ int t2 = this.C2 ^ KW[ROUNDS][2];
+
+ int r = ROUNDS - 1, r0, r1, r2, r3 = this.C3 ^ KW[ROUNDS][3];
+ int i0, i1, i2, i3;
+
+ while (r > 1)
+ {
+ i0 = t0; i1 = r3 >>> 8; i2 = t2 >>> 16; i3 = t1 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r0 = Tinv[i0] ^ Tinv[256 + i1] ^ Tinv[512 + i2] ^ Tinv[768 + i3] ^ KW[r][0];
+
+ i0 = t1; i1 = t0 >>> 8; i2 = r3 >>> 16; i3 = t2 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r1 = Tinv[i0] ^ Tinv[256 + i1] ^ Tinv[512 + i2] ^ Tinv[768 + i3] ^ KW[r][1];
+
+ i0 = t2; i1 = t1 >>> 8; i2 = t0 >>> 16; i3 = r3 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r2 = Tinv[i0] ^ Tinv[256 + i1] ^ Tinv[512 + i2] ^ Tinv[768 + i3] ^ KW[r][2];
+
+ i0 = r3; i1 = t2 >>> 8; i2 = t1 >>> 16; i3 = t0 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r3 = Tinv[i0] ^ Tinv[256 + i1] ^ Tinv[512 + i2] ^ Tinv[768 + i3] ^ KW[r--][3];
+
+ i0 = r0; i1 = r3 >>> 8; i2 = r2 >>> 16; i3 = r1 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ t0 = Tinv[i0] ^ Tinv[256 + i1] ^ Tinv[512 + i2] ^ Tinv[768 + i3] ^ KW[r][0];
+
+ i0 = r1; i1 = r0 >>> 8; i2 = r3 >>> 16; i3 = r2 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ t1 = Tinv[i0] ^ Tinv[256 + i1] ^ Tinv[512 + i2] ^ Tinv[768 + i3] ^ KW[r][1];
+
+ i0 = r2; i1 = r1 >>> 8; i2 = r0 >>> 16; i3 = r3 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ t2 = Tinv[i0] ^ Tinv[256 + i1] ^ Tinv[512 + i2] ^ Tinv[768 + i3] ^ KW[r][2];
+
+ i0 = r3; i1 = r2 >>> 8; i2 = r1 >>> 16; i3 = r0 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r3 = Tinv[i0] ^ Tinv[256 + i1] ^ Tinv[512 + i2] ^ Tinv[768 + i3] ^ KW[r--][3];
+ }
+
+ i0 = t0; i1 = r3 >>> 8; i2 = t2 >>> 16; i3 = t1 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r0 = Tinv[i0] ^ Tinv[256 + i1] ^ Tinv[512 + i2] ^ Tinv[768 + i3] ^ KW[1][0];
+
+ i0 = t1; i1 = t0 >>> 8; i2 = r3 >>> 16; i3 = t2 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r1 = Tinv[i0] ^ Tinv[256 + i1] ^ Tinv[512 + i2] ^ Tinv[768 + i3] ^ KW[1][1];
+
+ i0 = t2; i1 = t1 >>> 8; i2 = t0 >>> 16; i3 = r3 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r2 = Tinv[i0] ^ Tinv[256 + i1] ^ Tinv[512 + i2] ^ Tinv[768 + i3] ^ KW[1][2];
+
+ i0 = r3; i1 = t2 >>> 8; i2 = t1 >>> 16; i3 = t0 >>> 24;
+ i0 &= 255; i1 &= 255; i2 &= 255; i3 &= 255;
+ r3 = Tinv[i0] ^ Tinv[256 + i1] ^ Tinv[512 + i2] ^ Tinv[768 + i3] ^ KW[1][3];
+
+ // the final round's table is a simple function of Si so we don't use a whole other four tables for it
+
+ i0 = r0; i1 = r3 >>> 8; i2 = r2 >>> 16; i3 = r1 >>> 24;
+ i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
+ this.C0 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][0];
+
+ i0 = r1; i1 = r0 >>> 8; i2 = r3 >>> 16; i3 = r2 >>> 24;
+ i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
+ this.C1 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][1];
+
+ i0 = r2; i1 = r1 >>> 8; i2 = r0 >>> 16; i3 = r3 >>> 24;
+ i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
+ this.C2 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][2];
+
+ i0 = r3; i1 = r2 >>> 8; i2 = r1 >>> 16; i3 = r0 >>> 24;
+ i0 = Si[i0 & 255] & 255; i1 = Si[i1 & 255] & 255; i2 = Si[i2 & 255] & 255; i3 = Si[i3 & 255] & 255;
+ this.C3 = i0 ^ i1 << 8 ^ i2 << 16 ^ i3 << 24 ^ KW[0][3];
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESWrapEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESWrapEngine.java
new file mode 100644
index 00000000..2b45af8c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESWrapEngine.java
@@ -0,0 +1,31 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+/**
+ * an implementation of the AES Key Wrapper from the NIST Key Wrap
+ * Specification.
+ * <p>
+ * For further details see: <a href="https://csrc.nist.gov/encryption/kms/key-wrap.pdf">https://csrc.nist.gov/encryption/kms/key-wrap.pdf</a>.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AESWrapEngine
+ extends RFC3394WrapEngine
+{
+ /**
+ * Create a regular AESWrapEngine specifying the encrypt for wrapping, decrypt for unwrapping.
+ */
+ public AESWrapEngine()
+ {
+ super(new AESEngine());
+ }
+
+ /**
+ * Create an AESWrapEngine where the underlying cipher is set to decrypt for wrapping, encrypt for unwrapping.
+ *
+ * @param useReverseDirection true if underlying cipher should be used in decryption mode, false otherwise.
+ */
+ public AESWrapEngine(boolean useReverseDirection)
+ {
+ super(new AESEngine(), useReverseDirection);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/BlowfishEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/BlowfishEngine.java
new file mode 100644
index 00000000..adbb0d34
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/BlowfishEngine.java
@@ -0,0 +1,580 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+
+/**
+ * A class that provides Blowfish key encryption operations,
+ * such as encoding data and generating keys.
+ * All the algorithms herein are from Applied Cryptography
+ * and implement a simplified cryptography interface.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class BlowfishEngine
+implements BlockCipher
+{
+ private final static int[]
+ KP = {
+ 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
+ 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
+ 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
+ 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
+ 0x9216D5D9, 0x8979FB1B
+ },
+
+ KS0 = {
+ 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
+ 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
+ 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
+ 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
+ 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE,
+ 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
+ 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF,
+ 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
+ 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
+ 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
+ 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE,
+ 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
+ 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E,
+ 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
+ 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
+ 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
+ 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88,
+ 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
+ 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E,
+ 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
+ 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
+ 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
+ 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88,
+ 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
+ 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6,
+ 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
+ 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
+ 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
+ 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA,
+ 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
+ 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F,
+ 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
+ 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
+ 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
+ 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279,
+ 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
+ 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB,
+ 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
+ 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
+ 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
+ 0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0,
+ 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
+ 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790,
+ 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
+ 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
+ 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
+ 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7,
+ 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
+ 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD,
+ 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
+ 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
+ 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
+ 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477,
+ 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
+ 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49,
+ 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
+ 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
+ 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
+ 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41,
+ 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
+ 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
+ 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
+ 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
+ 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
+ },
+
+ KS1 = {
+ 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
+ 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
+ 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
+ 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
+ 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
+ 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
+ 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
+ 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
+ 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
+ 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
+ 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
+ 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
+ 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
+ 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
+ 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
+ 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
+ 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
+ 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
+ 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
+ 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
+ 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
+ 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
+ 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
+ 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
+ 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
+ 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
+ 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
+ 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
+ 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
+ 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
+ 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
+ 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
+ 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
+ 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
+ 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
+ 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
+ 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
+ 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
+ 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
+ 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
+ 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
+ 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
+ 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
+ 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
+ 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
+ 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
+ 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128,
+ 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
+ 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0,
+ 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
+ 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
+ 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
+ 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3,
+ 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
+ 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00,
+ 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
+ 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
+ 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
+ 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735,
+ 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
+ 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9,
+ 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
+ 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
+ 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
+ },
+
+ KS2 = {
+ 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
+ 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
+ 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
+ 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
+ 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
+ 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
+ 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
+ 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
+ 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
+ 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
+ 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
+ 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
+ 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
+ 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
+ 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
+ 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
+ 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
+ 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
+ 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
+ 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
+ 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
+ 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
+ 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
+ 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
+ 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
+ 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
+ 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
+ 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
+ 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37,
+ 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
+ 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804,
+ 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
+ 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
+ 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
+ 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D,
+ 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
+ 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350,
+ 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
+ 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
+ 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
+ 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D,
+ 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
+ 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F,
+ 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
+ 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
+ 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
+ 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2,
+ 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
+ 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E,
+ 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
+ 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
+ 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
+ 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52,
+ 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
+ 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5,
+ 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
+ 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
+ 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
+ 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24,
+ 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
+ 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4,
+ 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
+ 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
+ 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
+ },
+
+ KS3 = {
+ 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
+ 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
+ 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
+ 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
+ 0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
+ 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
+ 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
+ 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
+ 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
+ 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
+ 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9,
+ 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
+ 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593,
+ 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
+ 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
+ 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
+ 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B,
+ 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
+ 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C,
+ 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
+ 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
+ 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
+ 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB,
+ 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
+ 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991,
+ 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
+ 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
+ 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
+ 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE,
+ 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
+ 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5,
+ 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
+ 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
+ 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
+ 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84,
+ 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
+ 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8,
+ 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
+ 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
+ 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
+ 0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
+ 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
+ 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
+ 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
+ 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
+ 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
+ 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
+ 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
+ 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
+ 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
+ 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
+ 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
+ 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
+ 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
+ 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
+ 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
+ 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
+ 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
+ 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
+ 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
+ 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
+ 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
+ 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
+ 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
+ };
+
+ //====================================
+ // Useful constants
+ //====================================
+
+ private static final int ROUNDS = 16;
+ private static final int BLOCK_SIZE = 8; // bytes = 64 bits
+ private static final int SBOX_SK = 256;
+ private static final int P_SZ = ROUNDS+2;
+
+ private final int[] S0, S1, S2, S3; // the s-boxes
+ private final int[] P; // the p-array
+
+ private boolean encrypting = false;
+
+ private byte[] workingKey = null;
+
+ public BlowfishEngine()
+ {
+ S0 = new int[SBOX_SK];
+ S1 = new int[SBOX_SK];
+ S2 = new int[SBOX_SK];
+ S3 = new int[SBOX_SK];
+ P = new int[P_SZ];
+ }
+
+ /**
+ * initialise a Blowfish cipher.
+ *
+ * @param encrypting whether or not we are for encryption.
+ * @param params the parameters required to set up the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean encrypting,
+ CipherParameters params)
+ {
+ if (params instanceof KeyParameter)
+ {
+ this.encrypting = encrypting;
+ this.workingKey = ((KeyParameter)params).getKey();
+ setKey(this.workingKey);
+
+ return;
+ }
+
+ throw new IllegalArgumentException("invalid parameter passed to Blowfish init - " + params.getClass().getName());
+ }
+
+ public String getAlgorithmName()
+ {
+ return "Blowfish";
+ }
+
+ public final int processBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ {
+ if (workingKey == null)
+ {
+ throw new IllegalStateException("Blowfish not initialised");
+ }
+
+ if ((inOff + BLOCK_SIZE) > in.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+
+ if ((outOff + BLOCK_SIZE) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ if (encrypting)
+ {
+ encryptBlock(in, inOff, out, outOff);
+ }
+ else
+ {
+ decryptBlock(in, inOff, out, outOff);
+ }
+
+ return BLOCK_SIZE;
+ }
+
+ public void reset()
+ {
+ }
+
+ public int getBlockSize()
+ {
+ return BLOCK_SIZE;
+ }
+
+ //==================================
+ // Private Implementation
+ //==================================
+
+ private int F(int x)
+ {
+ return (((S0[(x >>> 24)] + S1[(x >>> 16) & 0xff])
+ ^ S2[(x >>> 8) & 0xff]) + S3[x & 0xff]);
+ }
+
+ /**
+ * apply the encryption cycle to each value pair in the table.
+ */
+ private void processTable(
+ int xl,
+ int xr,
+ int[] table)
+ {
+ int size = table.length;
+
+ for (int s = 0; s < size; s += 2)
+ {
+ xl ^= P[0];
+
+ for (int i = 1; i < ROUNDS; i += 2)
+ {
+ xr ^= F(xl) ^ P[i];
+ xl ^= F(xr) ^ P[i + 1];
+ }
+
+ xr ^= P[ROUNDS + 1];
+
+ // suppress LGTM warnings index-out-of-bounds since the loop increments s by 2
+ table[s] = xr;
+ table[s + 1] = xl; // lgtm [java/index-out-of-bounds]
+
+ xr = xl; // end of cycle swap
+ xl = table[s];
+ }
+ }
+
+ private void setKey(byte[] key)
+ {
+ /*
+ * - comments are from _Applied Crypto_, Schneier, p338
+ * please be careful comparing the two, AC numbers the
+ * arrays from 1, the enclosed code from 0.
+ *
+ * (1)
+ * Initialise the S-boxes and the P-array, with a fixed string
+ * This string contains the hexadecimal digits of pi (3.141...)
+ */
+ System.arraycopy(KS0, 0, S0, 0, SBOX_SK);
+ System.arraycopy(KS1, 0, S1, 0, SBOX_SK);
+ System.arraycopy(KS2, 0, S2, 0, SBOX_SK);
+ System.arraycopy(KS3, 0, S3, 0, SBOX_SK);
+
+ System.arraycopy(KP, 0, P, 0, P_SZ);
+
+ /*
+ * (2)
+ * Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with the
+ * second 32-bits of the key, and so on for all bits of the key
+ * (up to P[17]). Repeatedly cycle through the key bits until the
+ * entire P-array has been XOR-ed with the key bits
+ */
+ int keyLength = key.length;
+ int keyIndex = 0;
+
+ for (int i=0; i < P_SZ; i++)
+ {
+ // get the 32 bits of the key, in 4 * 8 bit chunks
+ int data = 0x0000000;
+ for (int j=0; j < 4; j++)
+ {
+ // create a 32 bit block
+ data = (data << 8) | (key[keyIndex++] & 0xff);
+
+ // wrap when we get to the end of the key
+ if (keyIndex >= keyLength)
+ {
+ keyIndex = 0;
+ }
+ }
+ // XOR the newly created 32 bit chunk onto the P-array
+ P[i] ^= data;
+ }
+
+ /*
+ * (3)
+ * Encrypt the all-zero string with the Blowfish algorithm, using
+ * the subkeys described in (1) and (2)
+ *
+ * (4)
+ * Replace P1 and P2 with the output of step (3)
+ *
+ * (5)
+ * Encrypt the output of step(3) using the Blowfish algorithm,
+ * with the modified subkeys.
+ *
+ * (6)
+ * Replace P3 and P4 with the output of step (5)
+ *
+ * (7)
+ * Continue the process, replacing all elements of the P-array
+ * and then all four S-boxes in order, with the output of the
+ * continuously changing Blowfish algorithm
+ */
+
+ processTable(0, 0, P);
+ processTable(P[P_SZ - 2], P[P_SZ - 1], S0);
+ processTable(S0[SBOX_SK - 2], S0[SBOX_SK - 1], S1);
+ processTable(S1[SBOX_SK - 2], S1[SBOX_SK - 1], S2);
+ processTable(S2[SBOX_SK - 2], S2[SBOX_SK - 1], S3);
+ }
+
+ /**
+ * Encrypt the given input starting at the given offset and place
+ * the result in the provided buffer starting at the given offset.
+ * The input will be an exact multiple of our blocksize.
+ */
+ private void encryptBlock(
+ byte[] src,
+ int srcIndex,
+ byte[] dst,
+ int dstIndex)
+ {
+ int xl = BytesTo32bits(src, srcIndex);
+ int xr = BytesTo32bits(src, srcIndex+4);
+
+ xl ^= P[0];
+
+ for (int i = 1; i < ROUNDS; i += 2)
+ {
+ xr ^= F(xl) ^ P[i];
+ xl ^= F(xr) ^ P[i + 1];
+ }
+
+ xr ^= P[ROUNDS + 1];
+
+ Bits32ToBytes(xr, dst, dstIndex);
+ Bits32ToBytes(xl, dst, dstIndex + 4);
+ }
+
+ /**
+ * Decrypt the given input starting at the given offset and place
+ * the result in the provided buffer starting at the given offset.
+ * The input will be an exact multiple of our blocksize.
+ */
+ private void decryptBlock(
+ byte[] src,
+ int srcIndex,
+ byte[] dst,
+ int dstIndex)
+ {
+ int xl = BytesTo32bits(src, srcIndex);
+ int xr = BytesTo32bits(src, srcIndex + 4);
+
+ xl ^= P[ROUNDS + 1];
+
+ for (int i = ROUNDS; i > 0 ; i -= 2)
+ {
+ xr ^= F(xl) ^ P[i];
+ xl ^= F(xr) ^ P[i - 1];
+ }
+
+ xr ^= P[0];
+
+ Bits32ToBytes(xr, dst, dstIndex);
+ Bits32ToBytes(xl, dst, dstIndex+4);
+ }
+
+ private int BytesTo32bits(byte[] b, int i)
+ {
+ return ((b[i] & 0xff) << 24) |
+ ((b[i+1] & 0xff) << 16) |
+ ((b[i+2] & 0xff) << 8) |
+ ((b[i+3] & 0xff));
+ }
+
+ private void Bits32ToBytes(int in, byte[] b, int offset)
+ {
+ b[offset + 3] = (byte)in;
+ b[offset + 2] = (byte)(in >> 8);
+ b[offset + 1] = (byte)(in >> 16);
+ b[offset] = (byte)(in >> 24);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESEngine.java
new file mode 100644
index 00000000..dbef671b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESEngine.java
@@ -0,0 +1,485 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * a class that provides a basic DES engine.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DESEngine
+ implements BlockCipher
+{
+ protected static final int BLOCK_SIZE = 8;
+
+ private int[] workingKey = null;
+
+ /**
+ * standard constructor.
+ */
+ public DESEngine()
+ {
+ }
+
+ /**
+ * initialise a DES cipher.
+ *
+ * @param encrypting whether or not we are for encryption.
+ * @param params the parameters required to set up the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean encrypting,
+ CipherParameters params)
+ {
+ if (params instanceof KeyParameter)
+ {
+ if (((KeyParameter)params).getKey().length > 8)
+ {
+ throw new IllegalArgumentException("DES key too long - should be 8 bytes");
+ }
+
+ workingKey = generateWorkingKey(encrypting,
+ ((KeyParameter)params).getKey());
+
+ return;
+ }
+
+ throw new IllegalArgumentException("invalid parameter passed to DES init - " + params.getClass().getName());
+ }
+
+ public String getAlgorithmName()
+ {
+ return "DES";
+ }
+
+ public int getBlockSize()
+ {
+ return BLOCK_SIZE;
+ }
+
+ public int processBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ {
+ if (workingKey == null)
+ {
+ throw new IllegalStateException("DES engine not initialised");
+ }
+
+ if ((inOff + BLOCK_SIZE) > in.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+
+ if ((outOff + BLOCK_SIZE) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ desFunc(workingKey, in, inOff, out, outOff);
+
+ return BLOCK_SIZE;
+ }
+
+ public void reset()
+ {
+ }
+
+ /**
+ * what follows is mainly taken from "Applied Cryptography", by
+ * Bruce Schneier, however it also bears great resemblance to Richard
+ * Outerbridge's D3DES...
+ */
+
+// private static final short[] Df_Key =
+// {
+// 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+// 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
+// 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
+// };
+
+ private static final short[] bytebit =
+ {
+ 0200, 0100, 040, 020, 010, 04, 02, 01
+ };
+
+ private static final int[] bigbyte =
+ {
+ 0x800000, 0x400000, 0x200000, 0x100000,
+ 0x80000, 0x40000, 0x20000, 0x10000,
+ 0x8000, 0x4000, 0x2000, 0x1000,
+ 0x800, 0x400, 0x200, 0x100,
+ 0x80, 0x40, 0x20, 0x10,
+ 0x8, 0x4, 0x2, 0x1
+ };
+
+ /*
+ * Use the key schedule specified in the Standard (ANSI X3.92-1981).
+ */
+
+ private static final byte[] pc1 =
+ {
+ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
+ 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
+ 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
+ 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
+ };
+
+ private static final byte[] totrot =
+ {
+ 1, 2, 4, 6, 8, 10, 12, 14,
+ 15, 17, 19, 21, 23, 25, 27, 28
+ };
+
+ private static final byte[] pc2 =
+ {
+ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
+ 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
+ 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
+ 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
+ };
+
+ private static final int[] SP1 = {
+ 0x01010400, 0x00000000, 0x00010000, 0x01010404,
+ 0x01010004, 0x00010404, 0x00000004, 0x00010000,
+ 0x00000400, 0x01010400, 0x01010404, 0x00000400,
+ 0x01000404, 0x01010004, 0x01000000, 0x00000004,
+ 0x00000404, 0x01000400, 0x01000400, 0x00010400,
+ 0x00010400, 0x01010000, 0x01010000, 0x01000404,
+ 0x00010004, 0x01000004, 0x01000004, 0x00010004,
+ 0x00000000, 0x00000404, 0x00010404, 0x01000000,
+ 0x00010000, 0x01010404, 0x00000004, 0x01010000,
+ 0x01010400, 0x01000000, 0x01000000, 0x00000400,
+ 0x01010004, 0x00010000, 0x00010400, 0x01000004,
+ 0x00000400, 0x00000004, 0x01000404, 0x00010404,
+ 0x01010404, 0x00010004, 0x01010000, 0x01000404,
+ 0x01000004, 0x00000404, 0x00010404, 0x01010400,
+ 0x00000404, 0x01000400, 0x01000400, 0x00000000,
+ 0x00010004, 0x00010400, 0x00000000, 0x01010004
+ };
+
+ private static final int[] SP2 = {
+ 0x80108020, 0x80008000, 0x00008000, 0x00108020,
+ 0x00100000, 0x00000020, 0x80100020, 0x80008020,
+ 0x80000020, 0x80108020, 0x80108000, 0x80000000,
+ 0x80008000, 0x00100000, 0x00000020, 0x80100020,
+ 0x00108000, 0x00100020, 0x80008020, 0x00000000,
+ 0x80000000, 0x00008000, 0x00108020, 0x80100000,
+ 0x00100020, 0x80000020, 0x00000000, 0x00108000,
+ 0x00008020, 0x80108000, 0x80100000, 0x00008020,
+ 0x00000000, 0x00108020, 0x80100020, 0x00100000,
+ 0x80008020, 0x80100000, 0x80108000, 0x00008000,
+ 0x80100000, 0x80008000, 0x00000020, 0x80108020,
+ 0x00108020, 0x00000020, 0x00008000, 0x80000000,
+ 0x00008020, 0x80108000, 0x00100000, 0x80000020,
+ 0x00100020, 0x80008020, 0x80000020, 0x00100020,
+ 0x00108000, 0x00000000, 0x80008000, 0x00008020,
+ 0x80000000, 0x80100020, 0x80108020, 0x00108000
+ };
+
+ private static final int[] SP3 = {
+ 0x00000208, 0x08020200, 0x00000000, 0x08020008,
+ 0x08000200, 0x00000000, 0x00020208, 0x08000200,
+ 0x00020008, 0x08000008, 0x08000008, 0x00020000,
+ 0x08020208, 0x00020008, 0x08020000, 0x00000208,
+ 0x08000000, 0x00000008, 0x08020200, 0x00000200,
+ 0x00020200, 0x08020000, 0x08020008, 0x00020208,
+ 0x08000208, 0x00020200, 0x00020000, 0x08000208,
+ 0x00000008, 0x08020208, 0x00000200, 0x08000000,
+ 0x08020200, 0x08000000, 0x00020008, 0x00000208,
+ 0x00020000, 0x08020200, 0x08000200, 0x00000000,
+ 0x00000200, 0x00020008, 0x08020208, 0x08000200,
+ 0x08000008, 0x00000200, 0x00000000, 0x08020008,
+ 0x08000208, 0x00020000, 0x08000000, 0x08020208,
+ 0x00000008, 0x00020208, 0x00020200, 0x08000008,
+ 0x08020000, 0x08000208, 0x00000208, 0x08020000,
+ 0x00020208, 0x00000008, 0x08020008, 0x00020200
+ };
+
+ private static final int[] SP4 = {
+ 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 0x00802080, 0x00800081, 0x00800001, 0x00002001,
+ 0x00000000, 0x00802000, 0x00802000, 0x00802081,
+ 0x00000081, 0x00000000, 0x00800080, 0x00800001,
+ 0x00000001, 0x00002000, 0x00800000, 0x00802001,
+ 0x00000080, 0x00800000, 0x00002001, 0x00002080,
+ 0x00800081, 0x00000001, 0x00002080, 0x00800080,
+ 0x00002000, 0x00802080, 0x00802081, 0x00000081,
+ 0x00800080, 0x00800001, 0x00802000, 0x00802081,
+ 0x00000081, 0x00000000, 0x00000000, 0x00802000,
+ 0x00002080, 0x00800080, 0x00800081, 0x00000001,
+ 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 0x00802081, 0x00000081, 0x00000001, 0x00002000,
+ 0x00800001, 0x00002001, 0x00802080, 0x00800081,
+ 0x00002001, 0x00002080, 0x00800000, 0x00802001,
+ 0x00000080, 0x00800000, 0x00002000, 0x00802080
+ };
+
+ private static final int[] SP5 = {
+ 0x00000100, 0x02080100, 0x02080000, 0x42000100,
+ 0x00080000, 0x00000100, 0x40000000, 0x02080000,
+ 0x40080100, 0x00080000, 0x02000100, 0x40080100,
+ 0x42000100, 0x42080000, 0x00080100, 0x40000000,
+ 0x02000000, 0x40080000, 0x40080000, 0x00000000,
+ 0x40000100, 0x42080100, 0x42080100, 0x02000100,
+ 0x42080000, 0x40000100, 0x00000000, 0x42000000,
+ 0x02080100, 0x02000000, 0x42000000, 0x00080100,
+ 0x00080000, 0x42000100, 0x00000100, 0x02000000,
+ 0x40000000, 0x02080000, 0x42000100, 0x40080100,
+ 0x02000100, 0x40000000, 0x42080000, 0x02080100,
+ 0x40080100, 0x00000100, 0x02000000, 0x42080000,
+ 0x42080100, 0x00080100, 0x42000000, 0x42080100,
+ 0x02080000, 0x00000000, 0x40080000, 0x42000000,
+ 0x00080100, 0x02000100, 0x40000100, 0x00080000,
+ 0x00000000, 0x40080000, 0x02080100, 0x40000100
+ };
+
+ private static final int[] SP6 = {
+ 0x20000010, 0x20400000, 0x00004000, 0x20404010,
+ 0x20400000, 0x00000010, 0x20404010, 0x00400000,
+ 0x20004000, 0x00404010, 0x00400000, 0x20000010,
+ 0x00400010, 0x20004000, 0x20000000, 0x00004010,
+ 0x00000000, 0x00400010, 0x20004010, 0x00004000,
+ 0x00404000, 0x20004010, 0x00000010, 0x20400010,
+ 0x20400010, 0x00000000, 0x00404010, 0x20404000,
+ 0x00004010, 0x00404000, 0x20404000, 0x20000000,
+ 0x20004000, 0x00000010, 0x20400010, 0x00404000,
+ 0x20404010, 0x00400000, 0x00004010, 0x20000010,
+ 0x00400000, 0x20004000, 0x20000000, 0x00004010,
+ 0x20000010, 0x20404010, 0x00404000, 0x20400000,
+ 0x00404010, 0x20404000, 0x00000000, 0x20400010,
+ 0x00000010, 0x00004000, 0x20400000, 0x00404010,
+ 0x00004000, 0x00400010, 0x20004010, 0x00000000,
+ 0x20404000, 0x20000000, 0x00400010, 0x20004010
+ };
+
+ private static final int[] SP7 = {
+ 0x00200000, 0x04200002, 0x04000802, 0x00000000,
+ 0x00000800, 0x04000802, 0x00200802, 0x04200800,
+ 0x04200802, 0x00200000, 0x00000000, 0x04000002,
+ 0x00000002, 0x04000000, 0x04200002, 0x00000802,
+ 0x04000800, 0x00200802, 0x00200002, 0x04000800,
+ 0x04000002, 0x04200000, 0x04200800, 0x00200002,
+ 0x04200000, 0x00000800, 0x00000802, 0x04200802,
+ 0x00200800, 0x00000002, 0x04000000, 0x00200800,
+ 0x04000000, 0x00200800, 0x00200000, 0x04000802,
+ 0x04000802, 0x04200002, 0x04200002, 0x00000002,
+ 0x00200002, 0x04000000, 0x04000800, 0x00200000,
+ 0x04200800, 0x00000802, 0x00200802, 0x04200800,
+ 0x00000802, 0x04000002, 0x04200802, 0x04200000,
+ 0x00200800, 0x00000000, 0x00000002, 0x04200802,
+ 0x00000000, 0x00200802, 0x04200000, 0x00000800,
+ 0x04000002, 0x04000800, 0x00000800, 0x00200002
+ };
+
+ private static final int[] SP8 = {
+ 0x10001040, 0x00001000, 0x00040000, 0x10041040,
+ 0x10000000, 0x10001040, 0x00000040, 0x10000000,
+ 0x00040040, 0x10040000, 0x10041040, 0x00041000,
+ 0x10041000, 0x00041040, 0x00001000, 0x00000040,
+ 0x10040000, 0x10000040, 0x10001000, 0x00001040,
+ 0x00041000, 0x00040040, 0x10040040, 0x10041000,
+ 0x00001040, 0x00000000, 0x00000000, 0x10040040,
+ 0x10000040, 0x10001000, 0x00041040, 0x00040000,
+ 0x00041040, 0x00040000, 0x10041000, 0x00001000,
+ 0x00000040, 0x10040040, 0x00001000, 0x00041040,
+ 0x10001000, 0x00000040, 0x10000040, 0x10040000,
+ 0x10040040, 0x10000000, 0x00040000, 0x10001040,
+ 0x00000000, 0x10041040, 0x00040040, 0x10000040,
+ 0x10040000, 0x10001000, 0x10001040, 0x00000000,
+ 0x10041040, 0x00041000, 0x00041000, 0x00001040,
+ 0x00001040, 0x00040040, 0x10000000, 0x10041000
+ };
+
+ /**
+ * generate an integer based working key based on our secret key
+ * and what we processing we are planning to do.
+ *
+ * Acknowledgements for this routine go to James Gillogly &amp; Phil Karn.
+ * (whoever, and wherever they are!).
+ */
+ protected int[] generateWorkingKey(
+ boolean encrypting,
+ byte[] key)
+ {
+ int[] newKey = new int[32];
+ boolean[] pc1m = new boolean[56],
+ pcr = new boolean[56];
+
+ for (int j = 0; j < 56; j++)
+ {
+ int l = pc1[j];
+
+ pc1m[j] = ((key[l >>> 3] & bytebit[l & 07]) != 0);
+ }
+
+ for (int i = 0; i < 16; i++)
+ {
+ int l, m, n;
+
+ if (encrypting)
+ {
+ m = i << 1;
+ }
+ else
+ {
+ m = (15 - i) << 1;
+ }
+
+ n = m + 1;
+ newKey[m] = newKey[n] = 0;
+
+ for (int j = 0; j < 28; j++)
+ {
+ l = j + totrot[i];
+ if (l < 28)
+ {
+ pcr[j] = pc1m[l];
+ }
+ else
+ {
+ pcr[j] = pc1m[l - 28];
+ }
+ }
+
+ for (int j = 28; j < 56; j++)
+ {
+ l = j + totrot[i];
+ if (l < 56)
+ {
+ pcr[j] = pc1m[l];
+ }
+ else
+ {
+ pcr[j] = pc1m[l - 28];
+ }
+ }
+
+ for (int j = 0; j < 24; j++)
+ {
+ if (pcr[pc2[j]])
+ {
+ newKey[m] |= bigbyte[j];
+ }
+
+ if (pcr[pc2[j + 24]])
+ {
+ newKey[n] |= bigbyte[j];
+ }
+ }
+ }
+
+ //
+ // store the processed key
+ //
+ for (int i = 0; i != 32; i += 2)
+ {
+ int i1, i2;
+
+ i1 = newKey[i];
+ i2 = newKey[i + 1];
+
+ newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10)
+ | ((i2 & 0x00fc0000) >>> 10) | ((i2 & 0x00000fc0) >>> 6);
+
+ newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16)
+ | ((i2 & 0x0003f000) >>> 4) | (i2 & 0x0000003f);
+ }
+
+ return newKey;
+ }
+
+ /**
+ * the DES engine.
+ */
+ protected void desFunc(
+ int[] wKey,
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ {
+ int work, right, left;
+
+ left = Pack.bigEndianToInt(in, inOff);
+ right = Pack.bigEndianToInt(in, inOff + 4);
+
+ work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
+ right ^= work;
+ left ^= (work << 4);
+ work = ((left >>> 16) ^ right) & 0x0000ffff;
+ right ^= work;
+ left ^= (work << 16);
+ work = ((right >>> 2) ^ left) & 0x33333333;
+ left ^= work;
+ right ^= (work << 2);
+ work = ((right >>> 8) ^ left) & 0x00ff00ff;
+ left ^= work;
+ right ^= (work << 8);
+ right = (right << 1) | (right >>> 31);
+ work = (left ^ right) & 0xaaaaaaaa;
+ left ^= work;
+ right ^= work;
+ left = (left << 1) | (left >>> 31);
+
+ for (int round = 0; round < 8; round++)
+ {
+ int fval;
+
+ work = (right << 28) | (right >>> 4);
+ work ^= wKey[round * 4 + 0];
+ fval = SP7[ work & 0x3f];
+ fval |= SP5[(work >>> 8) & 0x3f];
+ fval |= SP3[(work >>> 16) & 0x3f];
+ fval |= SP1[(work >>> 24) & 0x3f];
+ work = right ^ wKey[round * 4 + 1];
+ fval |= SP8[ work & 0x3f];
+ fval |= SP6[(work >>> 8) & 0x3f];
+ fval |= SP4[(work >>> 16) & 0x3f];
+ fval |= SP2[(work >>> 24) & 0x3f];
+ left ^= fval;
+ work = (left << 28) | (left >>> 4);
+ work ^= wKey[round * 4 + 2];
+ fval = SP7[ work & 0x3f];
+ fval |= SP5[(work >>> 8) & 0x3f];
+ fval |= SP3[(work >>> 16) & 0x3f];
+ fval |= SP1[(work >>> 24) & 0x3f];
+ work = left ^ wKey[round * 4 + 3];
+ fval |= SP8[ work & 0x3f];
+ fval |= SP6[(work >>> 8) & 0x3f];
+ fval |= SP4[(work >>> 16) & 0x3f];
+ fval |= SP2[(work >>> 24) & 0x3f];
+ right ^= fval;
+ }
+
+ right = (right << 31) | (right >>> 1);
+ work = (left ^ right) & 0xaaaaaaaa;
+ left ^= work;
+ right ^= work;
+ left = (left << 31) | (left >>> 1);
+ work = ((left >>> 8) ^ right) & 0x00ff00ff;
+ right ^= work;
+ left ^= (work << 8);
+ work = ((left >>> 2) ^ right) & 0x33333333;
+ right ^= work;
+ left ^= (work << 2);
+ work = ((right >>> 16) ^ left) & 0x0000ffff;
+ left ^= work;
+ right ^= (work << 16);
+ work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
+ left ^= work;
+ right ^= (work << 4);
+
+ Pack.intToBigEndian(right, out, outOff);
+ Pack.intToBigEndian(left, out, outOff + 4);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeEngine.java
new file mode 100644
index 00000000..7fa0b9ff
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeEngine.java
@@ -0,0 +1,129 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+
+/**
+ * a class that provides a basic DESede (or Triple DES) engine.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DESedeEngine
+ extends DESEngine
+{
+ protected static final int BLOCK_SIZE = 8;
+
+ private int[] workingKey1 = null;
+ private int[] workingKey2 = null;
+ private int[] workingKey3 = null;
+
+ private boolean forEncryption;
+
+ /**
+ * standard constructor.
+ */
+ public DESedeEngine()
+ {
+ }
+
+ /**
+ * initialise a DESede cipher.
+ *
+ * @param encrypting whether or not we are for encryption.
+ * @param params the parameters required to set up the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean encrypting,
+ CipherParameters params)
+ {
+ if (!(params instanceof KeyParameter))
+ {
+ throw new IllegalArgumentException("invalid parameter passed to DESede init - " + params.getClass().getName());
+ }
+
+ byte[] keyMaster = ((KeyParameter)params).getKey();
+
+ if (keyMaster.length != 24 && keyMaster.length != 16)
+ {
+ throw new IllegalArgumentException("key size must be 16 or 24 bytes.");
+ }
+
+ this.forEncryption = encrypting;
+
+ byte[] key1 = new byte[8];
+ System.arraycopy(keyMaster, 0, key1, 0, key1.length);
+ workingKey1 = generateWorkingKey(encrypting, key1);
+
+ byte[] key2 = new byte[8];
+ System.arraycopy(keyMaster, 8, key2, 0, key2.length);
+ workingKey2 = generateWorkingKey(!encrypting, key2);
+
+ if (keyMaster.length == 24)
+ {
+ byte[] key3 = new byte[8];
+ System.arraycopy(keyMaster, 16, key3, 0, key3.length);
+ workingKey3 = generateWorkingKey(encrypting, key3);
+ }
+ else // 16 byte key
+ {
+ workingKey3 = workingKey1;
+ }
+ }
+
+ public String getAlgorithmName()
+ {
+ return "DESede";
+ }
+
+ public int getBlockSize()
+ {
+ return BLOCK_SIZE;
+ }
+
+ public int processBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ {
+ if (workingKey1 == null)
+ {
+ throw new IllegalStateException("DESede engine not initialised");
+ }
+
+ if ((inOff + BLOCK_SIZE) > in.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+
+ if ((outOff + BLOCK_SIZE) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ byte[] temp = new byte[BLOCK_SIZE];
+
+ if (forEncryption)
+ {
+ desFunc(workingKey1, in, inOff, temp, 0);
+ desFunc(workingKey2, temp, 0, temp, 0);
+ desFunc(workingKey3, temp, 0, out, outOff);
+ }
+ else
+ {
+ desFunc(workingKey3, in, inOff, temp, 0);
+ desFunc(workingKey2, temp, 0, temp, 0);
+ desFunc(workingKey1, temp, 0, out, outOff);
+ }
+
+ return BLOCK_SIZE;
+ }
+
+ public void reset()
+ {
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeWrapEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
new file mode 100644
index 00000000..d3ee6cad
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
@@ -0,0 +1,356 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.Wrapper;
+import com.android.internal.org.bouncycastle.crypto.modes.CBCBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+// Android-changed: Use Android digests
+// import org.bouncycastle.crypto.util.DigestFactory;
+import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Wrap keys according to
+ * <A HREF="https://www.ietf.org/rfc/rfc3217.txt">
+ * RFC 3217</A>.
+ * <p>
+ * Note:
+ * <ul>
+ * <li>if you are using this to wrap triple-des keys you need to set the
+ * parity bits on the key and, if it's a two-key triple-des key, pad it
+ * yourself.
+ * </ul>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DESedeWrapEngine
+ implements Wrapper
+{
+ /** Field engine */
+ private CBCBlockCipher engine;
+
+ /** Field param */
+ private KeyParameter param;
+
+ /** Field paramPlusIV */
+ private ParametersWithIV paramPlusIV;
+
+ /** Field iv */
+ private byte[] iv;
+
+ /** Field forWrapping */
+ private boolean forWrapping;
+
+ /** Field IV2 */
+ private static final byte[] IV2 = { (byte) 0x4a, (byte) 0xdd, (byte) 0xa2,
+ (byte) 0x2c, (byte) 0x79, (byte) 0xe8,
+ (byte) 0x21, (byte) 0x05 };
+
+ //
+ // checksum digest
+ //
+ // Android-changed: Use Android digests
+ // Digest sha1 = DigestFactory.createSHA1();
+ Digest sha1 = AndroidDigestFactory.getSHA1();
+ byte[] digest = new byte[20];
+
+ /**
+ * Method init
+ *
+ * @param forWrapping true if for wrapping, false otherwise.
+ * @param param necessary parameters, may include KeyParameter, ParametersWithRandom, and ParametersWithIV
+ */
+ public void init(boolean forWrapping, CipherParameters param)
+ {
+
+ this.forWrapping = forWrapping;
+ this.engine = new CBCBlockCipher(new DESedeEngine());
+
+ SecureRandom sr;
+ if (param instanceof ParametersWithRandom)
+ {
+ ParametersWithRandom pr = (ParametersWithRandom) param;
+ param = pr.getParameters();
+ sr = pr.getRandom();
+ }
+ else
+ {
+ sr = CryptoServicesRegistrar.getSecureRandom();
+ }
+
+ if (param instanceof KeyParameter)
+ {
+ this.param = (KeyParameter)param;
+
+ if (this.forWrapping)
+ {
+
+ // Hm, we have no IV but we want to wrap ?!?
+ // well, then we have to create our own IV.
+ this.iv = new byte[8];
+ sr.nextBytes(iv);
+
+ this.paramPlusIV = new ParametersWithIV(this.param, this.iv);
+ }
+ }
+ else if (param instanceof ParametersWithIV)
+ {
+ this.paramPlusIV = (ParametersWithIV)param;
+ this.iv = this.paramPlusIV.getIV();
+ this.param = (KeyParameter)this.paramPlusIV.getParameters();
+
+ if (this.forWrapping)
+ {
+ if ((this.iv == null) || (this.iv.length != 8))
+ {
+ throw new IllegalArgumentException("IV is not 8 octets");
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "You should not supply an IV for unwrapping");
+ }
+ }
+ }
+
+ /**
+ * Method getAlgorithmName
+ *
+ * @return the algorithm name "DESede".
+ */
+ public String getAlgorithmName()
+ {
+ return "DESede";
+ }
+
+ /**
+ * Method wrap
+ *
+ * @param in byte array containing the encoded key.
+ * @param inOff off set into in that the data starts at.
+ * @param inLen length of the data.
+ * @return the wrapped bytes.
+ */
+ public byte[] wrap(byte[] in, int inOff, int inLen)
+ {
+ if (!forWrapping)
+ {
+ throw new IllegalStateException("Not initialized for wrapping");
+ }
+
+ byte keyToBeWrapped[] = new byte[inLen];
+
+ System.arraycopy(in, inOff, keyToBeWrapped, 0, inLen);
+
+ // Compute the CMS Key Checksum, (section 5.6.1), call this CKS.
+ byte[] CKS = calculateCMSKeyChecksum(keyToBeWrapped);
+
+ // Let WKCKS = WK || CKS where || is concatenation.
+ byte[] WKCKS = new byte[keyToBeWrapped.length + CKS.length];
+
+ System.arraycopy(keyToBeWrapped, 0, WKCKS, 0, keyToBeWrapped.length);
+ System.arraycopy(CKS, 0, WKCKS, keyToBeWrapped.length, CKS.length);
+
+ // Encrypt WKCKS in CBC mode using KEK as the key and IV as the
+ // initialization vector. Call the results TEMP1.
+
+ int blockSize = engine.getBlockSize();
+
+ if (WKCKS.length % blockSize != 0)
+ {
+ throw new IllegalStateException("Not multiple of block length");
+ }
+
+ engine.init(true, paramPlusIV);
+
+ byte TEMP1[] = new byte[WKCKS.length];
+
+ for (int currentBytePos = 0; currentBytePos != WKCKS.length; currentBytePos += blockSize)
+ {
+ engine.processBlock(WKCKS, currentBytePos, TEMP1, currentBytePos);
+ }
+
+ // Let TEMP2 = IV || TEMP1.
+ byte[] TEMP2 = new byte[this.iv.length + TEMP1.length];
+
+ System.arraycopy(this.iv, 0, TEMP2, 0, this.iv.length);
+ System.arraycopy(TEMP1, 0, TEMP2, this.iv.length, TEMP1.length);
+
+ // Reverse the order of the octets in TEMP2 and call the result TEMP3.
+ byte[] TEMP3 = reverse(TEMP2);
+
+ // Encrypt TEMP3 in CBC mode using the KEK and an initialization vector
+ // of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the desired
+ // result. It is 40 octets long if a 168 bit key is being wrapped.
+ ParametersWithIV param2 = new ParametersWithIV(this.param, IV2);
+
+ this.engine.init(true, param2);
+
+ for (int currentBytePos = 0; currentBytePos != TEMP3.length; currentBytePos += blockSize)
+ {
+ engine.processBlock(TEMP3, currentBytePos, TEMP3, currentBytePos);
+ }
+
+ return TEMP3;
+ }
+
+ /**
+ * Method unwrap
+ *
+ * @param in byte array containing the wrapped key.
+ * @param inOff off set into in that the data starts at.
+ * @param inLen length of the data.
+ * @return the unwrapped bytes.
+ * @throws InvalidCipherTextException
+ */
+ public byte[] unwrap(byte[] in, int inOff, int inLen)
+ throws InvalidCipherTextException
+ {
+ if (forWrapping)
+ {
+ throw new IllegalStateException("Not set for unwrapping");
+ }
+
+ if (in == null)
+ {
+ throw new InvalidCipherTextException("Null pointer as ciphertext");
+ }
+
+ final int blockSize = engine.getBlockSize();
+ if (inLen % blockSize != 0)
+ {
+ throw new InvalidCipherTextException("Ciphertext not multiple of " + blockSize);
+ }
+
+ /*
+ // Check if the length of the cipher text is reasonable given the key
+ // type. It must be 40 bytes for a 168 bit key and either 32, 40, or
+ // 48 bytes for a 128, 192, or 256 bit key. If the length is not supported
+ // or inconsistent with the algorithm for which the key is intended,
+ // return error.
+ //
+ // we do not accept 168 bit keys. it has to be 192 bit.
+ int lengthA = (estimatedKeyLengthInBit / 8) + 16;
+ int lengthB = estimatedKeyLengthInBit % 8;
+
+ if ((lengthA != keyToBeUnwrapped.length) || (lengthB != 0)) {
+ throw new XMLSecurityException("empty");
+ }
+ */
+
+ // Decrypt the cipher text with TRIPLedeS in CBC mode using the KEK
+ // and an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP3.
+ ParametersWithIV param2 = new ParametersWithIV(this.param, IV2);
+
+ this.engine.init(false, param2);
+
+ byte TEMP3[] = new byte[inLen];
+
+ for (int currentBytePos = 0; currentBytePos != inLen; currentBytePos += blockSize)
+ {
+ engine.processBlock(in, inOff + currentBytePos, TEMP3, currentBytePos);
+ }
+
+ // Reverse the order of the octets in TEMP3 and call the result TEMP2.
+ byte[] TEMP2 = reverse(TEMP3);
+
+ // Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets.
+ this.iv = new byte[8];
+
+ byte[] TEMP1 = new byte[TEMP2.length - 8];
+
+ System.arraycopy(TEMP2, 0, this.iv, 0, 8);
+ System.arraycopy(TEMP2, 8, TEMP1, 0, TEMP2.length - 8);
+
+ // Decrypt TEMP1 using TRIPLedeS in CBC mode using the KEK and the IV
+ // found in the previous step. Call the result WKCKS.
+ this.paramPlusIV = new ParametersWithIV(this.param, this.iv);
+
+ this.engine.init(false, this.paramPlusIV);
+
+ byte[] WKCKS = new byte[TEMP1.length];
+
+ for (int currentBytePos = 0; currentBytePos != WKCKS.length; currentBytePos += blockSize)
+ {
+ engine.processBlock(TEMP1, currentBytePos, WKCKS, currentBytePos);
+ }
+
+ // Decompose WKCKS. CKS is the last 8 octets and WK, the wrapped key, are
+ // those octets before the CKS.
+ byte[] result = new byte[WKCKS.length - 8];
+ byte[] CKStoBeVerified = new byte[8];
+
+ System.arraycopy(WKCKS, 0, result, 0, WKCKS.length - 8);
+ System.arraycopy(WKCKS, WKCKS.length - 8, CKStoBeVerified, 0, 8);
+
+ // Calculate a CMS Key Checksum, (section 5.6.1), over the WK and compare
+ // with the CKS extracted in the above step. If they are not equal, return error.
+ if (!checkCMSKeyChecksum(result, CKStoBeVerified))
+ {
+ throw new InvalidCipherTextException(
+ "Checksum inside ciphertext is corrupted");
+ }
+
+ // WK is the wrapped key, now extracted for use in data decryption.
+ return result;
+ }
+
+ /**
+ * Some key wrap algorithms make use of the Key Checksum defined
+ * in CMS [CMS-Algorithms]. This is used to provide an integrity
+ * check value for the key being wrapped. The algorithm is
+ *
+ * - Compute the 20 octet SHA-1 hash on the key being wrapped.
+ * - Use the first 8 octets of this hash as the checksum value.
+ *
+ * For details see https://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum.
+ *
+ * @param key the key to check,
+ * @return the CMS checksum.
+ * @throws RuntimeException
+ */
+ private byte[] calculateCMSKeyChecksum(
+ byte[] key)
+ {
+ byte[] result = new byte[8];
+
+ sha1.update(key, 0, key.length);
+ sha1.doFinal(digest, 0);
+
+ System.arraycopy(digest, 0, result, 0, 8);
+
+ return result;
+ }
+
+ /**
+ * For details see https://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum
+ *
+ * @param key key to be validated.
+ * @param checksum the checksum.
+ * @return true if okay, false otherwise.
+ */
+ private boolean checkCMSKeyChecksum(
+ byte[] key,
+ byte[] checksum)
+ {
+ return Arrays.constantTimeAreEqual(calculateCMSKeyChecksum(key), checksum);
+ }
+
+ private static byte[] reverse(byte[] bs)
+ {
+ byte[] result = new byte[bs.length];
+ for (int i = 0; i < bs.length; i++)
+ {
+ result[i] = bs[bs.length - (i + 1)];
+ }
+ return result;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC2Engine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC2Engine.java
new file mode 100644
index 00000000..997f8547
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC2Engine.java
@@ -0,0 +1,319 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.RC2Parameters;
+
+/**
+ * an implementation of RC2 as described in RFC 2268
+ * "A Description of the RC2(r) Encryption Algorithm" R. Rivest.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RC2Engine
+ implements BlockCipher
+{
+ //
+ // the values we use for key expansion (based on the digits of PI)
+ //
+ private static byte[] piTable =
+ {
+ (byte)0xd9, (byte)0x78, (byte)0xf9, (byte)0xc4, (byte)0x19, (byte)0xdd, (byte)0xb5, (byte)0xed,
+ (byte)0x28, (byte)0xe9, (byte)0xfd, (byte)0x79, (byte)0x4a, (byte)0xa0, (byte)0xd8, (byte)0x9d,
+ (byte)0xc6, (byte)0x7e, (byte)0x37, (byte)0x83, (byte)0x2b, (byte)0x76, (byte)0x53, (byte)0x8e,
+ (byte)0x62, (byte)0x4c, (byte)0x64, (byte)0x88, (byte)0x44, (byte)0x8b, (byte)0xfb, (byte)0xa2,
+ (byte)0x17, (byte)0x9a, (byte)0x59, (byte)0xf5, (byte)0x87, (byte)0xb3, (byte)0x4f, (byte)0x13,
+ (byte)0x61, (byte)0x45, (byte)0x6d, (byte)0x8d, (byte)0x9, (byte)0x81, (byte)0x7d, (byte)0x32,
+ (byte)0xbd, (byte)0x8f, (byte)0x40, (byte)0xeb, (byte)0x86, (byte)0xb7, (byte)0x7b, (byte)0xb,
+ (byte)0xf0, (byte)0x95, (byte)0x21, (byte)0x22, (byte)0x5c, (byte)0x6b, (byte)0x4e, (byte)0x82,
+ (byte)0x54, (byte)0xd6, (byte)0x65, (byte)0x93, (byte)0xce, (byte)0x60, (byte)0xb2, (byte)0x1c,
+ (byte)0x73, (byte)0x56, (byte)0xc0, (byte)0x14, (byte)0xa7, (byte)0x8c, (byte)0xf1, (byte)0xdc,
+ (byte)0x12, (byte)0x75, (byte)0xca, (byte)0x1f, (byte)0x3b, (byte)0xbe, (byte)0xe4, (byte)0xd1,
+ (byte)0x42, (byte)0x3d, (byte)0xd4, (byte)0x30, (byte)0xa3, (byte)0x3c, (byte)0xb6, (byte)0x26,
+ (byte)0x6f, (byte)0xbf, (byte)0xe, (byte)0xda, (byte)0x46, (byte)0x69, (byte)0x7, (byte)0x57,
+ (byte)0x27, (byte)0xf2, (byte)0x1d, (byte)0x9b, (byte)0xbc, (byte)0x94, (byte)0x43, (byte)0x3,
+ (byte)0xf8, (byte)0x11, (byte)0xc7, (byte)0xf6, (byte)0x90, (byte)0xef, (byte)0x3e, (byte)0xe7,
+ (byte)0x6, (byte)0xc3, (byte)0xd5, (byte)0x2f, (byte)0xc8, (byte)0x66, (byte)0x1e, (byte)0xd7,
+ (byte)0x8, (byte)0xe8, (byte)0xea, (byte)0xde, (byte)0x80, (byte)0x52, (byte)0xee, (byte)0xf7,
+ (byte)0x84, (byte)0xaa, (byte)0x72, (byte)0xac, (byte)0x35, (byte)0x4d, (byte)0x6a, (byte)0x2a,
+ (byte)0x96, (byte)0x1a, (byte)0xd2, (byte)0x71, (byte)0x5a, (byte)0x15, (byte)0x49, (byte)0x74,
+ (byte)0x4b, (byte)0x9f, (byte)0xd0, (byte)0x5e, (byte)0x4, (byte)0x18, (byte)0xa4, (byte)0xec,
+ (byte)0xc2, (byte)0xe0, (byte)0x41, (byte)0x6e, (byte)0xf, (byte)0x51, (byte)0xcb, (byte)0xcc,
+ (byte)0x24, (byte)0x91, (byte)0xaf, (byte)0x50, (byte)0xa1, (byte)0xf4, (byte)0x70, (byte)0x39,
+ (byte)0x99, (byte)0x7c, (byte)0x3a, (byte)0x85, (byte)0x23, (byte)0xb8, (byte)0xb4, (byte)0x7a,
+ (byte)0xfc, (byte)0x2, (byte)0x36, (byte)0x5b, (byte)0x25, (byte)0x55, (byte)0x97, (byte)0x31,
+ (byte)0x2d, (byte)0x5d, (byte)0xfa, (byte)0x98, (byte)0xe3, (byte)0x8a, (byte)0x92, (byte)0xae,
+ (byte)0x5, (byte)0xdf, (byte)0x29, (byte)0x10, (byte)0x67, (byte)0x6c, (byte)0xba, (byte)0xc9,
+ (byte)0xd3, (byte)0x0, (byte)0xe6, (byte)0xcf, (byte)0xe1, (byte)0x9e, (byte)0xa8, (byte)0x2c,
+ (byte)0x63, (byte)0x16, (byte)0x1, (byte)0x3f, (byte)0x58, (byte)0xe2, (byte)0x89, (byte)0xa9,
+ (byte)0xd, (byte)0x38, (byte)0x34, (byte)0x1b, (byte)0xab, (byte)0x33, (byte)0xff, (byte)0xb0,
+ (byte)0xbb, (byte)0x48, (byte)0xc, (byte)0x5f, (byte)0xb9, (byte)0xb1, (byte)0xcd, (byte)0x2e,
+ (byte)0xc5, (byte)0xf3, (byte)0xdb, (byte)0x47, (byte)0xe5, (byte)0xa5, (byte)0x9c, (byte)0x77,
+ (byte)0xa, (byte)0xa6, (byte)0x20, (byte)0x68, (byte)0xfe, (byte)0x7f, (byte)0xc1, (byte)0xad
+ };
+
+ private static final int BLOCK_SIZE = 8;
+
+ private int[] workingKey;
+ private boolean encrypting;
+
+ private int[] generateWorkingKey(
+ byte[] key,
+ int bits)
+ {
+ int x;
+ int[] xKey = new int[128];
+
+ for (int i = 0; i != key.length; i++)
+ {
+ xKey[i] = key[i] & 0xff;
+ }
+
+ // Phase 1: Expand input key to 128 bytes
+ int len = key.length;
+
+ if (len < 128)
+ {
+ int index = 0;
+
+ x = xKey[len - 1];
+
+ do
+ {
+ x = piTable[(x + xKey[index++]) & 255] & 0xff;
+ xKey[len++] = x;
+ }
+ while (len < 128);
+ }
+
+ // Phase 2 - reduce effective key size to "bits"
+ len = (bits + 7) >> 3;
+ x = piTable[xKey[128 - len] & (255 >> (7 & -bits))] & 0xff;
+ xKey[128 - len] = x;
+
+ for (int i = 128 - len - 1; i >= 0; i--)
+ {
+ x = piTable[x ^ xKey[i + len]] & 0xff;
+ xKey[i] = x;
+ }
+
+ // Phase 3 - copy to newKey in little-endian order
+ int[] newKey = new int[64];
+
+ for (int i = 0; i != newKey.length; i++)
+ {
+ newKey[i] = (xKey[2 * i] + (xKey[2 * i + 1] << 8));
+ }
+
+ return newKey;
+ }
+
+ /**
+ * initialise a RC2 cipher.
+ *
+ * @param encrypting whether or not we are for encryption.
+ * @param params the parameters required to set up the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean encrypting,
+ CipherParameters params)
+ {
+ this.encrypting = encrypting;
+
+ if (params instanceof RC2Parameters)
+ {
+ RC2Parameters param = (RC2Parameters)params;
+
+ workingKey = generateWorkingKey(param.getKey(),
+ param.getEffectiveKeyBits());
+ }
+ else if (params instanceof KeyParameter)
+ {
+ byte[] key = ((KeyParameter)params).getKey();
+
+ workingKey = generateWorkingKey(key, key.length * 8);
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid parameter passed to RC2 init - " + params.getClass().getName());
+ }
+
+ }
+
+ public void reset()
+ {
+ }
+
+ public String getAlgorithmName()
+ {
+ return "RC2";
+ }
+
+ public int getBlockSize()
+ {
+ return BLOCK_SIZE;
+ }
+
+ public final int processBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ {
+ if (workingKey == null)
+ {
+ throw new IllegalStateException("RC2 engine not initialised");
+ }
+
+ if ((inOff + BLOCK_SIZE) > in.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+
+ if ((outOff + BLOCK_SIZE) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ if (encrypting)
+ {
+ encryptBlock(in, inOff, out, outOff);
+ }
+ else
+ {
+ decryptBlock(in, inOff, out, outOff);
+ }
+
+ return BLOCK_SIZE;
+ }
+
+ /**
+ * return the result rotating the 16 bit number in x left by y
+ */
+ private int rotateWordLeft(
+ int x,
+ int y)
+ {
+ x &= 0xffff;
+ return (x << y) | (x >> (16 - y));
+ }
+
+ private void encryptBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ {
+ int x76, x54, x32, x10;
+
+ x76 = ((in[inOff + 7] & 0xff) << 8) + (in[inOff + 6] & 0xff);
+ x54 = ((in[inOff + 5] & 0xff) << 8) + (in[inOff + 4] & 0xff);
+ x32 = ((in[inOff + 3] & 0xff) << 8) + (in[inOff + 2] & 0xff);
+ x10 = ((in[inOff + 1] & 0xff) << 8) + (in[inOff + 0] & 0xff);
+
+ for (int i = 0; i <= 16; i += 4)
+ {
+ x10 = rotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1);
+ x32 = rotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2);
+ x54 = rotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3);
+ x76 = rotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5);
+ }
+
+ x10 += workingKey[x76 & 63];
+ x32 += workingKey[x10 & 63];
+ x54 += workingKey[x32 & 63];
+ x76 += workingKey[x54 & 63];
+
+ for (int i = 20; i <= 40; i += 4)
+ {
+ x10 = rotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1);
+ x32 = rotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2);
+ x54 = rotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3);
+ x76 = rotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5);
+ }
+
+ x10 += workingKey[x76 & 63];
+ x32 += workingKey[x10 & 63];
+ x54 += workingKey[x32 & 63];
+ x76 += workingKey[x54 & 63];
+
+ for (int i = 44; i < 64; i += 4)
+ {
+ x10 = rotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1);
+ x32 = rotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2);
+ x54 = rotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3);
+ x76 = rotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5);
+ }
+
+ out[outOff + 0] = (byte)x10;
+ out[outOff + 1] = (byte)(x10 >> 8);
+ out[outOff + 2] = (byte)x32;
+ out[outOff + 3] = (byte)(x32 >> 8);
+ out[outOff + 4] = (byte)x54;
+ out[outOff + 5] = (byte)(x54 >> 8);
+ out[outOff + 6] = (byte)x76;
+ out[outOff + 7] = (byte)(x76 >> 8);
+ }
+
+ private void decryptBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ {
+ int x76, x54, x32, x10;
+
+ x76 = ((in[inOff + 7] & 0xff) << 8) + (in[inOff + 6] & 0xff);
+ x54 = ((in[inOff + 5] & 0xff) << 8) + (in[inOff + 4] & 0xff);
+ x32 = ((in[inOff + 3] & 0xff) << 8) + (in[inOff + 2] & 0xff);
+ x10 = ((in[inOff + 1] & 0xff) << 8) + (in[inOff + 0] & 0xff);
+
+ for (int i = 60; i >= 44; i -= 4)
+ {
+ x76 = rotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]);
+ x54 = rotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]);
+ x32 = rotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]);
+ x10 = rotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]);
+ }
+
+ x76 -= workingKey[x54 & 63];
+ x54 -= workingKey[x32 & 63];
+ x32 -= workingKey[x10 & 63];
+ x10 -= workingKey[x76 & 63];
+
+ for (int i = 40; i >= 20; i -= 4)
+ {
+ x76 = rotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]);
+ x54 = rotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]);
+ x32 = rotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]);
+ x10 = rotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]);
+ }
+
+ x76 -= workingKey[x54 & 63];
+ x54 -= workingKey[x32 & 63];
+ x32 -= workingKey[x10 & 63];
+ x10 -= workingKey[x76 & 63];
+
+ for (int i = 16; i >= 0; i -= 4)
+ {
+ x76 = rotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]);
+ x54 = rotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]);
+ x32 = rotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]);
+ x10 = rotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]);
+ }
+
+ out[outOff + 0] = (byte)x10;
+ out[outOff + 1] = (byte)(x10 >> 8);
+ out[outOff + 2] = (byte)x32;
+ out[outOff + 3] = (byte)(x32 >> 8);
+ out[outOff + 4] = (byte)x54;
+ out[outOff + 5] = (byte)(x54 >> 8);
+ out[outOff + 6] = (byte)x76;
+ out[outOff + 7] = (byte)(x76 >> 8);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC4Engine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC4Engine.java
new file mode 100644
index 00000000..02c138cb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RC4Engine.java
@@ -0,0 +1,150 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.StreamCipher;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RC4Engine implements StreamCipher
+{
+ private final static int STATE_LENGTH = 256;
+
+ /*
+ * variables to hold the state of the RC4 engine
+ * during encryption and decryption
+ */
+
+ private byte[] engineState = null;
+ private int x = 0;
+ private int y = 0;
+ private byte[] workingKey = null;
+
+ /**
+ * initialise a RC4 cipher.
+ *
+ * @param forEncryption whether or not we are for encryption.
+ * @param params the parameters required to set up the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean forEncryption,
+ CipherParameters params
+ )
+ {
+ if (params instanceof KeyParameter)
+ {
+ /*
+ * RC4 encryption and decryption is completely
+ * symmetrical, so the 'forEncryption' is
+ * irrelevant.
+ */
+ workingKey = ((KeyParameter)params).getKey();
+ setKey(workingKey);
+
+ return;
+ }
+
+ throw new IllegalArgumentException("invalid parameter passed to RC4 init - " + params.getClass().getName());
+ }
+
+ public String getAlgorithmName()
+ {
+ return "RC4";
+ }
+
+ public byte returnByte(byte in)
+ {
+ x = (x + 1) & 0xff;
+ y = (engineState[x] + y) & 0xff;
+
+ // swap
+ byte tmp = engineState[x];
+ engineState[x] = engineState[y];
+ engineState[y] = tmp;
+
+ // xor
+ return (byte)(in ^ engineState[(engineState[x] + engineState[y]) & 0xff]);
+ }
+
+ public int processBytes(
+ byte[] in,
+ int inOff,
+ int len,
+ byte[] out,
+ int outOff)
+ {
+ if ((inOff + len) > in.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+
+ if ((outOff + len) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ for (int i = 0; i < len ; i++)
+ {
+ x = (x + 1) & 0xff;
+ y = (engineState[x] + y) & 0xff;
+
+ // swap
+ byte tmp = engineState[x];
+ engineState[x] = engineState[y];
+ engineState[y] = tmp;
+
+ // xor
+ out[i+outOff] = (byte)(in[i + inOff]
+ ^ engineState[(engineState[x] + engineState[y]) & 0xff]);
+ }
+
+ return len;
+ }
+
+ public void reset()
+ {
+ setKey(workingKey);
+ }
+
+ // Private implementation
+
+ private void setKey(byte[] keyBytes)
+ {
+ workingKey = keyBytes;
+
+ // System.out.println("the key length is ; "+ workingKey.length);
+
+ x = 0;
+ y = 0;
+
+ if (engineState == null)
+ {
+ engineState = new byte[STATE_LENGTH];
+ }
+
+ // reset the state of the engine
+ for (int i=0; i < STATE_LENGTH; i++)
+ {
+ engineState[i] = (byte)i;
+ }
+
+ int i1 = 0;
+ int i2 = 0;
+
+ for (int i=0; i < STATE_LENGTH; i++)
+ {
+ i2 = ((keyBytes[i1] & 0xff) + engineState[i] + i2) & 0xff;
+ // do the byte-swap inline
+ byte tmp = engineState[i];
+ engineState[i] = engineState[i2];
+ engineState[i2] = tmp;
+ i1 = (i1+1) % keyBytes.length;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
new file mode 100644
index 00000000..ed18b615
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
@@ -0,0 +1,197 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.Wrapper;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * an implementation of the AES Key Wrapper from the NIST Key Wrap
+ * Specification as described in RFC 3394.
+ * <p>
+ * For further details see: <a href="https://www.ietf.org/rfc/rfc3394.txt">https://www.ietf.org/rfc/rfc3394.txt</a>
+ * and <a href="https://csrc.nist.gov/encryption/kms/key-wrap.pdf">https://csrc.nist.gov/encryption/kms/key-wrap.pdf</a>.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RFC3394WrapEngine
+ implements Wrapper
+{
+ private BlockCipher engine;
+ private boolean wrapCipherMode;
+ private KeyParameter param;
+ private boolean forWrapping;
+
+ private byte[] iv = {
+ (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6,
+ (byte)0xa6, (byte)0xa6, (byte)0xa6, (byte)0xa6 };
+
+ /**
+ * Create a RFC 3394 WrapEngine specifying the encrypt for wrapping, decrypt for unwrapping.
+ *
+ * @param engine the block cipher to be used for wrapping.
+ */
+ public RFC3394WrapEngine(BlockCipher engine)
+ {
+ this(engine, false);
+ }
+
+ /**
+ * Create a RFC 3394 WrapEngine specifying the direction for wrapping and unwrapping..
+ *
+ * @param engine the block cipher to be used for wrapping.
+ * @param useReverseDirection true if engine should be used in decryption mode for wrapping, false otherwise.
+ */
+ public RFC3394WrapEngine(BlockCipher engine, boolean useReverseDirection)
+ {
+ this.engine = engine;
+ this.wrapCipherMode = (useReverseDirection) ? false : true;
+ }
+
+ public void init(
+ boolean forWrapping,
+ CipherParameters param)
+ {
+ this.forWrapping = forWrapping;
+
+ if (param instanceof ParametersWithRandom)
+ {
+ param = ((ParametersWithRandom) param).getParameters();
+ }
+
+ if (param instanceof KeyParameter)
+ {
+ this.param = (KeyParameter)param;
+ }
+ else if (param instanceof ParametersWithIV)
+ {
+ this.iv = ((ParametersWithIV)param).getIV();
+ this.param = (KeyParameter)((ParametersWithIV) param).getParameters();
+ if (this.iv.length != 8)
+ {
+ throw new IllegalArgumentException("IV not equal to 8");
+ }
+ }
+ }
+
+ public String getAlgorithmName()
+ {
+ return engine.getAlgorithmName();
+ }
+
+ public byte[] wrap(
+ byte[] in,
+ int inOff,
+ int inLen)
+ {
+ if (!forWrapping)
+ {
+ throw new IllegalStateException("not set for wrapping");
+ }
+
+ int n = inLen / 8;
+
+ if ((n * 8) != inLen)
+ {
+ throw new DataLengthException("wrap data must be a multiple of 8 bytes");
+ }
+
+ byte[] block = new byte[inLen + iv.length];
+ byte[] buf = new byte[8 + iv.length];
+
+ System.arraycopy(iv, 0, block, 0, iv.length);
+ System.arraycopy(in, inOff, block, iv.length, inLen);
+
+ engine.init(wrapCipherMode, param);
+
+ for (int j = 0; j != 6; j++)
+ {
+ for (int i = 1; i <= n; i++)
+ {
+ System.arraycopy(block, 0, buf, 0, iv.length);
+ System.arraycopy(block, 8 * i, buf, iv.length, 8);
+ engine.processBlock(buf, 0, buf, 0);
+
+ int t = n * j + i;
+ for (int k = 1; t != 0; k++)
+ {
+ byte v = (byte)t;
+
+ buf[iv.length - k] ^= v;
+
+ t >>>= 8;
+ }
+
+ System.arraycopy(buf, 0, block, 0, 8);
+ System.arraycopy(buf, 8, block, 8 * i, 8);
+ }
+ }
+
+ return block;
+ }
+
+ public byte[] unwrap(
+ byte[] in,
+ int inOff,
+ int inLen)
+ throws InvalidCipherTextException
+ {
+ if (forWrapping)
+ {
+ throw new IllegalStateException("not set for unwrapping");
+ }
+
+ int n = inLen / 8;
+
+ if ((n * 8) != inLen)
+ {
+ throw new InvalidCipherTextException("unwrap data must be a multiple of 8 bytes");
+ }
+
+ byte[] block = new byte[inLen - iv.length];
+ byte[] a = new byte[iv.length];
+ byte[] buf = new byte[8 + iv.length];
+
+ System.arraycopy(in, inOff, a, 0, iv.length);
+ System.arraycopy(in, inOff + iv.length, block, 0, inLen - iv.length);
+
+ engine.init(!wrapCipherMode, param);
+
+ n = n - 1;
+
+ for (int j = 5; j >= 0; j--)
+ {
+ for (int i = n; i >= 1; i--)
+ {
+ System.arraycopy(a, 0, buf, 0, iv.length);
+ System.arraycopy(block, 8 * (i - 1), buf, iv.length, 8);
+
+ int t = n * j + i;
+ for (int k = 1; t != 0; k++)
+ {
+ byte v = (byte)t;
+
+ buf[iv.length - k] ^= v;
+
+ t >>>= 8;
+ }
+
+ engine.processBlock(buf, 0, buf, 0);
+ System.arraycopy(buf, 0, a, 0, 8);
+ System.arraycopy(buf, 8, block, 8 * (i - 1), 8);
+ }
+ }
+
+ if (!Arrays.constantTimeAreEqual(a, iv))
+ {
+ throw new InvalidCipherTextException("checksum failed");
+ }
+
+ return block;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSABlindedEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSABlindedEngine.java
new file mode 100644
index 00000000..14f6c2fd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSABlindedEngine.java
@@ -0,0 +1,150 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.AsymmetricBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+import com.android.internal.org.bouncycastle.crypto.params.RSAKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * this does your basic RSA algorithm with blinding
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RSABlindedEngine
+ implements AsymmetricBlockCipher
+{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+
+ private RSACoreEngine core = new RSACoreEngine();
+ private RSAKeyParameters key;
+ private SecureRandom random;
+
+ /**
+ * initialise the RSA engine.
+ *
+ * @param forEncryption true if we are encrypting, false otherwise.
+ * @param param the necessary RSA key parameters.
+ */
+ public void init(
+ boolean forEncryption,
+ CipherParameters param)
+ {
+ core.init(forEncryption, param);
+
+ if (param instanceof ParametersWithRandom)
+ {
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
+
+ this.key = (RSAKeyParameters)rParam.getParameters();
+
+ if (key instanceof RSAPrivateCrtKeyParameters)
+ {
+ this.random = rParam.getRandom();
+ }
+ else
+ {
+ this.random = null;
+ }
+ }
+ else
+ {
+ this.key = (RSAKeyParameters)param;
+
+ if (key instanceof RSAPrivateCrtKeyParameters)
+ {
+ this.random = CryptoServicesRegistrar.getSecureRandom();
+ }
+ else
+ {
+ this.random = null;
+ }
+ }
+ }
+
+ /**
+ * Return the maximum size for an input block to this engine.
+ * For RSA this is always one byte less than the key size on
+ * encryption, and the same length as the key size on decryption.
+ *
+ * @return maximum size for an input block.
+ */
+ public int getInputBlockSize()
+ {
+ return core.getInputBlockSize();
+ }
+
+ /**
+ * Return the maximum size for an output block to this engine.
+ * For RSA this is always one byte less than the key size on
+ * decryption, and the same length as the key size on encryption.
+ *
+ * @return maximum size for an output block.
+ */
+ public int getOutputBlockSize()
+ {
+ return core.getOutputBlockSize();
+ }
+
+ /**
+ * Process a single block using the basic RSA algorithm.
+ *
+ * @param in the input array.
+ * @param inOff the offset into the input buffer where the data starts.
+ * @param inLen the length of the data to be processed.
+ * @return the result of the RSA process.
+ * @exception DataLengthException the input block is too large.
+ */
+ public byte[] processBlock(
+ byte[] in,
+ int inOff,
+ int inLen)
+ {
+ if (key == null)
+ {
+ throw new IllegalStateException("RSA engine not initialised");
+ }
+
+ BigInteger input = core.convertInput(in, inOff, inLen);
+
+ BigInteger result;
+ if (key instanceof RSAPrivateCrtKeyParameters)
+ {
+ RSAPrivateCrtKeyParameters k = (RSAPrivateCrtKeyParameters)key;
+
+ BigInteger e = k.getPublicExponent();
+ if (e != null) // can't do blinding without a public exponent
+ {
+ BigInteger m = k.getModulus();
+ BigInteger r = BigIntegers.createRandomInRange(ONE, m.subtract(ONE), random);
+
+ BigInteger blindedInput = r.modPow(e, m).multiply(input).mod(m);
+ BigInteger blindedResult = core.processBlock(blindedInput);
+
+ BigInteger rInv = BigIntegers.modOddInverse(m, r);
+ result = blindedResult.multiply(rInv).mod(m);
+ // defence against Arjen Lenstra’s CRT attack
+ if (!input.equals(result.modPow(e, m)))
+ {
+ throw new IllegalStateException("RSA engine faulty decryption/signing detected");
+ }
+ }
+ else
+ {
+ result = core.processBlock(input);
+ }
+ }
+ else
+ {
+ result = core.processBlock(input);
+ }
+
+ return core.convertOutput(result);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSACoreEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSACoreEngine.java
new file mode 100644
index 00000000..7ab640dd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSACoreEngine.java
@@ -0,0 +1,214 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+import com.android.internal.org.bouncycastle.crypto.params.RSAKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * this does your basic RSA algorithm.
+ */
+class RSACoreEngine
+{
+ private RSAKeyParameters key;
+ private boolean forEncryption;
+
+ /**
+ * initialise the RSA engine.
+ *
+ * @param forEncryption true if we are encrypting, false otherwise.
+ * @param param the necessary RSA key parameters.
+ */
+ public void init(
+ boolean forEncryption,
+ CipherParameters param)
+ {
+ if (param instanceof ParametersWithRandom)
+ {
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
+
+ key = (RSAKeyParameters)rParam.getParameters();
+ }
+ else
+ {
+ key = (RSAKeyParameters)param;
+ }
+
+ this.forEncryption = forEncryption;
+ }
+
+ /**
+ * Return the maximum size for an input block to this engine.
+ * For RSA this is always one byte less than the key size on
+ * encryption, and the same length as the key size on decryption.
+ *
+ * @return maximum size for an input block.
+ */
+ public int getInputBlockSize()
+ {
+ int bitSize = key.getModulus().bitLength();
+
+ if (forEncryption)
+ {
+ return (bitSize + 7) / 8 - 1;
+ }
+ else
+ {
+ return (bitSize + 7) / 8;
+ }
+ }
+
+ /**
+ * Return the maximum size for an output block to this engine.
+ * For RSA this is always one byte less than the key size on
+ * decryption, and the same length as the key size on encryption.
+ *
+ * @return maximum size for an output block.
+ */
+ public int getOutputBlockSize()
+ {
+ int bitSize = key.getModulus().bitLength();
+
+ if (forEncryption)
+ {
+ return (bitSize + 7) / 8;
+ }
+ else
+ {
+ return (bitSize + 7) / 8 - 1;
+ }
+ }
+
+ public BigInteger convertInput(
+ byte[] in,
+ int inOff,
+ int inLen)
+ {
+ if (inLen > (getInputBlockSize() + 1))
+ {
+ throw new DataLengthException("input too large for RSA cipher.");
+ }
+ else if (inLen == (getInputBlockSize() + 1) && !forEncryption)
+ {
+ throw new DataLengthException("input too large for RSA cipher.");
+ }
+
+ byte[] block;
+
+ if (inOff != 0 || inLen != in.length)
+ {
+ block = new byte[inLen];
+
+ System.arraycopy(in, inOff, block, 0, inLen);
+ }
+ else
+ {
+ block = in;
+ }
+
+ BigInteger res = new BigInteger(1, block);
+ if (res.compareTo(key.getModulus()) >= 0)
+ {
+ throw new DataLengthException("input too large for RSA cipher.");
+ }
+
+ return res;
+ }
+
+ public byte[] convertOutput(
+ BigInteger result)
+ {
+ byte[] output = result.toByteArray();
+
+ if (forEncryption)
+ {
+ if (output[0] == 0 && output.length > getOutputBlockSize()) // have ended up with an extra zero byte, copy down.
+ {
+ byte[] tmp = new byte[output.length - 1];
+
+ System.arraycopy(output, 1, tmp, 0, tmp.length);
+
+ return tmp;
+ }
+
+ if (output.length < getOutputBlockSize()) // have ended up with less bytes than normal, lengthen
+ {
+ byte[] tmp = new byte[getOutputBlockSize()];
+
+ System.arraycopy(output, 0, tmp, tmp.length - output.length, output.length);
+
+ return tmp;
+ }
+
+ return output;
+ }
+ else
+ {
+ byte[] rv;
+ if (output[0] == 0) // have ended up with an extra zero byte, copy down.
+ {
+ rv = new byte[output.length - 1];
+
+ System.arraycopy(output, 1, rv, 0, rv.length);
+ }
+ else // maintain decryption time
+ {
+ rv = new byte[output.length];
+
+ System.arraycopy(output, 0, rv, 0, rv.length);
+ }
+
+ Arrays.fill(output, (byte)0);
+
+ return rv;
+ }
+ }
+
+ public BigInteger processBlock(BigInteger input)
+ {
+ if (key instanceof RSAPrivateCrtKeyParameters)
+ {
+ //
+ // we have the extra factors, use the Chinese Remainder Theorem - the author
+ // wishes to express his thanks to Dirk Bonekaemper at rtsffm.com for
+ // advice regarding the expression of this.
+ //
+ RSAPrivateCrtKeyParameters crtKey = (RSAPrivateCrtKeyParameters)key;
+
+ BigInteger p = crtKey.getP();
+ BigInteger q = crtKey.getQ();
+ BigInteger dP = crtKey.getDP();
+ BigInteger dQ = crtKey.getDQ();
+ BigInteger qInv = crtKey.getQInv();
+
+ BigInteger mP, mQ, h, m;
+
+ // mP = ((input mod p) ^ dP)) mod p
+ mP = (input.remainder(p)).modPow(dP, p);
+
+ // mQ = ((input mod q) ^ dQ)) mod q
+ mQ = (input.remainder(q)).modPow(dQ, q);
+
+ // h = qInv * (mP - mQ) mod p
+ h = mP.subtract(mQ);
+ h = h.multiply(qInv);
+ h = h.mod(p); // mod (in Java) returns the positive residual
+
+ // m = h * q + mQ
+ m = h.multiply(q);
+ m = m.add(mQ);
+
+ return m;
+ }
+ else
+ {
+ return input.modPow(
+ key.getExponent(), key.getModulus());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/TwofishEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/TwofishEngine.java
new file mode 100644
index 00000000..e7ba6de1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/TwofishEngine.java
@@ -0,0 +1,682 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.engines;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+
+/**
+ * A class that provides Twofish encryption operations.
+ *
+ * This Java implementation is based on the Java reference
+ * implementation provided by Bruce Schneier and developed
+ * by Raif S. Naffah.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class TwofishEngine
+ implements BlockCipher
+{
+ private static final byte[][] P = {
+ { // p0
+ (byte) 0xA9, (byte) 0x67, (byte) 0xB3, (byte) 0xE8,
+ (byte) 0x04, (byte) 0xFD, (byte) 0xA3, (byte) 0x76,
+ (byte) 0x9A, (byte) 0x92, (byte) 0x80, (byte) 0x78,
+ (byte) 0xE4, (byte) 0xDD, (byte) 0xD1, (byte) 0x38,
+ (byte) 0x0D, (byte) 0xC6, (byte) 0x35, (byte) 0x98,
+ (byte) 0x18, (byte) 0xF7, (byte) 0xEC, (byte) 0x6C,
+ (byte) 0x43, (byte) 0x75, (byte) 0x37, (byte) 0x26,
+ (byte) 0xFA, (byte) 0x13, (byte) 0x94, (byte) 0x48,
+ (byte) 0xF2, (byte) 0xD0, (byte) 0x8B, (byte) 0x30,
+ (byte) 0x84, (byte) 0x54, (byte) 0xDF, (byte) 0x23,
+ (byte) 0x19, (byte) 0x5B, (byte) 0x3D, (byte) 0x59,
+ (byte) 0xF3, (byte) 0xAE, (byte) 0xA2, (byte) 0x82,
+ (byte) 0x63, (byte) 0x01, (byte) 0x83, (byte) 0x2E,
+ (byte) 0xD9, (byte) 0x51, (byte) 0x9B, (byte) 0x7C,
+ (byte) 0xA6, (byte) 0xEB, (byte) 0xA5, (byte) 0xBE,
+ (byte) 0x16, (byte) 0x0C, (byte) 0xE3, (byte) 0x61,
+ (byte) 0xC0, (byte) 0x8C, (byte) 0x3A, (byte) 0xF5,
+ (byte) 0x73, (byte) 0x2C, (byte) 0x25, (byte) 0x0B,
+ (byte) 0xBB, (byte) 0x4E, (byte) 0x89, (byte) 0x6B,
+ (byte) 0x53, (byte) 0x6A, (byte) 0xB4, (byte) 0xF1,
+ (byte) 0xE1, (byte) 0xE6, (byte) 0xBD, (byte) 0x45,
+ (byte) 0xE2, (byte) 0xF4, (byte) 0xB6, (byte) 0x66,
+ (byte) 0xCC, (byte) 0x95, (byte) 0x03, (byte) 0x56,
+ (byte) 0xD4, (byte) 0x1C, (byte) 0x1E, (byte) 0xD7,
+ (byte) 0xFB, (byte) 0xC3, (byte) 0x8E, (byte) 0xB5,
+ (byte) 0xE9, (byte) 0xCF, (byte) 0xBF, (byte) 0xBA,
+ (byte) 0xEA, (byte) 0x77, (byte) 0x39, (byte) 0xAF,
+ (byte) 0x33, (byte) 0xC9, (byte) 0x62, (byte) 0x71,
+ (byte) 0x81, (byte) 0x79, (byte) 0x09, (byte) 0xAD,
+ (byte) 0x24, (byte) 0xCD, (byte) 0xF9, (byte) 0xD8,
+ (byte) 0xE5, (byte) 0xC5, (byte) 0xB9, (byte) 0x4D,
+ (byte) 0x44, (byte) 0x08, (byte) 0x86, (byte) 0xE7,
+ (byte) 0xA1, (byte) 0x1D, (byte) 0xAA, (byte) 0xED,
+ (byte) 0x06, (byte) 0x70, (byte) 0xB2, (byte) 0xD2,
+ (byte) 0x41, (byte) 0x7B, (byte) 0xA0, (byte) 0x11,
+ (byte) 0x31, (byte) 0xC2, (byte) 0x27, (byte) 0x90,
+ (byte) 0x20, (byte) 0xF6, (byte) 0x60, (byte) 0xFF,
+ (byte) 0x96, (byte) 0x5C, (byte) 0xB1, (byte) 0xAB,
+ (byte) 0x9E, (byte) 0x9C, (byte) 0x52, (byte) 0x1B,
+ (byte) 0x5F, (byte) 0x93, (byte) 0x0A, (byte) 0xEF,
+ (byte) 0x91, (byte) 0x85, (byte) 0x49, (byte) 0xEE,
+ (byte) 0x2D, (byte) 0x4F, (byte) 0x8F, (byte) 0x3B,
+ (byte) 0x47, (byte) 0x87, (byte) 0x6D, (byte) 0x46,
+ (byte) 0xD6, (byte) 0x3E, (byte) 0x69, (byte) 0x64,
+ (byte) 0x2A, (byte) 0xCE, (byte) 0xCB, (byte) 0x2F,
+ (byte) 0xFC, (byte) 0x97, (byte) 0x05, (byte) 0x7A,
+ (byte) 0xAC, (byte) 0x7F, (byte) 0xD5, (byte) 0x1A,
+ (byte) 0x4B, (byte) 0x0E, (byte) 0xA7, (byte) 0x5A,
+ (byte) 0x28, (byte) 0x14, (byte) 0x3F, (byte) 0x29,
+ (byte) 0x88, (byte) 0x3C, (byte) 0x4C, (byte) 0x02,
+ (byte) 0xB8, (byte) 0xDA, (byte) 0xB0, (byte) 0x17,
+ (byte) 0x55, (byte) 0x1F, (byte) 0x8A, (byte) 0x7D,
+ (byte) 0x57, (byte) 0xC7, (byte) 0x8D, (byte) 0x74,
+ (byte) 0xB7, (byte) 0xC4, (byte) 0x9F, (byte) 0x72,
+ (byte) 0x7E, (byte) 0x15, (byte) 0x22, (byte) 0x12,
+ (byte) 0x58, (byte) 0x07, (byte) 0x99, (byte) 0x34,
+ (byte) 0x6E, (byte) 0x50, (byte) 0xDE, (byte) 0x68,
+ (byte) 0x65, (byte) 0xBC, (byte) 0xDB, (byte) 0xF8,
+ (byte) 0xC8, (byte) 0xA8, (byte) 0x2B, (byte) 0x40,
+ (byte) 0xDC, (byte) 0xFE, (byte) 0x32, (byte) 0xA4,
+ (byte) 0xCA, (byte) 0x10, (byte) 0x21, (byte) 0xF0,
+ (byte) 0xD3, (byte) 0x5D, (byte) 0x0F, (byte) 0x00,
+ (byte) 0x6F, (byte) 0x9D, (byte) 0x36, (byte) 0x42,
+ (byte) 0x4A, (byte) 0x5E, (byte) 0xC1, (byte) 0xE0 },
+ { // p1
+ (byte) 0x75, (byte) 0xF3, (byte) 0xC6, (byte) 0xF4,
+ (byte) 0xDB, (byte) 0x7B, (byte) 0xFB, (byte) 0xC8,
+ (byte) 0x4A, (byte) 0xD3, (byte) 0xE6, (byte) 0x6B,
+ (byte) 0x45, (byte) 0x7D, (byte) 0xE8, (byte) 0x4B,
+ (byte) 0xD6, (byte) 0x32, (byte) 0xD8, (byte) 0xFD,
+ (byte) 0x37, (byte) 0x71, (byte) 0xF1, (byte) 0xE1,
+ (byte) 0x30, (byte) 0x0F, (byte) 0xF8, (byte) 0x1B,
+ (byte) 0x87, (byte) 0xFA, (byte) 0x06, (byte) 0x3F,
+ (byte) 0x5E, (byte) 0xBA, (byte) 0xAE, (byte) 0x5B,
+ (byte) 0x8A, (byte) 0x00, (byte) 0xBC, (byte) 0x9D,
+ (byte) 0x6D, (byte) 0xC1, (byte) 0xB1, (byte) 0x0E,
+ (byte) 0x80, (byte) 0x5D, (byte) 0xD2, (byte) 0xD5,
+ (byte) 0xA0, (byte) 0x84, (byte) 0x07, (byte) 0x14,
+ (byte) 0xB5, (byte) 0x90, (byte) 0x2C, (byte) 0xA3,
+ (byte) 0xB2, (byte) 0x73, (byte) 0x4C, (byte) 0x54,
+ (byte) 0x92, (byte) 0x74, (byte) 0x36, (byte) 0x51,
+ (byte) 0x38, (byte) 0xB0, (byte) 0xBD, (byte) 0x5A,
+ (byte) 0xFC, (byte) 0x60, (byte) 0x62, (byte) 0x96,
+ (byte) 0x6C, (byte) 0x42, (byte) 0xF7, (byte) 0x10,
+ (byte) 0x7C, (byte) 0x28, (byte) 0x27, (byte) 0x8C,
+ (byte) 0x13, (byte) 0x95, (byte) 0x9C, (byte) 0xC7,
+ (byte) 0x24, (byte) 0x46, (byte) 0x3B, (byte) 0x70,
+ (byte) 0xCA, (byte) 0xE3, (byte) 0x85, (byte) 0xCB,
+ (byte) 0x11, (byte) 0xD0, (byte) 0x93, (byte) 0xB8,
+ (byte) 0xA6, (byte) 0x83, (byte) 0x20, (byte) 0xFF,
+ (byte) 0x9F, (byte) 0x77, (byte) 0xC3, (byte) 0xCC,
+ (byte) 0x03, (byte) 0x6F, (byte) 0x08, (byte) 0xBF,
+ (byte) 0x40, (byte) 0xE7, (byte) 0x2B, (byte) 0xE2,
+ (byte) 0x79, (byte) 0x0C, (byte) 0xAA, (byte) 0x82,
+ (byte) 0x41, (byte) 0x3A, (byte) 0xEA, (byte) 0xB9,
+ (byte) 0xE4, (byte) 0x9A, (byte) 0xA4, (byte) 0x97,
+ (byte) 0x7E, (byte) 0xDA, (byte) 0x7A, (byte) 0x17,
+ (byte) 0x66, (byte) 0x94, (byte) 0xA1, (byte) 0x1D,
+ (byte) 0x3D, (byte) 0xF0, (byte) 0xDE, (byte) 0xB3,
+ (byte) 0x0B, (byte) 0x72, (byte) 0xA7, (byte) 0x1C,
+ (byte) 0xEF, (byte) 0xD1, (byte) 0x53, (byte) 0x3E,
+ (byte) 0x8F, (byte) 0x33, (byte) 0x26, (byte) 0x5F,
+ (byte) 0xEC, (byte) 0x76, (byte) 0x2A, (byte) 0x49,
+ (byte) 0x81, (byte) 0x88, (byte) 0xEE, (byte) 0x21,
+ (byte) 0xC4, (byte) 0x1A, (byte) 0xEB, (byte) 0xD9,
+ (byte) 0xC5, (byte) 0x39, (byte) 0x99, (byte) 0xCD,
+ (byte) 0xAD, (byte) 0x31, (byte) 0x8B, (byte) 0x01,
+ (byte) 0x18, (byte) 0x23, (byte) 0xDD, (byte) 0x1F,
+ (byte) 0x4E, (byte) 0x2D, (byte) 0xF9, (byte) 0x48,
+ (byte) 0x4F, (byte) 0xF2, (byte) 0x65, (byte) 0x8E,
+ (byte) 0x78, (byte) 0x5C, (byte) 0x58, (byte) 0x19,
+ (byte) 0x8D, (byte) 0xE5, (byte) 0x98, (byte) 0x57,
+ (byte) 0x67, (byte) 0x7F, (byte) 0x05, (byte) 0x64,
+ (byte) 0xAF, (byte) 0x63, (byte) 0xB6, (byte) 0xFE,
+ (byte) 0xF5, (byte) 0xB7, (byte) 0x3C, (byte) 0xA5,
+ (byte) 0xCE, (byte) 0xE9, (byte) 0x68, (byte) 0x44,
+ (byte) 0xE0, (byte) 0x4D, (byte) 0x43, (byte) 0x69,
+ (byte) 0x29, (byte) 0x2E, (byte) 0xAC, (byte) 0x15,
+ (byte) 0x59, (byte) 0xA8, (byte) 0x0A, (byte) 0x9E,
+ (byte) 0x6E, (byte) 0x47, (byte) 0xDF, (byte) 0x34,
+ (byte) 0x35, (byte) 0x6A, (byte) 0xCF, (byte) 0xDC,
+ (byte) 0x22, (byte) 0xC9, (byte) 0xC0, (byte) 0x9B,
+ (byte) 0x89, (byte) 0xD4, (byte) 0xED, (byte) 0xAB,
+ (byte) 0x12, (byte) 0xA2, (byte) 0x0D, (byte) 0x52,
+ (byte) 0xBB, (byte) 0x02, (byte) 0x2F, (byte) 0xA9,
+ (byte) 0xD7, (byte) 0x61, (byte) 0x1E, (byte) 0xB4,
+ (byte) 0x50, (byte) 0x04, (byte) 0xF6, (byte) 0xC2,
+ (byte) 0x16, (byte) 0x25, (byte) 0x86, (byte) 0x56,
+ (byte) 0x55, (byte) 0x09, (byte) 0xBE, (byte) 0x91 }
+ };
+
+ /**
+ * Define the fixed p0/p1 permutations used in keyed S-box lookup.
+ * By changing the following constant definitions, the S-boxes will
+ * automatically get changed in the Twofish engine.
+ */
+ private static final int P_00 = 1;
+ private static final int P_01 = 0;
+ private static final int P_02 = 0;
+ private static final int P_03 = P_01 ^ 1;
+ private static final int P_04 = 1;
+
+ private static final int P_10 = 0;
+ private static final int P_11 = 0;
+ private static final int P_12 = 1;
+ private static final int P_13 = P_11 ^ 1;
+ private static final int P_14 = 0;
+
+ private static final int P_20 = 1;
+ private static final int P_21 = 1;
+ private static final int P_22 = 0;
+ private static final int P_23 = P_21 ^ 1;
+ private static final int P_24 = 0;
+
+ private static final int P_30 = 0;
+ private static final int P_31 = 1;
+ private static final int P_32 = 1;
+ private static final int P_33 = P_31 ^ 1;
+ private static final int P_34 = 1;
+
+ /* Primitive polynomial for GF(256) */
+ private static final int GF256_FDBK = 0x169;
+ private static final int GF256_FDBK_2 = GF256_FDBK / 2;
+ private static final int GF256_FDBK_4 = GF256_FDBK / 4;
+
+ private static final int RS_GF_FDBK = 0x14D; // field generator
+
+ //====================================
+ // Useful constants
+ //====================================
+
+ private static final int ROUNDS = 16;
+ private static final int MAX_ROUNDS = 16; // bytes = 128 bits
+ private static final int BLOCK_SIZE = 16; // bytes = 128 bits
+ private static final int MAX_KEY_BITS = 256;
+
+ private static final int INPUT_WHITEN=0;
+ private static final int OUTPUT_WHITEN=INPUT_WHITEN+BLOCK_SIZE/4; // 4
+ private static final int ROUND_SUBKEYS=OUTPUT_WHITEN+BLOCK_SIZE/4;// 8
+
+ private static final int TOTAL_SUBKEYS=ROUND_SUBKEYS+2*MAX_ROUNDS;// 40
+
+ private static final int SK_STEP = 0x02020202;
+ private static final int SK_BUMP = 0x01010101;
+ private static final int SK_ROTL = 9;
+
+ private boolean encrypting = false;
+
+ private int[] gMDS0 = new int[MAX_KEY_BITS];
+ private int[] gMDS1 = new int[MAX_KEY_BITS];
+ private int[] gMDS2 = new int[MAX_KEY_BITS];
+ private int[] gMDS3 = new int[MAX_KEY_BITS];
+
+ /**
+ * gSubKeys[] and gSBox[] are eventually used in the
+ * encryption and decryption methods.
+ */
+ private int[] gSubKeys;
+ private int[] gSBox;
+
+ private int k64Cnt = 0;
+
+ private byte[] workingKey = null;
+
+ public TwofishEngine()
+ {
+ // calculate the MDS matrix
+ int[] m1 = new int[2];
+ int[] mX = new int[2];
+ int[] mY = new int[2];
+ int j;
+
+ for (int i=0; i< MAX_KEY_BITS ; i++)
+ {
+ j = P[0][i] & 0xff;
+ m1[0] = j;
+ mX[0] = Mx_X(j) & 0xff;
+ mY[0] = Mx_Y(j) & 0xff;
+
+ j = P[1][i] & 0xff;
+ m1[1] = j;
+ mX[1] = Mx_X(j) & 0xff;
+ mY[1] = Mx_Y(j) & 0xff;
+
+ gMDS0[i] = m1[P_00] | mX[P_00] << 8 |
+ mY[P_00] << 16 | mY[P_00] << 24;
+
+ gMDS1[i] = mY[P_10] | mY[P_10] << 8 |
+ mX[P_10] << 16 | m1[P_10] << 24;
+
+ gMDS2[i] = mX[P_20] | mY[P_20] << 8 |
+ m1[P_20] << 16 | mY[P_20] << 24;
+
+ gMDS3[i] = mX[P_30] | m1[P_30] << 8 |
+ mY[P_30] << 16 | mX[P_30] << 24;
+ }
+ }
+
+ /**
+ * initialise a Twofish cipher.
+ *
+ * @param encrypting whether or not we are for encryption.
+ * @param params the parameters required to set up the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean encrypting,
+ CipherParameters params)
+ {
+ if (params instanceof KeyParameter)
+ {
+ this.encrypting = encrypting;
+ this.workingKey = ((KeyParameter)params).getKey();
+ this.k64Cnt = (this.workingKey.length / 8); // pre-padded ?
+ setKey(this.workingKey);
+
+ return;
+ }
+
+ throw new IllegalArgumentException("invalid parameter passed to Twofish init - " + params.getClass().getName());
+ }
+
+ public String getAlgorithmName()
+ {
+ return "Twofish";
+ }
+
+ public int processBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ {
+ if (workingKey == null)
+ {
+ throw new IllegalStateException("Twofish not initialised");
+ }
+
+ if ((inOff + BLOCK_SIZE) > in.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+
+ if ((outOff + BLOCK_SIZE) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ if (encrypting)
+ {
+ encryptBlock(in, inOff, out, outOff);
+ }
+ else
+ {
+ decryptBlock(in, inOff, out, outOff);
+ }
+
+ return BLOCK_SIZE;
+ }
+
+ public void reset()
+ {
+ if (this.workingKey != null)
+ {
+ setKey(this.workingKey);
+ }
+ }
+
+ public int getBlockSize()
+ {
+ return BLOCK_SIZE;
+ }
+
+ //==================================
+ // Private Implementation
+ //==================================
+
+ private void setKey(byte[] key)
+ {
+ int[] k32e = new int[MAX_KEY_BITS/64]; // 4
+ int[] k32o = new int[MAX_KEY_BITS/64]; // 4
+
+ int[] sBoxKeys = new int[MAX_KEY_BITS/64]; // 4
+ gSubKeys = new int[TOTAL_SUBKEYS];
+
+ if (k64Cnt < 1)
+ {
+ throw new IllegalArgumentException("Key size less than 64 bits");
+ }
+
+ if (k64Cnt > 4)
+ {
+ throw new IllegalArgumentException("Key size larger than 256 bits");
+ }
+
+ /*
+ * k64Cnt is the number of 8 byte blocks (64 chunks)
+ * that are in the input key. The input key is a
+ * maximum of 32 bytes (256 bits), so the range
+ * for k64Cnt is 1..4
+ */
+ for (int i=0; i<k64Cnt ; i++)
+ {
+ int p = i* 8;
+
+ k32e[i] = BytesTo32Bits(key, p);
+ k32o[i] = BytesTo32Bits(key, p+4);
+
+ sBoxKeys[k64Cnt-1-i] = RS_MDS_Encode(k32e[i], k32o[i]);
+ }
+
+ int q,A,B;
+ for (int i=0; i < TOTAL_SUBKEYS / 2 ; i++)
+ {
+ q = i*SK_STEP;
+ A = F32(q, k32e);
+ B = F32(q+SK_BUMP, k32o);
+ B = B << 8 | B >>> 24;
+ A += B;
+ gSubKeys[i*2] = A;
+ A += B;
+ gSubKeys[i*2 + 1] = A << SK_ROTL | A >>> (32-SK_ROTL);
+ }
+
+ /*
+ * fully expand the table for speed
+ */
+ int k0 = sBoxKeys[0];
+ int k1 = sBoxKeys[1];
+ int k2 = sBoxKeys[2];
+ int k3 = sBoxKeys[3];
+ int b0, b1, b2, b3;
+ gSBox = new int[4*MAX_KEY_BITS];
+ for (int i=0; i<MAX_KEY_BITS; i++)
+ {
+ b0 = b1 = b2 = b3 = i;
+ switch (k64Cnt & 3)
+ {
+ case 1:
+ gSBox[i*2] = gMDS0[(P[P_01][b0] & 0xff) ^ b0(k0)];
+ gSBox[i*2+1] = gMDS1[(P[P_11][b1] & 0xff) ^ b1(k0)];
+ gSBox[i*2+0x200] = gMDS2[(P[P_21][b2] & 0xff) ^ b2(k0)];
+ gSBox[i*2+0x201] = gMDS3[(P[P_31][b3] & 0xff) ^ b3(k0)];
+ break;
+ case 0: // 256 bits of key
+ b0 = (P[P_04][b0] & 0xff) ^ b0(k3);
+ b1 = (P[P_14][b1] & 0xff) ^ b1(k3);
+ b2 = (P[P_24][b2] & 0xff) ^ b2(k3);
+ b3 = (P[P_34][b3] & 0xff) ^ b3(k3);
+ // fall through, having pre-processed b[0]..b[3] with k32[3]
+ case 3: // 192 bits of key
+ b0 = (P[P_03][b0] & 0xff) ^ b0(k2);
+ b1 = (P[P_13][b1] & 0xff) ^ b1(k2);
+ b2 = (P[P_23][b2] & 0xff) ^ b2(k2);
+ b3 = (P[P_33][b3] & 0xff) ^ b3(k2);
+ // fall through, having pre-processed b[0]..b[3] with k32[2]
+ case 2: // 128 bits of key
+ gSBox[i*2] = gMDS0[(P[P_01]
+ [(P[P_02][b0] & 0xff) ^ b0(k1)] & 0xff) ^ b0(k0)];
+ gSBox[i*2+1] = gMDS1[(P[P_11]
+ [(P[P_12][b1] & 0xff) ^ b1(k1)] & 0xff) ^ b1(k0)];
+ gSBox[i*2+0x200] = gMDS2[(P[P_21]
+ [(P[P_22][b2] & 0xff) ^ b2(k1)] & 0xff) ^ b2(k0)];
+ gSBox[i*2+0x201] = gMDS3[(P[P_31]
+ [(P[P_32][b3] & 0xff) ^ b3(k1)] & 0xff) ^ b3(k0)];
+ break;
+ }
+ }
+
+ /*
+ * the function exits having setup the gSBox with the
+ * input key material.
+ */
+ }
+
+ /**
+ * Encrypt the given input starting at the given offset and place
+ * the result in the provided buffer starting at the given offset.
+ * The input will be an exact multiple of our blocksize.
+ *
+ * encryptBlock uses the pre-calculated gSBox[] and subKey[]
+ * arrays.
+ */
+ private void encryptBlock(
+ byte[] src,
+ int srcIndex,
+ byte[] dst,
+ int dstIndex)
+ {
+ int x0 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[INPUT_WHITEN];
+ int x1 = BytesTo32Bits(src, srcIndex + 4) ^ gSubKeys[INPUT_WHITEN + 1];
+ int x2 = BytesTo32Bits(src, srcIndex + 8) ^ gSubKeys[INPUT_WHITEN + 2];
+ int x3 = BytesTo32Bits(src, srcIndex + 12) ^ gSubKeys[INPUT_WHITEN + 3];
+
+ int k = ROUND_SUBKEYS;
+ int t0, t1;
+ for (int r = 0; r < ROUNDS; r +=2)
+ {
+ t0 = Fe32_0(x0);
+ t1 = Fe32_3(x1);
+ x2 ^= t0 + t1 + gSubKeys[k++];
+ x2 = x2 >>>1 | x2 << 31;
+ x3 = (x3 << 1 | x3 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]);
+
+ t0 = Fe32_0(x2);
+ t1 = Fe32_3(x3);
+ x0 ^= t0 + t1 + gSubKeys[k++];
+ x0 = x0 >>>1 | x0 << 31;
+ x1 = (x1 << 1 | x1 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]);
+ }
+
+ Bits32ToBytes(x2 ^ gSubKeys[OUTPUT_WHITEN], dst, dstIndex);
+ Bits32ToBytes(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], dst, dstIndex + 4);
+ Bits32ToBytes(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], dst, dstIndex + 8);
+ Bits32ToBytes(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], dst, dstIndex + 12);
+ }
+
+ /**
+ * Decrypt the given input starting at the given offset and place
+ * the result in the provided buffer starting at the given offset.
+ * The input will be an exact multiple of our blocksize.
+ */
+ private void decryptBlock(
+ byte[] src,
+ int srcIndex,
+ byte[] dst,
+ int dstIndex)
+ {
+ int x2 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[OUTPUT_WHITEN];
+ int x3 = BytesTo32Bits(src, srcIndex+4) ^ gSubKeys[OUTPUT_WHITEN + 1];
+ int x0 = BytesTo32Bits(src, srcIndex+8) ^ gSubKeys[OUTPUT_WHITEN + 2];
+ int x1 = BytesTo32Bits(src, srcIndex+12) ^ gSubKeys[OUTPUT_WHITEN + 3];
+
+ int k = ROUND_SUBKEYS + 2 * ROUNDS -1 ;
+ int t0, t1;
+ for (int r = 0; r< ROUNDS ; r +=2)
+ {
+ t0 = Fe32_0(x2);
+ t1 = Fe32_3(x3);
+ x1 ^= t0 + 2*t1 + gSubKeys[k--];
+ x0 = (x0 << 1 | x0 >>> 31) ^ (t0 + t1 + gSubKeys[k--]);
+ x1 = x1 >>>1 | x1 << 31;
+
+ t0 = Fe32_0(x0);
+ t1 = Fe32_3(x1);
+ x3 ^= t0 + 2*t1 + gSubKeys[k--];
+ x2 = (x2 << 1 | x2 >>> 31) ^ (t0 + t1 + gSubKeys[k--]);
+ x3 = x3 >>>1 | x3 << 31;
+ }
+
+ Bits32ToBytes(x0 ^ gSubKeys[INPUT_WHITEN], dst, dstIndex);
+ Bits32ToBytes(x1 ^ gSubKeys[INPUT_WHITEN + 1], dst, dstIndex + 4);
+ Bits32ToBytes(x2 ^ gSubKeys[INPUT_WHITEN + 2], dst, dstIndex + 8);
+ Bits32ToBytes(x3 ^ gSubKeys[INPUT_WHITEN + 3], dst, dstIndex + 12);
+ }
+
+ /*
+ * TODO: This can be optimised and made cleaner by combining
+ * the functionality in this function and applying it appropriately
+ * to the creation of the subkeys during key setup.
+ */
+ private int F32(int x, int[] k32)
+ {
+ int b0 = b0(x);
+ int b1 = b1(x);
+ int b2 = b2(x);
+ int b3 = b3(x);
+ int k0 = k32[0];
+ int k1 = k32[1];
+ int k2 = k32[2];
+ int k3 = k32[3];
+
+ int result = 0;
+ switch (k64Cnt & 3)
+ {
+ case 1:
+ result = gMDS0[(P[P_01][b0] & 0xff) ^ b0(k0)] ^
+ gMDS1[(P[P_11][b1] & 0xff) ^ b1(k0)] ^
+ gMDS2[(P[P_21][b2] & 0xff) ^ b2(k0)] ^
+ gMDS3[(P[P_31][b3] & 0xff) ^ b3(k0)];
+ break;
+ case 0: /* 256 bits of key */
+ b0 = (P[P_04][b0] & 0xff) ^ b0(k3);
+ b1 = (P[P_14][b1] & 0xff) ^ b1(k3);
+ b2 = (P[P_24][b2] & 0xff) ^ b2(k3);
+ b3 = (P[P_34][b3] & 0xff) ^ b3(k3);
+ case 3:
+ b0 = (P[P_03][b0] & 0xff) ^ b0(k2);
+ b1 = (P[P_13][b1] & 0xff) ^ b1(k2);
+ b2 = (P[P_23][b2] & 0xff) ^ b2(k2);
+ b3 = (P[P_33][b3] & 0xff) ^ b3(k2);
+ case 2:
+ result =
+ gMDS0[(P[P_01][(P[P_02][b0]&0xff)^b0(k1)]&0xff)^b0(k0)] ^
+ gMDS1[(P[P_11][(P[P_12][b1]&0xff)^b1(k1)]&0xff)^b1(k0)] ^
+ gMDS2[(P[P_21][(P[P_22][b2]&0xff)^b2(k1)]&0xff)^b2(k0)] ^
+ gMDS3[(P[P_31][(P[P_32][b3]&0xff)^b3(k1)]&0xff)^b3(k0)];
+ break;
+ }
+ return result;
+ }
+
+ /**
+ * Use (12, 8) Reed-Solomon code over GF(256) to produce
+ * a key S-box 32-bit entity from 2 key material 32-bit
+ * entities.
+ *
+ * @param k0 first 32-bit entity
+ * @param k1 second 32-bit entity
+ * @return Remainder polynomial generated using RS code
+ */
+ private int RS_MDS_Encode(int k0, int k1)
+ {
+ int r = k1;
+ for (int i = 0 ; i < 4 ; i++) // shift 1 byte at a time
+ {
+ r = RS_rem(r);
+ }
+ r ^= k0;
+ for (int i=0 ; i < 4 ; i++)
+ {
+ r = RS_rem(r);
+ }
+
+ return r;
+ }
+
+ /**
+ * Reed-Solomon code parameters: (12,8) reversible code:<p>
+ * <pre>
+ * g(x) = x^4 + (a+1/a)x^3 + ax^2 + (a+1/a)x + 1
+ * </pre>
+ * where a = primitive root of field generator 0x14D
+ */
+ private int RS_rem(int x)
+ {
+ int b = (x >>> 24) & 0xff;
+ int g2 = ((b << 1) ^
+ ((b & 0x80) != 0 ? RS_GF_FDBK : 0)) & 0xff;
+ int g3 = ((b >>> 1) ^
+ ((b & 0x01) != 0 ? (RS_GF_FDBK >>> 1) : 0)) ^ g2 ;
+ return ((x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b);
+ }
+
+ private int LFSR1(int x)
+ {
+ return (x >> 1) ^
+ (((x & 0x01) != 0) ? GF256_FDBK_2 : 0);
+ }
+
+ private int LFSR2(int x)
+ {
+ return (x >> 2) ^
+ (((x & 0x02) != 0) ? GF256_FDBK_2 : 0) ^
+ (((x & 0x01) != 0) ? GF256_FDBK_4 : 0);
+ }
+
+ private int Mx_X(int x)
+ {
+ return x ^ LFSR2(x);
+ } // 5B
+
+ private int Mx_Y(int x)
+ {
+ return x ^ LFSR1(x) ^ LFSR2(x);
+ } // EF
+
+ private int b0(int x)
+ {
+ return x & 0xff;
+ }
+
+ private int b1(int x)
+ {
+ return (x >>> 8) & 0xff;
+ }
+
+ private int b2(int x)
+ {
+ return (x >>> 16) & 0xff;
+ }
+
+ private int b3(int x)
+ {
+ return (x >>> 24) & 0xff;
+ }
+
+ private int Fe32_0(int x)
+ {
+ return gSBox[ 0x000 + 2*(x & 0xff) ] ^
+ gSBox[ 0x001 + 2*((x >>> 8) & 0xff) ] ^
+ gSBox[ 0x200 + 2*((x >>> 16) & 0xff) ] ^
+ gSBox[ 0x201 + 2*((x >>> 24) & 0xff) ];
+ }
+
+ private int Fe32_3(int x)
+ {
+ return gSBox[ 0x000 + 2*((x >>> 24) & 0xff) ] ^
+ gSBox[ 0x001 + 2*(x & 0xff) ] ^
+ gSBox[ 0x200 + 2*((x >>> 8) & 0xff) ] ^
+ gSBox[ 0x201 + 2*((x >>> 16) & 0xff) ];
+ }
+
+ private int BytesTo32Bits(byte[] b, int p)
+ {
+ return ((b[p] & 0xff)) |
+ ((b[p+1] & 0xff) << 8) |
+ ((b[p+2] & 0xff) << 16) |
+ ((b[p+3] & 0xff) << 24);
+ }
+
+ private void Bits32ToBytes(int in, byte[] b, int offset)
+ {
+ b[offset] = (byte)in;
+ b[offset + 1] = (byte)(in >> 8);
+ b[offset + 2] = (byte)(in >> 16);
+ b[offset + 3] = (byte)(in >> 24);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESKeyGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESKeyGenerator.java
new file mode 100644
index 00000000..3a5090a9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESKeyGenerator.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import com.android.internal.org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DESParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DESKeyGenerator
+ extends CipherKeyGenerator
+{
+ /**
+ * initialise the key generator - if strength is set to zero
+ * the key generated will be 64 bits in size, otherwise
+ * strength can be 64 or 56 bits (if you don't count the parity bits).
+ *
+ * @param param the parameters to be used for key generation
+ */
+ public void init(
+ KeyGenerationParameters param)
+ {
+ super.init(param);
+
+ if (strength == 0 || strength == (56 / 8))
+ {
+ strength = DESParameters.DES_KEY_LENGTH;
+ }
+ else if (strength != DESParameters.DES_KEY_LENGTH)
+ {
+ throw new IllegalArgumentException("DES key must be "
+ + (DESParameters.DES_KEY_LENGTH * 8)
+ + " bits long.");
+ }
+ }
+
+ public byte[] generateKey()
+ {
+ byte[] newKey = new byte[DESParameters.DES_KEY_LENGTH];
+
+ do
+ {
+ random.nextBytes(newKey);
+
+ DESParameters.setOddParity(newKey);
+ }
+ while (DESParameters.isWeakKey(newKey, 0));
+
+ return newKey;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java
new file mode 100644
index 00000000..c718a7da
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java
@@ -0,0 +1,68 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DESedeParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DESedeKeyGenerator
+ extends DESKeyGenerator
+{
+ private static final int MAX_IT = 20;
+
+ /**
+ * initialise the key generator - if strength is set to zero
+ * the key generated will be 192 bits in size, otherwise
+ * strength can be 128 or 192 (or 112 or 168 if you don't count
+ * parity bits), depending on whether you wish to do 2-key or 3-key
+ * triple DES.
+ *
+ * @param param the parameters to be used for key generation
+ */
+ public void init(
+ KeyGenerationParameters param)
+ {
+ this.random = param.getRandom();
+ this.strength = (param.getStrength() + 7) / 8;
+
+ if (strength == 0 || strength == (168 / 8))
+ {
+ strength = DESedeParameters.DES_EDE_KEY_LENGTH;
+ }
+ else if (strength == (112 / 8))
+ {
+ strength = 2 * DESedeParameters.DES_KEY_LENGTH;
+ }
+ else if (strength != DESedeParameters.DES_EDE_KEY_LENGTH
+ && strength != (2 * DESedeParameters.DES_KEY_LENGTH))
+ {
+ throw new IllegalArgumentException("DESede key must be "
+ + (DESedeParameters.DES_EDE_KEY_LENGTH * 8) + " or "
+ + (2 * 8 * DESedeParameters.DES_KEY_LENGTH)
+ + " bits long.");
+ }
+ }
+
+ public byte[] generateKey()
+ {
+ byte[] newKey = new byte[strength];
+ int count = 0;
+
+ do
+ {
+ random.nextBytes(newKey);
+
+ DESedeParameters.setOddParity(newKey);
+ }
+ while (++count < MAX_IT && (DESedeParameters.isWeakKey(newKey, 0, newKey.length) || !DESedeParameters.isRealEDEKey(newKey, 0)));
+
+ if (DESedeParameters.isWeakKey(newKey, 0, newKey.length) || !DESedeParameters.isRealEDEKey(newKey, 0))
+ {
+ throw new IllegalStateException("Unable to generate DES-EDE key");
+ }
+
+ return newKey;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java
new file mode 100644
index 00000000..75d1e3c2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHBasicKeyPairGenerator.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHKeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPublicKeyParameters;
+
+import java.math.BigInteger;
+
+/**
+ * a basic Diffie-Hellman key pair generator.
+ *
+ * This generates keys consistent for use with the basic algorithm for
+ * Diffie-Hellman.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHBasicKeyPairGenerator
+ implements AsymmetricCipherKeyPairGenerator
+{
+ private DHKeyGenerationParameters param;
+
+ public void init(
+ KeyGenerationParameters param)
+ {
+ this.param = (DHKeyGenerationParameters)param;
+ }
+
+ public AsymmetricCipherKeyPair generateKeyPair()
+ {
+ DHKeyGeneratorHelper helper = DHKeyGeneratorHelper.INSTANCE;
+ DHParameters dhp = param.getParameters();
+
+ BigInteger x = helper.calculatePrivate(dhp, param.getRandom());
+ BigInteger y = helper.calculatePublic(dhp, x);
+
+ return new AsymmetricCipherKeyPair(
+ new DHPublicKeyParameters(y, dhp),
+ new DHPrivateKeyParameters(x, dhp));
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHKeyGeneratorHelper.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHKeyGeneratorHelper.java
new file mode 100644
index 00000000..0ef8365a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHKeyGeneratorHelper.java
@@ -0,0 +1,68 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.math.ec.WNafUtil;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+class DHKeyGeneratorHelper
+{
+ static final DHKeyGeneratorHelper INSTANCE = new DHKeyGeneratorHelper();
+
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+
+ private DHKeyGeneratorHelper()
+ {
+ }
+
+ BigInteger calculatePrivate(DHParameters dhParams, SecureRandom random)
+ {
+ int limit = dhParams.getL();
+
+ if (limit != 0)
+ {
+ int minWeight = limit >>> 2;
+ for (;;)
+ {
+ BigInteger x = BigIntegers.createRandomBigInteger(limit, random).setBit(limit - 1);
+ if (WNafUtil.getNafWeight(x) >= minWeight)
+ {
+ return x;
+ }
+ }
+ }
+
+ BigInteger min = TWO;
+ int m = dhParams.getM();
+ if (m != 0)
+ {
+ min = ONE.shiftLeft(m - 1);
+ }
+
+ BigInteger q = dhParams.getQ();
+ if (q == null)
+ {
+ q = dhParams.getP();
+ }
+ BigInteger max = q.subtract(TWO);
+
+ int minWeight = max.bitLength() >>> 2;
+ for (;;)
+ {
+ BigInteger x = BigIntegers.createRandomInRange(min, max, random);
+ if (WNafUtil.getNafWeight(x) >= minWeight)
+ {
+ return x;
+ }
+ }
+ }
+
+ BigInteger calculatePublic(DHParameters dhParams, BigInteger x)
+ {
+ return dhParams.getG().modPow(x, dhParams.getP());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHParametersGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHParametersGenerator.java
new file mode 100644
index 00000000..2b83ea94
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHParametersGenerator.java
@@ -0,0 +1,57 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHParametersGenerator
+{
+ private int size;
+ private int certainty;
+ private SecureRandom random;
+
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+
+ /**
+ * Initialise the parameters generator.
+ *
+ * @param size bit length for the prime p
+ * @param certainty level of certainty for the prime number tests
+ * @param random a source of randomness
+ */
+ public void init(
+ int size,
+ int certainty,
+ SecureRandom random)
+ {
+ this.size = size;
+ this.certainty = certainty;
+ this.random = random;
+ }
+
+ /**
+ * which generates the p and g values from the given parameters,
+ * returning the DHParameters object.
+ * <p>
+ * Note: can take a while...
+ * @return a generated Diffie-Hellman parameters object.
+ */
+ public DHParameters generateParameters()
+ {
+ //
+ // find a safe prime p where p = 2*q + 1, where p and q are prime.
+ //
+ BigInteger[] safePrimes = DHParametersHelper.generateSafePrimes(size, certainty, random);
+
+ BigInteger p = safePrimes[0];
+ BigInteger q = safePrimes[1];
+ BigInteger g = DHParametersHelper.selectGenerator(p, q, random);
+
+ return new DHParameters(p, g, q, TWO, null);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHParametersHelper.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHParametersHelper.java
new file mode 100644
index 00000000..f999286b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DHParametersHelper.java
@@ -0,0 +1,111 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+// Android-added: Log long-running operation
+import java.util.logging.Logger;
+import com.android.internal.org.bouncycastle.math.ec.WNafUtil;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+class DHParametersHelper
+{
+ // Android-added: Log long-running operation
+ private static final Logger logger = Logger.getLogger(DHParametersHelper.class.getName());
+
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+
+ /*
+ * Finds a pair of prime BigInteger's {p, q: p = 2q + 1}
+ *
+ * (see: Handbook of Applied Cryptography 4.86)
+ */
+ static BigInteger[] generateSafePrimes(int size, int certainty, SecureRandom random)
+ {
+ // BEGIN Android-added: Log long-running operation
+ logger.info("Generating safe primes. This may take a long time.");
+ long start = System.currentTimeMillis();
+ int tries = 0;
+ // END Android-added: Log long-running operation
+ BigInteger p, q;
+ int qLength = size - 1;
+ int minWeight = size >>> 2;
+
+ for (;;)
+ {
+ // Android-added: Log long-running operation
+ tries++;
+ q = BigIntegers.createRandomPrime(qLength, 2, random);
+
+ // p <- 2q + 1
+ p = q.shiftLeft(1).add(ONE);
+
+ if (!p.isProbablePrime(certainty))
+ {
+ continue;
+ }
+
+ if (certainty > 2 && !q.isProbablePrime(certainty - 2))
+ {
+ continue;
+ }
+
+ /*
+ * Require a minimum weight of the NAF representation, since low-weight primes may be
+ * weak against a version of the number-field-sieve for the discrete-logarithm-problem.
+ *
+ * See "The number field sieve for integers of low weight", Oliver Schirokauer.
+ */
+ if (WNafUtil.getNafWeight(p) < minWeight)
+ {
+ continue;
+ }
+
+ break;
+ }
+ // BEGIN Android-added: Log long-running operation
+ long end = System.currentTimeMillis();
+ long duration = end - start;
+ logger.info("Generated safe primes: " + tries + " tries took " + duration + "ms");
+ // END Android-added: Log long-running operation
+
+ return new BigInteger[] { p, q };
+ }
+
+ /*
+ * Select a high order element of the multiplicative group Zp*
+ *
+ * p and q must be s.t. p = 2*q + 1, where p and q are prime (see generateSafePrimes)
+ */
+ static BigInteger selectGenerator(BigInteger p, BigInteger q, SecureRandom random)
+ {
+ BigInteger pMinusTwo = p.subtract(TWO);
+ BigInteger g;
+
+ /*
+ * (see: Handbook of Applied Cryptography 4.80)
+ */
+// do
+// {
+// g = BigIntegers.createRandomInRange(TWO, pMinusTwo, random);
+// }
+// while (g.modPow(TWO, p).equals(ONE) || g.modPow(q, p).equals(ONE));
+
+
+ /*
+ * RFC 2631 2.2.1.2 (and see: Handbook of Applied Cryptography 4.81)
+ */
+ do
+ {
+ BigInteger h = BigIntegers.createRandomInRange(TWO, pMinusTwo, random);
+
+ g = h.modPow(TWO, p);
+ }
+ while (g.equals(ONE));
+
+
+ return g;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java
new file mode 100644
index 00000000..570d45af
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java
@@ -0,0 +1,71 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAKeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPublicKeyParameters;
+import com.android.internal.org.bouncycastle.math.ec.WNafUtil;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * a DSA key pair generator.
+ *
+ * This generates DSA keys in line with the method described
+ * in <i>FIPS 186-3 B.1 FFC Key Pair Generation</i>.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DSAKeyPairGenerator
+ implements AsymmetricCipherKeyPairGenerator
+{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+
+ private DSAKeyGenerationParameters param;
+
+ public void init(
+ KeyGenerationParameters param)
+ {
+ this.param = (DSAKeyGenerationParameters)param;
+ }
+
+ public AsymmetricCipherKeyPair generateKeyPair()
+ {
+ DSAParameters dsaParams = param.getParameters();
+
+ BigInteger x = generatePrivateKey(dsaParams.getQ(), param.getRandom());
+ BigInteger y = calculatePublicKey(dsaParams.getP(), dsaParams.getG(), x);
+
+ return new AsymmetricCipherKeyPair(
+ new DSAPublicKeyParameters(y, dsaParams),
+ new DSAPrivateKeyParameters(x, dsaParams));
+ }
+
+ private static BigInteger generatePrivateKey(BigInteger q, SecureRandom random)
+ {
+ // B.1.2 Key Pair Generation by Testing Candidates
+ int minWeight = q.bitLength() >>> 2;
+ for (;;)
+ {
+ // TODO Prefer this method? (change test cases that used fixed random)
+ // B.1.1 Key Pair Generation Using Extra Random Bits
+// BigInteger x = new BigInteger(q.bitLength() + 64, random).mod(q.subtract(ONE)).add(ONE);
+
+ BigInteger x = BigIntegers.createRandomInRange(ONE, q.subtract(ONE), random);
+ if (WNafUtil.getNafWeight(x) >= minWeight)
+ {
+ return x;
+ }
+ }
+ }
+
+ private static BigInteger calculatePublicKey(BigInteger p, BigInteger g, BigInteger x)
+ {
+ return g.modPow(x, p);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DSAParametersGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
new file mode 100644
index 00000000..f10fa48b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
@@ -0,0 +1,416 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameterGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAValidationParameters;
+// Android-changed: Use Android digests
+// import org.bouncycastle.crypto.util.DigestFactory;
+import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * Generate suitable parameters for DSA, in line with FIPS 186-2, or FIPS 186-3.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DSAParametersGenerator
+{
+ private static final BigInteger ZERO = BigInteger.valueOf(0);
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+
+ private Digest digest;
+ private int L, N;
+ private int certainty;
+ private int iterations;
+ private SecureRandom random;
+ private boolean use186_3;
+ private int usageIndex;
+
+ public DSAParametersGenerator()
+ {
+ // Android-changed: Use Android digests
+ // this(DigestFactory.createSHA1());
+ this(AndroidDigestFactory.getSHA1());
+ }
+
+ public DSAParametersGenerator(Digest digest)
+ {
+ this.digest = digest;
+ }
+
+ /**
+ * initialise the key generator.
+ *
+ * @param size size of the key (range 2^512 -&gt; 2^1024 - 64 bit increments)
+ * @param certainty measure of robustness of prime (for FIPS 186-2 compliance this should be at least 80).
+ * @param random random byte source.
+ */
+ public void init(
+ int size,
+ int certainty,
+ SecureRandom random)
+ {
+ this.L = size;
+ this.N = getDefaultN(size);
+ this.certainty = certainty;
+ this.iterations = Math.max(getMinimumIterations(L), (certainty + 1) / 2);
+ this.random = random;
+ this.use186_3 = false;
+ this.usageIndex = -1;
+ }
+
+ /**
+ * Initialise the key generator for DSA 2.
+ * <p>
+ * Use this init method if you need to generate parameters for DSA 2 keys.
+ * </p>
+ *
+ * @param params DSA 2 key generation parameters.
+ */
+ public void init(
+ DSAParameterGenerationParameters params)
+ {
+ int L = params.getL(), N = params.getN();
+
+ if ((L < 1024 || L > 3072) || L % 1024 != 0)
+ {
+ throw new IllegalArgumentException("L values must be between 1024 and 3072 and a multiple of 1024");
+ }
+ else if (L == 1024 && N != 160)
+ {
+ throw new IllegalArgumentException("N must be 160 for L = 1024");
+ }
+ else if (L == 2048 && (N != 224 && N != 256))
+ {
+ throw new IllegalArgumentException("N must be 224 or 256 for L = 2048");
+ }
+ else if (L == 3072 && N != 256)
+ {
+ throw new IllegalArgumentException("N must be 256 for L = 3072");
+ }
+
+ if (digest.getDigestSize() * 8 < N)
+ {
+ throw new IllegalStateException("Digest output size too small for value of N");
+ }
+
+ this.L = L;
+ this.N = N;
+ this.certainty = params.getCertainty();
+ this.iterations = Math.max(getMinimumIterations(L), (certainty + 1) / 2);
+ this.random = params.getRandom();
+ this.use186_3 = true;
+ this.usageIndex = params.getUsageIndex();
+ }
+
+ /**
+ * which generates the p and g values from the given parameters,
+ * returning the DSAParameters object.
+ * <p>
+ * Note: can take a while...
+ * @return a generated DSA parameters object.
+ */
+ public DSAParameters generateParameters()
+ {
+ return (use186_3)
+ ? generateParameters_FIPS186_3()
+ : generateParameters_FIPS186_2();
+ }
+
+ private DSAParameters generateParameters_FIPS186_2()
+ {
+ byte[] seed = new byte[20];
+ byte[] part1 = new byte[20];
+ byte[] part2 = new byte[20];
+ byte[] u = new byte[20];
+ int n = (L - 1) / 160;
+ byte[] w = new byte[L / 8];
+
+ // Android-changed: Use Android digests
+ // if (!(digest instanceof SHA1Digest))
+ if (!(digest.getAlgorithmName().equals("SHA-1")))
+ {
+ throw new IllegalStateException("can only use SHA-1 for generating FIPS 186-2 parameters");
+ }
+
+ for (;;)
+ {
+ random.nextBytes(seed);
+
+ hash(digest, seed, part1, 0);
+ System.arraycopy(seed, 0, part2, 0, seed.length);
+ inc(part2);
+ hash(digest, part2, part2, 0);
+
+ for (int i = 0; i != u.length; i++)
+ {
+ u[i] = (byte)(part1[i] ^ part2[i]);
+ }
+
+ u[0] |= (byte)0x80;
+ u[19] |= (byte)0x01;
+
+ BigInteger q = new BigInteger(1, u);
+
+ if (!isProbablePrime(q))
+ {
+ continue;
+ }
+
+ byte[] offset = Arrays.clone(seed);
+ inc(offset);
+
+ for (int counter = 0; counter < 4096; ++counter)
+ {
+ {
+ for (int k = 1; k <= n; k++)
+ {
+ inc(offset);
+ hash(digest, offset, w, w.length - k * part1.length);
+ }
+
+ int remaining = w.length - (n * part1.length);
+ inc(offset);
+ hash(digest, offset, part1, 0);
+ System.arraycopy(part1, part1.length - remaining, w, 0, remaining);
+
+ w[0] |= (byte)0x80;
+ }
+
+ BigInteger x = new BigInteger(1, w);
+
+ BigInteger c = x.mod(q.shiftLeft(1));
+
+ BigInteger p = x.subtract(c.subtract(ONE));
+
+ if (p.bitLength() != L)
+ {
+ continue;
+ }
+
+ if (isProbablePrime(p))
+ {
+ BigInteger g = calculateGenerator_FIPS186_2(p, q, random);
+
+ return new DSAParameters(p, q, g, new DSAValidationParameters(seed, counter));
+ }
+ }
+ }
+ }
+
+ private static BigInteger calculateGenerator_FIPS186_2(BigInteger p, BigInteger q, SecureRandom r)
+ {
+ BigInteger e = p.subtract(ONE).divide(q);
+ BigInteger pSub2 = p.subtract(TWO);
+
+ for (;;)
+ {
+ BigInteger h = BigIntegers.createRandomInRange(TWO, pSub2, r);
+ BigInteger g = h.modPow(e, p);
+ if (g.bitLength() > 1)
+ {
+ return g;
+ }
+ }
+ }
+
+ /**
+ * generate suitable parameters for DSA, in line with
+ * <i>FIPS 186-3 A.1 Generation of the FFC Primes p and q</i>.
+ */
+ private DSAParameters generateParameters_FIPS186_3()
+ {
+// A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function
+ // FIXME This should be configurable (digest size in bits must be >= N)
+ Digest d = digest;
+ int outlen = d.getDigestSize() * 8;
+
+// 1. Check that the (L, N) pair is in the list of acceptable (L, N pairs) (see Section 4.2). If
+// the pair is not in the list, then return INVALID.
+ // Note: checked at initialisation
+
+// 2. If (seedlen < N), then return INVALID.
+ // FIXME This should be configurable (must be >= N)
+ int seedlen = N;
+ byte[] seed = new byte[seedlen / 8];
+
+// 3. n = ceiling(L / outlen) - 1.
+ int n = (L - 1) / outlen;
+
+// 4. b = L - 1 - (n * outlen).
+ int b = (L - 1) % outlen;
+
+ byte[] w = new byte[L / 8];
+ byte[] output = new byte[d.getDigestSize()];
+ for (;;)
+ {
+// 5. Get an arbitrary sequence of seedlen bits as the domain_parameter_seed.
+ random.nextBytes(seed);
+
+// 6. U = Hash (domain_parameter_seed) mod 2^(N–1).
+ hash(d, seed, output, 0);
+
+ BigInteger U = new BigInteger(1, output).mod(ONE.shiftLeft(N - 1));
+
+// 7. q = 2^(N–1) + U + 1 – ( U mod 2).
+ BigInteger q = U.setBit(0).setBit(N - 1);
+
+// 8. Test whether or not q is prime as specified in Appendix C.3.
+ if (!isProbablePrime(q))
+ {
+// 9. If q is not a prime, then go to step 5.
+ continue;
+ }
+
+// 10. offset = 1.
+ // Note: 'offset' value managed incrementally
+ byte[] offset = Arrays.clone(seed);
+
+// 11. For counter = 0 to (4L – 1) do
+ int counterLimit = 4 * L;
+ for (int counter = 0; counter < counterLimit; ++counter)
+ {
+// 11.1 For j = 0 to n do
+// Vj = Hash ((domain_parameter_seed + offset + j) mod 2^seedlen).
+// 11.2 W = V0 + (V1 ∗ 2^outlen) + ... + (V^(n–1) ∗ 2^((n–1) ∗ outlen)) + ((Vn mod 2^b) ∗ 2^(n ∗ outlen)).
+ {
+ for (int j = 1; j <= n; ++j)
+ {
+ inc(offset);
+ hash(d, offset, w, w.length - j * output.length);
+ }
+
+ int remaining = w.length - (n * output.length);
+ inc(offset);
+ hash(d, offset, output, 0);
+ System.arraycopy(output, output.length - remaining, w, 0, remaining);
+
+// 11.3 X = W + 2^(L–1). Comment: 0 ≤ W < 2^(L–1); hence, 2^(L–1) ≤ X < 2^L.
+ w[0] |= (byte)0x80;
+ }
+
+ BigInteger X = new BigInteger(1, w);
+
+// 11.4 c = X mod 2q.
+ BigInteger c = X.mod(q.shiftLeft(1));
+
+// 11.5 p = X - (c - 1). Comment: p ≡ 1 (mod 2q).
+ BigInteger p = X.subtract(c.subtract(ONE));
+
+// 11.6 If (p < 2^(L-1)), then go to step 11.9
+ if (p.bitLength() != L)
+ {
+ continue;
+ }
+
+// 11.7 Test whether or not p is prime as specified in Appendix C.3.
+ if (isProbablePrime(p))
+ {
+// 11.8 If p is determined to be prime, then return VALID and the values of p, q and
+// (optionally) the values of domain_parameter_seed and counter.
+ if (usageIndex >= 0)
+ {
+ BigInteger g = calculateGenerator_FIPS186_3_Verifiable(d, p, q, seed, usageIndex);
+ if (g != null)
+ {
+ return new DSAParameters(p, q, g, new DSAValidationParameters(seed, counter, usageIndex));
+ }
+ }
+
+ BigInteger g = calculateGenerator_FIPS186_3_Unverifiable(p, q, random);
+
+ return new DSAParameters(p, q, g, new DSAValidationParameters(seed, counter));
+ }
+
+// 11.9 offset = offset + n + 1. Comment: Increment offset; then, as part of
+// the loop in step 11, increment counter; if
+// counter < 4L, repeat steps 11.1 through 11.8.
+ // Note: 'offset' value already incremented in inner loop
+ }
+// 12. Go to step 5.
+ }
+ }
+
+ private boolean isProbablePrime(BigInteger x)
+ {
+ /*
+ * TODO Use Primes class for FIPS 186-4 C.3 primality checking - but it breaks existing
+ * tests using FixedSecureRandom
+ */
+// return !Primes.hasAnySmallFactors(x) && Primes.isMRProbablePrime(x, random, iterations);
+ return x.isProbablePrime(certainty);
+ }
+
+ private static BigInteger calculateGenerator_FIPS186_3_Unverifiable(BigInteger p, BigInteger q,
+ SecureRandom r)
+ {
+ return calculateGenerator_FIPS186_2(p, q, r);
+ }
+
+ private static BigInteger calculateGenerator_FIPS186_3_Verifiable(Digest d, BigInteger p, BigInteger q,
+ byte[] seed, int index)
+ {
+// A.2.3 Verifiable Canonical Generation of the Generator g
+ BigInteger e = p.subtract(ONE).divide(q);
+ byte[] ggen = Hex.decodeStrict("6767656E");
+
+ // 7. U = domain_parameter_seed || "ggen" || index || count.
+ byte[] U = new byte[seed.length + ggen.length + 1 + 2];
+ System.arraycopy(seed, 0, U, 0, seed.length);
+ System.arraycopy(ggen, 0, U, seed.length, ggen.length);
+ U[U.length - 3] = (byte)index;
+
+ byte[] w = new byte[d.getDigestSize()];
+ for (int count = 1; count < (1 << 16); ++count)
+ {
+ inc(U);
+ hash(d, U, w, 0);
+ BigInteger W = new BigInteger(1, w);
+ BigInteger g = W.modPow(e, p);
+ if (g.compareTo(TWO) >= 0)
+ {
+ return g;
+ }
+ }
+
+ return null;
+ }
+
+ private static void hash(Digest d, byte[] input, byte[] output, int outputPos)
+ {
+ d.update(input, 0, input.length);
+ d.doFinal(output, outputPos);
+ }
+
+ private static int getDefaultN(int L)
+ {
+ return L > 1024 ? 256 : 160;
+ }
+
+ private static int getMinimumIterations(int L)
+ {
+ // Values based on FIPS 186-4 C.3 Table C.1
+ return L <= 1024 ? 40 : (48 + 8 * ((L - 1) / 1024));
+ }
+
+ private static void inc(byte[] buf)
+ {
+ for (int i = buf.length - 1; i >= 0; --i)
+ {
+ byte b = (byte)((buf[i] + 1) & 0xff);
+ buf[i] = b;
+
+ if (b != 0)
+ {
+ break;
+ }
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
new file mode 100644
index 00000000..1b649ebc
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
@@ -0,0 +1,78 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECKeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECMultiplier;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.ec.FixedPointCombMultiplier;
+import com.android.internal.org.bouncycastle.math.ec.WNafUtil;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECKeyPairGenerator
+ implements AsymmetricCipherKeyPairGenerator, ECConstants
+{
+ ECDomainParameters params;
+ SecureRandom random;
+
+ public void init(
+ KeyGenerationParameters param)
+ {
+ ECKeyGenerationParameters ecP = (ECKeyGenerationParameters)param;
+
+ this.random = ecP.getRandom();
+ this.params = ecP.getDomainParameters();
+ }
+
+ /**
+ * Given the domain parameters this routine generates an EC key
+ * pair in accordance with X9.62 section 5.2.1 pages 26, 27.
+ */
+ public AsymmetricCipherKeyPair generateKeyPair()
+ {
+ BigInteger n = params.getN();
+ int nBitLength = n.bitLength();
+ int minWeight = nBitLength >>> 2;
+
+ BigInteger d;
+ for (;;)
+ {
+ d = BigIntegers.createRandomBigInteger(nBitLength, random);
+
+ if (d.compareTo(ONE) < 0 || (d.compareTo(n) >= 0))
+ {
+ continue;
+ }
+
+ if (WNafUtil.getNafWeight(d) < minWeight)
+ {
+ continue;
+ }
+
+ break;
+ }
+
+ ECPoint Q = createBasePointMultiplier().multiply(params.getG(), d);
+
+ return new AsymmetricCipherKeyPair(
+ new ECPublicKeyParameters(Q, params),
+ new ECPrivateKeyParameters(d, params));
+ }
+
+ protected ECMultiplier createBasePointMultiplier()
+ {
+ return new FixedPointCombMultiplier();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
new file mode 100644
index 00000000..43b5b5c5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
@@ -0,0 +1,137 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.PBEParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+// Android-changed: Use Android digests
+// import org.bouncycastle.crypto.util.DigestFactory;
+import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+
+/**
+ * Generator for PBE derived keys and ivs as usd by OpenSSL.
+ * <p>
+ * The scheme is a simple extension of PKCS 5 V2.0 Scheme 1 using MD5 with an
+ * iteration count of 1.
+ * <p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OpenSSLPBEParametersGenerator
+ extends PBEParametersGenerator
+{
+ // Android-changed: Use Android digests
+ // private Digest digest = DigestFactory.createMD5();
+ private Digest digest = AndroidDigestFactory.getMD5();
+
+ /**
+ * Construct a OpenSSL Parameters generator.
+ */
+ public OpenSSLPBEParametersGenerator()
+ {
+ }
+
+ /**
+ * Initialise - note the iteration count for this algorithm is fixed at 1.
+ *
+ * @param password password to use.
+ * @param salt salt to use.
+ */
+ public void init(
+ byte[] password,
+ byte[] salt)
+ {
+ super.init(password, salt, 1);
+ }
+
+ /**
+ * the derived key function, the ith hash of the password and the salt.
+ */
+ private byte[] generateDerivedKey(
+ int bytesNeeded)
+ {
+ byte[] buf = new byte[digest.getDigestSize()];
+ byte[] key = new byte[bytesNeeded];
+ int offset = 0;
+
+ for (;;)
+ {
+ digest.update(password, 0, password.length);
+ digest.update(salt, 0, salt.length);
+
+ digest.doFinal(buf, 0);
+
+ int len = (bytesNeeded > buf.length) ? buf.length : bytesNeeded;
+ System.arraycopy(buf, 0, key, offset, len);
+ offset += len;
+
+ // check if we need any more
+ bytesNeeded -= len;
+ if (bytesNeeded == 0)
+ {
+ break;
+ }
+
+ // do another round
+ digest.reset();
+ digest.update(buf, 0, buf.length);
+ }
+
+ return key;
+ }
+
+ /**
+ * Generate a key parameter derived from the password, salt, and iteration
+ * count we are currently initialised with.
+ *
+ * @param keySize the size of the key we want (in bits)
+ * @return a KeyParameter object.
+ * @exception IllegalArgumentException if the key length larger than the base hash size.
+ */
+ public CipherParameters generateDerivedParameters(
+ int keySize)
+ {
+ keySize = keySize / 8;
+
+ byte[] dKey = generateDerivedKey(keySize);
+
+ return new KeyParameter(dKey, 0, keySize);
+ }
+
+ /**
+ * Generate a key with initialisation vector parameter derived from
+ * the password, salt, and iteration count we are currently initialised
+ * with.
+ *
+ * @param keySize the size of the key we want (in bits)
+ * @param ivSize the size of the iv we want (in bits)
+ * @return a ParametersWithIV object.
+ * @exception IllegalArgumentException if keySize + ivSize is larger than the base hash size.
+ */
+ public CipherParameters generateDerivedParameters(
+ int keySize,
+ int ivSize)
+ {
+ keySize = keySize / 8;
+ ivSize = ivSize / 8;
+
+ byte[] dKey = generateDerivedKey(keySize + ivSize);
+
+ return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize);
+ }
+
+ /**
+ * Generate a key parameter for use with a MAC derived from the password,
+ * salt, and iteration count we are currently initialised with.
+ *
+ * @param keySize the size of the key we want (in bits)
+ * @return a KeyParameter object.
+ * @exception IllegalArgumentException if the key length larger than the base hash size.
+ */
+ public CipherParameters generateDerivedMacParameters(
+ int keySize)
+ {
+ return generateDerivedParameters(keySize);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java
new file mode 100644
index 00000000..d9d39900
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java
@@ -0,0 +1,222 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.ExtendedDigest;
+import com.android.internal.org.bouncycastle.crypto.PBEParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+
+/**
+ * Generator for PBE derived keys and ivs as defined by PKCS 12 V1.0.
+ * <p>
+ * The document this implementation is based on can be found at
+ * <a href=https://www.rsasecurity.com/rsalabs/pkcs/pkcs-12/index.html>
+ * RSA's PKCS12 Page</a>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS12ParametersGenerator
+ extends PBEParametersGenerator
+{
+ public static final int KEY_MATERIAL = 1;
+ public static final int IV_MATERIAL = 2;
+ public static final int MAC_MATERIAL = 3;
+
+ private Digest digest;
+
+ private int u;
+ private int v;
+
+ /**
+ * Construct a PKCS 12 Parameters generator. This constructor will
+ * accept any digest which also implements ExtendedDigest.
+ *
+ * @param digest the digest to be used as the source of derived keys.
+ * @exception IllegalArgumentException if an unknown digest is passed in.
+ */
+ public PKCS12ParametersGenerator(
+ Digest digest)
+ {
+ this.digest = digest;
+ if (digest instanceof ExtendedDigest)
+ {
+ u = digest.getDigestSize();
+ v = ((ExtendedDigest)digest).getByteLength();
+ }
+ else
+ {
+ throw new IllegalArgumentException("Digest " + digest.getAlgorithmName() + " unsupported");
+ }
+ }
+
+ /**
+ * add a + b + 1, returning the result in a. The a value is treated
+ * as a BigInteger of length (b.length * 8) bits. The result is
+ * modulo 2^b.length in case of overflow.
+ */
+ private void adjust(
+ byte[] a,
+ int aOff,
+ byte[] b)
+ {
+ int x = (b[b.length - 1] & 0xff) + (a[aOff + b.length - 1] & 0xff) + 1;
+
+ a[aOff + b.length - 1] = (byte)x;
+ x >>>= 8;
+
+ for (int i = b.length - 2; i >= 0; i--)
+ {
+ x += (b[i] & 0xff) + (a[aOff + i] & 0xff);
+ a[aOff + i] = (byte)x;
+ x >>>= 8;
+ }
+ }
+
+ /**
+ * generation of a derived key ala PKCS12 V1.0.
+ */
+ private byte[] generateDerivedKey(
+ int idByte,
+ int n)
+ {
+ byte[] D = new byte[v];
+ byte[] dKey = new byte[n];
+
+ for (int i = 0; i != D.length; i++)
+ {
+ D[i] = (byte)idByte;
+ }
+
+ byte[] S;
+
+ if ((salt != null) && (salt.length != 0))
+ {
+ S = new byte[v * ((salt.length + v - 1) / v)];
+
+ for (int i = 0; i != S.length; i++)
+ {
+ S[i] = salt[i % salt.length];
+ }
+ }
+ else
+ {
+ S = new byte[0];
+ }
+
+ byte[] P;
+
+ if ((password != null) && (password.length != 0))
+ {
+ P = new byte[v * ((password.length + v - 1) / v)];
+
+ for (int i = 0; i != P.length; i++)
+ {
+ P[i] = password[i % password.length];
+ }
+ }
+ else
+ {
+ P = new byte[0];
+ }
+
+ byte[] I = new byte[S.length + P.length];
+
+ System.arraycopy(S, 0, I, 0, S.length);
+ System.arraycopy(P, 0, I, S.length, P.length);
+
+ byte[] B = new byte[v];
+ int c = (n + u - 1) / u;
+ byte[] A = new byte[u];
+
+ for (int i = 1; i <= c; i++)
+ {
+ digest.update(D, 0, D.length);
+ digest.update(I, 0, I.length);
+ digest.doFinal(A, 0);
+ for (int j = 1; j < iterationCount; j++)
+ {
+ digest.update(A, 0, A.length);
+ digest.doFinal(A, 0);
+ }
+
+ for (int j = 0; j != B.length; j++)
+ {
+ B[j] = A[j % A.length];
+ }
+
+ for (int j = 0; j != I.length / v; j++)
+ {
+ adjust(I, j * v, B);
+ }
+
+ if (i == c)
+ {
+ System.arraycopy(A, 0, dKey, (i - 1) * u, dKey.length - ((i - 1) * u));
+ }
+ else
+ {
+ System.arraycopy(A, 0, dKey, (i - 1) * u, A.length);
+ }
+ }
+
+ return dKey;
+ }
+
+ /**
+ * Generate a key parameter derived from the password, salt, and iteration
+ * count we are currently initialised with.
+ *
+ * @param keySize the size of the key we want (in bits)
+ * @return a KeyParameter object.
+ */
+ public CipherParameters generateDerivedParameters(
+ int keySize)
+ {
+ keySize = keySize / 8;
+
+ byte[] dKey = generateDerivedKey(KEY_MATERIAL, keySize);
+
+ return new KeyParameter(dKey, 0, keySize);
+ }
+
+ /**
+ * Generate a key with initialisation vector parameter derived from
+ * the password, salt, and iteration count we are currently initialised
+ * with.
+ *
+ * @param keySize the size of the key we want (in bits)
+ * @param ivSize the size of the iv we want (in bits)
+ * @return a ParametersWithIV object.
+ */
+ public CipherParameters generateDerivedParameters(
+ int keySize,
+ int ivSize)
+ {
+ keySize = keySize / 8;
+ ivSize = ivSize / 8;
+
+ byte[] dKey = generateDerivedKey(KEY_MATERIAL, keySize);
+
+ byte[] iv = generateDerivedKey(IV_MATERIAL, ivSize);
+
+ return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), iv, 0, ivSize);
+ }
+
+ /**
+ * Generate a key parameter for use with a MAC derived from the password,
+ * salt, and iteration count we are currently initialised with.
+ *
+ * @param keySize the size of the key we want (in bits)
+ * @return a KeyParameter object.
+ */
+ public CipherParameters generateDerivedMacParameters(
+ int keySize)
+ {
+ keySize = keySize / 8;
+
+ byte[] dKey = generateDerivedKey(MAC_MATERIAL, keySize);
+
+ return new KeyParameter(dKey, 0, keySize);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java
new file mode 100644
index 00000000..1e666239
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java
@@ -0,0 +1,121 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.PBEParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+
+/**
+ * Generator for PBE derived keys and ivs as defined by PKCS 5 V2.0 Scheme 1.
+ * Note this generator is limited to the size of the hash produced by the
+ * digest used to drive it.
+ * <p>
+ * The document this implementation is based on can be found at
+ * <a href=https://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html>
+ * RSA's PKCS5 Page</a>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS5S1ParametersGenerator
+ extends PBEParametersGenerator
+{
+ private Digest digest;
+
+ /**
+ * Construct a PKCS 5 Scheme 1 Parameters generator.
+ *
+ * @param digest the digest to be used as the source of derived keys.
+ */
+ public PKCS5S1ParametersGenerator(
+ Digest digest)
+ {
+ this.digest = digest;
+ }
+
+ /**
+ * the derived key function, the ith hash of the password and the salt.
+ */
+ private byte[] generateDerivedKey()
+ {
+ byte[] digestBytes = new byte[digest.getDigestSize()];
+
+ digest.update(password, 0, password.length);
+ digest.update(salt, 0, salt.length);
+
+ digest.doFinal(digestBytes, 0);
+ for (int i = 1; i < iterationCount; i++)
+ {
+ digest.update(digestBytes, 0, digestBytes.length);
+ digest.doFinal(digestBytes, 0);
+ }
+
+ return digestBytes;
+ }
+
+ /**
+ * Generate a key parameter derived from the password, salt, and iteration
+ * count we are currently initialised with.
+ *
+ * @param keySize the size of the key we want (in bits)
+ * @return a KeyParameter object.
+ * @exception IllegalArgumentException if the key length larger than the base hash size.
+ */
+ public CipherParameters generateDerivedParameters(
+ int keySize)
+ {
+ keySize = keySize / 8;
+
+ if (keySize > digest.getDigestSize())
+ {
+ throw new IllegalArgumentException(
+ "Can't generate a derived key " + keySize + " bytes long.");
+ }
+
+ byte[] dKey = generateDerivedKey();
+
+ return new KeyParameter(dKey, 0, keySize);
+ }
+
+ /**
+ * Generate a key with initialisation vector parameter derived from
+ * the password, salt, and iteration count we are currently initialised
+ * with.
+ *
+ * @param keySize the size of the key we want (in bits)
+ * @param ivSize the size of the iv we want (in bits)
+ * @return a ParametersWithIV object.
+ * @exception IllegalArgumentException if keySize + ivSize is larger than the base hash size.
+ */
+ public CipherParameters generateDerivedParameters(
+ int keySize,
+ int ivSize)
+ {
+ keySize = keySize / 8;
+ ivSize = ivSize / 8;
+
+ if ((keySize + ivSize) > digest.getDigestSize())
+ {
+ throw new IllegalArgumentException(
+ "Can't generate a derived key " + (keySize + ivSize) + " bytes long.");
+ }
+
+ byte[] dKey = generateDerivedKey();
+
+ return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize);
+ }
+
+ /**
+ * Generate a key parameter for use with a MAC derived from the password,
+ * salt, and iteration count we are currently initialised with.
+ *
+ * @param keySize the size of the key we want (in bits)
+ * @return a KeyParameter object.
+ * @exception IllegalArgumentException if the key length larger than the base hash size.
+ */
+ public CipherParameters generateDerivedMacParameters(
+ int keySize)
+ {
+ return generateDerivedParameters(keySize);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
new file mode 100644
index 00000000..d26027fe
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
@@ -0,0 +1,160 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.Mac;
+import com.android.internal.org.bouncycastle.crypto.PBEParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.macs.HMac;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+// Android-changed: Use Android digests
+// import org.bouncycastle.crypto.util.DigestFactory;
+import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Generator for PBE derived keys and ivs as defined by PKCS 5 V2.0 Scheme 2.
+ * This generator uses a SHA-1 HMac as the calculation function.
+ * <p>
+ * The document this implementation is based on can be found at
+ * <a href=https://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html>
+ * RSA's PKCS5 Page</a>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS5S2ParametersGenerator
+ extends PBEParametersGenerator
+{
+ private Mac hMac;
+ private byte[] state;
+
+ /**
+ * construct a PKCS5 Scheme 2 Parameters generator.
+ */
+ public PKCS5S2ParametersGenerator()
+ {
+ // Android-changed: Use Android digests
+ // this(DigestFactory.createSHA1());
+ this(AndroidDigestFactory.getSHA1());
+ }
+
+ public PKCS5S2ParametersGenerator(Digest digest)
+ {
+ hMac = new HMac(digest);
+ state = new byte[hMac.getMacSize()];
+ }
+
+ private void F(
+ byte[] S,
+ int c,
+ byte[] iBuf,
+ byte[] out,
+ int outOff)
+ {
+ if (c == 0)
+ {
+ throw new IllegalArgumentException("iteration count must be at least 1.");
+ }
+
+ if (S != null)
+ {
+ hMac.update(S, 0, S.length);
+ }
+
+ hMac.update(iBuf, 0, iBuf.length);
+ hMac.doFinal(state, 0);
+
+ System.arraycopy(state, 0, out, outOff, state.length);
+
+ for (int count = 1; count < c; count++)
+ {
+ hMac.update(state, 0, state.length);
+ hMac.doFinal(state, 0);
+
+ for (int j = 0; j != state.length; j++)
+ {
+ out[outOff + j] ^= state[j];
+ }
+ }
+ }
+
+ private byte[] generateDerivedKey(
+ int dkLen)
+ {
+ int hLen = hMac.getMacSize();
+ int l = (dkLen + hLen - 1) / hLen;
+ byte[] iBuf = new byte[4];
+ byte[] outBytes = new byte[l * hLen];
+ int outPos = 0;
+
+ CipherParameters param = new KeyParameter(password);
+
+ hMac.init(param);
+
+ for (int i = 1; i <= l; i++)
+ {
+ // Increment the value in 'iBuf'
+ int pos = 3;
+ while (++iBuf[pos] == 0)
+ {
+ --pos;
+ }
+
+ F(salt, iterationCount, iBuf, outBytes, outPos);
+ outPos += hLen;
+ }
+
+ return outBytes;
+ }
+
+ /**
+ * Generate a key parameter derived from the password, salt, and iteration
+ * count we are currently initialised with.
+ *
+ * @param keySize the size of the key we want (in bits)
+ * @return a KeyParameter object.
+ */
+ public CipherParameters generateDerivedParameters(
+ int keySize)
+ {
+ keySize = keySize / 8;
+
+ byte[] dKey = generateDerivedKey(keySize);
+
+ return new KeyParameter(dKey, 0, keySize);
+ }
+
+ /**
+ * Generate a key with initialisation vector parameter derived from
+ * the password, salt, and iteration count we are currently initialised
+ * with.
+ *
+ * @param keySize the size of the key we want (in bits)
+ * @param ivSize the size of the iv we want (in bits)
+ * @return a ParametersWithIV object.
+ */
+ public CipherParameters generateDerivedParameters(
+ int keySize,
+ int ivSize)
+ {
+ keySize = keySize / 8;
+ ivSize = ivSize / 8;
+
+ byte[] dKey = generateDerivedKey(keySize + ivSize);
+
+ return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize);
+ }
+
+ /**
+ * Generate a key parameter for use with a MAC derived from the password,
+ * salt, and iteration count we are currently initialised with.
+ *
+ * @param keySize the size of the key we want (in bits)
+ * @return a KeyParameter object.
+ */
+ public CipherParameters generateDerivedMacParameters(
+ int keySize)
+ {
+ return generateDerivedParameters(keySize);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
new file mode 100644
index 00000000..86a62fe5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
@@ -0,0 +1,234 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.generators;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
+import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.RSAKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import com.android.internal.org.bouncycastle.math.Primes;
+import com.android.internal.org.bouncycastle.math.ec.WNafUtil;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * an RSA key pair generator.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RSAKeyPairGenerator
+ implements AsymmetricCipherKeyPairGenerator
+{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+
+ private RSAKeyGenerationParameters param;
+
+ public void init(KeyGenerationParameters param)
+ {
+ this.param = (RSAKeyGenerationParameters)param;
+ }
+
+ public AsymmetricCipherKeyPair generateKeyPair()
+ {
+ AsymmetricCipherKeyPair result = null;
+ boolean done = false;
+
+ //
+ // p and q values should have a length of half the strength in bits
+ //
+ int strength = param.getStrength();
+ int pbitlength = (strength + 1) / 2;
+ int qbitlength = strength - pbitlength;
+ int mindiffbits = (strength / 2) - 100;
+
+ if (mindiffbits < strength / 3)
+ {
+ mindiffbits = strength / 3;
+ }
+
+ int minWeight = strength >> 2;
+
+ // d lower bound is 2^(strength / 2)
+ BigInteger dLowerBound = BigInteger.valueOf(2).pow(strength / 2);
+ // squared bound (sqrt(2)*2^(nlen/2-1))^2
+ BigInteger squaredBound = ONE.shiftLeft(strength - 1);
+ // 2^(nlen/2 - 100)
+ BigInteger minDiff = ONE.shiftLeft(mindiffbits);
+
+ while (!done)
+ {
+ BigInteger p, q, n, d, e, pSub1, qSub1, gcd, lcm;
+
+ e = param.getPublicExponent();
+
+ p = chooseRandomPrime(pbitlength, e, squaredBound);
+
+ //
+ // generate a modulus of the required length
+ //
+ for (; ; )
+ {
+ q = chooseRandomPrime(qbitlength, e, squaredBound);
+
+ // p and q should not be too close together (or equal!)
+ BigInteger diff = q.subtract(p).abs();
+ if (diff.bitLength() < mindiffbits || diff.compareTo(minDiff) <= 0)
+ {
+ continue;
+ }
+
+ //
+ // calculate the modulus
+ //
+ n = p.multiply(q);
+
+ if (n.bitLength() != strength)
+ {
+ //
+ // if we get here our primes aren't big enough, make the largest
+ // of the two p and try again
+ //
+ p = p.max(q);
+ continue;
+ }
+
+ /*
+ * Require a minimum weight of the NAF representation, since low-weight composites may
+ * be weak against a version of the number-field-sieve for factoring.
+ *
+ * See "The number field sieve for integers of low weight", Oliver Schirokauer.
+ */
+ if (WNafUtil.getNafWeight(n) < minWeight)
+ {
+ p = chooseRandomPrime(pbitlength, e, squaredBound);
+ continue;
+ }
+
+ break;
+ }
+
+ if (p.compareTo(q) < 0)
+ {
+ gcd = p;
+ p = q;
+ q = gcd;
+ }
+
+ pSub1 = p.subtract(ONE);
+ qSub1 = q.subtract(ONE);
+ gcd = pSub1.gcd(qSub1);
+ lcm = pSub1.divide(gcd).multiply(qSub1);
+
+ //
+ // calculate the private exponent
+ //
+ d = e.modInverse(lcm);
+
+ if (d.compareTo(dLowerBound) <= 0)
+ {
+ continue;
+ }
+ else
+ {
+ done = true;
+ }
+
+ //
+ // calculate the CRT factors
+ //
+ BigInteger dP, dQ, qInv;
+
+ dP = d.remainder(pSub1);
+ dQ = d.remainder(qSub1);
+ qInv = BigIntegers.modOddInverse(p, q);
+
+ result = new AsymmetricCipherKeyPair(
+ new RSAKeyParameters(false, n, e),
+ new RSAPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv));
+ }
+
+ return result;
+ }
+
+ /**
+ * Choose a random prime value for use with RSA
+ *
+ * @param bitlength the bit-length of the returned prime
+ * @param e the RSA public exponent
+ * @return A prime p, with (p-1) relatively prime to e
+ */
+ protected BigInteger chooseRandomPrime(int bitlength, BigInteger e, BigInteger sqrdBound)
+ {
+ for (int i = 0; i != 5 * bitlength; i++)
+ {
+ BigInteger p = BigIntegers.createRandomPrime(bitlength, 1, param.getRandom());
+
+ if (p.mod(e).equals(ONE))
+ {
+ continue;
+ }
+
+ if (p.multiply(p).compareTo(sqrdBound) < 0)
+ {
+ continue;
+ }
+
+ if (!isProbablePrime(p))
+ {
+ continue;
+ }
+
+ if (!e.gcd(p.subtract(ONE)).equals(ONE))
+ {
+ continue;
+ }
+
+ return p;
+ }
+
+ throw new IllegalStateException("unable to generate prime number for RSA key");
+ }
+
+ protected boolean isProbablePrime(BigInteger x)
+ {
+ int iterations = getNumberOfIterations(x.bitLength(), param.getCertainty());
+
+ /*
+ * Primes class for FIPS 186-4 C.3 primality checking
+ */
+ return !Primes.hasAnySmallFactors(x) && Primes.isMRProbablePrime(x, param.getRandom(), iterations);
+ }
+
+ private static int getNumberOfIterations(int bits, int certainty)
+ {
+ /*
+ * NOTE: We enforce a minimum 'certainty' of 100 for bits >= 1024 (else 80). Where the
+ * certainty is higher than the FIPS 186-4 tables (C.2/C.3) cater to, extra iterations
+ * are added at the "worst case rate" for the excess.
+ */
+ if (bits >= 1536)
+ {
+ return certainty <= 100 ? 3
+ : certainty <= 128 ? 4
+ : 4 + (certainty - 128 + 1) / 2;
+ }
+ else if (bits >= 1024)
+ {
+ return certainty <= 100 ? 4
+ : certainty <= 112 ? 5
+ : 5 + (certainty - 112 + 1) / 2;
+ }
+ else if (bits >= 512)
+ {
+ return certainty <= 80 ? 5
+ : certainty <= 100 ? 7
+ : 7 + (certainty - 100 + 1) / 2;
+ }
+ else
+ {
+ return certainty <= 80 ? 40
+ : 40 + (certainty - 80 + 1) / 2;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/DigestInputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/DigestInputStream.java
new file mode 100644
index 00000000..a746acc9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/DigestInputStream.java
@@ -0,0 +1,56 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.io;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.android.internal.org.bouncycastle.crypto.Digest;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DigestInputStream
+ extends FilterInputStream
+{
+ protected Digest digest;
+
+ public DigestInputStream(
+ InputStream stream,
+ Digest digest)
+ {
+ super(stream);
+ this.digest = digest;
+ }
+
+ public int read()
+ throws IOException
+ {
+ int b = in.read();
+
+ if (b >= 0)
+ {
+ digest.update((byte)b);
+ }
+ return b;
+ }
+
+ public int read(
+ byte[] b,
+ int off,
+ int len)
+ throws IOException
+ {
+ int n = in.read(b, off, len);
+ if (n > 0)
+ {
+ digest.update(b, off, n);
+ }
+ return n;
+ }
+
+ public Digest getDigest()
+ {
+ return digest;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/DigestOutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/DigestOutputStream.java
new file mode 100644
index 00000000..4996e70e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/DigestOutputStream.java
@@ -0,0 +1,46 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.crypto.Digest;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DigestOutputStream
+ extends OutputStream
+{
+ protected Digest digest;
+
+ public DigestOutputStream(
+ Digest Digest)
+ {
+ this.digest = Digest;
+ }
+
+ public void write(int b)
+ throws IOException
+ {
+ digest.update((byte)b);
+ }
+
+ public void write(
+ byte[] b,
+ int off,
+ int len)
+ throws IOException
+ {
+ digest.update(b, off, len);
+ }
+
+ public byte[] getDigest()
+ {
+ byte[] res = new byte[digest.getDigestSize()];
+
+ digest.doFinal(res, 0);
+
+ return res;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/MacInputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/MacInputStream.java
new file mode 100644
index 00000000..d4059bbc
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/MacInputStream.java
@@ -0,0 +1,56 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.io;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.android.internal.org.bouncycastle.crypto.Mac;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class MacInputStream
+ extends FilterInputStream
+{
+ protected Mac mac;
+
+ public MacInputStream(
+ InputStream stream,
+ Mac mac)
+ {
+ super(stream);
+ this.mac = mac;
+ }
+
+ public int read()
+ throws IOException
+ {
+ int b = in.read();
+
+ if (b >= 0)
+ {
+ mac.update((byte)b);
+ }
+ return b;
+ }
+
+ public int read(
+ byte[] b,
+ int off,
+ int len)
+ throws IOException
+ {
+ int n = in.read(b, off, len);
+ if (n >= 0)
+ {
+ mac.update(b, off, n);
+ }
+ return n;
+ }
+
+ public Mac getMac()
+ {
+ return mac;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/MacOutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/MacOutputStream.java
new file mode 100644
index 00000000..c57bcd18
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/io/MacOutputStream.java
@@ -0,0 +1,46 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.crypto.Mac;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class MacOutputStream
+ extends OutputStream
+{
+ protected Mac mac;
+
+ public MacOutputStream(
+ Mac mac)
+ {
+ this.mac = mac;
+ }
+
+ public void write(int b)
+ throws IOException
+ {
+ mac.update((byte)b);
+ }
+
+ public void write(
+ byte[] b,
+ int off,
+ int len)
+ throws IOException
+ {
+ mac.update(b, off, len);
+ }
+
+ public byte[] getMac()
+ {
+ byte[] res = new byte[mac.getMacSize()];
+
+ mac.doFinal(res, 0);
+
+ return res;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java
new file mode 100644
index 00000000..38efe5cb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/CBCBlockCipherMac.java
@@ -0,0 +1,231 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.macs;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.Mac;
+import com.android.internal.org.bouncycastle.crypto.modes.CBCBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.paddings.BlockCipherPadding;
+
+/**
+ * standard CBC Block Cipher MAC - if no padding is specified the default of
+ * pad of zeroes is used.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CBCBlockCipherMac
+ implements Mac
+{
+ private byte[] mac;
+
+ private byte[] buf;
+ private int bufOff;
+ private BlockCipher cipher;
+ private BlockCipherPadding padding;
+
+ private int macSize;
+
+ /**
+ * create a standard MAC based on a CBC block cipher. This will produce an
+ * authentication code half the length of the block size of the cipher.
+ *
+ * @param cipher the cipher to be used as the basis of the MAC generation.
+ */
+ public CBCBlockCipherMac(
+ BlockCipher cipher)
+ {
+ this(cipher, (cipher.getBlockSize() * 8) / 2, null);
+ }
+
+ /**
+ * create a standard MAC based on a CBC block cipher. This will produce an
+ * authentication code half the length of the block size of the cipher.
+ *
+ * @param cipher the cipher to be used as the basis of the MAC generation.
+ * @param padding the padding to be used to complete the last block.
+ */
+ public CBCBlockCipherMac(
+ BlockCipher cipher,
+ BlockCipherPadding padding)
+ {
+ this(cipher, (cipher.getBlockSize() * 8) / 2, padding);
+ }
+
+ /**
+ * create a standard MAC based on a block cipher with the size of the
+ * MAC been given in bits. This class uses CBC mode as the basis for the
+ * MAC generation.
+ * <p>
+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81),
+ * or 16 bits if being used as a data authenticator (FIPS Publication 113),
+ * and in general should be less than the size of the block cipher as it reduces
+ * the chance of an exhaustive attack (see Handbook of Applied Cryptography).
+ *
+ * @param cipher the cipher to be used as the basis of the MAC generation.
+ * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8.
+ */
+ public CBCBlockCipherMac(
+ BlockCipher cipher,
+ int macSizeInBits)
+ {
+ this(cipher, macSizeInBits, null);
+ }
+
+ /**
+ * create a standard MAC based on a block cipher with the size of the
+ * MAC been given in bits. This class uses CBC mode as the basis for the
+ * MAC generation.
+ * <p>
+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81),
+ * or 16 bits if being used as a data authenticator (FIPS Publication 113),
+ * and in general should be less than the size of the block cipher as it reduces
+ * the chance of an exhaustive attack (see Handbook of Applied Cryptography).
+ *
+ * @param cipher the cipher to be used as the basis of the MAC generation.
+ * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8.
+ * @param padding the padding to be used to complete the last block.
+ */
+ public CBCBlockCipherMac(
+ BlockCipher cipher,
+ int macSizeInBits,
+ BlockCipherPadding padding)
+ {
+ if ((macSizeInBits % 8) != 0)
+ {
+ throw new IllegalArgumentException("MAC size must be multiple of 8");
+ }
+
+ this.cipher = new CBCBlockCipher(cipher);
+ this.padding = padding;
+ this.macSize = macSizeInBits / 8;
+
+ mac = new byte[cipher.getBlockSize()];
+
+ buf = new byte[cipher.getBlockSize()];
+ bufOff = 0;
+ }
+
+ public String getAlgorithmName()
+ {
+ return cipher.getAlgorithmName();
+ }
+
+ public void init(
+ CipherParameters params)
+ {
+ reset();
+
+ cipher.init(true, params);
+ }
+
+ public int getMacSize()
+ {
+ return macSize;
+ }
+
+ public void update(
+ byte in)
+ {
+ if (bufOff == buf.length)
+ {
+ cipher.processBlock(buf, 0, mac, 0);
+ bufOff = 0;
+ }
+
+ buf[bufOff++] = in;
+ }
+
+ public void update(
+ byte[] in,
+ int inOff,
+ int len)
+ {
+ if (len < 0)
+ {
+ throw new IllegalArgumentException("Can't have a negative input length!");
+ }
+
+ int blockSize = cipher.getBlockSize();
+ int gapLen = blockSize - bufOff;
+
+ if (len > gapLen)
+ {
+ System.arraycopy(in, inOff, buf, bufOff, gapLen);
+
+ cipher.processBlock(buf, 0, mac, 0);
+
+ bufOff = 0;
+ len -= gapLen;
+ inOff += gapLen;
+
+ while (len > blockSize)
+ {
+ cipher.processBlock(in, inOff, mac, 0);
+
+ len -= blockSize;
+ inOff += blockSize;
+ }
+ }
+
+ System.arraycopy(in, inOff, buf, bufOff, len);
+
+ bufOff += len;
+ }
+
+ public int doFinal(
+ byte[] out,
+ int outOff)
+ {
+ int blockSize = cipher.getBlockSize();
+
+ if (padding == null)
+ {
+ //
+ // pad with zeroes
+ //
+ while (bufOff < blockSize)
+ {
+ buf[bufOff] = 0;
+ bufOff++;
+ }
+ }
+ else
+ {
+ if (bufOff == blockSize)
+ {
+ cipher.processBlock(buf, 0, mac, 0);
+ bufOff = 0;
+ }
+
+ padding.addPadding(buf, bufOff);
+ }
+
+ cipher.processBlock(buf, 0, mac, 0);
+
+ System.arraycopy(mac, 0, out, outOff, macSize);
+
+ reset();
+
+ return macSize;
+ }
+
+ /**
+ * Reset the mac generator.
+ */
+ public void reset()
+ {
+ /*
+ * clean the buffer.
+ */
+ for (int i = 0; i < buf.length; i++)
+ {
+ buf[i] = 0;
+ }
+
+ bufOff = 0;
+
+ /*
+ * reset the underlying cipher.
+ */
+ cipher.reset();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/HMac.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/HMac.java
new file mode 100644
index 00000000..c88919b3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/macs/HMac.java
@@ -0,0 +1,239 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.macs;
+
+import java.util.Hashtable;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.ExtendedDigest;
+import com.android.internal.org.bouncycastle.crypto.Mac;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.util.Integers;
+import com.android.internal.org.bouncycastle.util.Memoable;
+
+/**
+ * HMAC implementation based on RFC2104
+ *
+ * H(K XOR opad, H(K XOR ipad, text))
+ * @hide This class is not part of the Android public SDK API
+ */
+public class HMac
+ implements Mac
+{
+ private final static byte IPAD = (byte)0x36;
+ private final static byte OPAD = (byte)0x5C;
+
+ private Digest digest;
+ private int digestSize;
+ private int blockLength;
+ private Memoable ipadState;
+ private Memoable opadState;
+
+ private byte[] inputPad;
+ private byte[] outputBuf;
+
+ private static Hashtable blockLengths;
+
+ static
+ {
+ blockLengths = new Hashtable();
+
+ // BEGIN Android-removed: Unsupported algorithms
+ // blockLengths.put("GOST3411", Integers.valueOf(32));
+ //
+ // blockLengths.put("MD2", Integers.valueOf(16));
+ // blockLengths.put("MD4", Integers.valueOf(64));
+ // END Android-removed: Unsupported algorithms
+ blockLengths.put("MD5", Integers.valueOf(64));
+
+ // BEGIN Android-removed: Unsupported algorithms
+ // blockLengths.put("RIPEMD128", Integers.valueOf(64));
+ // blockLengths.put("RIPEMD160", Integers.valueOf(64));
+ // END Android-removed: Unsupported algorithms
+
+ blockLengths.put("SHA-1", Integers.valueOf(64));
+ blockLengths.put("SHA-224", Integers.valueOf(64));
+ blockLengths.put("SHA-256", Integers.valueOf(64));
+ blockLengths.put("SHA-384", Integers.valueOf(128));
+ blockLengths.put("SHA-512", Integers.valueOf(128));
+
+ // BEGIN Android-removed: Unsupported algorithms
+ // blockLengths.put("Tiger", Integers.valueOf(64));
+ // blockLengths.put("Whirlpool", Integers.valueOf(64));
+ // END Android-removed: Unsupported algorithms
+ }
+
+ private static int getByteLength(
+ Digest digest)
+ {
+ if (digest instanceof ExtendedDigest)
+ {
+ return ((ExtendedDigest)digest).getByteLength();
+ }
+
+ Integer b = (Integer)blockLengths.get(digest.getAlgorithmName());
+
+ if (b == null)
+ {
+ throw new IllegalArgumentException("unknown digest passed: " + digest.getAlgorithmName());
+ }
+
+ return b.intValue();
+ }
+
+ /**
+ * Base constructor for one of the standard digest algorithms that the
+ * byteLength of the algorithm is know for.
+ *
+ * @param digest the digest.
+ */
+ public HMac(
+ Digest digest)
+ {
+ this(digest, getByteLength(digest));
+ }
+
+ private HMac(
+ Digest digest,
+ int byteLength)
+ {
+ this.digest = digest;
+ this.digestSize = digest.getDigestSize();
+ this.blockLength = byteLength;
+ this.inputPad = new byte[blockLength];
+ this.outputBuf = new byte[blockLength + digestSize];
+ }
+
+ public String getAlgorithmName()
+ {
+ return digest.getAlgorithmName() + "/HMAC";
+ }
+
+ public Digest getUnderlyingDigest()
+ {
+ return digest;
+ }
+
+ public void init(
+ CipherParameters params)
+ {
+ digest.reset();
+
+ byte[] key = ((KeyParameter)params).getKey();
+ int keyLength = key.length;
+
+ if (keyLength > blockLength)
+ {
+ digest.update(key, 0, keyLength);
+ digest.doFinal(inputPad, 0);
+
+ keyLength = digestSize;
+ }
+ else
+ {
+ System.arraycopy(key, 0, inputPad, 0, keyLength);
+ }
+
+ for (int i = keyLength; i < inputPad.length; i++)
+ {
+ inputPad[i] = 0;
+ }
+
+ System.arraycopy(inputPad, 0, outputBuf, 0, blockLength);
+
+ xorPad(inputPad, blockLength, IPAD);
+ xorPad(outputBuf, blockLength, OPAD);
+
+ if (digest instanceof Memoable)
+ {
+ opadState = ((Memoable)digest).copy();
+
+ ((Digest)opadState).update(outputBuf, 0, blockLength);
+ }
+
+ digest.update(inputPad, 0, inputPad.length);
+
+ if (digest instanceof Memoable)
+ {
+ ipadState = ((Memoable)digest).copy();
+ }
+ }
+
+ public int getMacSize()
+ {
+ return digestSize;
+ }
+
+ public void update(
+ byte in)
+ {
+ digest.update(in);
+ }
+
+ public void update(
+ byte[] in,
+ int inOff,
+ int len)
+ {
+ digest.update(in, inOff, len);
+ }
+
+ public int doFinal(
+ byte[] out,
+ int outOff)
+ {
+ digest.doFinal(outputBuf, blockLength);
+
+ if (opadState != null)
+ {
+ ((Memoable)digest).reset(opadState);
+ digest.update(outputBuf, blockLength, digest.getDigestSize());
+ }
+ else
+ {
+ digest.update(outputBuf, 0, outputBuf.length);
+ }
+
+ int len = digest.doFinal(out, outOff);
+
+ for (int i = blockLength; i < outputBuf.length; i++)
+ {
+ outputBuf[i] = 0;
+ }
+
+ if (ipadState != null)
+ {
+ ((Memoable)digest).reset(ipadState);
+ }
+ else
+ {
+ digest.update(inputPad, 0, inputPad.length);
+ }
+
+ return len;
+ }
+
+ /**
+ * Reset the mac generator.
+ */
+ public void reset()
+ {
+ /*
+ * reset the underlying digest.
+ */
+ digest.reset();
+
+ /*
+ * reinitialize the digest.
+ */
+ digest.update(inputPad, 0, inputPad.length);
+ }
+
+ private static void xorPad(byte[] pad, int len, byte n)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ pad[i] ^= n;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/AEADBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/AEADBlockCipher.java
new file mode 100644
index 00000000..aa233b16
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/AEADBlockCipher.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+
+/**
+ * An {@link AEADCipher} based on a {@link BlockCipher}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface AEADBlockCipher
+ extends AEADCipher
+{
+ /**
+ * return the {@link BlockCipher} this object wraps.
+ *
+ * @return the {@link BlockCipher} this object wraps.
+ */
+ public BlockCipher getUnderlyingCipher();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/AEADCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/AEADCipher.java
new file mode 100644
index 00000000..8ac9dd86
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/AEADCipher.java
@@ -0,0 +1,140 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+
+/**
+ * A cipher mode that includes authenticated encryption with a streaming mode and optional associated data.
+ * <p>
+ * Implementations of this interface may operate in a packet mode (where all input data is buffered and
+ * processed during the call to {@link #doFinal(byte[], int)}), or in a streaming mode (where output data is
+ * incrementally produced with each call to {@link #processByte(byte, byte[], int)} or
+ * {@link #processBytes(byte[], int, int, byte[], int)}.
+ * </p>
+ * This is important to consider during decryption: in a streaming mode, unauthenticated plaintext data
+ * may be output prior to the call to {@link #doFinal(byte[], int)} that results in an authentication
+ * failure. The higher level protocol utilising this cipher must ensure the plaintext data is handled
+ * appropriately until the end of data is reached and the entire ciphertext is authenticated.
+ * @see com.android.internal.org.bouncycastle.crypto.params.AEADParameters
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface AEADCipher
+{
+ /**
+ * initialise the underlying cipher. Parameter can either be an AEADParameters or a ParametersWithIV object.
+ *
+ * @param forEncryption true if we are setting up for encryption, false otherwise.
+ * @param params the necessary parameters for the underlying cipher to be initialised.
+ * @exception IllegalArgumentException if the params argument is inappropriate.
+ */
+ public void init(boolean forEncryption, CipherParameters params)
+ throws IllegalArgumentException;
+
+ /**
+ * Return the name of the algorithm.
+ *
+ * @return the algorithm name.
+ */
+ public String getAlgorithmName();
+
+ /**
+ * Add a single byte to the associated data check.
+ * <br>If the implementation supports it, this will be an online operation and will not retain the associated data.
+ *
+ * @param in the byte to be processed.
+ */
+ public void processAADByte(byte in);
+
+ /**
+ * Add a sequence of bytes to the associated data check.
+ * <br>If the implementation supports it, this will be an online operation and will not retain the associated data.
+ *
+ * @param in the input byte array.
+ * @param inOff the offset into the in array where the data to be processed starts.
+ * @param len the number of bytes to be processed.
+ */
+ public void processAADBytes(byte[] in, int inOff, int len);
+
+ /**
+ * encrypt/decrypt a single byte.
+ *
+ * @param in the byte to be processed.
+ * @param out the output buffer the processed byte goes into.
+ * @param outOff the offset into the output byte array the processed data starts at.
+ * @return the number of bytes written to out.
+ * @exception DataLengthException if the output buffer is too small.
+ */
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException;
+
+ /**
+ * process a block of bytes from in putting the result into out.
+ *
+ * @param in the input byte array.
+ * @param inOff the offset into the in array where the data to be processed starts.
+ * @param len the number of bytes to be processed.
+ * @param out the output buffer the processed bytes go into.
+ * @param outOff the offset into the output byte array the processed data starts at.
+ * @return the number of bytes written to out.
+ * @exception DataLengthException if the output buffer is too small.
+ */
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException;
+
+ /**
+ * Finish the operation either appending or verifying the MAC at the end of the data.
+ *
+ * @param out space for any resulting output data.
+ * @param outOff offset into out to start copying the data at.
+ * @return number of bytes written into out.
+ * @throws IllegalStateException if the cipher is in an inappropriate state.
+ * @throws com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException if the MAC fails to match.
+ */
+ public int doFinal(byte[] out, int outOff)
+ throws IllegalStateException, InvalidCipherTextException;
+
+ /**
+ * Return the value of the MAC associated with the last stream processed.
+ *
+ * @return MAC for plaintext data.
+ */
+ public byte[] getMac();
+
+ /**
+ * return the size of the output buffer required for a processBytes
+ * an input of len bytes.
+ * <p>
+ * The returned size may be dependent on the initialisation of this cipher
+ * and may not be accurate once subsequent input data is processed - this method
+ * should be invoked immediately prior to input data being processed.
+ * </p>
+ *
+ * @param len the length of the input.
+ * @return the space required to accommodate a call to processBytes
+ * with len bytes of input.
+ */
+ public int getUpdateOutputSize(int len);
+
+ /**
+ * return the size of the output buffer required for a processBytes plus a
+ * doFinal with an input of len bytes.
+ * <p>
+ * The returned size may be dependent on the initialisation of this cipher
+ * and may not be accurate once subsequent input data is processed - this method
+ * should be invoked immediately prior to a call to final processing of input data
+ * and a call to {@link #doFinal(byte[], int)}.
+ * </p>
+ * @param len the length of the input.
+ * @return the space required to accommodate a call to processBytes and doFinal
+ * with len bytes of input.
+ */
+ public int getOutputSize(int len);
+
+ /**
+ * Reset the cipher. After resetting the cipher is in the same state
+ * as it was after the last init (if there was one).
+ */
+ public void reset();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CBCBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CBCBlockCipher.java
new file mode 100644
index 00000000..d767a6aa
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CBCBlockCipher.java
@@ -0,0 +1,255 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * implements Cipher-Block-Chaining (CBC) mode on top of a simple cipher.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CBCBlockCipher
+ implements BlockCipher
+{
+ private byte[] IV;
+ private byte[] cbcV;
+ private byte[] cbcNextV;
+
+ private int blockSize;
+ private BlockCipher cipher = null;
+ private boolean encrypting;
+
+ /**
+ * Basic constructor.
+ *
+ * @param cipher the block cipher to be used as the basis of chaining.
+ */
+ public CBCBlockCipher(
+ BlockCipher cipher)
+ {
+ this.cipher = cipher;
+ this.blockSize = cipher.getBlockSize();
+
+ this.IV = new byte[blockSize];
+ this.cbcV = new byte[blockSize];
+ this.cbcNextV = new byte[blockSize];
+ }
+
+ /**
+ * return the underlying block cipher that we are wrapping.
+ *
+ * @return the underlying block cipher that we are wrapping.
+ */
+ public BlockCipher getUnderlyingCipher()
+ {
+ return cipher;
+ }
+
+ /**
+ * Initialise the cipher and, possibly, the initialisation vector (IV).
+ * If an IV isn't passed as part of the parameter, the IV will be all zeros.
+ *
+ * @param encrypting if true the cipher is initialised for
+ * encryption, if false for decryption.
+ * @param params the key and other data required by the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean encrypting,
+ CipherParameters params)
+ throws IllegalArgumentException
+ {
+ boolean oldEncrypting = this.encrypting;
+
+ this.encrypting = encrypting;
+
+ if (params instanceof ParametersWithIV)
+ {
+ ParametersWithIV ivParam = (ParametersWithIV)params;
+ byte[] iv = ivParam.getIV();
+
+ if (iv.length != blockSize)
+ {
+ throw new IllegalArgumentException("initialisation vector must be the same length as block size");
+ }
+
+ System.arraycopy(iv, 0, IV, 0, iv.length);
+
+ reset();
+
+ // if null it's an IV changed only.
+ if (ivParam.getParameters() != null)
+ {
+ cipher.init(encrypting, ivParam.getParameters());
+ }
+ else if (oldEncrypting != encrypting)
+ {
+ throw new IllegalArgumentException("cannot change encrypting state without providing key.");
+ }
+ }
+ else
+ {
+ reset();
+
+ // if it's null, key is to be reused.
+ if (params != null)
+ {
+ cipher.init(encrypting, params);
+ }
+ else if (oldEncrypting != encrypting)
+ {
+ throw new IllegalArgumentException("cannot change encrypting state without providing key.");
+ }
+ }
+ }
+
+ /**
+ * return the algorithm name and mode.
+ *
+ * @return the name of the underlying algorithm followed by "/CBC".
+ */
+ public String getAlgorithmName()
+ {
+ return cipher.getAlgorithmName() + "/CBC";
+ }
+
+ /**
+ * return the block size of the underlying cipher.
+ *
+ * @return the block size of the underlying cipher.
+ */
+ public int getBlockSize()
+ {
+ return cipher.getBlockSize();
+ }
+
+ /**
+ * Process one block of input from the array in and write it to
+ * the out array.
+ *
+ * @param in the array containing the input data.
+ * @param inOff offset into the in array the data starts at.
+ * @param out the array the output data will be copied into.
+ * @param outOff the offset into the out array the output will start at.
+ * @exception DataLengthException if there isn't enough data in in, or
+ * space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ * @return the number of bytes processed and produced.
+ */
+ public int processBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ return (encrypting) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff);
+ }
+
+ /**
+ * reset the chaining vector back to the IV and reset the underlying
+ * cipher.
+ */
+ public void reset()
+ {
+ System.arraycopy(IV, 0, cbcV, 0, IV.length);
+ Arrays.fill(cbcNextV, (byte)0);
+
+ cipher.reset();
+ }
+
+ /**
+ * Do the appropriate chaining step for CBC mode encryption.
+ *
+ * @param in the array containing the data to be encrypted.
+ * @param inOff offset into the in array the data starts at.
+ * @param out the array the encrypted data will be copied into.
+ * @param outOff the offset into the out array the output will start at.
+ * @exception DataLengthException if there isn't enough data in in, or
+ * space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ * @return the number of bytes processed and produced.
+ */
+ private int encryptBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ if ((inOff + blockSize) > in.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+
+ /*
+ * XOR the cbcV and the input,
+ * then encrypt the cbcV
+ */
+ for (int i = 0; i < blockSize; i++)
+ {
+ cbcV[i] ^= in[inOff + i];
+ }
+
+ int length = cipher.processBlock(cbcV, 0, out, outOff);
+
+ /*
+ * copy ciphertext to cbcV
+ */
+ System.arraycopy(out, outOff, cbcV, 0, cbcV.length);
+
+ return length;
+ }
+
+ /**
+ * Do the appropriate chaining step for CBC mode decryption.
+ *
+ * @param in the array containing the data to be decrypted.
+ * @param inOff offset into the in array the data starts at.
+ * @param out the array the decrypted data will be copied into.
+ * @param outOff the offset into the out array the output will start at.
+ * @exception DataLengthException if there isn't enough data in in, or
+ * space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ * @return the number of bytes processed and produced.
+ */
+ private int decryptBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ if ((inOff + blockSize) > in.length)
+ {
+ throw new DataLengthException("input buffer too short");
+ }
+
+ System.arraycopy(in, inOff, cbcNextV, 0, blockSize);
+
+ int length = cipher.processBlock(in, inOff, out, outOff);
+
+ /*
+ * XOR the cbcV and the output
+ */
+ for (int i = 0; i < blockSize; i++)
+ {
+ out[outOff + i] ^= cbcV[i];
+ }
+
+ /*
+ * swap the back up buffer into next position
+ */
+ byte[] tmp;
+
+ tmp = cbcV;
+ cbcV = cbcNextV;
+ cbcNextV = tmp;
+
+ return length;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CCMBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CCMBlockCipher.java
new file mode 100644
index 00000000..f93c727b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CCMBlockCipher.java
@@ -0,0 +1,471 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+import java.io.ByteArrayOutputStream;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.Mac;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.macs.CBCBlockCipherMac;
+import com.android.internal.org.bouncycastle.crypto.params.AEADParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Implements the Counter with Cipher Block Chaining mode (CCM) detailed in
+ * NIST Special Publication 800-38C.
+ * <p>
+ * <b>Note</b>: this mode is a packet mode - it needs all the data up front.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CCMBlockCipher
+ implements AEADBlockCipher
+{
+ private BlockCipher cipher;
+ private int blockSize;
+ private boolean forEncryption;
+ private byte[] nonce;
+ private byte[] initialAssociatedText;
+ private int macSize;
+ private CipherParameters keyParam;
+ private byte[] macBlock;
+ private ExposedByteArrayOutputStream associatedText = new ExposedByteArrayOutputStream();
+ private ExposedByteArrayOutputStream data = new ExposedByteArrayOutputStream();
+
+ /**
+ * Basic constructor.
+ *
+ * @param c the block cipher to be used.
+ */
+ public CCMBlockCipher(BlockCipher c)
+ {
+ this.cipher = c;
+ this.blockSize = c.getBlockSize();
+ this.macBlock = new byte[blockSize];
+
+ if (blockSize != 16)
+ {
+ throw new IllegalArgumentException("cipher required with a block size of 16.");
+ }
+ }
+
+ /**
+ * return the underlying block cipher that we are wrapping.
+ *
+ * @return the underlying block cipher that we are wrapping.
+ */
+ public BlockCipher getUnderlyingCipher()
+ {
+ return cipher;
+ }
+
+
+ public void init(boolean forEncryption, CipherParameters params)
+ throws IllegalArgumentException
+ {
+ this.forEncryption = forEncryption;
+
+ CipherParameters cipherParameters;
+ if (params instanceof AEADParameters)
+ {
+ AEADParameters param = (AEADParameters)params;
+
+ nonce = param.getNonce();
+ initialAssociatedText = param.getAssociatedText();
+ macSize = getMacSize(forEncryption, param.getMacSize());
+ cipherParameters = param.getKey();
+ }
+ else if (params instanceof ParametersWithIV)
+ {
+ ParametersWithIV param = (ParametersWithIV)params;
+
+ nonce = param.getIV();
+ initialAssociatedText = null;
+ macSize = getMacSize(forEncryption, 64);
+ cipherParameters = param.getParameters();
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid parameters passed to CCM: " + params.getClass().getName());
+ }
+
+ // NOTE: Very basic support for key re-use, but no performance gain from it
+ if (cipherParameters != null)
+ {
+ keyParam = cipherParameters;
+ }
+
+ if (nonce == null || nonce.length < 7 || nonce.length > 13)
+ {
+ throw new IllegalArgumentException("nonce must have length from 7 to 13 octets");
+ }
+
+ reset();
+ }
+
+ public String getAlgorithmName()
+ {
+ return cipher.getAlgorithmName() + "/CCM";
+ }
+
+ public void processAADByte(byte in)
+ {
+ associatedText.write(in);
+ }
+
+ public void processAADBytes(byte[] in, int inOff, int len)
+ {
+ // TODO: Process AAD online
+ associatedText.write(in, inOff, len);
+ }
+
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ data.write(in);
+
+ return 0;
+ }
+
+ public int processBytes(byte[] in, int inOff, int inLen, byte[] out, int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ if (in.length < (inOff + inLen))
+ {
+ throw new DataLengthException("Input buffer too short");
+ }
+ data.write(in, inOff, inLen);
+
+ return 0;
+ }
+
+ public int doFinal(byte[] out, int outOff)
+ throws IllegalStateException, InvalidCipherTextException
+ {
+ int len = processPacket(data.getBuffer(), 0, data.size(), out, outOff);
+
+ reset();
+
+ return len;
+ }
+
+ public void reset()
+ {
+ cipher.reset();
+ associatedText.reset();
+ data.reset();
+ }
+
+ /**
+ * Returns a byte array containing the mac calculated as part of the
+ * last encrypt or decrypt operation.
+ *
+ * @return the last mac calculated.
+ */
+ public byte[] getMac()
+ {
+ byte[] mac = new byte[macSize];
+
+ System.arraycopy(macBlock, 0, mac, 0, mac.length);
+
+ return mac;
+ }
+
+ public int getUpdateOutputSize(int len)
+ {
+ return 0;
+ }
+
+ public int getOutputSize(int len)
+ {
+ int totalData = len + data.size();
+
+ if (forEncryption)
+ {
+ return totalData + macSize;
+ }
+
+ return totalData < macSize ? 0 : totalData - macSize;
+ }
+
+ /**
+ * Process a packet of data for either CCM decryption or encryption.
+ *
+ * @param in data for processing.
+ * @param inOff offset at which data starts in the input array.
+ * @param inLen length of the data in the input array.
+ * @return a byte array containing the processed input..
+ * @throws IllegalStateException if the cipher is not appropriately set up.
+ * @throws InvalidCipherTextException if the input data is truncated or the mac check fails.
+ */
+ public byte[] processPacket(byte[] in, int inOff, int inLen)
+ throws IllegalStateException, InvalidCipherTextException
+ {
+ byte[] output;
+
+ if (forEncryption)
+ {
+ output = new byte[inLen + macSize];
+ }
+ else
+ {
+ if (inLen < macSize)
+ {
+ throw new InvalidCipherTextException("data too short");
+ }
+ output = new byte[inLen - macSize];
+ }
+
+ processPacket(in, inOff, inLen, output, 0);
+
+ return output;
+ }
+
+ /**
+ * Process a packet of data for either CCM decryption or encryption.
+ *
+ * @param in data for processing.
+ * @param inOff offset at which data starts in the input array.
+ * @param inLen length of the data in the input array.
+ * @param output output array.
+ * @param outOff offset into output array to start putting processed bytes.
+ * @return the number of bytes added to output.
+ * @throws IllegalStateException if the cipher is not appropriately set up.
+ * @throws InvalidCipherTextException if the input data is truncated or the mac check fails.
+ * @throws DataLengthException if output buffer too short.
+ */
+ public int processPacket(byte[] in, int inOff, int inLen, byte[] output, int outOff)
+ throws IllegalStateException, InvalidCipherTextException, DataLengthException
+ {
+ // TODO: handle null keyParam (e.g. via RepeatedKeySpec)
+ // Need to keep the CTR and CBC Mac parts around and reset
+ if (keyParam == null)
+ {
+ throw new IllegalStateException("CCM cipher unitialized.");
+ }
+
+ int n = nonce.length;
+ int q = 15 - n;
+ if (q < 4)
+ {
+ int limitLen = 1 << (8 * q);
+ if (inLen >= limitLen)
+ {
+ throw new IllegalStateException("CCM packet too large for choice of q.");
+ }
+ }
+
+ byte[] iv = new byte[blockSize];
+ iv[0] = (byte)((q - 1) & 0x7);
+ System.arraycopy(nonce, 0, iv, 1, nonce.length);
+
+ BlockCipher ctrCipher = new SICBlockCipher(cipher);
+ ctrCipher.init(forEncryption, new ParametersWithIV(keyParam, iv));
+
+ int outputLen;
+ int inIndex = inOff;
+ int outIndex = outOff;
+
+ if (forEncryption)
+ {
+ outputLen = inLen + macSize;
+ if (output.length < (outputLen + outOff))
+ {
+ throw new OutputLengthException("Output buffer too short.");
+ }
+
+ calculateMac(in, inOff, inLen, macBlock);
+
+ byte[] encMac = new byte[blockSize];
+
+ ctrCipher.processBlock(macBlock, 0, encMac, 0); // S0
+
+ while (inIndex < (inOff + inLen - blockSize)) // S1...
+ {
+ ctrCipher.processBlock(in, inIndex, output, outIndex);
+ outIndex += blockSize;
+ inIndex += blockSize;
+ }
+
+ byte[] block = new byte[blockSize];
+
+ System.arraycopy(in, inIndex, block, 0, inLen + inOff - inIndex);
+
+ ctrCipher.processBlock(block, 0, block, 0);
+
+ System.arraycopy(block, 0, output, outIndex, inLen + inOff - inIndex);
+
+ System.arraycopy(encMac, 0, output, outOff + inLen, macSize);
+ }
+ else
+ {
+ if (inLen < macSize)
+ {
+ throw new InvalidCipherTextException("data too short");
+ }
+ outputLen = inLen - macSize;
+ if (output.length < (outputLen + outOff))
+ {
+ throw new OutputLengthException("Output buffer too short.");
+ }
+
+ System.arraycopy(in, inOff + outputLen, macBlock, 0, macSize);
+
+ ctrCipher.processBlock(macBlock, 0, macBlock, 0);
+
+ for (int i = macSize; i != macBlock.length; i++)
+ {
+ macBlock[i] = 0;
+ }
+
+ while (inIndex < (inOff + outputLen - blockSize))
+ {
+ ctrCipher.processBlock(in, inIndex, output, outIndex);
+ outIndex += blockSize;
+ inIndex += blockSize;
+ }
+
+ byte[] block = new byte[blockSize];
+
+ System.arraycopy(in, inIndex, block, 0, outputLen - (inIndex - inOff));
+
+ ctrCipher.processBlock(block, 0, block, 0);
+
+ System.arraycopy(block, 0, output, outIndex, outputLen - (inIndex - inOff));
+
+ byte[] calculatedMacBlock = new byte[blockSize];
+
+ calculateMac(output, outOff, outputLen, calculatedMacBlock);
+
+ if (!Arrays.constantTimeAreEqual(macBlock, calculatedMacBlock))
+ {
+ throw new InvalidCipherTextException("mac check in CCM failed");
+ }
+ }
+
+ return outputLen;
+ }
+
+ private int calculateMac(byte[] data, int dataOff, int dataLen, byte[] macBlock)
+ {
+ Mac cMac = new CBCBlockCipherMac(cipher, macSize * 8);
+
+ cMac.init(keyParam);
+
+ //
+ // build b0
+ //
+ byte[] b0 = new byte[16];
+
+ if (hasAssociatedText())
+ {
+ b0[0] |= 0x40;
+ }
+
+ b0[0] |= (((cMac.getMacSize() - 2) / 2) & 0x7) << 3;
+
+ b0[0] |= ((15 - nonce.length) - 1) & 0x7;
+
+ System.arraycopy(nonce, 0, b0, 1, nonce.length);
+
+ int q = dataLen;
+ int count = 1;
+ while (q > 0)
+ {
+ b0[b0.length - count] = (byte)(q & 0xff);
+ q >>>= 8;
+ count++;
+ }
+
+ cMac.update(b0, 0, b0.length);
+
+ //
+ // process associated text
+ //
+ if (hasAssociatedText())
+ {
+ int extra;
+
+ int textLength = getAssociatedTextLength();
+ if (textLength < ((1 << 16) - (1 << 8)))
+ {
+ cMac.update((byte)(textLength >> 8));
+ cMac.update((byte)textLength);
+
+ extra = 2;
+ }
+ else // can't go any higher than 2^32
+ {
+ cMac.update((byte)0xff);
+ cMac.update((byte)0xfe);
+ cMac.update((byte)(textLength >> 24));
+ cMac.update((byte)(textLength >> 16));
+ cMac.update((byte)(textLength >> 8));
+ cMac.update((byte)textLength);
+
+ extra = 6;
+ }
+
+ if (initialAssociatedText != null)
+ {
+ cMac.update(initialAssociatedText, 0, initialAssociatedText.length);
+ }
+ if (associatedText.size() > 0)
+ {
+ cMac.update(associatedText.getBuffer(), 0, associatedText.size());
+ }
+
+ extra = (extra + textLength) % 16;
+ if (extra != 0)
+ {
+ for (int i = extra; i != 16; i++)
+ {
+ cMac.update((byte)0x00);
+ }
+ }
+ }
+
+ //
+ // add the text
+ //
+ cMac.update(data, dataOff, dataLen);
+
+ return cMac.doFinal(macBlock, 0);
+ }
+
+ private int getMacSize(boolean forEncryption, int requestedMacBits)
+ {
+ if (forEncryption && (requestedMacBits < 32 || requestedMacBits > 128 || 0 != (requestedMacBits & 15)))
+ {
+ throw new IllegalArgumentException("tag length in octets must be one of {4,6,8,10,12,14,16}");
+ }
+
+ return requestedMacBits >>> 3;
+ }
+
+ private int getAssociatedTextLength()
+ {
+ return associatedText.size() + ((initialAssociatedText == null) ? 0 : initialAssociatedText.length);
+ }
+
+ private boolean hasAssociatedText()
+ {
+ return getAssociatedTextLength() > 0;
+ }
+
+ private class ExposedByteArrayOutputStream
+ extends ByteArrayOutputStream
+ {
+ public ExposedByteArrayOutputStream()
+ {
+ }
+
+ public byte[] getBuffer()
+ {
+ return this.buf;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBBlockCipher.java
new file mode 100644
index 00000000..d8f51e35
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBBlockCipher.java
@@ -0,0 +1,276 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.StreamBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * implements a Cipher-FeedBack (CFB) mode on top of a simple cipher.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CFBBlockCipher
+ extends StreamBlockCipher
+{
+ private byte[] IV;
+ private byte[] cfbV;
+ private byte[] cfbOutV;
+ private byte[] inBuf;
+
+ private int blockSize;
+ private BlockCipher cipher = null;
+ private boolean encrypting;
+ private int byteCount;
+
+ /**
+ * Basic constructor.
+ *
+ * @param cipher the block cipher to be used as the basis of the
+ * feedback mode.
+ * @param bitBlockSize the block size in bits (note: a multiple of 8)
+ */
+ public CFBBlockCipher(
+ BlockCipher cipher,
+ int bitBlockSize)
+ {
+ super(cipher);
+
+ if (bitBlockSize > (cipher.getBlockSize() * 8) || bitBlockSize < 8 || bitBlockSize % 8 != 0)
+ {
+ throw new IllegalArgumentException("CFB" + bitBlockSize + " not supported");
+ }
+
+ this.cipher = cipher;
+ this.blockSize = bitBlockSize / 8;
+
+ this.IV = new byte[cipher.getBlockSize()];
+ this.cfbV = new byte[cipher.getBlockSize()];
+ this.cfbOutV = new byte[cipher.getBlockSize()];
+ this.inBuf = new byte[blockSize];
+ }
+
+ /**
+ * Initialise the cipher and, possibly, the initialisation vector (IV).
+ * If an IV isn't passed as part of the parameter, the IV will be all zeros.
+ * An IV which is too short is handled in FIPS compliant fashion.
+ *
+ * @param encrypting if true the cipher is initialised for
+ * encryption, if false for decryption.
+ * @param params the key and other data required by the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean encrypting,
+ CipherParameters params)
+ throws IllegalArgumentException
+ {
+ this.encrypting = encrypting;
+
+ if (params instanceof ParametersWithIV)
+ {
+ ParametersWithIV ivParam = (ParametersWithIV)params;
+ byte[] iv = ivParam.getIV();
+
+ if (iv.length < IV.length)
+ {
+ // prepend the supplied IV with zeros (per FIPS PUB 81)
+ System.arraycopy(iv, 0, IV, IV.length - iv.length, iv.length);
+ for (int i = 0; i < IV.length - iv.length; i++)
+ {
+ IV[i] = 0;
+ }
+ }
+ else
+ {
+ System.arraycopy(iv, 0, IV, 0, IV.length);
+ }
+
+ reset();
+
+ // if null it's an IV changed only.
+ if (ivParam.getParameters() != null)
+ {
+ cipher.init(true, ivParam.getParameters());
+ }
+ }
+ else
+ {
+ reset();
+
+ // if it's null, key is to be reused.
+ if (params != null)
+ {
+ cipher.init(true, params);
+ }
+ }
+ }
+
+ /**
+ * return the algorithm name and mode.
+ *
+ * @return the name of the underlying algorithm followed by "/CFB"
+ * and the block size in bits.
+ */
+ public String getAlgorithmName()
+ {
+ return cipher.getAlgorithmName() + "/CFB" + (blockSize * 8);
+ }
+
+ protected byte calculateByte(byte in)
+ throws DataLengthException, IllegalStateException
+ {
+ return (encrypting) ? encryptByte(in) : decryptByte(in);
+ }
+
+ private byte encryptByte(byte in)
+ {
+ if (byteCount == 0)
+ {
+ cipher.processBlock(cfbV, 0, cfbOutV, 0);
+ }
+
+ byte rv = (byte)(cfbOutV[byteCount] ^ in);
+ inBuf[byteCount++] = rv;
+
+ if (byteCount == blockSize)
+ {
+ byteCount = 0;
+
+ System.arraycopy(cfbV, blockSize, cfbV, 0, cfbV.length - blockSize);
+ System.arraycopy(inBuf, 0, cfbV, cfbV.length - blockSize, blockSize);
+ }
+
+ return rv;
+ }
+
+ private byte decryptByte(byte in)
+ {
+ if (byteCount == 0)
+ {
+ cipher.processBlock(cfbV, 0, cfbOutV, 0);
+ }
+
+ inBuf[byteCount] = in;
+ byte rv = (byte)(cfbOutV[byteCount++] ^ in);
+
+ if (byteCount == blockSize)
+ {
+ byteCount = 0;
+
+ System.arraycopy(cfbV, blockSize, cfbV, 0, cfbV.length - blockSize);
+ System.arraycopy(inBuf, 0, cfbV, cfbV.length - blockSize, blockSize);
+ }
+
+ return rv;
+ }
+
+ /**
+ * return the block size we are operating at.
+ *
+ * @return the block size we are operating at (in bytes).
+ */
+ public int getBlockSize()
+ {
+ return blockSize;
+ }
+
+ /**
+ * Process one block of input from the array in and write it to
+ * the out array.
+ *
+ * @param in the array containing the input data.
+ * @param inOff offset into the in array the data starts at.
+ * @param out the array the output data will be copied into.
+ * @param outOff the offset into the out array the output will start at.
+ * @exception DataLengthException if there isn't enough data in in, or
+ * space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ * @return the number of bytes processed and produced.
+ */
+ public int processBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ processBytes(in, inOff, blockSize, out, outOff);
+
+ return blockSize;
+ }
+
+ /**
+ * Do the appropriate processing for CFB mode encryption.
+ *
+ * @param in the array containing the data to be encrypted.
+ * @param inOff offset into the in array the data starts at.
+ * @param out the array the encrypted data will be copied into.
+ * @param outOff the offset into the out array the output will start at.
+ * @exception DataLengthException if there isn't enough data in in, or
+ * space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ * @return the number of bytes processed and produced.
+ */
+ public int encryptBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ processBytes(in, inOff, blockSize, out, outOff);
+
+ return blockSize;
+ }
+
+ /**
+ * Do the appropriate processing for CFB mode decryption.
+ *
+ * @param in the array containing the data to be decrypted.
+ * @param inOff offset into the in array the data starts at.
+ * @param out the array the encrypted data will be copied into.
+ * @param outOff the offset into the out array the output will start at.
+ * @exception DataLengthException if there isn't enough data in in, or
+ * space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ * @return the number of bytes processed and produced.
+ */
+ public int decryptBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ processBytes(in, inOff, blockSize, out, outOff);
+
+ return blockSize;
+ }
+
+ /**
+ * Return the current state of the initialisation vector.
+ *
+ * @return current IV
+ */
+ public byte[] getCurrentIV()
+ {
+ return Arrays.clone(cfbV);
+ }
+
+ /**
+ * reset the chaining vector back to the IV and reset the underlying
+ * cipher.
+ */
+ public void reset()
+ {
+ System.arraycopy(IV, 0, cfbV, 0, IV.length);
+ Arrays.fill(inBuf, (byte)0);
+ byteCount = 0;
+
+ cipher.reset();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CTSBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CTSBlockCipher.java
new file mode 100644
index 00000000..a277ae2e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CTSBlockCipher.java
@@ -0,0 +1,290 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.BufferedBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.StreamBlockCipher;
+
+/**
+ * A Cipher Text Stealing (CTS) mode cipher. CTS allows block ciphers to
+ * be used to produce cipher text which is the same length as the plain text.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CTSBlockCipher
+ extends BufferedBlockCipher
+{
+ private int blockSize;
+
+ /**
+ * Create a buffered block cipher that uses Cipher Text Stealing
+ *
+ * @param cipher the underlying block cipher this buffering object wraps.
+ */
+ public CTSBlockCipher(
+ BlockCipher cipher)
+ {
+ if (cipher instanceof StreamBlockCipher)
+ {
+ throw new IllegalArgumentException("CTSBlockCipher can only accept ECB, or CBC ciphers");
+ }
+
+ this.cipher = cipher;
+
+ blockSize = cipher.getBlockSize();
+
+ buf = new byte[blockSize * 2];
+ bufOff = 0;
+ }
+
+ /**
+ * return the size of the output buffer required for an update
+ * an input of len bytes.
+ *
+ * @param len the length of the input.
+ * @return the space required to accommodate a call to update
+ * with len bytes of input.
+ */
+ public int getUpdateOutputSize(
+ int len)
+ {
+ int total = len + bufOff;
+ int leftOver = total % buf.length;
+
+ if (leftOver == 0)
+ {
+ return total - buf.length;
+ }
+
+ return total - leftOver;
+ }
+
+ /**
+ * return the size of the output buffer required for an update plus a
+ * doFinal with an input of len bytes.
+ *
+ * @param len the length of the input.
+ * @return the space required to accommodate a call to update and doFinal
+ * with len bytes of input.
+ */
+ public int getOutputSize(
+ int len)
+ {
+ return len + bufOff;
+ }
+
+ /**
+ * process a single byte, producing an output block if necessary.
+ *
+ * @param in the input byte.
+ * @param out the space for any output that might be produced.
+ * @param outOff the offset from which the output will be copied.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there isn't enough space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ */
+ public int processByte(
+ byte in,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ int resultLen = 0;
+
+ if (bufOff == buf.length)
+ {
+ resultLen = cipher.processBlock(buf, 0, out, outOff);
+ System.arraycopy(buf, blockSize, buf, 0, blockSize);
+
+ bufOff = blockSize;
+ }
+
+ buf[bufOff++] = in;
+
+ return resultLen;
+ }
+
+ /**
+ * process an array of bytes, producing output if necessary.
+ *
+ * @param in the input byte array.
+ * @param inOff the offset at which the input data starts.
+ * @param len the number of bytes to be copied out of the input array.
+ * @param out the space for any output that might be produced.
+ * @param outOff the offset from which the output will be copied.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there isn't enough space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ */
+ public int processBytes(
+ byte[] in,
+ int inOff,
+ int len,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ if (len < 0)
+ {
+ throw new IllegalArgumentException("Can't have a negative input length!");
+ }
+
+ int blockSize = getBlockSize();
+ int length = getUpdateOutputSize(len);
+
+ if (length > 0)
+ {
+ if ((outOff + length) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ }
+
+ int resultLen = 0;
+ int gapLen = buf.length - bufOff;
+
+ if (len > gapLen)
+ {
+ System.arraycopy(in, inOff, buf, bufOff, gapLen);
+
+ resultLen += cipher.processBlock(buf, 0, out, outOff);
+ System.arraycopy(buf, blockSize, buf, 0, blockSize);
+
+ bufOff = blockSize;
+
+ len -= gapLen;
+ inOff += gapLen;
+
+ while (len > blockSize)
+ {
+ System.arraycopy(in, inOff, buf, bufOff, blockSize);
+ resultLen += cipher.processBlock(buf, 0, out, outOff + resultLen);
+ System.arraycopy(buf, blockSize, buf, 0, blockSize);
+
+ len -= blockSize;
+ inOff += blockSize;
+ }
+ }
+
+ System.arraycopy(in, inOff, buf, bufOff, len);
+
+ bufOff += len;
+
+ return resultLen;
+ }
+
+ /**
+ * Process the last block in the buffer.
+ *
+ * @param out the array the block currently being held is copied into.
+ * @param outOff the offset at which the copying starts.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there is insufficient space in out for
+ * the output.
+ * @exception IllegalStateException if the underlying cipher is not
+ * initialised.
+ * @exception InvalidCipherTextException if cipher text decrypts wrongly (in
+ * case the exception will never get thrown).
+ */
+ public int doFinal(
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException, InvalidCipherTextException
+ {
+ if (bufOff + outOff > out.length)
+ {
+ throw new OutputLengthException("output buffer to small in doFinal");
+ }
+
+ int blockSize = cipher.getBlockSize();
+ int len = bufOff - blockSize;
+ byte[] block = new byte[blockSize];
+
+ if (forEncryption)
+ {
+ if (bufOff < blockSize)
+ {
+ throw new DataLengthException("need at least one block of input for CTS");
+ }
+
+ cipher.processBlock(buf, 0, block, 0);
+
+ if (bufOff > blockSize)
+ {
+ for (int i = bufOff; i != buf.length; i++)
+ {
+ buf[i] = block[i - blockSize];
+ }
+
+ for (int i = blockSize; i != bufOff; i++)
+ {
+ buf[i] ^= block[i - blockSize];
+ }
+
+ if (cipher instanceof CBCBlockCipher)
+ {
+ BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher();
+
+ c.processBlock(buf, blockSize, out, outOff);
+ }
+ else
+ {
+ cipher.processBlock(buf, blockSize, out, outOff);
+ }
+
+ System.arraycopy(block, 0, out, outOff + blockSize, len);
+ }
+ else
+ {
+ System.arraycopy(block, 0, out, outOff, blockSize);
+ }
+ }
+ else
+ {
+ if (bufOff < blockSize)
+ {
+ throw new DataLengthException("need at least one block of input for CTS");
+ }
+
+ byte[] lastBlock = new byte[blockSize];
+
+ if (bufOff > blockSize)
+ {
+ if (cipher instanceof CBCBlockCipher)
+ {
+ BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher();
+
+ c.processBlock(buf, 0, block, 0);
+ }
+ else
+ {
+ cipher.processBlock(buf, 0, block, 0);
+ }
+
+ for (int i = blockSize; i != bufOff; i++)
+ {
+ lastBlock[i - blockSize] = (byte)(block[i - blockSize] ^ buf[i]);
+ }
+
+ System.arraycopy(buf, blockSize, block, 0, len);
+
+ cipher.processBlock(block, 0, out, outOff);
+ System.arraycopy(lastBlock, 0, out, outOff + blockSize, len);
+ }
+ else
+ {
+ cipher.processBlock(buf, 0, block, 0);
+
+ System.arraycopy(block, 0, out, outOff, blockSize);
+ }
+ }
+
+ int offset = bufOff;
+
+ reset();
+
+ return offset;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/GCMBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/GCMBlockCipher.java
new file mode 100644
index 00000000..e74dd6b4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/GCMBlockCipher.java
@@ -0,0 +1,692 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.modes.gcm.BasicGCMExponentiator;
+import com.android.internal.org.bouncycastle.crypto.modes.gcm.GCMExponentiator;
+import com.android.internal.org.bouncycastle.crypto.modes.gcm.GCMMultiplier;
+import com.android.internal.org.bouncycastle.crypto.modes.gcm.GCMUtil;
+import com.android.internal.org.bouncycastle.crypto.modes.gcm.Tables4kGCMMultiplier;
+import com.android.internal.org.bouncycastle.crypto.params.AEADParameters;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * Implements the Galois/Counter mode (GCM) detailed in
+ * NIST Special Publication 800-38D.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GCMBlockCipher
+ implements AEADBlockCipher
+{
+ private static final int BLOCK_SIZE = 16;
+ // BEGIN Android-added: Max input size limitation from NIST.
+ // 2^36-32 : limitation imposed by NIST GCM as otherwise the counter is wrapped and it can leak
+ // plaintext and authentication key
+ private static final long MAX_INPUT_SIZE = 68719476704L;
+ // END Android-added: Max input size limitation from NIST.
+
+ // not final due to a compiler bug
+ private BlockCipher cipher;
+ private GCMMultiplier multiplier;
+ private GCMExponentiator exp;
+
+ // These fields are set by init and not modified by processing
+ private boolean forEncryption;
+ private boolean initialised;
+ private int macSize;
+ private byte[] lastKey;
+ private byte[] nonce;
+ private byte[] initialAssociatedText;
+ private byte[] H;
+ private byte[] J0;
+
+ // These fields are modified during processing
+ private byte[] bufBlock;
+ private byte[] macBlock;
+ private byte[] S, S_at, S_atPre;
+ private byte[] counter;
+ private int blocksRemaining;
+ private int bufOff;
+ private long totalLength;
+ private byte[] atBlock;
+ private int atBlockPos;
+ private long atLength;
+ private long atLengthPre;
+
+ public GCMBlockCipher(BlockCipher c)
+ {
+ this(c, null);
+ }
+
+ public GCMBlockCipher(BlockCipher c, GCMMultiplier m)
+ {
+ if (c.getBlockSize() != BLOCK_SIZE)
+ {
+ throw new IllegalArgumentException(
+ "cipher required with a block size of " + BLOCK_SIZE + ".");
+ }
+
+ if (m == null)
+ {
+ m = new Tables4kGCMMultiplier();
+ }
+
+ this.cipher = c;
+ this.multiplier = m;
+ }
+
+ public BlockCipher getUnderlyingCipher()
+ {
+ return cipher;
+ }
+
+ public String getAlgorithmName()
+ {
+ return cipher.getAlgorithmName() + "/GCM";
+ }
+
+ /**
+ * NOTE: MAC sizes from 32 bits to 128 bits (must be a multiple of 8) are supported. The default is 128 bits.
+ * Sizes less than 96 are not recommended, but are supported for specialized applications.
+ */
+ public void init(boolean forEncryption, CipherParameters params)
+ throws IllegalArgumentException
+ {
+ this.forEncryption = forEncryption;
+ this.macBlock = null;
+ this.initialised = true;
+
+ KeyParameter keyParam;
+ byte[] newNonce = null;
+
+ if (params instanceof AEADParameters)
+ {
+ AEADParameters param = (AEADParameters)params;
+
+ newNonce = param.getNonce();
+ initialAssociatedText = param.getAssociatedText();
+
+ int macSizeBits = param.getMacSize();
+ if (macSizeBits < 32 || macSizeBits > 128 || macSizeBits % 8 != 0)
+ {
+ throw new IllegalArgumentException("Invalid value for MAC size: " + macSizeBits);
+ }
+
+ macSize = macSizeBits / 8;
+ keyParam = param.getKey();
+ }
+ else if (params instanceof ParametersWithIV)
+ {
+ ParametersWithIV param = (ParametersWithIV)params;
+
+ newNonce = param.getIV();
+ initialAssociatedText = null;
+ macSize = 16;
+ keyParam = (KeyParameter)param.getParameters();
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid parameters passed to GCM");
+ }
+
+ int bufLength = forEncryption ? BLOCK_SIZE : (BLOCK_SIZE + macSize);
+ this.bufBlock = new byte[bufLength];
+
+ if (newNonce == null || newNonce.length < 1)
+ {
+ throw new IllegalArgumentException("IV must be at least 1 byte");
+ }
+
+ if (forEncryption)
+ {
+ if (nonce != null && Arrays.areEqual(nonce, newNonce))
+ {
+ if (keyParam == null)
+ {
+ throw new IllegalArgumentException("cannot reuse nonce for GCM encryption");
+ }
+ if (lastKey != null && Arrays.areEqual(lastKey, keyParam.getKey()))
+ {
+ throw new IllegalArgumentException("cannot reuse nonce for GCM encryption");
+ }
+ }
+ }
+
+ nonce = newNonce;
+ if (keyParam != null)
+ {
+ lastKey = keyParam.getKey();
+ }
+
+ // TODO Restrict macSize to 16 if nonce length not 12?
+
+ // Cipher always used in forward mode
+ // if keyParam is null we're reusing the last key.
+ if (keyParam != null)
+ {
+ cipher.init(true, keyParam);
+
+ this.H = new byte[BLOCK_SIZE];
+ cipher.processBlock(H, 0, H, 0);
+
+ // GCMMultiplier tables don't change unless the key changes (and are expensive to init)
+ multiplier.init(H);
+ exp = null;
+ }
+ else if (this.H == null)
+ {
+ throw new IllegalArgumentException("Key must be specified in initial init");
+ }
+
+ this.J0 = new byte[BLOCK_SIZE];
+
+ if (nonce.length == 12)
+ {
+ System.arraycopy(nonce, 0, J0, 0, nonce.length);
+ this.J0[BLOCK_SIZE - 1] = 0x01;
+ }
+ else
+ {
+ gHASH(J0, nonce, nonce.length);
+ byte[] X = new byte[BLOCK_SIZE];
+ Pack.longToBigEndian((long)nonce.length * 8, X, 8);
+ gHASHBlock(J0, X);
+ }
+
+ this.S = new byte[BLOCK_SIZE];
+ this.S_at = new byte[BLOCK_SIZE];
+ this.S_atPre = new byte[BLOCK_SIZE];
+ this.atBlock = new byte[BLOCK_SIZE];
+ this.atBlockPos = 0;
+ this.atLength = 0;
+ this.atLengthPre = 0;
+ this.counter = Arrays.clone(J0);
+ this.blocksRemaining = -2; // page 8, len(P) <= 2^39 - 256, 1 block used by tag but done on J0
+ this.bufOff = 0;
+ this.totalLength = 0;
+
+ if (initialAssociatedText != null)
+ {
+ processAADBytes(initialAssociatedText, 0, initialAssociatedText.length);
+ }
+ }
+
+ public byte[] getMac()
+ {
+ if (macBlock == null)
+ {
+ return new byte[macSize];
+ }
+ return Arrays.clone(macBlock);
+ }
+
+ public int getOutputSize(int len)
+ {
+ int totalData = len + bufOff;
+
+ if (forEncryption)
+ {
+ return totalData + macSize;
+ }
+
+ return totalData < macSize ? 0 : totalData - macSize;
+ }
+
+ // BEGIN Android-added: Max input size limitation from NIST.
+ /** Helper used to ensure that {@link #MAX_INPUT_SIZE} is not exceeded. */
+ private long getTotalInputSizeAfterNewInput(int newInputLen)
+ {
+ return totalLength + newInputLen + bufOff;
+ }
+ // END Android-added: Max input size limitation from NIST.
+
+ public int getUpdateOutputSize(int len)
+ {
+ int totalData = len + bufOff;
+ if (!forEncryption)
+ {
+ if (totalData < macSize)
+ {
+ return 0;
+ }
+ totalData -= macSize;
+ }
+ return totalData - totalData % BLOCK_SIZE;
+ }
+
+ public void processAADByte(byte in)
+ {
+ checkStatus();
+ // BEGIN Android-added: Max input size limitation from NIST.
+ if (getTotalInputSizeAfterNewInput(1) > MAX_INPUT_SIZE) {
+ throw new DataLengthException("Input exceeded " + MAX_INPUT_SIZE + " bytes");
+ }
+ // END Android-added: Max input size limitation from NIST.
+
+ atBlock[atBlockPos] = in;
+ if (++atBlockPos == BLOCK_SIZE)
+ {
+ // Hash each block as it fills
+ gHASHBlock(S_at, atBlock);
+ atBlockPos = 0;
+ atLength += BLOCK_SIZE;
+ }
+ }
+
+ public void processAADBytes(byte[] in, int inOff, int len)
+ {
+ checkStatus();
+ // BEGIN Android-added: Max input size limitation from NIST.
+ if (getTotalInputSizeAfterNewInput(len) > MAX_INPUT_SIZE) {
+ throw new DataLengthException("Input exceeded " + MAX_INPUT_SIZE + " bytes");
+ }
+ // END Android-added: Max input size limitation from NIST.
+
+ for (int i = 0; i < len; ++i)
+ {
+ atBlock[atBlockPos] = in[inOff + i];
+ if (++atBlockPos == BLOCK_SIZE)
+ {
+ // Hash each block as it fills
+ gHASHBlock(S_at, atBlock);
+ atBlockPos = 0;
+ atLength += BLOCK_SIZE;
+ }
+ }
+ }
+
+ private void initCipher()
+ {
+ if (atLength > 0)
+ {
+ System.arraycopy(S_at, 0, S_atPre, 0, BLOCK_SIZE);
+ atLengthPre = atLength;
+ }
+
+ // Finish hash for partial AAD block
+ if (atBlockPos > 0)
+ {
+ gHASHPartial(S_atPre, atBlock, 0, atBlockPos);
+ atLengthPre += atBlockPos;
+ }
+
+ if (atLengthPre > 0)
+ {
+ System.arraycopy(S_atPre, 0, S, 0, BLOCK_SIZE);
+ }
+ }
+
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException
+ {
+ checkStatus();
+ // BEGIN Android-added: Max input size limitation from NIST.
+ if (getTotalInputSizeAfterNewInput(1) > MAX_INPUT_SIZE) {
+ throw new DataLengthException("Input exceeded " + MAX_INPUT_SIZE + " bytes");
+ }
+ // END Android-added: Max input size limitation from NIST.
+
+ bufBlock[bufOff] = in;
+ if (++bufOff == bufBlock.length)
+ {
+ processBlock(bufBlock, 0, out, outOff);
+ if (forEncryption)
+ {
+ bufOff = 0;
+ }
+ else
+ {
+ System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, macSize);
+ bufOff = macSize;
+ }
+ return BLOCK_SIZE;
+ }
+ return 0;
+ }
+
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException
+ {
+ checkStatus();
+ // BEGIN Android-added: Max input size limitation from NIST.
+ if (getTotalInputSizeAfterNewInput(len) > MAX_INPUT_SIZE) {
+ throw new DataLengthException("Input exceeded " + MAX_INPUT_SIZE + " bytes");
+ }
+ // END Android-added: Max input size limitation from NIST.
+
+ if ((in.length - inOff) < len)
+ {
+ throw new DataLengthException("Input buffer too short");
+ }
+
+ int resultLen = 0;
+
+ if (forEncryption)
+ {
+ if (bufOff != 0)
+ {
+ while (len > 0)
+ {
+ --len;
+ bufBlock[bufOff] = in[inOff++];
+ if (++bufOff == BLOCK_SIZE)
+ {
+ processBlock(bufBlock, 0, out, outOff);
+ bufOff = 0;
+ resultLen += BLOCK_SIZE;
+ break;
+ }
+ }
+ }
+
+ while (len >= BLOCK_SIZE)
+ {
+ processBlock(in, inOff, out, outOff + resultLen);
+ inOff += BLOCK_SIZE;
+ len -= BLOCK_SIZE;
+ resultLen += BLOCK_SIZE;
+ }
+
+ if (len > 0)
+ {
+ System.arraycopy(in, inOff, bufBlock, 0, len);
+ bufOff = len;
+ }
+ }
+ else
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ bufBlock[bufOff] = in[inOff + i];
+ if (++bufOff == bufBlock.length)
+ {
+ processBlock(bufBlock, 0, out, outOff + resultLen);
+ System.arraycopy(bufBlock, BLOCK_SIZE, bufBlock, 0, macSize);
+ bufOff = macSize;
+ resultLen += BLOCK_SIZE;
+ }
+ }
+ }
+
+ return resultLen;
+ }
+
+ public int doFinal(byte[] out, int outOff)
+ throws IllegalStateException, InvalidCipherTextException
+ {
+ checkStatus();
+
+ if (totalLength == 0)
+ {
+ initCipher();
+ }
+
+ int extra = bufOff;
+
+ if (forEncryption)
+ {
+ if ((out.length - outOff) < (extra + macSize))
+ {
+ throw new OutputLengthException("Output buffer too short");
+ }
+ }
+ else
+ {
+ if (extra < macSize)
+ {
+ throw new InvalidCipherTextException("data too short");
+ }
+ extra -= macSize;
+
+ if ((out.length - outOff) < extra)
+ {
+ throw new OutputLengthException("Output buffer too short");
+ }
+ }
+
+ if (extra > 0)
+ {
+ processPartial(bufBlock, 0, extra, out, outOff);
+ }
+
+ atLength += atBlockPos;
+
+ if (atLength > atLengthPre)
+ {
+ /*
+ * Some AAD was sent after the cipher started. We determine the difference b/w the hash value
+ * we actually used when the cipher started (S_atPre) and the final hash value calculated (S_at).
+ * Then we carry this difference forward by multiplying by H^c, where c is the number of (full or
+ * partial) cipher-text blocks produced, and adjust the current hash.
+ */
+
+ // Finish hash for partial AAD block
+ if (atBlockPos > 0)
+ {
+ gHASHPartial(S_at, atBlock, 0, atBlockPos);
+ }
+
+ // Find the difference between the AAD hashes
+ if (atLengthPre > 0)
+ {
+ GCMUtil.xor(S_at, S_atPre);
+ }
+
+ // Number of cipher-text blocks produced
+ long c = ((totalLength * 8) + 127) >>> 7;
+
+ // Calculate the adjustment factor
+ byte[] H_c = new byte[16];
+ if (exp == null)
+ {
+ exp = new BasicGCMExponentiator();
+ exp.init(H);
+ }
+ exp.exponentiateX(c, H_c);
+
+ // Carry the difference forward
+ GCMUtil.multiply(S_at, H_c);
+
+ // Adjust the current hash
+ GCMUtil.xor(S, S_at);
+ }
+
+ // Final gHASH
+ byte[] X = new byte[BLOCK_SIZE];
+ Pack.longToBigEndian(atLength * 8, X, 0);
+ Pack.longToBigEndian(totalLength * 8, X, 8);
+
+ gHASHBlock(S, X);
+
+ // T = MSBt(GCTRk(J0,S))
+ byte[] tag = new byte[BLOCK_SIZE];
+ cipher.processBlock(J0, 0, tag, 0);
+ GCMUtil.xor(tag, S);
+
+ int resultLen = extra;
+
+ // We place into macBlock our calculated value for T
+ this.macBlock = new byte[macSize];
+ System.arraycopy(tag, 0, macBlock, 0, macSize);
+
+ if (forEncryption)
+ {
+ // Append T to the message
+ System.arraycopy(macBlock, 0, out, outOff + bufOff, macSize);
+ resultLen += macSize;
+ }
+ else
+ {
+ // Retrieve the T value from the message and compare to calculated one
+ byte[] msgMac = new byte[macSize];
+ System.arraycopy(bufBlock, extra, msgMac, 0, macSize);
+ if (!Arrays.constantTimeAreEqual(this.macBlock, msgMac))
+ {
+ throw new InvalidCipherTextException("mac check in GCM failed");
+ }
+ }
+
+ reset(false);
+
+ return resultLen;
+ }
+
+ public void reset()
+ {
+ reset(true);
+ }
+
+ private void reset(
+ boolean clearMac)
+ {
+ cipher.reset();
+
+ // note: we do not reset the nonce.
+
+ S = new byte[BLOCK_SIZE];
+ S_at = new byte[BLOCK_SIZE];
+ S_atPre = new byte[BLOCK_SIZE];
+ atBlock = new byte[BLOCK_SIZE];
+ atBlockPos = 0;
+ atLength = 0;
+ atLengthPre = 0;
+ counter = Arrays.clone(J0);
+ blocksRemaining = -2;
+ bufOff = 0;
+ totalLength = 0;
+
+ if (bufBlock != null)
+ {
+ Arrays.fill(bufBlock, (byte)0);
+ }
+
+ if (clearMac)
+ {
+ macBlock = null;
+ }
+
+ if (forEncryption)
+ {
+ initialised = false;
+ }
+ else
+ {
+ if (initialAssociatedText != null)
+ {
+ processAADBytes(initialAssociatedText, 0, initialAssociatedText.length);
+ }
+ }
+ }
+
+ private void processBlock(byte[] buf, int bufOff, byte[] out, int outOff)
+ {
+ if ((out.length - outOff) < BLOCK_SIZE)
+ {
+ throw new OutputLengthException("Output buffer too short");
+ }
+ if (totalLength == 0)
+ {
+ initCipher();
+ }
+
+ byte[] ctrBlock = new byte[BLOCK_SIZE];
+ getNextCTRBlock(ctrBlock);
+
+ if (forEncryption)
+ {
+ GCMUtil.xor(ctrBlock, buf, bufOff);
+ gHASHBlock(S, ctrBlock);
+ System.arraycopy(ctrBlock, 0, out, outOff, BLOCK_SIZE);
+ }
+ else
+ {
+ gHASHBlock(S, buf, bufOff);
+ GCMUtil.xor(ctrBlock, 0, buf, bufOff, out, outOff);
+ }
+
+ totalLength += BLOCK_SIZE;
+ }
+
+ private void processPartial(byte[] buf, int off, int len, byte[] out, int outOff)
+ {
+ byte[] ctrBlock = new byte[BLOCK_SIZE];
+ getNextCTRBlock(ctrBlock);
+
+ if (forEncryption)
+ {
+ GCMUtil.xor(buf, off, ctrBlock, 0, len);
+ gHASHPartial(S, buf, off, len);
+ }
+ else
+ {
+ gHASHPartial(S, buf, off, len);
+ GCMUtil.xor(buf, off, ctrBlock, 0, len);
+ }
+
+ System.arraycopy(buf, off, out, outOff, len);
+ totalLength += len;
+ }
+
+ private void gHASH(byte[] Y, byte[] b, int len)
+ {
+ for (int pos = 0; pos < len; pos += BLOCK_SIZE)
+ {
+ int num = Math.min(len - pos, BLOCK_SIZE);
+ gHASHPartial(Y, b, pos, num);
+ }
+ }
+
+ private void gHASHBlock(byte[] Y, byte[] b)
+ {
+ GCMUtil.xor(Y, b);
+ multiplier.multiplyH(Y);
+ }
+
+ private void gHASHBlock(byte[] Y, byte[] b, int off)
+ {
+ GCMUtil.xor(Y, b, off);
+ multiplier.multiplyH(Y);
+ }
+
+ private void gHASHPartial(byte[] Y, byte[] b, int off, int len)
+ {
+ GCMUtil.xor(Y, b, off, len);
+ multiplier.multiplyH(Y);
+ }
+
+ private void getNextCTRBlock(byte[] block)
+ {
+ if (blocksRemaining == 0)
+ {
+ throw new IllegalStateException("Attempt to process too many blocks");
+ }
+ blocksRemaining--;
+
+ int c = 1;
+ c += counter[15] & 0xFF; counter[15] = (byte)c; c >>>= 8;
+ c += counter[14] & 0xFF; counter[14] = (byte)c; c >>>= 8;
+ c += counter[13] & 0xFF; counter[13] = (byte)c; c >>>= 8;
+ c += counter[12] & 0xFF; counter[12] = (byte)c;
+
+ cipher.processBlock(counter, 0, block, 0);
+ }
+
+ private void checkStatus()
+ {
+ if (!initialised)
+ {
+ if (forEncryption)
+ {
+ throw new IllegalStateException("GCM cipher cannot be reused for encryption");
+ }
+ throw new IllegalStateException("GCM cipher needs to be initialised");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/OFBBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/OFBBlockCipher.java
new file mode 100644
index 00000000..73ff41dc
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/OFBBlockCipher.java
@@ -0,0 +1,185 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.StreamBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+
+/**
+ * implements a Output-FeedBack (OFB) mode on top of a simple cipher.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OFBBlockCipher
+ extends StreamBlockCipher
+{
+ private int byteCount;
+ private byte[] IV;
+ private byte[] ofbV;
+ private byte[] ofbOutV;
+
+ private final int blockSize;
+ private final BlockCipher cipher;
+
+ /**
+ * Basic constructor.
+ *
+ * @param cipher the block cipher to be used as the basis of the
+ * feedback mode.
+ * @param bitBlockSize the block size in bits (note: a multiple of 8)
+ */
+ public OFBBlockCipher(
+ BlockCipher cipher,
+ int bitBlockSize)
+ {
+ super(cipher);
+
+ if (bitBlockSize > (cipher.getBlockSize() * 8) || bitBlockSize < 8 || bitBlockSize % 8 != 0)
+ {
+ throw new IllegalArgumentException("0FB" + bitBlockSize + " not supported");
+ }
+
+ this.cipher = cipher;
+ this.blockSize = bitBlockSize / 8;
+
+ this.IV = new byte[cipher.getBlockSize()];
+ this.ofbV = new byte[cipher.getBlockSize()];
+ this.ofbOutV = new byte[cipher.getBlockSize()];
+ }
+
+ /**
+ * Initialise the cipher and, possibly, the initialisation vector (IV).
+ * If an IV isn't passed as part of the parameter, the IV will be all zeros.
+ * An IV which is too short is handled in FIPS compliant fashion.
+ *
+ * @param encrypting if true the cipher is initialised for
+ * encryption, if false for decryption.
+ * @param params the key and other data required by the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean encrypting, //ignored by this OFB mode
+ CipherParameters params)
+ throws IllegalArgumentException
+ {
+ if (params instanceof ParametersWithIV)
+ {
+ ParametersWithIV ivParam = (ParametersWithIV)params;
+ byte[] iv = ivParam.getIV();
+
+ if (iv.length < IV.length)
+ {
+ // prepend the supplied IV with zeros (per FIPS PUB 81)
+ System.arraycopy(iv, 0, IV, IV.length - iv.length, iv.length);
+ for (int i = 0; i < IV.length - iv.length; i++)
+ {
+ IV[i] = 0;
+ }
+ }
+ else
+ {
+ System.arraycopy(iv, 0, IV, 0, IV.length);
+ }
+
+ reset();
+
+ // if null it's an IV changed only.
+ if (ivParam.getParameters() != null)
+ {
+ cipher.init(true, ivParam.getParameters());
+ }
+ }
+ else
+ {
+ reset();
+
+ // if it's null, key is to be reused.
+ if (params != null)
+ {
+ cipher.init(true, params);
+ }
+ }
+ }
+
+ /**
+ * return the algorithm name and mode.
+ *
+ * @return the name of the underlying algorithm followed by "/OFB"
+ * and the block size in bits
+ */
+ public String getAlgorithmName()
+ {
+ return cipher.getAlgorithmName() + "/OFB" + (blockSize * 8);
+ }
+
+
+ /**
+ * return the block size we are operating at (in bytes).
+ *
+ * @return the block size we are operating at (in bytes).
+ */
+ public int getBlockSize()
+ {
+ return blockSize;
+ }
+
+ /**
+ * Process one block of input from the array in and write it to
+ * the out array.
+ *
+ * @param in the array containing the input data.
+ * @param inOff offset into the in array the data starts at.
+ * @param out the array the output data will be copied into.
+ * @param outOff the offset into the out array the output will start at.
+ * @exception DataLengthException if there isn't enough data in in, or
+ * space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ * @return the number of bytes processed and produced.
+ */
+ public int processBlock(
+ byte[] in,
+ int inOff,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ processBytes(in, inOff, blockSize, out, outOff);
+
+ return blockSize;
+ }
+
+ /**
+ * reset the feedback vector back to the IV and reset the underlying
+ * cipher.
+ */
+ public void reset()
+ {
+ System.arraycopy(IV, 0, ofbV, 0, IV.length);
+ byteCount = 0;
+
+ cipher.reset();
+ }
+
+ protected byte calculateByte(byte in)
+ throws DataLengthException, IllegalStateException
+ {
+ if (byteCount == 0)
+ {
+ cipher.processBlock(ofbV, 0, ofbOutV, 0);
+ }
+
+ byte rv = (byte)(ofbOutV[byteCount++] ^ in);
+
+ if (byteCount == blockSize)
+ {
+ byteCount = 0;
+
+ System.arraycopy(ofbV, blockSize, ofbV, 0, ofbV.length - blockSize);
+ System.arraycopy(ofbOutV, 0, ofbV, ofbV.length - blockSize, blockSize);
+ }
+
+ return rv;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/SICBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/SICBlockCipher.java
new file mode 100644
index 00000000..b4121be7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/SICBlockCipher.java
@@ -0,0 +1,292 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.SkippingStreamCipher;
+import com.android.internal.org.bouncycastle.crypto.StreamBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * Implements the Segmented Integer Counter (SIC) mode on top of a simple
+ * block cipher. This mode is also known as CTR mode.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SICBlockCipher
+ extends StreamBlockCipher
+ implements SkippingStreamCipher
+{
+ private final BlockCipher cipher;
+ private final int blockSize;
+
+ private byte[] IV;
+ private byte[] counter;
+ private byte[] counterOut;
+ private int byteCount;
+
+ /**
+ * Basic constructor.
+ *
+ * @param c the block cipher to be used.
+ */
+ public SICBlockCipher(BlockCipher c)
+ {
+ super(c);
+
+ this.cipher = c;
+ this.blockSize = cipher.getBlockSize();
+ this.IV = new byte[blockSize];
+ this.counter = new byte[blockSize];
+ this.counterOut = new byte[blockSize];
+ this.byteCount = 0;
+ }
+
+ public void init(
+ boolean forEncryption, //ignored by this CTR mode
+ CipherParameters params)
+ throws IllegalArgumentException
+ {
+ if (params instanceof ParametersWithIV)
+ {
+ ParametersWithIV ivParam = (ParametersWithIV)params;
+ this.IV = Arrays.clone(ivParam.getIV());
+
+ if (blockSize < IV.length)
+ {
+ throw new IllegalArgumentException("CTR/SIC mode requires IV no greater than: " + blockSize + " bytes.");
+ }
+
+ int maxCounterSize = (8 > blockSize / 2) ? blockSize / 2 : 8;
+
+ if (blockSize - IV.length > maxCounterSize)
+ {
+ throw new IllegalArgumentException("CTR/SIC mode requires IV of at least: " + (blockSize - maxCounterSize) + " bytes.");
+ }
+
+ // if null it's an IV changed only.
+ if (ivParam.getParameters() != null)
+ {
+ cipher.init(true, ivParam.getParameters());
+ }
+
+ reset();
+ }
+ else
+ {
+ throw new IllegalArgumentException("CTR/SIC mode requires ParametersWithIV");
+ }
+ }
+
+ public String getAlgorithmName()
+ {
+ return cipher.getAlgorithmName() + "/SIC";
+ }
+
+ public int getBlockSize()
+ {
+ return cipher.getBlockSize();
+ }
+
+ public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ processBytes(in, inOff, blockSize, out, outOff);
+
+ return blockSize;
+ }
+
+ protected byte calculateByte(byte in)
+ throws DataLengthException, IllegalStateException
+ {
+ if (byteCount == 0)
+ {
+ cipher.processBlock(counter, 0, counterOut, 0);
+
+ return (byte)(counterOut[byteCount++] ^ in);
+ }
+
+ byte rv = (byte)(counterOut[byteCount++] ^ in);
+
+ if (byteCount == counter.length)
+ {
+ byteCount = 0;
+
+ incrementCounterAt(0);
+
+ checkCounter();
+ }
+
+ return rv;
+ }
+
+ private void checkCounter()
+ {
+ // if the IV is the same as the blocksize we assume the user knows what they are doing
+ if (IV.length < blockSize)
+ {
+ for (int i = 0; i != IV.length; i++)
+ {
+ if (counter[i] != IV[i])
+ {
+ throw new IllegalStateException("Counter in CTR/SIC mode out of range.");
+ }
+ }
+ }
+ }
+
+ private void incrementCounterAt(int pos)
+ {
+ int i = counter.length - pos;
+ while (--i >= 0)
+ {
+ if (++counter[i] != 0)
+ {
+ break;
+ }
+ }
+ }
+
+ private void incrementCounter(int offSet)
+ {
+ byte old = counter[counter.length - 1];
+
+ counter[counter.length - 1] += offSet;
+
+ if (old != 0 && counter[counter.length - 1] < old)
+ {
+ incrementCounterAt(1);
+ }
+ }
+
+ private void decrementCounterAt(int pos)
+ {
+ int i = counter.length - pos;
+ while (--i >= 0)
+ {
+ if (--counter[i] != -1)
+ {
+ return;
+ }
+ }
+ }
+
+ private void adjustCounter(long n)
+ {
+ if (n >= 0)
+ {
+ long numBlocks = (n + byteCount) / blockSize;
+
+ long rem = numBlocks;
+ if (rem > 255)
+ {
+ for (int i = 5; i >= 1; i--)
+ {
+ long diff = 1L << (8 * i);
+ while (rem >= diff)
+ {
+ incrementCounterAt(i);
+ rem -= diff;
+ }
+ }
+ }
+
+ incrementCounter((int)rem);
+
+ byteCount = (int)((n + byteCount) - (blockSize * numBlocks));
+ }
+ else
+ {
+ long numBlocks = (-n - byteCount) / blockSize;
+
+ long rem = numBlocks;
+ if (rem > 255)
+ {
+ for (int i = 5; i >= 1; i--)
+ {
+ long diff = 1L << (8 * i);
+ while (rem > diff)
+ {
+ decrementCounterAt(i);
+ rem -= diff;
+ }
+ }
+ }
+
+ for (long i = 0; i != rem; i++)
+ {
+ decrementCounterAt(0);
+ }
+
+ int gap = (int)(byteCount + n + (blockSize * numBlocks));
+
+ if (gap >= 0)
+ {
+ byteCount = 0;
+ }
+ else
+ {
+ decrementCounterAt(0);
+ byteCount = blockSize + gap;
+ }
+ }
+ }
+
+ public void reset()
+ {
+ Arrays.fill(counter, (byte)0);
+ System.arraycopy(IV, 0, counter, 0, IV.length);
+ cipher.reset();
+ this.byteCount = 0;
+ }
+
+ public long skip(long numberOfBytes)
+ {
+ adjustCounter(numberOfBytes);
+
+ checkCounter();
+
+ cipher.processBlock(counter, 0, counterOut, 0);
+
+ return numberOfBytes;
+ }
+
+ public long seekTo(long position)
+ {
+ reset();
+
+ return skip(position);
+ }
+
+ public long getPosition()
+ {
+ byte[] res = new byte[counter.length];
+
+ System.arraycopy(counter, 0, res, 0, res.length);
+
+ for (int i = res.length - 1; i >= 1; i--)
+ {
+ int v;
+ if (i < IV.length)
+ {
+ v = (res[i] & 0xff) - (IV[i] & 0xff);
+ }
+ else
+ {
+ v = (res[i] & 0xff);
+ }
+
+ if (v < 0)
+ {
+ res[i - 1]--;
+ v += 256;
+ }
+
+ res[i] = (byte)v;
+ }
+
+ return Pack.bigEndianToLong(res, res.length - 8) * blockSize + byteCount;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java
new file mode 100644
index 00000000..2d317ff8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java
@@ -0,0 +1,41 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes.gcm;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BasicGCMExponentiator
+ implements GCMExponentiator
+{
+ private long[] x;
+
+ public void init(byte[] x)
+ {
+ this.x = GCMUtil.asLongs(x);
+ }
+
+ public void exponentiateX(long pow, byte[] output)
+ {
+ // Initial value is little-endian 1
+ long[] y = GCMUtil.oneAsLongs();
+
+ if (pow > 0)
+ {
+ long[] powX = Arrays.clone(x);
+ do
+ {
+ if ((pow & 1L) != 0)
+ {
+ GCMUtil.multiply(y, powX);
+ }
+ GCMUtil.square(powX, powX);
+ pow >>>= 1;
+ }
+ while (pow > 0);
+ }
+
+ GCMUtil.asBytes(y, output);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMExponentiator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMExponentiator.java
new file mode 100644
index 00000000..82f912f3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMExponentiator.java
@@ -0,0 +1,11 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes.gcm;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface GCMExponentiator
+{
+ void init(byte[] x);
+ void exponentiateX(long pow, byte[] output);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMMultiplier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMMultiplier.java
new file mode 100644
index 00000000..873b8e81
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMMultiplier.java
@@ -0,0 +1,11 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes.gcm;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface GCMMultiplier
+{
+ void init(byte[] H);
+ void multiplyH(byte[] x);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
new file mode 100644
index 00000000..0797bca2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
@@ -0,0 +1,449 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes.gcm;
+
+import com.android.internal.org.bouncycastle.math.raw.Interleave;
+import com.android.internal.org.bouncycastle.util.Longs;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class GCMUtil
+{
+ private static final int E1 = 0xe1000000;
+ private static final long E1L = (E1 & 0xFFFFFFFFL) << 32;
+
+ public static byte[] oneAsBytes()
+ {
+ byte[] tmp = new byte[16];
+ tmp[0] = (byte)0x80;
+ return tmp;
+ }
+
+ public static int[] oneAsInts()
+ {
+ int[] tmp = new int[4];
+ tmp[0] = 1 << 31;
+ return tmp;
+ }
+
+ public static long[] oneAsLongs()
+ {
+ long[] tmp = new long[2];
+ tmp[0] = 1L << 63;
+ return tmp;
+ }
+
+ public static byte[] asBytes(int[] x)
+ {
+ byte[] z = new byte[16];
+ Pack.intToBigEndian(x, z, 0);
+ return z;
+ }
+
+ public static void asBytes(int[] x, byte[] z)
+ {
+ Pack.intToBigEndian(x, z, 0);
+ }
+
+ public static byte[] asBytes(long[] x)
+ {
+ byte[] z = new byte[16];
+ Pack.longToBigEndian(x, z, 0);
+ return z;
+ }
+
+ public static void asBytes(long[] x, byte[] z)
+ {
+ Pack.longToBigEndian(x, z, 0);
+ }
+
+ public static int[] asInts(byte[] x)
+ {
+ int[] z = new int[4];
+ Pack.bigEndianToInt(x, 0, z);
+ return z;
+ }
+
+ public static void asInts(byte[] x, int[] z)
+ {
+ Pack.bigEndianToInt(x, 0, z);
+ }
+
+ public static long[] asLongs(byte[] x)
+ {
+ long[] z = new long[2];
+ Pack.bigEndianToLong(x, 0, z);
+ return z;
+ }
+
+ public static void asLongs(byte[] x, long[] z)
+ {
+ Pack.bigEndianToLong(x, 0, z);
+ }
+
+ public static void copy(int[] x, int[] z)
+ {
+ z[0] = x[0];
+ z[1] = x[1];
+ z[2] = x[2];
+ z[3] = x[3];
+ }
+
+ public static void copy(long[] x, long[] z)
+ {
+ z[0] = x[0];
+ z[1] = x[1];
+ }
+
+ public static void divideP(long[] x, long[] z)
+ {
+ long x0 = x[0], x1 = x[1];
+ long m = x0 >> 63;
+ x0 ^= (m & E1L);
+ z[0] = (x0 << 1) | (x1 >>> 63);
+ z[1] = (x1 << 1) | -m;
+ }
+
+ public static void multiply(byte[] x, byte[] y)
+ {
+ long[] t1 = GCMUtil.asLongs(x);
+ long[] t2 = GCMUtil.asLongs(y);
+ GCMUtil.multiply(t1, t2);
+ GCMUtil.asBytes(t1, x);
+ }
+
+ public static void multiply(int[] x, int[] y)
+ {
+ int y0 = y[0], y1 = y[1], y2 = y[2], y3 = y[3];
+ int z0 = 0, z1 = 0, z2 = 0, z3 = 0;
+
+ for (int i = 0; i < 4; ++i)
+ {
+ int bits = x[i];
+ for (int j = 0; j < 32; ++j)
+ {
+ int m1 = bits >> 31; bits <<= 1;
+ z0 ^= (y0 & m1);
+ z1 ^= (y1 & m1);
+ z2 ^= (y2 & m1);
+ z3 ^= (y3 & m1);
+
+ int m2 = (y3 << 31) >> 8;
+ y3 = (y3 >>> 1) | (y2 << 31);
+ y2 = (y2 >>> 1) | (y1 << 31);
+ y1 = (y1 >>> 1) | (y0 << 31);
+ y0 = (y0 >>> 1) ^ (m2 & E1);
+ }
+ }
+
+ x[0] = z0;
+ x[1] = z1;
+ x[2] = z2;
+ x[3] = z3;
+ }
+
+ public static void multiply(long[] x, long[] y)
+ {
+// long x0 = x[0], x1 = x[1];
+// long y0 = y[0], y1 = y[1];
+// long z0 = 0, z1 = 0, z2 = 0;
+//
+// for (int j = 0; j < 64; ++j)
+// {
+// long m0 = x0 >> 63; x0 <<= 1;
+// z0 ^= (y0 & m0);
+// z1 ^= (y1 & m0);
+//
+// long m1 = x1 >> 63; x1 <<= 1;
+// z1 ^= (y0 & m1);
+// z2 ^= (y1 & m1);
+//
+// long c = (y1 << 63) >> 8;
+// y1 = (y1 >>> 1) | (y0 << 63);
+// y0 = (y0 >>> 1) ^ (c & E1L);
+// }
+//
+// z0 ^= z2 ^ (z2 >>> 1) ^ (z2 >>> 2) ^ (z2 >>> 7);
+// z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57);
+//
+// x[0] = z0;
+// x[1] = z1;
+
+ /*
+ * "Three-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein.
+ *
+ * Without access to the high part of a 64x64 product x * y, we use a bit reversal to calculate it:
+ * rev(x) * rev(y) == rev((x * y) << 1)
+ */
+
+ long x0 = x[0], x1 = x[1];
+ long y0 = y[0], y1 = y[1];
+ long x0r = Longs.reverse(x0), x1r = Longs.reverse(x1);
+ long y0r = Longs.reverse(y0), y1r = Longs.reverse(y1);
+
+ long h0 = Longs.reverse(implMul64(x0r, y0r));
+ long h1 = implMul64(x0, y0) << 1;
+ long h2 = Longs.reverse(implMul64(x1r, y1r));
+ long h3 = implMul64(x1, y1) << 1;
+ long h4 = Longs.reverse(implMul64(x0r ^ x1r, y0r ^ y1r));
+ long h5 = implMul64(x0 ^ x1, y0 ^ y1) << 1;
+
+ long z0 = h0;
+ long z1 = h1 ^ h0 ^ h2 ^ h4;
+ long z2 = h2 ^ h1 ^ h3 ^ h5;
+ long z3 = h3;
+
+ z1 ^= z3 ^ (z3 >>> 1) ^ (z3 >>> 2) ^ (z3 >>> 7);
+// z2 ^= (z3 << 63) ^ (z3 << 62) ^ (z3 << 57);
+ z2 ^= (z3 << 62) ^ (z3 << 57);
+
+ z0 ^= z2 ^ (z2 >>> 1) ^ (z2 >>> 2) ^ (z2 >>> 7);
+ z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57);
+
+ x[0] = z0;
+ x[1] = z1;
+ }
+
+ public static void multiplyP(int[] x)
+ {
+ int x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3];
+ int m = (x3 << 31) >> 31;
+ x[0] = (x0 >>> 1) ^ (m & E1);
+ x[1] = (x1 >>> 1) | (x0 << 31);
+ x[2] = (x2 >>> 1) | (x1 << 31);
+ x[3] = (x3 >>> 1) | (x2 << 31);
+ }
+
+ public static void multiplyP(int[] x, int[] z)
+ {
+ int x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3];
+ int m = (x3 << 31) >> 31;
+ z[0] = (x0 >>> 1) ^ (m & E1);
+ z[1] = (x1 >>> 1) | (x0 << 31);
+ z[2] = (x2 >>> 1) | (x1 << 31);
+ z[3] = (x3 >>> 1) | (x2 << 31);
+ }
+
+ public static void multiplyP(long[] x)
+ {
+ long x0 = x[0], x1 = x[1];
+ long m = (x1 << 63) >> 63;
+ x[0] = (x0 >>> 1) ^ (m & E1L);
+ x[1] = (x1 >>> 1) | (x0 << 63);
+ }
+
+ public static void multiplyP(long[] x, long[] z)
+ {
+ long x0 = x[0], x1 = x[1];
+ long m = (x1 << 63) >> 63;
+ z[0] = (x0 >>> 1) ^ (m & E1L);
+ z[1] = (x1 >>> 1) | (x0 << 63);
+ }
+
+ public static void multiplyP3(long[] x, long[] z)
+ {
+ long x0 = x[0], x1 = x[1];
+ long c = x1 << 61;
+ z[0] = (x0 >>> 3) ^ c ^ (c >>> 1) ^ (c >>> 2) ^ (c >>> 7);
+ z[1] = (x1 >>> 3) | (x0 << 61);
+ }
+
+ public static void multiplyP4(long[] x, long[] z)
+ {
+ long x0 = x[0], x1 = x[1];
+ long c = x1 << 60;
+ z[0] = (x0 >>> 4) ^ c ^ (c >>> 1) ^ (c >>> 2) ^ (c >>> 7);
+ z[1] = (x1 >>> 4) | (x0 << 60);
+ }
+
+ public static void multiplyP7(long[] x, long[] z)
+ {
+ long x0 = x[0], x1 = x[1];
+ long c = x1 << 57;
+ z[0] = (x0 >>> 7) ^ c ^ (c >>> 1) ^ (c >>> 2) ^ (c >>> 7);
+ z[1] = (x1 >>> 7) | (x0 << 57);
+ }
+
+ public static void multiplyP8(int[] x)
+ {
+ int x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3];
+ int c = x3 << 24;
+ x[0] = (x0 >>> 8) ^ c ^ (c >>> 1) ^ (c >>> 2) ^ (c >>> 7);
+ x[1] = (x1 >>> 8) | (x0 << 24);
+ x[2] = (x2 >>> 8) | (x1 << 24);
+ x[3] = (x3 >>> 8) | (x2 << 24);
+ }
+
+ public static void multiplyP8(int[] x, int[] y)
+ {
+ int x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3];
+ int c = x3 << 24;
+ y[0] = (x0 >>> 8) ^ c ^ (c >>> 1) ^ (c >>> 2) ^ (c >>> 7);
+ y[1] = (x1 >>> 8) | (x0 << 24);
+ y[2] = (x2 >>> 8) | (x1 << 24);
+ y[3] = (x3 >>> 8) | (x2 << 24);
+ }
+
+ public static void multiplyP8(long[] x)
+ {
+ long x0 = x[0], x1 = x[1];
+ long c = x1 << 56;
+ x[0] = (x0 >>> 8) ^ c ^ (c >>> 1) ^ (c >>> 2) ^ (c >>> 7);
+ x[1] = (x1 >>> 8) | (x0 << 56);
+ }
+
+ public static void multiplyP8(long[] x, long[] y)
+ {
+ long x0 = x[0], x1 = x[1];
+ long c = x1 << 56;
+ y[0] = (x0 >>> 8) ^ c ^ (c >>> 1) ^ (c >>> 2) ^ (c >>> 7);
+ y[1] = (x1 >>> 8) | (x0 << 56);
+ }
+
+ public static long[] pAsLongs()
+ {
+ long[] tmp = new long[2];
+ tmp[0] = 1L << 62;
+ return tmp;
+ }
+
+ public static void square(long[] x, long[] z)
+ {
+ long[] t = new long[4];
+ Interleave.expand64To128Rev(x[0], t, 0);
+ Interleave.expand64To128Rev(x[1], t, 2);
+
+ long z0 = t[0], z1 = t[1], z2 = t[2], z3 = t[3];
+
+ z1 ^= z3 ^ (z3 >>> 1) ^ (z3 >>> 2) ^ (z3 >>> 7);
+ z2 ^= (z3 << 63) ^ (z3 << 62) ^ (z3 << 57);
+
+ z0 ^= z2 ^ (z2 >>> 1) ^ (z2 >>> 2) ^ (z2 >>> 7);
+ z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57);
+
+ z[0] = z0;
+ z[1] = z1;
+ }
+
+ public static void xor(byte[] x, byte[] y)
+ {
+ int i = 0;
+ do
+ {
+ x[i] ^= y[i]; ++i;
+ x[i] ^= y[i]; ++i;
+ x[i] ^= y[i]; ++i;
+ x[i] ^= y[i]; ++i;
+ }
+ while (i < 16);
+ }
+
+ public static void xor(byte[] x, byte[] y, int yOff)
+ {
+ int i = 0;
+ do
+ {
+ x[i] ^= y[yOff + i]; ++i;
+ x[i] ^= y[yOff + i]; ++i;
+ x[i] ^= y[yOff + i]; ++i;
+ x[i] ^= y[yOff + i]; ++i;
+ }
+ while (i < 16);
+ }
+
+ public static void xor(byte[] x, int xOff, byte[] y, int yOff, byte[] z, int zOff)
+ {
+ int i = 0;
+ do
+ {
+ z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i;
+ z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i;
+ z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i;
+ z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i;
+ }
+ while (i < 16);
+ }
+
+ public static void xor(byte[] x, byte[] y, int yOff, int yLen)
+ {
+ while (--yLen >= 0)
+ {
+ x[yLen] ^= y[yOff + yLen];
+ }
+ }
+
+ public static void xor(byte[] x, int xOff, byte[] y, int yOff, int len)
+ {
+ while (--len >= 0)
+ {
+ x[xOff + len] ^= y[yOff + len];
+ }
+ }
+
+ public static void xor(byte[] x, byte[] y, byte[] z)
+ {
+ int i = 0;
+ do
+ {
+ z[i] = (byte)(x[i] ^ y[i]); ++i;
+ z[i] = (byte)(x[i] ^ y[i]); ++i;
+ z[i] = (byte)(x[i] ^ y[i]); ++i;
+ z[i] = (byte)(x[i] ^ y[i]); ++i;
+ }
+ while (i < 16);
+ }
+
+ public static void xor(int[] x, int[] y)
+ {
+ x[0] ^= y[0];
+ x[1] ^= y[1];
+ x[2] ^= y[2];
+ x[3] ^= y[3];
+ }
+
+ public static void xor(int[] x, int[] y, int[] z)
+ {
+ z[0] = x[0] ^ y[0];
+ z[1] = x[1] ^ y[1];
+ z[2] = x[2] ^ y[2];
+ z[3] = x[3] ^ y[3];
+ }
+
+ public static void xor(long[] x, long[] y)
+ {
+ x[0] ^= y[0];
+ x[1] ^= y[1];
+ }
+
+ public static void xor(long[] x, long[] y, long[] z)
+ {
+ z[0] = x[0] ^ y[0];
+ z[1] = x[1] ^ y[1];
+ }
+
+ private static long implMul64(long x, long y)
+ {
+ long x0 = x & 0x1111111111111111L;
+ long x1 = x & 0x2222222222222222L;
+ long x2 = x & 0x4444444444444444L;
+ long x3 = x & 0x8888888888888888L;
+
+ long y0 = y & 0x1111111111111111L;
+ long y1 = y & 0x2222222222222222L;
+ long y2 = y & 0x4444444444444444L;
+ long y3 = y & 0x8888888888888888L;
+
+ long z0 = (x0 * y0) ^ (x1 * y3) ^ (x2 * y2) ^ (x3 * y1);
+ long z1 = (x0 * y1) ^ (x1 * y0) ^ (x2 * y3) ^ (x3 * y2);
+ long z2 = (x0 * y2) ^ (x1 * y1) ^ (x2 * y0) ^ (x3 * y3);
+ long z3 = (x0 * y3) ^ (x1 * y2) ^ (x2 * y1) ^ (x3 * y0);
+
+ z0 &= 0x1111111111111111L;
+ z1 &= 0x2222222222222222L;
+ z2 &= 0x4444444444444444L;
+ z3 &= 0x8888888888888888L;
+
+ return z0 | z1 | z2 | z3;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java
new file mode 100644
index 00000000..76893968
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables1kGCMExponentiator.java
@@ -0,0 +1,63 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes.gcm;
+
+import java.util.Vector;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Tables1kGCMExponentiator
+ implements GCMExponentiator
+{
+ // A lookup table of the power-of-two powers of 'x'
+ // - lookupPowX2[i] = x^(2^i)
+ private Vector lookupPowX2;
+
+ public void init(byte[] x)
+ {
+ long[] y = GCMUtil.asLongs(x);
+ if (lookupPowX2 != null && Arrays.areEqual(y, (long[])lookupPowX2.elementAt(0)))
+ {
+ return;
+ }
+
+ lookupPowX2 = new Vector(8);
+ lookupPowX2.addElement(y);
+ }
+
+ public void exponentiateX(long pow, byte[] output)
+ {
+ long[] y = GCMUtil.oneAsLongs();
+ int bit = 0;
+ while (pow > 0)
+ {
+ if ((pow & 1L) != 0)
+ {
+ ensureAvailable(bit);
+ GCMUtil.multiply(y, (long[])lookupPowX2.elementAt(bit));
+ }
+ ++bit;
+ pow >>>= 1;
+ }
+
+ GCMUtil.asBytes(y, output);
+ }
+
+ private void ensureAvailable(int bit)
+ {
+ int count = lookupPowX2.size();
+ if (count <= bit)
+ {
+ long[] tmp = (long[])lookupPowX2.elementAt(count - 1);
+ do
+ {
+ tmp = Arrays.clone(tmp);
+ GCMUtil.square(tmp, tmp);
+ lookupPowX2.addElement(tmp);
+ }
+ while (++count <= bit);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java
new file mode 100644
index 00000000..30f2af6a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables4kGCMMultiplier.java
@@ -0,0 +1,71 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes.gcm;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Tables4kGCMMultiplier
+ implements GCMMultiplier
+{
+ private byte[] H;
+ private long[][] T;
+
+ public void init(byte[] H)
+ {
+ if (T == null)
+ {
+ T = new long[256][2];
+ }
+ else if (Arrays.areEqual(this.H, H))
+ {
+ return;
+ }
+
+ this.H = Arrays.clone(H);
+
+ // T[0] = 0
+
+ // T[1] = H.p^7
+ GCMUtil.asLongs(this.H, T[1]);
+ GCMUtil.multiplyP7(T[1], T[1]);
+
+ for (int n = 2; n < 256; n += 2)
+ {
+ // T[2.n] = T[n].p^-1
+ GCMUtil.divideP(T[n >> 1], T[n]);
+
+ // T[2.n + 1] = T[2.n] + T[1]
+ GCMUtil.xor(T[n], T[1], T[n + 1]);
+ }
+ }
+
+ public void multiplyH(byte[] x)
+ {
+// long[] z = new long[2];
+// GCMUtil.copy(T[x[15] & 0xFF], z);
+// for (int i = 14; i >= 0; --i)
+// {
+// GCMUtil.multiplyP8(z);
+// GCMUtil.xor(z, T[x[i] & 0xFF]);
+// }
+// Pack.longToBigEndian(z, x, 0);
+
+ long[] t = T[x[15] & 0xFF];
+ long z0 = t[0], z1 = t[1];
+
+ for (int i = 14; i >= 0; --i)
+ {
+ t = T[x[i] & 0xFF];
+
+ long c = z1 << 56;
+ z1 = t[1] ^ ((z1 >>> 8) | (z0 << 56));
+ z0 = t[0] ^ (z0 >>> 8) ^ c ^ (c >>> 1) ^ (c >>> 2) ^ (c >>> 7);
+ }
+
+ Pack.longToBigEndian(z0, x, 0);
+ Pack.longToBigEndian(z1, x, 8);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java
new file mode 100644
index 00000000..3b925416
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/Tables8kGCMMultiplier.java
@@ -0,0 +1,83 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.modes.gcm;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Tables8kGCMMultiplier
+ implements GCMMultiplier
+{
+ private byte[] H;
+ private long[][][] T;
+
+ public void init(byte[] H)
+ {
+ if (T == null)
+ {
+ T = new long[32][16][2];
+ }
+ else if (Arrays.areEqual(this.H, H))
+ {
+ return;
+ }
+
+ this.H = Arrays.clone(H);
+
+ for (int i = 0; i < 32; ++i)
+ {
+ long[][] t = T[i];
+
+ // t[0] = 0
+
+ if (i == 0)
+ {
+ // t[1] = H.p^3
+ GCMUtil.asLongs(this.H, t[1]);
+ GCMUtil.multiplyP3(t[1], t[1]);
+ }
+ else
+ {
+ // t[1] = T[i-1][1].p^4
+ GCMUtil.multiplyP4(T[i - 1][1], t[1]);
+ }
+
+ for (int n = 2; n < 16; n += 2)
+ {
+ // t[2.n] = t[n].p^-1
+ GCMUtil.divideP(t[n >> 1], t[n]);
+
+ // t[2.n + 1] = t[2.n] + t[1]
+ GCMUtil.xor(t[n], t[1], t[n + 1]);
+ }
+ }
+
+ }
+
+ public void multiplyH(byte[] x)
+ {
+// long[] z = new long[2];
+// for (int i = 15; i >= 0; --i)
+// {
+// GCMUtil.xor(z, T[i + i + 1][(x[i] & 0x0F)]);
+// GCMUtil.xor(z, T[i + i ][(x[i] & 0xF0) >>> 4]);
+// }
+// Pack.longToBigEndian(z, x, 0);
+
+ long z0 = 0, z1 = 0;
+
+ for (int i = 15; i >= 0; --i)
+ {
+ long[] u = T[i + i + 1][(x[i] & 0x0F)];
+ long[] v = T[i + i ][(x[i] & 0xF0) >>> 4];
+
+ z0 ^= u[0] ^ v[0];
+ z1 ^= u[1] ^ v[1];
+ }
+
+ Pack.longToBigEndian(z0, x, 0);
+ Pack.longToBigEndian(z1, x, 8);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/BlockCipherPadding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/BlockCipherPadding.java
new file mode 100644
index 00000000..54d349bb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/BlockCipherPadding.java
@@ -0,0 +1,50 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.paddings;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+
+/**
+ * Block cipher padders are expected to conform to this interface
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface BlockCipherPadding
+{
+ /**
+ * Initialise the padder.
+ *
+ * @param random the source of randomness for the padding, if required.
+ */
+ public void init(SecureRandom random)
+ throws IllegalArgumentException;
+
+ /**
+ * Return the name of the algorithm the cipher implements.
+ *
+ * @return the name of the algorithm the cipher implements.
+ */
+ public String getPaddingName();
+
+ /**
+ * add the pad bytes to the passed in block, returning the
+ * number of bytes added.
+ * <p>
+ * Note: this assumes that the last block of plain text is always
+ * passed to it inside in. i.e. if inOff is zero, indicating the
+ * entire block is to be overwritten with padding the value of in
+ * should be the same as the last block of plain text. The reason
+ * for this is that some modes such as "trailing bit compliment"
+ * base the padding on the last byte of plain text.
+ * </p>
+ */
+ public int addPadding(byte[] in, int inOff);
+
+ /**
+ * return the number of pad bytes present in the block.
+ * @exception InvalidCipherTextException if the padding is badly formed
+ * or invalid.
+ */
+ public int padCount(byte[] in)
+ throws InvalidCipherTextException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
new file mode 100644
index 00000000..14c634a7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
@@ -0,0 +1,75 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.paddings;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+
+/**
+ * A padder that adds ISO10126-2 padding to a block.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ISO10126d2Padding
+ implements BlockCipherPadding
+{
+ SecureRandom random;
+
+ /**
+ * Initialise the padder.
+ *
+ * @param random a SecureRandom if available.
+ */
+ public void init(SecureRandom random)
+ throws IllegalArgumentException
+ {
+ this.random = CryptoServicesRegistrar.getSecureRandom(random);
+ }
+
+ /**
+ * Return the name of the algorithm the padder implements.
+ *
+ * @return the name of the algorithm the padder implements.
+ */
+ public String getPaddingName()
+ {
+ return "ISO10126-2";
+ }
+
+ /**
+ * add the pad bytes to the passed in block, returning the
+ * number of bytes added.
+ */
+ public int addPadding(
+ byte[] in,
+ int inOff)
+ {
+ byte code = (byte)(in.length - inOff);
+
+ while (inOff < (in.length - 1))
+ {
+ in[inOff] = (byte)random.nextInt();
+ inOff++;
+ }
+
+ in[inOff] = code;
+
+ return code;
+ }
+
+ /**
+ * return the number of pad bytes present in the block.
+ */
+ public int padCount(byte[] in)
+ throws InvalidCipherTextException
+ {
+ int count = in[in.length - 1] & 0xff;
+
+ if (count > in.length)
+ {
+ throw new InvalidCipherTextException("pad block corrupted");
+ }
+
+ return count;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java
new file mode 100644
index 00000000..9b20044b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java
@@ -0,0 +1,79 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.paddings;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+
+/**
+ * A padder that adds the padding according to the scheme referenced in
+ * ISO 7814-4 - scheme 2 from ISO 9797-1. The first byte is 0x80, rest is 0x00
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ISO7816d4Padding
+ implements BlockCipherPadding
+{
+ /**
+ * Initialise the padder.
+ *
+ * @param random - a SecureRandom if available.
+ */
+ public void init(SecureRandom random)
+ throws IllegalArgumentException
+ {
+ // nothing to do.
+ }
+
+ /**
+ * Return the name of the algorithm the padder implements.
+ *
+ * @return the name of the algorithm the padder implements.
+ */
+ public String getPaddingName()
+ {
+ return "ISO7816-4";
+ }
+
+ /**
+ * add the pad bytes to the passed in block, returning the
+ * number of bytes added.
+ */
+ public int addPadding(
+ byte[] in,
+ int inOff)
+ {
+ int added = (in.length - inOff);
+
+ in [inOff]= (byte) 0x80;
+ inOff ++;
+
+ while (inOff < in.length)
+ {
+ in[inOff] = (byte) 0;
+ inOff++;
+ }
+
+ return added;
+ }
+
+ /**
+ * return the number of pad bytes present in the block.
+ */
+ public int padCount(byte[] in)
+ throws InvalidCipherTextException
+ {
+ int count = in.length - 1;
+
+ while (count > 0 && in[count] == 0)
+ {
+ count--;
+ }
+
+ if (in[count] != (byte)0x80)
+ {
+ throw new InvalidCipherTextException("pad block corrupted");
+ }
+
+ return in.length - count;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PKCS7Padding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PKCS7Padding.java
new file mode 100644
index 00000000..f96d4b81
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PKCS7Padding.java
@@ -0,0 +1,79 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.paddings;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+
+/**
+ * A padder that adds PKCS7/PKCS5 padding to a block.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS7Padding
+ implements BlockCipherPadding
+{
+ /**
+ * Initialise the padder.
+ *
+ * @param random - a SecureRandom if available.
+ */
+ public void init(SecureRandom random)
+ throws IllegalArgumentException
+ {
+ // nothing to do.
+ }
+
+ /**
+ * Return the name of the algorithm the padder implements.
+ *
+ * @return the name of the algorithm the padder implements.
+ */
+ public String getPaddingName()
+ {
+ return "PKCS7";
+ }
+
+ /**
+ * add the pad bytes to the passed in block, returning the
+ * number of bytes added.
+ */
+ public int addPadding(
+ byte[] in,
+ int inOff)
+ {
+ byte code = (byte)(in.length - inOff);
+
+ while (inOff < in.length)
+ {
+ in[inOff] = code;
+ inOff++;
+ }
+
+ return code;
+ }
+
+ /**
+ * return the number of pad bytes present in the block.
+ */
+ public int padCount(byte[] in)
+ throws InvalidCipherTextException
+ {
+ int count = in[in.length - 1] & 0xff;
+ byte countAsbyte = (byte)count;
+
+ // constant time version
+ boolean failed = (count > in.length | count == 0);
+
+ for (int i = 0; i < in.length; i++)
+ {
+ failed |= (in.length - i <= count) & (in[i] != countAsbyte);
+ }
+
+ if (failed)
+ {
+ throw new InvalidCipherTextException("pad block corrupted");
+ }
+
+ return count;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java
new file mode 100644
index 00000000..f75ef535
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java
@@ -0,0 +1,301 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.paddings;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.BufferedBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+
+/**
+ * A wrapper class that allows block ciphers to be used to process data in
+ * a piecemeal fashion with padding. The PaddedBufferedBlockCipher
+ * outputs a block only when the buffer is full and more data is being added,
+ * or on a doFinal (unless the current block in the buffer is a pad block).
+ * The default padding mechanism used is the one outlined in PKCS5/PKCS7.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PaddedBufferedBlockCipher
+ extends BufferedBlockCipher
+{
+ BlockCipherPadding padding;
+
+ /**
+ * Create a buffered block cipher with the desired padding.
+ *
+ * @param cipher the underlying block cipher this buffering object wraps.
+ * @param padding the padding type.
+ */
+ public PaddedBufferedBlockCipher(
+ BlockCipher cipher,
+ BlockCipherPadding padding)
+ {
+ this.cipher = cipher;
+ this.padding = padding;
+
+ buf = new byte[cipher.getBlockSize()];
+ bufOff = 0;
+ }
+
+ /**
+ * Create a buffered block cipher PKCS7 padding
+ *
+ * @param cipher the underlying block cipher this buffering object wraps.
+ */
+ public PaddedBufferedBlockCipher(
+ BlockCipher cipher)
+ {
+ this(cipher, new PKCS7Padding());
+ }
+
+ /**
+ * initialise the cipher.
+ *
+ * @param forEncryption if true the cipher is initialised for
+ * encryption, if false for decryption.
+ * @param params the key and other data required by the cipher.
+ * @exception IllegalArgumentException if the params argument is
+ * inappropriate.
+ */
+ public void init(
+ boolean forEncryption,
+ CipherParameters params)
+ throws IllegalArgumentException
+ {
+ this.forEncryption = forEncryption;
+
+ reset();
+
+ if (params instanceof ParametersWithRandom)
+ {
+ ParametersWithRandom p = (ParametersWithRandom)params;
+
+ padding.init(p.getRandom());
+
+ cipher.init(forEncryption, p.getParameters());
+ }
+ else
+ {
+ padding.init(null);
+
+ cipher.init(forEncryption, params);
+ }
+ }
+
+ /**
+ * return the minimum size of the output buffer required for an update
+ * plus a doFinal with an input of len bytes.
+ *
+ * @param len the length of the input.
+ * @return the space required to accommodate a call to update and doFinal
+ * with len bytes of input.
+ */
+ public int getOutputSize(
+ int len)
+ {
+ int total = len + bufOff;
+ int leftOver = total % buf.length;
+
+ if (leftOver == 0)
+ {
+ if (forEncryption)
+ {
+ return total + buf.length;
+ }
+
+ return total;
+ }
+
+ return total - leftOver + buf.length;
+ }
+
+ /**
+ * return the size of the output buffer required for an update
+ * an input of len bytes.
+ *
+ * @param len the length of the input.
+ * @return the space required to accommodate a call to update
+ * with len bytes of input.
+ */
+ public int getUpdateOutputSize(
+ int len)
+ {
+ int total = len + bufOff;
+ int leftOver = total % buf.length;
+
+ if (leftOver == 0)
+ {
+ return Math.max(0, total - buf.length);
+ }
+
+ return total - leftOver;
+ }
+
+ /**
+ * process a single byte, producing an output block if neccessary.
+ *
+ * @param in the input byte.
+ * @param out the space for any output that might be produced.
+ * @param outOff the offset from which the output will be copied.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there isn't enough space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ */
+ public int processByte(
+ byte in,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ int resultLen = 0;
+
+ if (bufOff == buf.length)
+ {
+ resultLen = cipher.processBlock(buf, 0, out, outOff);
+ bufOff = 0;
+ }
+
+ buf[bufOff++] = in;
+
+ return resultLen;
+ }
+
+ /**
+ * process an array of bytes, producing output if necessary.
+ *
+ * @param in the input byte array.
+ * @param inOff the offset at which the input data starts.
+ * @param len the number of bytes to be copied out of the input array.
+ * @param out the space for any output that might be produced.
+ * @param outOff the offset from which the output will be copied.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there isn't enough space in out.
+ * @exception IllegalStateException if the cipher isn't initialised.
+ */
+ public int processBytes(
+ byte[] in,
+ int inOff,
+ int len,
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ if (len < 0)
+ {
+ throw new IllegalArgumentException("Can't have a negative input length!");
+ }
+
+ int blockSize = getBlockSize();
+ int length = getUpdateOutputSize(len);
+
+ if (length > 0)
+ {
+ if ((outOff + length) > out.length)
+ {
+ throw new OutputLengthException("output buffer too short");
+ }
+ }
+
+ int resultLen = 0;
+ int gapLen = buf.length - bufOff;
+
+ if (len > gapLen)
+ {
+ System.arraycopy(in, inOff, buf, bufOff, gapLen);
+
+ resultLen += cipher.processBlock(buf, 0, out, outOff);
+
+ bufOff = 0;
+ len -= gapLen;
+ inOff += gapLen;
+
+ while (len > buf.length)
+ {
+ resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen);
+
+ len -= blockSize;
+ inOff += blockSize;
+ }
+ }
+
+ System.arraycopy(in, inOff, buf, bufOff, len);
+
+ bufOff += len;
+
+ return resultLen;
+ }
+
+ /**
+ * Process the last block in the buffer. If the buffer is currently
+ * full and padding needs to be added a call to doFinal will produce
+ * 2 * getBlockSize() bytes.
+ *
+ * @param out the array the block currently being held is copied into.
+ * @param outOff the offset at which the copying starts.
+ * @return the number of output bytes copied to out.
+ * @exception DataLengthException if there is insufficient space in out for
+ * the output or we are decrypting and the input is not block size aligned.
+ * @exception IllegalStateException if the underlying cipher is not
+ * initialised.
+ * @exception InvalidCipherTextException if padding is expected and not found.
+ */
+ public int doFinal(
+ byte[] out,
+ int outOff)
+ throws DataLengthException, IllegalStateException, InvalidCipherTextException
+ {
+ int blockSize = cipher.getBlockSize();
+ int resultLen = 0;
+
+ if (forEncryption)
+ {
+ if (bufOff == blockSize)
+ {
+ if ((outOff + 2 * blockSize) > out.length)
+ {
+ reset();
+
+ throw new OutputLengthException("output buffer too short");
+ }
+
+ resultLen = cipher.processBlock(buf, 0, out, outOff);
+ bufOff = 0;
+ }
+
+ padding.addPadding(buf, bufOff);
+
+ resultLen += cipher.processBlock(buf, 0, out, outOff + resultLen);
+
+ reset();
+ }
+ else
+ {
+ if (bufOff == blockSize)
+ {
+ resultLen = cipher.processBlock(buf, 0, buf, 0);
+ bufOff = 0;
+ }
+ else
+ {
+ reset();
+
+ throw new DataLengthException("last block incomplete in decryption");
+ }
+
+ try
+ {
+ resultLen -= padding.padCount(buf);
+
+ System.arraycopy(buf, 0, out, outOff, resultLen);
+ }
+ finally
+ {
+ reset();
+ }
+ }
+
+ return resultLen;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/TBCPadding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/TBCPadding.java
new file mode 100644
index 00000000..fbaa0f34
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/TBCPadding.java
@@ -0,0 +1,91 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.paddings;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+
+/**
+ * A padder that adds Trailing-Bit-Compliment padding to a block.
+ * <p>
+ * This padding pads the block out with the compliment of the last bit
+ * of the plain text.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TBCPadding
+ implements BlockCipherPadding
+{
+ /**
+ * Initialise the padder.
+ *
+ * @param random - a SecureRandom if available.
+ */
+ public void init(SecureRandom random)
+ throws IllegalArgumentException
+ {
+ // nothing to do.
+ }
+
+ /**
+ * Return the name of the algorithm the padder implements.
+ *
+ * @return the name of the algorithm the padder implements.
+ */
+ public String getPaddingName()
+ {
+ return "TBC";
+ }
+
+ /**
+ * add the pad bytes to the passed in block, returning the
+ * number of bytes added.
+ * <p>
+ * Note: this assumes that the last block of plain text is always
+ * passed to it inside in. i.e. if inOff is zero, indicating the
+ * entire block is to be overwritten with padding the value of in
+ * should be the same as the last block of plain text.
+ * </p>
+ */
+ public int addPadding(
+ byte[] in,
+ int inOff)
+ {
+ int count = in.length - inOff;
+ byte code;
+
+ if (inOff > 0)
+ {
+ code = (byte)((in[inOff - 1] & 0x01) == 0 ? 0xff : 0x00);
+ }
+ else
+ {
+ code = (byte)((in[in.length - 1] & 0x01) == 0 ? 0xff : 0x00);
+ }
+
+ while (inOff < in.length)
+ {
+ in[inOff] = code;
+ inOff++;
+ }
+
+ return count;
+ }
+
+ /**
+ * return the number of pad bytes present in the block.
+ */
+ public int padCount(byte[] in)
+ throws InvalidCipherTextException
+ {
+ byte code = in[in.length - 1];
+
+ int index = in.length - 1;
+ while (index > 0 && in[index - 1] == code)
+ {
+ index--;
+ }
+
+ return in.length - index;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/X923Padding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/X923Padding.java
new file mode 100644
index 00000000..ca24e818
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/X923Padding.java
@@ -0,0 +1,82 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.paddings;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+
+/**
+ * A padder that adds X9.23 padding to a block - if a SecureRandom is
+ * passed in random padding is assumed, otherwise padding with zeros is used.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X923Padding
+ implements BlockCipherPadding
+{
+ SecureRandom random = null;
+
+ /**
+ * Initialise the padder.
+ *
+ * @param random a SecureRandom if one is available.
+ */
+ public void init(SecureRandom random)
+ throws IllegalArgumentException
+ {
+ this.random = random;
+ }
+
+ /**
+ * Return the name of the algorithm the padder implements.
+ *
+ * @return the name of the algorithm the padder implements.
+ */
+ public String getPaddingName()
+ {
+ return "X9.23";
+ }
+
+ /**
+ * add the pad bytes to the passed in block, returning the
+ * number of bytes added.
+ */
+ public int addPadding(
+ byte[] in,
+ int inOff)
+ {
+ byte code = (byte)(in.length - inOff);
+
+ while (inOff < in.length - 1)
+ {
+ if (random == null)
+ {
+ in[inOff] = 0;
+ }
+ else
+ {
+ in[inOff] = (byte)random.nextInt();
+ }
+ inOff++;
+ }
+
+ in[inOff] = code;
+
+ return code;
+ }
+
+ /**
+ * return the number of pad bytes present in the block.
+ */
+ public int padCount(byte[] in)
+ throws InvalidCipherTextException
+ {
+ int count = in[in.length - 1] & 0xff;
+
+ if (count > in.length)
+ {
+ throw new InvalidCipherTextException("pad block corrupted");
+ }
+
+ return count;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ZeroBytePadding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ZeroBytePadding.java
new file mode 100644
index 00000000..9553137b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ZeroBytePadding.java
@@ -0,0 +1,75 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.paddings;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+
+/**
+ * A padder that adds NULL byte padding to a block.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ZeroBytePadding
+ implements BlockCipherPadding
+{
+ /**
+ * Initialise the padder.
+ *
+ * @param random - a SecureRandom if available.
+ */
+ public void init(SecureRandom random)
+ throws IllegalArgumentException
+ {
+ // nothing to do.
+ }
+
+ /**
+ * Return the name of the algorithm the padder implements.
+ *
+ * @return the name of the algorithm the padder implements.
+ */
+ public String getPaddingName()
+ {
+ return "ZeroByte";
+ }
+
+ /**
+ * add the pad bytes to the passed in block, returning the
+ * number of bytes added.
+ */
+ public int addPadding(
+ byte[] in,
+ int inOff)
+ {
+ int added = (in.length - inOff);
+
+ while (inOff < in.length)
+ {
+ in[inOff] = (byte) 0;
+ inOff++;
+ }
+
+ return added;
+ }
+
+ /**
+ * return the number of pad bytes present in the block.
+ */
+ public int padCount(byte[] in)
+ throws InvalidCipherTextException
+ {
+ int count = in.length;
+
+ while (count > 0)
+ {
+ if (in[count - 1] != 0)
+ {
+ break;
+ }
+
+ count--;
+ }
+
+ return in.length - count;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/AEADParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/AEADParameters.java
new file mode 100644
index 00000000..9fb71905
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/AEADParameters.java
@@ -0,0 +1,65 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AEADParameters
+ implements CipherParameters
+{
+ private byte[] associatedText;
+ private byte[] nonce;
+ private KeyParameter key;
+ private int macSize;
+
+ /**
+ * Base constructor.
+ *
+ * @param key key to be used by underlying cipher
+ * @param macSize macSize in bits
+ * @param nonce nonce to be used
+ */
+ public AEADParameters(KeyParameter key, int macSize, byte[] nonce)
+ {
+ this(key, macSize, nonce, null);
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param key key to be used by underlying cipher
+ * @param macSize macSize in bits
+ * @param nonce nonce to be used
+ * @param associatedText initial associated text, if any
+ */
+ public AEADParameters(KeyParameter key, int macSize, byte[] nonce, byte[] associatedText)
+ {
+ this.key = key;
+ this.nonce = Arrays.clone(nonce);
+ this.macSize = macSize;
+ this.associatedText = Arrays.clone(associatedText);
+ }
+
+ public KeyParameter getKey()
+ {
+ return key;
+ }
+
+ public int getMacSize()
+ {
+ return macSize;
+ }
+
+ public byte[] getAssociatedText()
+ {
+ return Arrays.clone(associatedText);
+ }
+
+ public byte[] getNonce()
+ {
+ return Arrays.clone(nonce);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/AsymmetricKeyParameter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/AsymmetricKeyParameter.java
new file mode 100644
index 00000000..54a03767
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/AsymmetricKeyParameter.java
@@ -0,0 +1,24 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AsymmetricKeyParameter
+ implements CipherParameters
+{
+ boolean privateKey;
+
+ public AsymmetricKeyParameter(
+ boolean privateKey)
+ {
+ this.privateKey = privateKey;
+ }
+
+ public boolean isPrivate()
+ {
+ return privateKey;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DESParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DESParameters.java
new file mode 100644
index 00000000..d5c14d21
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DESParameters.java
@@ -0,0 +1,111 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DESParameters
+ extends KeyParameter
+{
+ public DESParameters(
+ byte[] key)
+ {
+ super(key);
+
+ if (isWeakKey(key, 0))
+ {
+ throw new IllegalArgumentException("attempt to create weak DES key");
+ }
+ }
+
+ /*
+ * DES Key length in bytes.
+ */
+ static public final int DES_KEY_LENGTH = 8;
+
+ /*
+ * Table of weak and semi-weak keys taken from Schneier pp281
+ */
+ static private final int N_DES_WEAK_KEYS = 16;
+
+ static private byte[] DES_weak_keys =
+ {
+ /* weak keys */
+ (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,
+ (byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e,
+ (byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1,
+ (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,
+
+ /* semi-weak keys */
+ (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe,
+ (byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0, (byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1,
+ (byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0, (byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1,
+ (byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe, (byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe,
+ (byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f, (byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e,
+ (byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe, (byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe,
+ (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01,
+ (byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f, (byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e,
+ (byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01, (byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01,
+ (byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f, (byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e,
+ (byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01, (byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01,
+ (byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0, (byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1
+ };
+
+ /**
+ * DES has 16 weak keys. This method will check
+ * if the given DES key material is weak or semi-weak.
+ * Key material that is too short is regarded as weak.
+ * <p>
+ * See <a href="https://www.counterpane.com/applied.html">"Applied
+ * Cryptography"</a> by Bruce Schneier for more information.
+ *
+ * @return true if the given DES key material is weak or semi-weak,
+ * false otherwise.
+ */
+ public static boolean isWeakKey(
+ byte[] key,
+ int offset)
+ {
+ if (key.length - offset < DES_KEY_LENGTH)
+ {
+ throw new IllegalArgumentException("key material too short.");
+ }
+
+ nextkey: for (int i = 0; i < N_DES_WEAK_KEYS; i++)
+ {
+ for (int j = 0; j < DES_KEY_LENGTH; j++)
+ {
+ if (key[j + offset] != DES_weak_keys[i * DES_KEY_LENGTH + j])
+ {
+ continue nextkey;
+ }
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * DES Keys use the LSB as the odd parity bit. This can
+ * be used to check for corrupt keys.
+ *
+ * @param bytes the byte array to set the parity on.
+ */
+ public static void setOddParity(
+ byte[] bytes)
+ {
+ for (int i = 0; i < bytes.length; i++)
+ {
+ int b = bytes[i];
+ bytes[i] = (byte)((b & 0xfe) |
+ ((((b >> 1) ^
+ (b >> 2) ^
+ (b >> 3) ^
+ (b >> 4) ^
+ (b >> 5) ^
+ (b >> 6) ^
+ (b >> 7)) ^ 0x01) & 0x01));
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DESedeParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DESedeParameters.java
new file mode 100644
index 00000000..1409b88c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DESedeParameters.java
@@ -0,0 +1,110 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DESedeParameters
+ extends DESParameters
+{
+ /*
+ * DES-EDE Key length in bytes.
+ */
+ static public final int DES_EDE_KEY_LENGTH = 24;
+
+ public DESedeParameters(
+ byte[] key)
+ {
+ super(key);
+
+ if (isWeakKey(key, 0, key.length))
+ {
+ throw new IllegalArgumentException("attempt to create weak DESede key");
+ }
+ }
+
+ /**
+ * return true if the passed in key is a DES-EDE weak key.
+ *
+ * @param key bytes making up the key
+ * @param offset offset into the byte array the key starts at
+ * @param length number of bytes making up the key
+ */
+ public static boolean isWeakKey(
+ byte[] key,
+ int offset,
+ int length)
+ {
+ for (int i = offset; i < length; i += DES_KEY_LENGTH)
+ {
+ if (DESParameters.isWeakKey(key, i))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * return true if the passed in key is a DES-EDE weak key.
+ *
+ * @param key bytes making up the key
+ * @param offset offset into the byte array the key starts at
+ */
+ public static boolean isWeakKey(
+ byte[] key,
+ int offset)
+ {
+ return isWeakKey(key, offset, key.length - offset);
+ }
+
+ /**
+ * return true if the passed in key is a real 2/3 part DES-EDE key.
+ *
+ * @param key bytes making up the key
+ * @param offset offset into the byte array the key starts at
+ */
+ public static boolean isRealEDEKey(byte[] key, int offset)
+ {
+ return key.length == 16 ? isReal2Key(key, offset) : isReal3Key(key, offset);
+ }
+
+ /**
+ * return true if the passed in key is a real 2 part DES-EDE key.
+ *
+ * @param key bytes making up the key
+ * @param offset offset into the byte array the key starts at
+ */
+ public static boolean isReal2Key(byte[] key, int offset)
+ {
+ boolean isValid = false;
+ for (int i = offset; i != offset + 8; i++)
+ {
+ if (key[i] != key[i + 8])
+ {
+ isValid = true;
+ }
+ }
+
+ return isValid;
+ }
+
+ /**
+ * return true if the passed in key is a real 3 part DES-EDE key.
+ *
+ * @param key bytes making up the key
+ * @param offset offset into the byte array the key starts at
+ */
+ public static boolean isReal3Key(byte[] key, int offset)
+ {
+ boolean diff12 = false, diff13 = false, diff23 = false;
+ for (int i = offset; i != offset + 8; i++)
+ {
+ diff12 |= (key[i] != key[i + 8]);
+ diff13 |= (key[i] != key[i + 16]);
+ diff23 |= (key[i + 8] != key[i + 16]);
+ }
+ return diff12 && diff13 && diff23;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHKeyGenerationParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHKeyGenerationParameters.java
new file mode 100644
index 00000000..3e206fe5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHKeyGenerationParameters.java
@@ -0,0 +1,34 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHKeyGenerationParameters
+ extends KeyGenerationParameters
+{
+ private DHParameters params;
+
+ public DHKeyGenerationParameters(
+ SecureRandom random,
+ DHParameters params)
+ {
+ super(random, getStrength(params));
+
+ this.params = params;
+ }
+
+ public DHParameters getParameters()
+ {
+ return params;
+ }
+
+ static int getStrength(DHParameters params)
+ {
+ return params.getL() != 0 ? params.getL() : params.getP().bitLength();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHKeyParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHKeyParameters.java
new file mode 100644
index 00000000..133e1663
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHKeyParameters.java
@@ -0,0 +1,58 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHKeyParameters
+ extends AsymmetricKeyParameter
+{
+ private DHParameters params;
+
+ protected DHKeyParameters(
+ boolean isPrivate,
+ DHParameters params)
+ {
+ super(isPrivate);
+
+ this.params = params;
+ }
+
+ public DHParameters getParameters()
+ {
+ return params;
+ }
+
+ public boolean equals(
+ Object obj)
+ {
+ if (!(obj instanceof DHKeyParameters))
+ {
+ return false;
+ }
+
+ DHKeyParameters dhKey = (DHKeyParameters)obj;
+
+ if (params == null)
+ {
+ return dhKey.getParameters() == null;
+ }
+ else
+ {
+ return params.equals(dhKey.getParameters());
+ }
+ }
+
+ public int hashCode()
+ {
+ int code = isPrivate() ? 0 : 1;
+
+ if (params != null)
+ {
+ code ^= params.hashCode();
+ }
+
+ return code;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHParameters.java
new file mode 100644
index 00000000..009e91ad
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHParameters.java
@@ -0,0 +1,198 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.util.Properties;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHParameters
+ implements CipherParameters
+{
+ private static final int DEFAULT_MINIMUM_LENGTH = 160;
+
+ // not final due to compiler bug in "simpler" JDKs
+ private BigInteger g;
+ private BigInteger p;
+ private BigInteger q;
+ private BigInteger j;
+ private int m;
+ private int l;
+ private DHValidationParameters validation;
+
+ private static int getDefaultMParam(
+ int lParam)
+ {
+ if (lParam == 0)
+ {
+ return DEFAULT_MINIMUM_LENGTH;
+ }
+
+ return lParam < DEFAULT_MINIMUM_LENGTH ? lParam : DEFAULT_MINIMUM_LENGTH;
+ }
+
+ public DHParameters(
+ BigInteger p,
+ BigInteger g)
+ {
+ this(p, g, null, 0);
+ }
+
+ public DHParameters(
+ BigInteger p,
+ BigInteger g,
+ BigInteger q)
+ {
+ this(p, g, q, 0);
+ }
+
+ public DHParameters(
+ BigInteger p,
+ BigInteger g,
+ BigInteger q,
+ int l)
+ {
+ this(p, g, q, getDefaultMParam(l), l, null, null);
+ }
+
+ public DHParameters(
+ BigInteger p,
+ BigInteger g,
+ BigInteger q,
+ int m,
+ int l)
+ {
+ this(p, g, q, m, l, null, null);
+ }
+
+ public DHParameters(
+ BigInteger p,
+ BigInteger g,
+ BigInteger q,
+ BigInteger j,
+ DHValidationParameters validation)
+ {
+ this(p, g, q, DEFAULT_MINIMUM_LENGTH, 0, j, validation);
+ }
+
+ public DHParameters(
+ BigInteger p,
+ BigInteger g,
+ BigInteger q,
+ int m,
+ int l,
+ BigInteger j,
+ DHValidationParameters validation)
+ {
+ if (l != 0)
+ {
+ if (l > p.bitLength())
+ {
+ throw new IllegalArgumentException("when l value specified, it must satisfy 2^(l-1) <= p");
+ }
+ if (l < m)
+ {
+ throw new IllegalArgumentException("when l value specified, it may not be less than m value");
+ }
+ }
+
+ if (m > p.bitLength() && !Properties.isOverrideSet("com.android.internal.org.bouncycastle.dh.allow_unsafe_p_value"))
+ {
+ throw new IllegalArgumentException("unsafe p value so small specific l required");
+ }
+
+ this.g = g;
+ this.p = p;
+ this.q = q;
+ this.m = m;
+ this.l = l;
+ this.j = j;
+ this.validation = validation;
+ }
+
+ public BigInteger getP()
+ {
+ return p;
+ }
+
+ public BigInteger getG()
+ {
+ return g;
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ /**
+ * Return the subgroup factor J.
+ *
+ * @return subgroup factor
+ */
+ public BigInteger getJ()
+ {
+ return j;
+ }
+
+ /**
+ * Return the minimum length of the private value.
+ *
+ * @return the minimum length of the private value in bits.
+ */
+ public int getM()
+ {
+ return m;
+ }
+
+ /**
+ * Return the private value length in bits - if set, zero otherwise
+ *
+ * @return the private value length in bits, zero otherwise.
+ */
+ public int getL()
+ {
+ return l;
+ }
+
+ public DHValidationParameters getValidationParameters()
+ {
+ return validation;
+ }
+
+ public boolean equals(
+ Object obj)
+ {
+ if (!(obj instanceof DHParameters))
+ {
+ return false;
+ }
+
+ DHParameters pm = (DHParameters)obj;
+
+ if (this.getQ() != null)
+ {
+ if (!this.getQ().equals(pm.getQ()))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (pm.getQ() != null)
+ {
+ return false;
+ }
+ }
+
+ return pm.getP().equals(p) && pm.getG().equals(g);
+ }
+
+ public int hashCode()
+ {
+ return getP().hashCode() ^ getG().hashCode() ^ (getQ() != null ? getQ().hashCode() : 0);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHPrivateKeyParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHPrivateKeyParameters.java
new file mode 100644
index 00000000..9837e779
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHPrivateKeyParameters.java
@@ -0,0 +1,45 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHPrivateKeyParameters
+ extends DHKeyParameters
+{
+ private BigInteger x;
+
+ public DHPrivateKeyParameters(
+ BigInteger x,
+ DHParameters params)
+ {
+ super(true, params);
+
+ this.x = x;
+ }
+
+ public BigInteger getX()
+ {
+ return x;
+ }
+
+ public int hashCode()
+ {
+ return x.hashCode() ^ super.hashCode();
+ }
+
+ public boolean equals(
+ Object obj)
+ {
+ if (!(obj instanceof DHPrivateKeyParameters))
+ {
+ return false;
+ }
+
+ DHPrivateKeyParameters other = (DHPrivateKeyParameters)obj;
+
+ return other.getX().equals(this.x) && super.equals(obj);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHPublicKeyParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHPublicKeyParameters.java
new file mode 100644
index 00000000..8f64d6b5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHPublicKeyParameters.java
@@ -0,0 +1,168 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.util.Integers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHPublicKeyParameters
+ extends DHKeyParameters
+{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+
+ private BigInteger y;
+
+ public DHPublicKeyParameters(
+ BigInteger y,
+ DHParameters params)
+ {
+ super(false, params);
+
+ this.y = validate(y, params);
+ }
+
+ private BigInteger validate(BigInteger y, DHParameters dhParams)
+ {
+ if (y == null)
+ {
+ throw new NullPointerException("y value cannot be null");
+ }
+
+ BigInteger p = dhParams.getP();
+
+ // TLS check
+ if (y.compareTo(TWO) < 0 || y.compareTo(p.subtract(TWO)) > 0)
+ {
+ throw new IllegalArgumentException("invalid DH public key");
+ }
+
+ BigInteger q = dhParams.getQ();
+ if (q == null)
+ {
+ return y; // we can't validate without Q.
+ }
+
+ if (p.testBit(0)
+ && p.bitLength() - 1 == q.bitLength()
+ && p.shiftRight(1).equals(q))
+ {
+ // Safe prime case
+ if (1 == legendre(y, p))
+ {
+ return y;
+ }
+ }
+ else
+ {
+ if (ONE.equals(y.modPow(q, p)))
+ {
+ return y;
+ }
+ }
+
+ throw new IllegalArgumentException("Y value does not appear to be in correct group");
+ }
+
+ public BigInteger getY()
+ {
+ return y;
+ }
+
+ public int hashCode()
+ {
+ return y.hashCode() ^ super.hashCode();
+ }
+
+ public boolean equals(
+ Object obj)
+ {
+ if (!(obj instanceof DHPublicKeyParameters))
+ {
+ return false;
+ }
+
+ DHPublicKeyParameters other = (DHPublicKeyParameters)obj;
+
+ return other.getY().equals(y) && super.equals(obj);
+ }
+
+ private static int legendre(BigInteger a, BigInteger b)
+ {
+// int r = 0, bits = b.intValue();
+//
+// for (;;)
+// {
+// int lowestSetBit = a.getLowestSetBit();
+// a = a.shiftRight(lowestSetBit);
+// r ^= (bits ^ (bits >>> 1)) & (lowestSetBit << 1);
+//
+// int cmp = a.compareTo(b);
+// if (cmp == 0)
+// {
+// break;
+// }
+//
+// if (cmp < 0)
+// {
+// BigInteger t = a; a = b; b = t;
+//
+// int oldBits = bits;
+// bits = b.intValue();
+// r ^= oldBits & bits;
+// }
+//
+// a = a.subtract(b);
+// }
+//
+// return ONE.equals(b) ? (1 - (r & 2)) : 0;
+
+ int bitLength = b.bitLength();
+ int[] A = Nat.fromBigInteger(bitLength, a);
+ int[] B = Nat.fromBigInteger(bitLength, b);
+
+ int r = 0;
+
+ int len = B.length;
+ for (;;)
+ {
+ while (A[0] == 0)
+ {
+ Nat.shiftDownWord(len, A, 0);
+ }
+
+ int shift = Integers.numberOfTrailingZeros(A[0]);
+ if (shift > 0)
+ {
+ Nat.shiftDownBits(len, A, shift, 0);
+ int bits = B[0];
+ r ^= (bits ^ (bits >>> 1)) & (shift << 1);
+ }
+
+ int cmp = Nat.compare(len, A, B);
+ if (cmp == 0)
+ {
+ break;
+ }
+
+ if (cmp < 0)
+ {
+ r ^= A[0] & B[0];
+ int[] t = A; A = B; B = t;
+ }
+
+ while (A[len - 1] == 0)
+ {
+ len = len - 1;
+ }
+
+ Nat.sub(len, A, B, A);
+ }
+
+ return Nat.isOne(len, B) ? (1 - (r & 2)) : 0;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHValidationParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHValidationParameters.java
new file mode 100644
index 00000000..86ac87c6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHValidationParameters.java
@@ -0,0 +1,54 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHValidationParameters
+{
+ private byte[] seed;
+ private int counter;
+
+ public DHValidationParameters(
+ byte[] seed,
+ int counter)
+ {
+ this.seed = Arrays.clone(seed);
+ this.counter = counter;
+ }
+
+ public int getCounter()
+ {
+ return counter;
+ }
+
+ public byte[] getSeed()
+ {
+ return Arrays.clone(seed);
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof DHValidationParameters))
+ {
+ return false;
+ }
+
+ DHValidationParameters other = (DHValidationParameters)o;
+
+ if (other.counter != this.counter)
+ {
+ return false;
+ }
+
+ return Arrays.areEqual(this.seed, other.seed);
+ }
+
+ public int hashCode()
+ {
+ return counter ^ Arrays.hashCode(seed);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAKeyGenerationParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAKeyGenerationParameters.java
new file mode 100644
index 00000000..ca6e830f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAKeyGenerationParameters.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DSAKeyGenerationParameters
+ extends KeyGenerationParameters
+{
+ private DSAParameters params;
+
+ public DSAKeyGenerationParameters(
+ SecureRandom random,
+ DSAParameters params)
+ {
+ super(random, params.getP().bitLength() - 1);
+
+ this.params = params;
+ }
+
+ public DSAParameters getParameters()
+ {
+ return params;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAKeyParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAKeyParameters.java
new file mode 100644
index 00000000..102a8cef
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAKeyParameters.java
@@ -0,0 +1,25 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DSAKeyParameters
+ extends AsymmetricKeyParameter
+{
+ private DSAParameters params;
+
+ public DSAKeyParameters(
+ boolean isPrivate,
+ DSAParameters params)
+ {
+ super(isPrivate);
+
+ this.params = params;
+ }
+
+ public DSAParameters getParameters()
+ {
+ return params;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAParameterGenerationParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAParameterGenerationParameters.java
new file mode 100644
index 00000000..d393c3fe
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAParameterGenerationParameters.java
@@ -0,0 +1,84 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.security.SecureRandom;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DSAParameterGenerationParameters
+{
+ public static final int DIGITAL_SIGNATURE_USAGE = 1;
+ public static final int KEY_ESTABLISHMENT_USAGE = 2;
+
+ private final int l;
+ private final int n;
+ private final int usageIndex;
+ private final int certainty;
+ private final SecureRandom random;
+
+ /**
+ * Construct without a usage index, this will do a random construction of G.
+ *
+ * @param L desired length of prime P in bits (the effective key size).
+ * @param N desired length of prime Q in bits.
+ * @param certainty certainty level for prime number generation.
+ * @param random the source of randomness to use.
+ */
+ public DSAParameterGenerationParameters(
+ int L,
+ int N,
+ int certainty,
+ SecureRandom random)
+ {
+ this(L, N, certainty, random, -1);
+ }
+
+ /**
+ * Construct for a specific usage index - this has the effect of using verifiable canonical generation of G.
+ *
+ * @param L desired length of prime P in bits (the effective key size).
+ * @param N desired length of prime Q in bits.
+ * @param certainty certainty level for prime number generation.
+ * @param random the source of randomness to use.
+ * @param usageIndex a valid usage index.
+ */
+ public DSAParameterGenerationParameters(
+ int L,
+ int N,
+ int certainty,
+ SecureRandom random,
+ int usageIndex)
+ {
+ this.l = L;
+ this.n = N;
+ this.certainty = certainty;
+ this.usageIndex = usageIndex;
+ this.random = random;
+ }
+
+ public int getL()
+ {
+ return l;
+ }
+
+ public int getN()
+ {
+ return n;
+ }
+
+ public int getCertainty()
+ {
+ return certainty;
+ }
+
+ public SecureRandom getRandom()
+ {
+ return random;
+ }
+
+ public int getUsageIndex()
+ {
+ return usageIndex;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAParameters.java
new file mode 100644
index 00000000..a94bcf3c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAParameters.java
@@ -0,0 +1,78 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DSAParameters
+ implements CipherParameters
+{
+ private BigInteger g;
+ private BigInteger q;
+ private BigInteger p;
+ private DSAValidationParameters validation;
+
+ public DSAParameters(
+ BigInteger p,
+ BigInteger q,
+ BigInteger g)
+ {
+ this.g = g;
+ this.p = p;
+ this.q = q;
+ }
+
+ public DSAParameters(
+ BigInteger p,
+ BigInteger q,
+ BigInteger g,
+ DSAValidationParameters params)
+ {
+ this.g = g;
+ this.p = p;
+ this.q = q;
+ this.validation = params;
+ }
+
+ public BigInteger getP()
+ {
+ return p;
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public BigInteger getG()
+ {
+ return g;
+ }
+
+ public DSAValidationParameters getValidationParameters()
+ {
+ return validation;
+ }
+
+ public boolean equals(
+ Object obj)
+ {
+ if (!(obj instanceof DSAParameters))
+ {
+ return false;
+ }
+
+ DSAParameters pm = (DSAParameters)obj;
+
+ return (pm.getP().equals(p) && pm.getQ().equals(q) && pm.getG().equals(g));
+ }
+
+ public int hashCode()
+ {
+ return getP().hashCode() ^ getQ().hashCode() ^ getG().hashCode();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAPrivateKeyParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAPrivateKeyParameters.java
new file mode 100644
index 00000000..c4438e37
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAPrivateKeyParameters.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DSAPrivateKeyParameters
+ extends DSAKeyParameters
+{
+ private BigInteger x;
+
+ public DSAPrivateKeyParameters(
+ BigInteger x,
+ DSAParameters params)
+ {
+ super(true, params);
+
+ this.x = x;
+ }
+
+ public BigInteger getX()
+ {
+ return x;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAPublicKeyParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAPublicKeyParameters.java
new file mode 100644
index 00000000..868c39b2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAPublicKeyParameters.java
@@ -0,0 +1,48 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DSAPublicKeyParameters
+ extends DSAKeyParameters
+{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+
+ private BigInteger y;
+
+ public DSAPublicKeyParameters(
+ BigInteger y,
+ DSAParameters params)
+ {
+ super(false, params);
+
+ this.y = validate(y, params);
+ }
+
+ private BigInteger validate(BigInteger y, DSAParameters params)
+ {
+ if (params != null)
+ {
+ if (TWO.compareTo(y) <= 0 && params.getP().subtract(TWO).compareTo(y) >= 0
+ && ONE.equals(y.modPow(params.getQ(), params.getP())))
+ {
+ return y;
+ }
+
+ throw new IllegalArgumentException("y value does not appear to be in correct group");
+ }
+ else
+ {
+ return y; // we can't validate without params, fortunately we can't use the key either...
+ }
+ }
+
+ public BigInteger getY()
+ {
+ return y;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAValidationParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAValidationParameters.java
new file mode 100644
index 00000000..120302bc
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DSAValidationParameters.java
@@ -0,0 +1,69 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DSAValidationParameters
+{
+ private int usageIndex;
+ private byte[] seed;
+ private int counter;
+
+ public DSAValidationParameters(
+ byte[] seed,
+ int counter)
+ {
+ this(seed, counter, -1);
+ }
+
+ public DSAValidationParameters(
+ byte[] seed,
+ int counter,
+ int usageIndex)
+ {
+ this.seed = Arrays.clone(seed);
+ this.counter = counter;
+ this.usageIndex = usageIndex;
+ }
+
+ public int getCounter()
+ {
+ return counter;
+ }
+
+ public byte[] getSeed()
+ {
+ return Arrays.clone(seed);
+ }
+
+ public int getUsageIndex()
+ {
+ return usageIndex;
+ }
+
+ public int hashCode()
+ {
+ return counter ^ Arrays.hashCode(seed);
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof DSAValidationParameters))
+ {
+ return false;
+ }
+
+ DSAValidationParameters other = (DSAValidationParameters)o;
+
+ if (other.counter != this.counter)
+ {
+ return false;
+ }
+
+ return Arrays.areEqual(this.seed, other.seed);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECDomainParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECDomainParameters.java
new file mode 100644
index 00000000..e461cad7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECDomainParameters.java
@@ -0,0 +1,182 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.math.ec.ECAlgorithms;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECDomainParameters
+ implements ECConstants
+{
+ private final ECCurve curve;
+ private final byte[] seed;
+ private final ECPoint G;
+ private final BigInteger n;
+ private final BigInteger h;
+
+ private BigInteger hInv = null;
+
+ public ECDomainParameters(X9ECParameters x9)
+ {
+ this(x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
+ }
+
+ public ECDomainParameters(
+ ECCurve curve,
+ ECPoint G,
+ BigInteger n)
+ {
+ this(curve, G, n, ONE, null);
+ }
+
+ public ECDomainParameters(
+ ECCurve curve,
+ ECPoint G,
+ BigInteger n,
+ BigInteger h)
+ {
+ this(curve, G, n, h, null);
+ }
+
+ public ECDomainParameters(
+ ECCurve curve,
+ ECPoint G,
+ BigInteger n,
+ BigInteger h,
+ byte[] seed)
+ {
+ if (curve == null)
+ {
+ throw new NullPointerException("curve");
+ }
+ if (n == null)
+ {
+ throw new NullPointerException("n");
+ }
+ // we can't check for h == null here as h is optional in X9.62 as it is not required for ECDSA
+
+ this.curve = curve;
+ this.G = validatePublicPoint(curve, G);
+ this.n = n;
+ this.h = h;
+ this.seed = Arrays.clone(seed);
+ }
+
+ public ECCurve getCurve()
+ {
+ return curve;
+ }
+
+ public ECPoint getG()
+ {
+ return G;
+ }
+
+ public BigInteger getN()
+ {
+ return n;
+ }
+
+ public BigInteger getH()
+ {
+ return h;
+ }
+
+ public synchronized BigInteger getHInv()
+ {
+ if (hInv == null)
+ {
+ hInv = BigIntegers.modOddInverseVar(n, h);
+ }
+ return hInv;
+ }
+
+ public byte[] getSeed()
+ {
+ return Arrays.clone(seed);
+ }
+
+ public boolean equals(
+ Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+
+ if (!(obj instanceof ECDomainParameters))
+ {
+ return false;
+ }
+
+ ECDomainParameters other = (ECDomainParameters)obj;
+
+ return this.curve.equals(other.curve)
+ && this.G.equals(other.G)
+ && this.n.equals(other.n);
+ }
+
+ public int hashCode()
+ {
+// return Arrays.hashCode(new Object[]{ curve, G, n });
+ int hc = 4;
+ hc *= 257;
+ hc ^= curve.hashCode();
+ hc *= 257;
+ hc ^= G.hashCode();
+ hc *= 257;
+ hc ^= n.hashCode();
+ return hc;
+ }
+
+ public BigInteger validatePrivateScalar(BigInteger d)
+ {
+ if (null == d)
+ {
+ throw new NullPointerException("Scalar cannot be null");
+ }
+
+ if (d.compareTo(ECConstants.ONE) < 0 || (d.compareTo(getN()) >= 0))
+ {
+ throw new IllegalArgumentException("Scalar is not in the interval [1, n - 1]");
+ }
+
+ return d;
+ }
+
+ public ECPoint validatePublicPoint(ECPoint q)
+ {
+ return validatePublicPoint(getCurve(), q);
+ }
+
+ static ECPoint validatePublicPoint(ECCurve c, ECPoint q)
+ {
+ if (null == q)
+ {
+ throw new NullPointerException("Point cannot be null");
+ }
+
+ q = ECAlgorithms.importPoint(c, q).normalize();
+
+ if (q.isInfinity())
+ {
+ throw new IllegalArgumentException("Point at infinity");
+ }
+
+ if (!q.isValid())
+ {
+ throw new IllegalArgumentException("Point not on curve");
+ }
+
+ return q;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECKeyGenerationParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECKeyGenerationParameters.java
new file mode 100644
index 00000000..fca2c57e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECKeyGenerationParameters.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECKeyGenerationParameters
+ extends KeyGenerationParameters
+{
+ private ECDomainParameters domainParams;
+
+ public ECKeyGenerationParameters(
+ ECDomainParameters domainParams,
+ SecureRandom random)
+ {
+ super(random, domainParams.getN().bitLength());
+
+ this.domainParams = domainParams;
+ }
+
+ public ECDomainParameters getDomainParameters()
+ {
+ return domainParams;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECKeyParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECKeyParameters.java
new file mode 100644
index 00000000..f45b269a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECKeyParameters.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECKeyParameters
+ extends AsymmetricKeyParameter
+{
+ private final ECDomainParameters parameters;
+
+ protected ECKeyParameters(
+ boolean isPrivate,
+ ECDomainParameters parameters)
+ {
+ super(isPrivate);
+
+ if (null == parameters)
+ {
+ throw new NullPointerException("'parameters' cannot be null");
+ }
+
+ this.parameters = parameters;
+ }
+
+ public ECDomainParameters getParameters()
+ {
+ return parameters;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECNamedDomainParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECNamedDomainParameters.java
new file mode 100644
index 00000000..8929ee04
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECNamedDomainParameters.java
@@ -0,0 +1,53 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECNamedDomainParameters
+ extends ECDomainParameters
+{
+ private ASN1ObjectIdentifier name;
+
+ public ECNamedDomainParameters(ASN1ObjectIdentifier name, ECCurve curve, ECPoint G, BigInteger n)
+ {
+ this(name, curve, G, n, ECConstants.ONE, null);
+ }
+
+ public ECNamedDomainParameters(ASN1ObjectIdentifier name, ECCurve curve, ECPoint G, BigInteger n, BigInteger h)
+ {
+ this(name, curve, G, n, h, null);
+ }
+
+ public ECNamedDomainParameters(ASN1ObjectIdentifier name, ECCurve curve, ECPoint G, BigInteger n, BigInteger h, byte[] seed)
+ {
+ super(curve, G, n, h, seed);
+
+ this.name = name;
+ }
+
+ public ECNamedDomainParameters(ASN1ObjectIdentifier name, ECDomainParameters domainParameters)
+ {
+ super(domainParameters.getCurve(), domainParameters.getG(), domainParameters.getN(), domainParameters.getH(), domainParameters.getSeed());
+ this.name = name;
+ }
+
+ public ECNamedDomainParameters(ASN1ObjectIdentifier name, X9ECParameters x9)
+ {
+ super(x9);
+ this.name = name;
+ }
+
+ public ASN1ObjectIdentifier getName()
+ {
+ return name;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java
new file mode 100644
index 00000000..a5b07d24
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECPrivateKeyParameters
+ extends ECKeyParameters
+{
+ private final BigInteger d;
+
+ public ECPrivateKeyParameters(
+ BigInteger d,
+ ECDomainParameters parameters)
+ {
+ super(true, parameters);
+
+ this.d = parameters.validatePrivateScalar(d);
+ }
+
+ public BigInteger getD()
+ {
+ return d;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECPublicKeyParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECPublicKeyParameters.java
new file mode 100644
index 00000000..f858cade
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECPublicKeyParameters.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECPublicKeyParameters
+ extends ECKeyParameters
+{
+ private final ECPoint q;
+
+ public ECPublicKeyParameters(
+ ECPoint q,
+ ECDomainParameters parameters)
+ {
+ super(false, parameters);
+
+ this.q = parameters.validatePublicPoint(q);
+ }
+
+ public ECPoint getQ()
+ {
+ return q;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/KDFParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/KDFParameters.java
new file mode 100644
index 00000000..dc763933
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/KDFParameters.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import com.android.internal.org.bouncycastle.crypto.DerivationParameters;
+
+/**
+ * parameters for Key derivation functions for IEEE P1363a
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KDFParameters
+ implements DerivationParameters
+{
+ byte[] iv;
+ byte[] shared;
+
+ public KDFParameters(
+ byte[] shared,
+ byte[] iv)
+ {
+ this.shared = shared;
+ this.iv = iv;
+ }
+
+ public byte[] getSharedSecret()
+ {
+ return shared;
+ }
+
+ public byte[] getIV()
+ {
+ return iv;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/KeyParameter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/KeyParameter.java
new file mode 100644
index 00000000..210e7d62
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/KeyParameter.java
@@ -0,0 +1,34 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyParameter
+ implements CipherParameters
+{
+ private byte[] key;
+
+ public KeyParameter(
+ byte[] key)
+ {
+ this(key, 0, key.length);
+ }
+
+ public KeyParameter(
+ byte[] key,
+ int keyOff,
+ int keyLen)
+ {
+ this.key = new byte[keyLen];
+
+ System.arraycopy(key, keyOff, this.key, 0, keyLen);
+ }
+
+ public byte[] getKey()
+ {
+ return key;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ParametersWithID.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ParametersWithID.java
new file mode 100644
index 00000000..7ee35560
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ParametersWithID.java
@@ -0,0 +1,32 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ParametersWithID
+ implements CipherParameters
+{
+ private CipherParameters parameters;
+ private byte[] id;
+
+ public ParametersWithID(
+ CipherParameters parameters,
+ byte[] id)
+ {
+ this.parameters = parameters;
+ this.id = id;
+ }
+
+ public byte[] getID()
+ {
+ return id;
+ }
+
+ public CipherParameters getParameters()
+ {
+ return parameters;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ParametersWithIV.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ParametersWithIV.java
new file mode 100644
index 00000000..79921008
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ParametersWithIV.java
@@ -0,0 +1,43 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ParametersWithIV
+ implements CipherParameters
+{
+ private byte[] iv;
+ private CipherParameters parameters;
+
+ public ParametersWithIV(
+ CipherParameters parameters,
+ byte[] iv)
+ {
+ this(parameters, iv, 0, iv.length);
+ }
+
+ public ParametersWithIV(
+ CipherParameters parameters,
+ byte[] iv,
+ int ivOff,
+ int ivLen)
+ {
+ this.iv = new byte[ivLen];
+ this.parameters = parameters;
+
+ System.arraycopy(iv, ivOff, this.iv, 0, ivLen);
+ }
+
+ public byte[] getIV()
+ {
+ return iv;
+ }
+
+ public CipherParameters getParameters()
+ {
+ return parameters;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ParametersWithRandom.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ParametersWithRandom.java
new file mode 100644
index 00000000..994aff49
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ParametersWithRandom.java
@@ -0,0 +1,41 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ParametersWithRandom
+ implements CipherParameters
+{
+ private SecureRandom random;
+ private CipherParameters parameters;
+
+ public ParametersWithRandom(
+ CipherParameters parameters,
+ SecureRandom random)
+ {
+ this.random = CryptoServicesRegistrar.getSecureRandom(random);
+ this.parameters = parameters;
+ }
+
+ public ParametersWithRandom(
+ CipherParameters parameters)
+ {
+ this(parameters, null);
+ }
+
+ public SecureRandom getRandom()
+ {
+ return random;
+ }
+
+ public CipherParameters getParameters()
+ {
+ return parameters;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RC2Parameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RC2Parameters.java
new file mode 100644
index 00000000..b1bf1662
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RC2Parameters.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RC2Parameters
+ extends KeyParameter
+{
+ private int bits;
+
+ public RC2Parameters(
+ byte[] key)
+ {
+ this(key, (key.length > 128) ? 1024 : (key.length * 8));
+ }
+
+ public RC2Parameters(
+ byte[] key,
+ int bits)
+ {
+ super(key);
+ this.bits = bits;
+ }
+
+ public int getEffectiveKeyBits()
+ {
+ return bits;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyGenerationParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyGenerationParameters.java
new file mode 100644
index 00000000..30d11799
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyGenerationParameters.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RSAKeyGenerationParameters
+ extends KeyGenerationParameters
+{
+ private BigInteger publicExponent;
+ private int certainty;
+
+ public RSAKeyGenerationParameters(
+ BigInteger publicExponent,
+ SecureRandom random,
+ int strength,
+ int certainty)
+ {
+ super(random, strength);
+
+ if (strength < 12)
+ {
+ throw new IllegalArgumentException("key strength too small");
+ }
+
+ //
+ // public exponent cannot be even
+ //
+ if (!publicExponent.testBit(0))
+ {
+ throw new IllegalArgumentException("public exponent cannot be even");
+ }
+
+ this.publicExponent = publicExponent;
+ this.certainty = certainty;
+ }
+
+ public BigInteger getPublicExponent()
+ {
+ return publicExponent;
+ }
+
+ public int getCertainty()
+ {
+ return certainty;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyParameters.java
new file mode 100644
index 00000000..c23d9f50
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyParameters.java
@@ -0,0 +1,79 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.util.Properties;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RSAKeyParameters
+ extends AsymmetricKeyParameter
+{
+ // Hexadecimal value of the product of the 131 smallest odd primes from 3 to 743
+ private static final BigInteger SMALL_PRIMES_PRODUCT = new BigInteger(
+ "8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
+ + "73d893fa424cd2edc8636a6c3285e022b0e3866a565ae8108eed8591cd4fe8d2"
+ + "ce86165a978d719ebf647f362d33fca29cd179fb42401cbaf3df0c614056f9c8"
+ + "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f",
+ 16);
+
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+
+ private BigInteger modulus;
+ private BigInteger exponent;
+
+ public RSAKeyParameters(
+ boolean isPrivate,
+ BigInteger modulus,
+ BigInteger exponent)
+ {
+ super(isPrivate);
+
+ if (!isPrivate)
+ {
+ if ((exponent.intValue() & 1) == 0)
+ {
+ throw new IllegalArgumentException("RSA publicExponent is even");
+ }
+ }
+
+ this.modulus = validate(modulus);
+ this.exponent = exponent;
+ }
+
+ private BigInteger validate(BigInteger modulus)
+ {
+ if ((modulus.intValue() & 1) == 0)
+ {
+ throw new IllegalArgumentException("RSA modulus is even");
+ }
+
+ // If you need to set this you need to have a serious word to whoever is generating
+ // your keys.
+ if (Properties.isOverrideSet("com.android.internal.org.bouncycastle.rsa.allow_unsafe_mod"))
+ {
+ return modulus;
+ }
+
+ if (!modulus.gcd(SMALL_PRIMES_PRODUCT).equals(ONE))
+ {
+ throw new IllegalArgumentException("RSA modulus has a small prime factor");
+ }
+
+ // TODO: add additional primePower/Composite test - expensive!!
+
+ return modulus;
+ }
+
+ public BigInteger getModulus()
+ {
+ return modulus;
+ }
+
+ public BigInteger getExponent()
+ {
+ return exponent;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java
new file mode 100644
index 00000000..1fc5f05c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAPrivateCrtKeyParameters.java
@@ -0,0 +1,71 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.params;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RSAPrivateCrtKeyParameters
+ extends RSAKeyParameters
+{
+ private BigInteger e;
+ private BigInteger p;
+ private BigInteger q;
+ private BigInteger dP;
+ private BigInteger dQ;
+ private BigInteger qInv;
+
+ /**
+ *
+ */
+ public RSAPrivateCrtKeyParameters(
+ BigInteger modulus,
+ BigInteger publicExponent,
+ BigInteger privateExponent,
+ BigInteger p,
+ BigInteger q,
+ BigInteger dP,
+ BigInteger dQ,
+ BigInteger qInv)
+ {
+ super(true, modulus, privateExponent);
+
+ this.e = publicExponent;
+ this.p = p;
+ this.q = q;
+ this.dP = dP;
+ this.dQ = dQ;
+ this.qInv = qInv;
+ }
+
+ public BigInteger getPublicExponent()
+ {
+ return e;
+ }
+
+ public BigInteger getP()
+ {
+ return p;
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public BigInteger getDP()
+ {
+ return dP;
+ }
+
+ public BigInteger getDQ()
+ {
+ return dQ;
+ }
+
+ public BigInteger getQInv()
+ {
+ return qInv;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSAEncoding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSAEncoding.java
new file mode 100644
index 00000000..1e5c5864
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSAEncoding.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.signers;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+/**
+ * An interface for different encoding formats for DSA signatures.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface DSAEncoding
+{
+ /**
+ * Decode the (r, s) pair of a DSA signature.
+ *
+ * @param n the order of the group that r, s belong to.
+ * @param encoding an encoding of the (r, s) pair of a DSA signature.
+ * @return the (r, s) of a DSA signature, stored in an array of exactly two elements, r followed by s.
+ * @throws IOException
+ */
+ BigInteger[] decode(BigInteger n, byte[] encoding) throws IOException;
+
+ /**
+ * Encode the (r, s) pair of a DSA signature.
+ *
+ * @param n the order of the group that r, s belong to.
+ * @param r the r value of a DSA signature.
+ * @param s the s value of a DSA signature.
+ * @return an encoding of the DSA signature given by the provided (r, s) pair.
+ * @throws IOException
+ */
+ byte[] encode(BigInteger n, BigInteger r, BigInteger s) throws IOException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSAKCalculator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSAKCalculator.java
new file mode 100644
index 00000000..cb4ed068
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSAKCalculator.java
@@ -0,0 +1,43 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.signers;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+/**
+ * Interface define calculators of K values for DSA/ECDSA.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface DSAKCalculator
+{
+ /**
+ * Return true if this calculator is deterministic, false otherwise.
+ *
+ * @return true if deterministic, otherwise false.
+ */
+ boolean isDeterministic();
+
+ /**
+ * Non-deterministic initialiser.
+ *
+ * @param n the order of the DSA group.
+ * @param random a source of randomness.
+ */
+ void init(BigInteger n, SecureRandom random);
+
+ /**
+ * Deterministic initialiser.
+ *
+ * @param n the order of the DSA group.
+ * @param d the DSA private value.
+ * @param message the message being signed.
+ */
+ void init(BigInteger n, BigInteger d, byte[] message);
+
+ /**
+ * Return the next valid value of K.
+ *
+ * @return a K value.
+ */
+ BigInteger nextK();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSASigner.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSASigner.java
new file mode 100644
index 00000000..0be6a4a6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSASigner.java
@@ -0,0 +1,184 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.signers;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.DSAExt;
+import com.android.internal.org.bouncycastle.crypto.params.DSAKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPublicKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * The Digital Signature Algorithm - as described in "Handbook of Applied
+ * Cryptography", pages 452 - 453.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DSASigner
+ implements DSAExt
+{
+ private final DSAKCalculator kCalculator;
+
+ private DSAKeyParameters key;
+ private SecureRandom random;
+
+ /**
+ * Default configuration, random K values.
+ */
+ public DSASigner()
+ {
+ this.kCalculator = new RandomDSAKCalculator();
+ }
+
+ /**
+ * Configuration with an alternate, possibly deterministic calculator of K.
+ *
+ * @param kCalculator a K value calculator.
+ */
+ public DSASigner(DSAKCalculator kCalculator)
+ {
+ this.kCalculator = kCalculator;
+ }
+
+ public void init(
+ boolean forSigning,
+ CipherParameters param)
+ {
+ SecureRandom providedRandom = null;
+
+ if (forSigning)
+ {
+ if (param instanceof ParametersWithRandom)
+ {
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
+
+ this.key = (DSAPrivateKeyParameters)rParam.getParameters();
+ providedRandom = rParam.getRandom();
+ }
+ else
+ {
+ this.key = (DSAPrivateKeyParameters)param;
+ }
+ }
+ else
+ {
+ this.key = (DSAPublicKeyParameters)param;
+ }
+
+ this.random = initSecureRandom(forSigning && !kCalculator.isDeterministic(), providedRandom);
+ }
+
+ public BigInteger getOrder()
+ {
+ return key.getParameters().getQ();
+ }
+
+ /**
+ * generate a signature for the given message using the key we were
+ * initialised with. For conventional DSA the message should be a SHA-1
+ * hash of the message of interest.
+ *
+ * @param message the message that will be verified later.
+ */
+ public BigInteger[] generateSignature(
+ byte[] message)
+ {
+ DSAParameters params = key.getParameters();
+ BigInteger q = params.getQ();
+ BigInteger m = calculateE(q, message);
+ BigInteger x = ((DSAPrivateKeyParameters)key).getX();
+
+ if (kCalculator.isDeterministic())
+ {
+ kCalculator.init(q, x, message);
+ }
+ else
+ {
+ kCalculator.init(q, random);
+ }
+
+ BigInteger k = kCalculator.nextK();
+
+ // the randomizer is to conceal timing information related to k and x.
+ BigInteger r = params.getG().modPow(k.add(getRandomizer(q, random)), params.getP()).mod(q);
+
+ k = BigIntegers.modOddInverse(q, k).multiply(m.add(x.multiply(r)));
+
+ BigInteger s = k.mod(q);
+
+ return new BigInteger[]{ r, s };
+ }
+
+ /**
+ * return true if the value r and s represent a DSA signature for
+ * the passed in message for standard DSA the message should be a
+ * SHA-1 hash of the real message to be verified.
+ */
+ public boolean verifySignature(
+ byte[] message,
+ BigInteger r,
+ BigInteger s)
+ {
+ DSAParameters params = key.getParameters();
+ BigInteger q = params.getQ();
+ BigInteger m = calculateE(q, message);
+ BigInteger zero = BigInteger.valueOf(0);
+
+ if (zero.compareTo(r) >= 0 || q.compareTo(r) <= 0)
+ {
+ return false;
+ }
+
+ if (zero.compareTo(s) >= 0 || q.compareTo(s) <= 0)
+ {
+ return false;
+ }
+
+ BigInteger w = BigIntegers.modOddInverseVar(q, s);
+
+ BigInteger u1 = m.multiply(w).mod(q);
+ BigInteger u2 = r.multiply(w).mod(q);
+
+ BigInteger p = params.getP();
+ u1 = params.getG().modPow(u1, p);
+ u2 = ((DSAPublicKeyParameters)key).getY().modPow(u2, p);
+
+ BigInteger v = u1.multiply(u2).mod(p).mod(q);
+
+ return v.equals(r);
+ }
+
+ private BigInteger calculateE(BigInteger n, byte[] message)
+ {
+ if (n.bitLength() >= message.length * 8)
+ {
+ return new BigInteger(1, message);
+ }
+ else
+ {
+ byte[] trunc = new byte[n.bitLength() / 8];
+
+ System.arraycopy(message, 0, trunc, 0, trunc.length);
+
+ return new BigInteger(1, trunc);
+ }
+ }
+
+ protected SecureRandom initSecureRandom(boolean needed, SecureRandom provided)
+ {
+ return needed ? CryptoServicesRegistrar.getSecureRandom(provided) : null;
+ }
+
+ private BigInteger getRandomizer(BigInteger q, SecureRandom provided)
+ {
+ // Calculate a random multiple of q to add to k. Note that g^q = 1 (mod p), so adding multiple of q to k does not change r.
+ int randomBits = 7;
+
+ return BigIntegers.createRandomBigInteger(randomBits, CryptoServicesRegistrar.getSecureRandom(provided)).add(BigInteger.valueOf(128)).multiply(q);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/ECDSASigner.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/ECDSASigner.java
new file mode 100644
index 00000000..0216020a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/ECDSASigner.java
@@ -0,0 +1,261 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.signers;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.DSAExt;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+import com.android.internal.org.bouncycastle.math.ec.ECAlgorithms;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECMultiplier;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.ec.FixedPointCombMultiplier;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * EC-DSA as described in X9.62
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECDSASigner
+ implements ECConstants, DSAExt
+{
+ private final DSAKCalculator kCalculator;
+
+ private ECKeyParameters key;
+ private SecureRandom random;
+
+ /**
+ * Default configuration, random K values.
+ */
+ public ECDSASigner()
+ {
+ this.kCalculator = new RandomDSAKCalculator();
+ }
+
+ /**
+ * Configuration with an alternate, possibly deterministic calculator of K.
+ *
+ * @param kCalculator a K value calculator.
+ */
+ public ECDSASigner(DSAKCalculator kCalculator)
+ {
+ this.kCalculator = kCalculator;
+ }
+
+ public void init(
+ boolean forSigning,
+ CipherParameters param)
+ {
+ SecureRandom providedRandom = null;
+
+ if (forSigning)
+ {
+ if (param instanceof ParametersWithRandom)
+ {
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
+
+ this.key = (ECPrivateKeyParameters)rParam.getParameters();
+ providedRandom = rParam.getRandom();
+ }
+ else
+ {
+ this.key = (ECPrivateKeyParameters)param;
+ }
+ }
+ else
+ {
+ this.key = (ECPublicKeyParameters)param;
+ }
+
+ this.random = initSecureRandom(forSigning && !kCalculator.isDeterministic(), providedRandom);
+ }
+
+ public BigInteger getOrder()
+ {
+ return key.getParameters().getN();
+ }
+
+ // 5.3 pg 28
+ /**
+ * generate a signature for the given message using the key we were
+ * initialised with. For conventional DSA the message should be a SHA-1
+ * hash of the message of interest.
+ *
+ * @param message the message that will be verified later.
+ */
+ public BigInteger[] generateSignature(
+ byte[] message)
+ {
+ ECDomainParameters ec = key.getParameters();
+ BigInteger n = ec.getN();
+ BigInteger e = calculateE(n, message);
+ BigInteger d = ((ECPrivateKeyParameters)key).getD();
+
+ if (kCalculator.isDeterministic())
+ {
+ kCalculator.init(n, d, message);
+ }
+ else
+ {
+ kCalculator.init(n, random);
+ }
+
+ BigInteger r, s;
+
+ ECMultiplier basePointMultiplier = createBasePointMultiplier();
+
+ // 5.3.2
+ do // generate s
+ {
+ BigInteger k;
+ do // generate r
+ {
+ k = kCalculator.nextK();
+
+ ECPoint p = basePointMultiplier.multiply(ec.getG(), k).normalize();
+
+ // 5.3.3
+ r = p.getAffineXCoord().toBigInteger().mod(n);
+ }
+ while (r.equals(ZERO));
+
+ s = BigIntegers.modOddInverse(n, k).multiply(e.add(d.multiply(r))).mod(n);
+ }
+ while (s.equals(ZERO));
+
+ return new BigInteger[]{ r, s };
+ }
+
+ // 5.4 pg 29
+ /**
+ * return true if the value r and s represent a DSA signature for
+ * the passed in message (for standard DSA the message should be
+ * a SHA-1 hash of the real message to be verified).
+ */
+ public boolean verifySignature(
+ byte[] message,
+ BigInteger r,
+ BigInteger s)
+ {
+ ECDomainParameters ec = key.getParameters();
+ BigInteger n = ec.getN();
+ BigInteger e = calculateE(n, message);
+
+ // r in the range [1,n-1]
+ if (r.compareTo(ONE) < 0 || r.compareTo(n) >= 0)
+ {
+ return false;
+ }
+
+ // s in the range [1,n-1]
+ if (s.compareTo(ONE) < 0 || s.compareTo(n) >= 0)
+ {
+ return false;
+ }
+
+ BigInteger c = BigIntegers.modOddInverseVar(n, s);
+
+ BigInteger u1 = e.multiply(c).mod(n);
+ BigInteger u2 = r.multiply(c).mod(n);
+
+ ECPoint G = ec.getG();
+ ECPoint Q = ((ECPublicKeyParameters)key).getQ();
+
+ ECPoint point = ECAlgorithms.sumOfTwoMultiplies(G, u1, Q, u2);
+
+ // components must be bogus.
+ if (point.isInfinity())
+ {
+ return false;
+ }
+
+ /*
+ * If possible, avoid normalizing the point (to save a modular inversion in the curve field).
+ *
+ * There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'.
+ * If the cofactor is known and small, we generate those possible field values and project each
+ * of them to the same "denominator" (depending on the particular projective coordinates in use)
+ * as the calculated point.X. If any of the projected values matches point.X, then we have:
+ * (point.X / Denominator mod p) mod n == r
+ * as required, and verification succeeds.
+ *
+ * Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in
+ * the libsecp256k1 project (https://github.com/bitcoin/secp256k1).
+ */
+ ECCurve curve = point.getCurve();
+ if (curve != null)
+ {
+ BigInteger cofactor = curve.getCofactor();
+ if (cofactor != null && cofactor.compareTo(EIGHT) <= 0)
+ {
+ ECFieldElement D = getDenominator(curve.getCoordinateSystem(), point);
+ if (D != null && !D.isZero())
+ {
+ ECFieldElement X = point.getXCoord();
+ while (curve.isValidFieldElement(r))
+ {
+ ECFieldElement R = curve.fromBigInteger(r).multiply(D);
+ if (R.equals(X))
+ {
+ return true;
+ }
+ r = r.add(n);
+ }
+ return false;
+ }
+ }
+ }
+
+ BigInteger v = point.normalize().getAffineXCoord().toBigInteger().mod(n);
+ return v.equals(r);
+ }
+
+ protected BigInteger calculateE(BigInteger n, byte[] message)
+ {
+ int log2n = n.bitLength();
+ int messageBitLength = message.length * 8;
+
+ BigInteger e = new BigInteger(1, message);
+ if (log2n < messageBitLength)
+ {
+ e = e.shiftRight(messageBitLength - log2n);
+ }
+ return e;
+ }
+
+ protected ECMultiplier createBasePointMultiplier()
+ {
+ return new FixedPointCombMultiplier();
+ }
+
+ protected ECFieldElement getDenominator(int coordinateSystem, ECPoint p)
+ {
+ switch (coordinateSystem)
+ {
+ case ECCurve.COORD_HOMOGENEOUS:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ case ECCurve.COORD_SKEWED:
+ return p.getZCoord(0);
+ case ECCurve.COORD_JACOBIAN:
+ case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ return p.getZCoord(0).square();
+ default:
+ return null;
+ }
+ }
+
+ protected SecureRandom initSecureRandom(boolean needed, SecureRandom provided)
+ {
+ return needed ? CryptoServicesRegistrar.getSecureRandom(provided) : null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/PlainDSAEncoding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/PlainDSAEncoding.java
new file mode 100644
index 00000000..6b1807bb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/PlainDSAEncoding.java
@@ -0,0 +1,66 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.signers;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PlainDSAEncoding
+ implements DSAEncoding
+{
+ public static final PlainDSAEncoding INSTANCE = new PlainDSAEncoding();
+
+ public byte[] encode(BigInteger n, BigInteger r, BigInteger s)
+ {
+ int valueLength = BigIntegers.getUnsignedByteLength(n);
+ byte[] result = new byte[valueLength * 2];
+ encodeValue(n, r, result, 0, valueLength);
+ encodeValue(n, s, result, valueLength, valueLength);
+ return result;
+ }
+
+ public BigInteger[] decode(BigInteger n, byte[] encoding)
+ {
+ int valueLength = BigIntegers.getUnsignedByteLength(n);
+ if (encoding.length != valueLength * 2)
+ {
+ throw new IllegalArgumentException("Encoding has incorrect length");
+ }
+
+ return new BigInteger[] {
+ decodeValue(n, encoding, 0, valueLength),
+ decodeValue(n, encoding, valueLength, valueLength),
+ };
+ }
+
+ protected BigInteger checkValue(BigInteger n, BigInteger x)
+ {
+ if (x.signum() < 0 || x.compareTo(n) >= 0)
+ {
+ throw new IllegalArgumentException("Value out of range");
+ }
+
+ return x;
+ }
+
+ protected BigInteger decodeValue(BigInteger n, byte[] buf, int off, int len)
+ {
+ byte[] bs = Arrays.copyOfRange(buf, off, off + len);
+ return checkValue(n, new BigInteger(1, bs));
+ }
+
+ private void encodeValue(BigInteger n, BigInteger x, byte[] buf, int off, int len)
+ {
+ byte[] bs = checkValue(n, x).toByteArray();
+ int bsOff = Math.max(0, bs.length - len);
+ int bsLen = bs.length - bsOff;
+
+ int pos = len - bsLen;
+ Arrays.fill(buf, off, off + pos, (byte)0);
+ System.arraycopy(bs, bsOff, buf, off + pos, bsLen);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/RSADigestSigner.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/RSADigestSigner.java
new file mode 100644
index 00000000..cee94d63
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/RSADigestSigner.java
@@ -0,0 +1,279 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.signers;
+
+import java.io.IOException;
+import java.util.Hashtable;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.DigestInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.AsymmetricBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoException;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.Signer;
+import com.android.internal.org.bouncycastle.crypto.encodings.PKCS1Encoding;
+import com.android.internal.org.bouncycastle.crypto.engines.RSABlindedEngine;
+import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RSADigestSigner
+ implements Signer
+{
+ private final AsymmetricBlockCipher rsaEngine = new PKCS1Encoding(new RSABlindedEngine());
+ private final AlgorithmIdentifier algId;
+ private final Digest digest;
+ private boolean forSigning;
+
+ private static final Hashtable oidMap = new Hashtable();
+
+ /*
+ * Load OID table.
+ */
+ static
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ // oidMap.put("RIPEMD128", TeleTrusTObjectIdentifiers.ripemd128);
+ // oidMap.put("RIPEMD160", TeleTrusTObjectIdentifiers.ripemd160);
+ // oidMap.put("RIPEMD256", TeleTrusTObjectIdentifiers.ripemd256);
+ // END Android-removed: Unsupported algorithms
+
+ oidMap.put("SHA-1", X509ObjectIdentifiers.id_SHA1);
+ oidMap.put("SHA-224", NISTObjectIdentifiers.id_sha224);
+ oidMap.put("SHA-256", NISTObjectIdentifiers.id_sha256);
+ oidMap.put("SHA-384", NISTObjectIdentifiers.id_sha384);
+ oidMap.put("SHA-512", NISTObjectIdentifiers.id_sha512);
+ oidMap.put("SHA-512/224", NISTObjectIdentifiers.id_sha512_224);
+ oidMap.put("SHA-512/256", NISTObjectIdentifiers.id_sha512_256);
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ oidMap.put("SHA3-224", NISTObjectIdentifiers.id_sha3_224);
+ oidMap.put("SHA3-256", NISTObjectIdentifiers.id_sha3_256);
+ oidMap.put("SHA3-384", NISTObjectIdentifiers.id_sha3_384);
+ oidMap.put("SHA3-512", NISTObjectIdentifiers.id_sha3_512);
+
+ oidMap.put("MD2", PKCSObjectIdentifiers.md2);
+ oidMap.put("MD4", PKCSObjectIdentifiers.md4);
+ */
+ // END Android-removed: Unsupported algorithms
+ oidMap.put("MD5", PKCSObjectIdentifiers.md5);
+ }
+
+ public RSADigestSigner(
+ Digest digest)
+ {
+ this(digest, (ASN1ObjectIdentifier)oidMap.get(digest.getAlgorithmName()));
+ }
+
+ public RSADigestSigner(
+ Digest digest,
+ ASN1ObjectIdentifier digestOid)
+ {
+ this.digest = digest;
+ if (digestOid != null)
+ {
+ this.algId = new AlgorithmIdentifier(digestOid, DERNull.INSTANCE);
+ }
+ else
+ {
+ // NULL digester, match behaviour with DigestSignatureSpi
+ this.algId = null;
+ }
+ }
+
+ /**
+ * @deprecated
+ */
+ public String getAlgorithmName()
+ {
+ return digest.getAlgorithmName() + "withRSA";
+ }
+
+ /**
+ * Initialize the signer for signing or verification.
+ *
+ * @param forSigning
+ * true if for signing, false otherwise
+ * @param parameters
+ * necessary parameters.
+ */
+ public void init(
+ boolean forSigning,
+ CipherParameters parameters)
+ {
+ this.forSigning = forSigning;
+ AsymmetricKeyParameter k;
+
+ if (parameters instanceof ParametersWithRandom)
+ {
+ k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).getParameters();
+ }
+ else
+ {
+ k = (AsymmetricKeyParameter)parameters;
+ }
+
+ if (forSigning && !k.isPrivate())
+ {
+ throw new IllegalArgumentException("signing requires private key");
+ }
+
+ if (!forSigning && k.isPrivate())
+ {
+ throw new IllegalArgumentException("verification requires public key");
+ }
+
+ reset();
+
+ rsaEngine.init(forSigning, parameters);
+ }
+
+ /**
+ * update the internal digest with the byte b
+ */
+ public void update(
+ byte input)
+ {
+ digest.update(input);
+ }
+
+ /**
+ * update the internal digest with the byte array in
+ */
+ public void update(
+ byte[] input,
+ int inOff,
+ int length)
+ {
+ digest.update(input, inOff, length);
+ }
+
+ /**
+ * Generate a signature for the message we've been loaded with using the key
+ * we were initialised with.
+ */
+ public byte[] generateSignature()
+ throws CryptoException, DataLengthException
+ {
+ if (!forSigning)
+ {
+ throw new IllegalStateException("RSADigestSigner not initialised for signature generation.");
+ }
+
+ byte[] hash = new byte[digest.getDigestSize()];
+ digest.doFinal(hash, 0);
+
+ try
+ {
+ byte[] data = derEncode(hash);
+ return rsaEngine.processBlock(data, 0, data.length);
+ }
+ catch (IOException e)
+ {
+ throw new CryptoException("unable to encode signature: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * return true if the internal state represents the signature described in
+ * the passed in array.
+ */
+ public boolean verifySignature(
+ byte[] signature)
+ {
+ if (forSigning)
+ {
+ throw new IllegalStateException("RSADigestSigner not initialised for verification");
+ }
+
+ byte[] hash = new byte[digest.getDigestSize()];
+
+ digest.doFinal(hash, 0);
+
+ byte[] sig;
+ byte[] expected;
+
+ try
+ {
+ sig = rsaEngine.processBlock(signature, 0, signature.length);
+ expected = derEncode(hash);
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+
+ if (sig.length == expected.length)
+ {
+ return Arrays.constantTimeAreEqual(sig, expected);
+ }
+ else if (sig.length == expected.length - 2) // NULL left out
+ {
+ int sigOffset = sig.length - hash.length - 2;
+ int expectedOffset = expected.length - hash.length - 2;
+
+ expected[1] -= 2; // adjust lengths
+ expected[3] -= 2;
+
+ int nonEqual = 0;
+
+ for (int i = 0; i < hash.length; i++)
+ {
+ nonEqual |= (sig[sigOffset + i] ^ expected[expectedOffset + i]);
+ }
+
+ for (int i = 0; i < sigOffset; i++)
+ {
+ nonEqual |= (sig[i] ^ expected[i]); // check header less NULL
+ }
+
+ return nonEqual == 0;
+ }
+ else
+ {
+ Arrays.constantTimeAreEqual(expected, expected); // keep time "steady".
+
+ return false;
+ }
+ }
+
+ public void reset()
+ {
+ digest.reset();
+ }
+
+ private byte[] derEncode(
+ byte[] hash)
+ throws IOException
+ {
+ if (algId == null)
+ {
+ try
+ {
+ // check hash is at least right format
+ DigestInfo.getInstance(hash);
+ return hash;
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new IOException("malformed DigestInfo for NONEwithRSA hash: " + e.getMessage());
+ }
+ }
+
+ DigestInfo dInfo = new DigestInfo(algId, hash);
+
+ return dInfo.getEncoded(ASN1Encoding.DER);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/RandomDSAKCalculator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/RandomDSAKCalculator.java
new file mode 100644
index 00000000..c37e8836
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/RandomDSAKCalculator.java
@@ -0,0 +1,49 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.signers;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RandomDSAKCalculator
+ implements DSAKCalculator
+{
+ private static final BigInteger ZERO = BigInteger.valueOf(0);
+
+ private BigInteger q;
+ private SecureRandom random;
+
+ public boolean isDeterministic()
+ {
+ return false;
+ }
+
+ public void init(BigInteger n, SecureRandom random)
+ {
+ this.q = n;
+ this.random = random;
+ }
+
+ public void init(BigInteger n, BigInteger d, byte[] message)
+ {
+ throw new IllegalStateException("Operation not supported");
+ }
+
+ public BigInteger nextK()
+ {
+ int qBitLength = q.bitLength();
+
+ BigInteger k;
+ do
+ {
+ k = BigIntegers.createRandomBigInteger(qBitLength, random);
+ }
+ while (k.equals(ZERO) || k.compareTo(q) >= 0);
+
+ return k;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/StandardDSAEncoding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/StandardDSAEncoding.java
new file mode 100644
index 00000000..30568bc5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/StandardDSAEncoding.java
@@ -0,0 +1,68 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.signers;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+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.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class StandardDSAEncoding
+ implements DSAEncoding
+{
+ public static final StandardDSAEncoding INSTANCE = new StandardDSAEncoding();
+
+ public byte[] encode(BigInteger n, BigInteger r, BigInteger s) throws IOException
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ encodeValue(n, v, r);
+ encodeValue(n, v, s);
+ return new DERSequence(v).getEncoded(ASN1Encoding.DER);
+ }
+
+ public BigInteger[] decode(BigInteger n, byte[] encoding) throws IOException
+ {
+ ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding);
+ if (seq.size() == 2)
+ {
+ BigInteger r = decodeValue(n, seq, 0);
+ BigInteger s = decodeValue(n, seq, 1);
+
+ byte[] expectedEncoding = encode(n, r, s);
+ if (Arrays.areEqual(expectedEncoding, encoding))
+ {
+ return new BigInteger[]{ r, s };
+ }
+ }
+
+ throw new IllegalArgumentException("Malformed signature");
+ }
+
+ protected BigInteger checkValue(BigInteger n, BigInteger x)
+ {
+ if (x.signum() < 0 || (null != n && x.compareTo(n) >= 0))
+ {
+ throw new IllegalArgumentException("Value out of range");
+ }
+
+ return x;
+ }
+
+ protected BigInteger decodeValue(BigInteger n, ASN1Sequence s, int pos)
+ {
+ return checkValue(n, ((ASN1Integer)s.getObjectAt(pos)).getValue());
+ }
+
+ protected void encodeValue(BigInteger n, ASN1EncodableVector v, BigInteger x)
+ {
+ v.add(new ASN1Integer(checkValue(n, x)));
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/tls/CertificateType.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/tls/CertificateType.java
new file mode 100644
index 00000000..4f4873a3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/tls/CertificateType.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.tls;
+
+/**
+ * RFC 6091
+ *
+ * @deprecated Migrate to the (D)TLS API in org.bouncycastle.tls (bctls jar).
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertificateType
+{
+ public static final short X509 = 0;
+ public static final short OpenPGP = 1;
+
+ /*
+ * RFC 7250
+ */
+ public static final short RawPublicKey = 2;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/tls/TlsCloseable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/tls/TlsCloseable.java
new file mode 100644
index 00000000..6934de21
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/tls/TlsCloseable.java
@@ -0,0 +1,13 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.tls;
+
+import java.io.IOException;
+
+/**
+ * @deprecated Migrate to the (D)TLS API in org.bouncycastle.tls (bctls jar).
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface TlsCloseable
+{
+ public void close() throws IOException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java
new file mode 100644
index 00000000..b096efb9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java
@@ -0,0 +1,23 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.tls;
+
+import java.io.EOFException;
+
+/**
+ * This exception will be thrown (only) when the connection is closed by the peer without sending a
+ * {@link AlertDescription#close_notify close_notify} warning alert. If this happens, the TLS
+ * protocol cannot rule out truncation of the connection data (potentially malicious). It may be
+ * possible to check for truncation via some property of a higher level protocol built upon TLS,
+ * e.g. the Content-Length header for HTTPS.
+ *
+ * @deprecated Migrate to the (D)TLS API in org.bouncycastle.tls (bctls jar).
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TlsNoCloseNotifyException
+ extends EOFException
+{
+ public TlsNoCloseNotifyException()
+ {
+ super("No close_notify alert received before connection closed");
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/Pack.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/Pack.java
new file mode 100644
index 00000000..272859c5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/Pack.java
@@ -0,0 +1,206 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.util;
+
+/**
+ * @deprecated use org.bouncycastle.util.pack
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class Pack
+{
+ public static int bigEndianToInt(byte[] bs, int off)
+ {
+ int n = bs[ off] << 24;
+ n |= (bs[++off] & 0xff) << 16;
+ n |= (bs[++off] & 0xff) << 8;
+ n |= (bs[++off] & 0xff);
+ return n;
+ }
+
+ public static void bigEndianToInt(byte[] bs, int off, int[] ns)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ ns[i] = bigEndianToInt(bs, off);
+ off += 4;
+ }
+ }
+
+ public static byte[] intToBigEndian(int n)
+ {
+ byte[] bs = new byte[4];
+ intToBigEndian(n, bs, 0);
+ return bs;
+ }
+
+ public static void intToBigEndian(int n, byte[] bs, int off)
+ {
+ bs[ off] = (byte)(n >>> 24);
+ bs[++off] = (byte)(n >>> 16);
+ bs[++off] = (byte)(n >>> 8);
+ bs[++off] = (byte)(n );
+ }
+
+ public static byte[] intToBigEndian(int[] ns)
+ {
+ byte[] bs = new byte[4 * ns.length];
+ intToBigEndian(ns, bs, 0);
+ return bs;
+ }
+
+ public static void intToBigEndian(int[] ns, byte[] bs, int off)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ intToBigEndian(ns[i], bs, off);
+ off += 4;
+ }
+ }
+
+ public static long bigEndianToLong(byte[] bs, int off)
+ {
+ int hi = bigEndianToInt(bs, off);
+ int lo = bigEndianToInt(bs, off + 4);
+ return ((long)(hi & 0xffffffffL) << 32) | (long)(lo & 0xffffffffL);
+ }
+
+ public static void bigEndianToLong(byte[] bs, int off, long[] ns)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ ns[i] = bigEndianToLong(bs, off);
+ off += 8;
+ }
+ }
+
+ public static byte[] longToBigEndian(long n)
+ {
+ byte[] bs = new byte[8];
+ longToBigEndian(n, bs, 0);
+ return bs;
+ }
+
+ public static void longToBigEndian(long n, byte[] bs, int off)
+ {
+ intToBigEndian((int)(n >>> 32), bs, off);
+ intToBigEndian((int)(n & 0xffffffffL), bs, off + 4);
+ }
+
+ public static byte[] longToBigEndian(long[] ns)
+ {
+ byte[] bs = new byte[8 * ns.length];
+ longToBigEndian(ns, bs, 0);
+ return bs;
+ }
+
+ public static void longToBigEndian(long[] ns, byte[] bs, int off)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ longToBigEndian(ns[i], bs, off);
+ off += 8;
+ }
+ }
+
+ public static int littleEndianToInt(byte[] bs, int off)
+ {
+ int n = bs[ off] & 0xff;
+ n |= (bs[++off] & 0xff) << 8;
+ n |= (bs[++off] & 0xff) << 16;
+ n |= bs[++off] << 24;
+ return n;
+ }
+
+ public static void littleEndianToInt(byte[] bs, int off, int[] ns)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ ns[i] = littleEndianToInt(bs, off);
+ off += 4;
+ }
+ }
+
+ public static void littleEndianToInt(byte[] bs, int bOff, int[] ns, int nOff, int count)
+ {
+ for (int i = 0; i < count; ++i)
+ {
+ ns[nOff + i] = littleEndianToInt(bs, bOff);
+ bOff += 4;
+ }
+ }
+
+ public static byte[] intToLittleEndian(int n)
+ {
+ byte[] bs = new byte[4];
+ intToLittleEndian(n, bs, 0);
+ return bs;
+ }
+
+ public static void intToLittleEndian(int n, byte[] bs, int off)
+ {
+ bs[ off] = (byte)(n );
+ bs[++off] = (byte)(n >>> 8);
+ bs[++off] = (byte)(n >>> 16);
+ bs[++off] = (byte)(n >>> 24);
+ }
+
+ public static byte[] intToLittleEndian(int[] ns)
+ {
+ byte[] bs = new byte[4 * ns.length];
+ intToLittleEndian(ns, bs, 0);
+ return bs;
+ }
+
+ public static void intToLittleEndian(int[] ns, byte[] bs, int off)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ intToLittleEndian(ns[i], bs, off);
+ off += 4;
+ }
+ }
+
+ public static long littleEndianToLong(byte[] bs, int off)
+ {
+ int lo = littleEndianToInt(bs, off);
+ int hi = littleEndianToInt(bs, off + 4);
+ return ((long)(hi & 0xffffffffL) << 32) | (long)(lo & 0xffffffffL);
+ }
+
+ public static void littleEndianToLong(byte[] bs, int off, long[] ns)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ ns[i] = littleEndianToLong(bs, off);
+ off += 8;
+ }
+ }
+
+ public static byte[] longToLittleEndian(long n)
+ {
+ byte[] bs = new byte[8];
+ longToLittleEndian(n, bs, 0);
+ return bs;
+ }
+
+ public static void longToLittleEndian(long n, byte[] bs, int off)
+ {
+ intToLittleEndian((int)(n & 0xffffffffL), bs, off);
+ intToLittleEndian((int)(n >>> 32), bs, off + 4);
+ }
+
+ public static byte[] longToLittleEndian(long[] ns)
+ {
+ byte[] bs = new byte[8 * ns.length];
+ longToLittleEndian(ns, bs, 0);
+ return bs;
+ }
+
+ public static void longToLittleEndian(long[] ns, byte[] bs, int off)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ longToLittleEndian(ns[i], bs, off);
+ off += 8;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PrivateKeyFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PrivateKeyFactory.java
new file mode 100644
index 00000000..323d2c59
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PrivateKeyFactory.java
@@ -0,0 +1,309 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.oiw.ElGamalParameter;
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
+// import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters;
+// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.DHParameter;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.pkcs.RSAPrivateKey;
+// import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.DSAParameter;
+import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable;
+import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves;
+import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.params.ECGOST3410Parameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECNamedDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.params.ElGamalParameters;
+// import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters;
+// import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
+// import org.bouncycastle.crypto.params.Ed448PrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.params.X25519PrivateKeyParameters;
+// import org.bouncycastle.crypto.params.X448PrivateKeyParameters;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Factory for creating private key objects from PKCS8 PrivateKeyInfo objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PrivateKeyFactory
+{
+ /**
+ * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding.
+ *
+ * @param privateKeyInfoData the PrivateKeyInfo encoding
+ * @return a suitable private key parameter
+ * @throws IOException on an error decoding the key
+ */
+ public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData)
+ throws IOException
+ {
+ return createKey(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(privateKeyInfoData)));
+ }
+
+ /**
+ * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding read from a
+ * stream.
+ *
+ * @param inStr the stream to read the PrivateKeyInfo encoding from
+ * @return a suitable private key parameter
+ * @throws IOException on an error decoding the key
+ */
+ public static AsymmetricKeyParameter createKey(InputStream inStr)
+ throws IOException
+ {
+ return createKey(PrivateKeyInfo.getInstance(new ASN1InputStream(inStr).readObject()));
+ }
+
+ /**
+ * Create a private key parameter from the passed in PKCS8 PrivateKeyInfo object.
+ *
+ * @param keyInfo the PrivateKeyInfo object containing the key material
+ * @return a suitable private key parameter
+ * @throws IOException on an error decoding the key
+ */
+ public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm();
+ ASN1ObjectIdentifier algOID = algId.getAlgorithm();
+
+ if (algOID.equals(PKCSObjectIdentifiers.rsaEncryption)
+ || algOID.equals(PKCSObjectIdentifiers.id_RSASSA_PSS)
+ || algOID.equals(X509ObjectIdentifiers.id_ea_rsa))
+ {
+ RSAPrivateKey keyStructure = RSAPrivateKey.getInstance(keyInfo.parsePrivateKey());
+
+ return new RSAPrivateCrtKeyParameters(keyStructure.getModulus(),
+ keyStructure.getPublicExponent(), keyStructure.getPrivateExponent(),
+ keyStructure.getPrime1(), keyStructure.getPrime2(), keyStructure.getExponent1(),
+ keyStructure.getExponent2(), keyStructure.getCoefficient());
+ }
+ // TODO?
+// else if (algOID.equals(X9ObjectIdentifiers.dhpublicnumber))
+ else if (algOID.equals(PKCSObjectIdentifiers.dhKeyAgreement))
+ {
+ DHParameter params = DHParameter.getInstance(algId.getParameters());
+ ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey();
+
+ BigInteger lVal = params.getL();
+ int l = lVal == null ? 0 : lVal.intValue();
+ DHParameters dhParams = new DHParameters(params.getP(), params.getG(), null, l);
+
+ return new DHPrivateKeyParameters(derX.getValue(), dhParams);
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (algOID.equals(OIWObjectIdentifiers.elGamalAlgorithm))
+ {
+ ElGamalParameter params = ElGamalParameter.getInstance(algId.getParameters());
+ ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey();
+
+ return new ElGamalPrivateKeyParameters(derX.getValue(), new ElGamalParameters(
+ params.getP(), params.getG()));
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ else if (algOID.equals(X9ObjectIdentifiers.id_dsa))
+ {
+ ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey();
+ ASN1Encodable de = algId.getParameters();
+
+ DSAParameters parameters = null;
+ if (de != null)
+ {
+ DSAParameter params = DSAParameter.getInstance(de.toASN1Primitive());
+ parameters = new DSAParameters(params.getP(), params.getQ(), params.getG());
+ }
+
+ return new DSAPrivateKeyParameters(derX.getValue(), parameters);
+ }
+ else if (algOID.equals(X9ObjectIdentifiers.id_ecPublicKey))
+ {
+ X962Parameters params = X962Parameters.getInstance(algId.getParameters());
+
+ X9ECParameters x9;
+ ECDomainParameters dParams;
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
+
+ x9 = CustomNamedCurves.getByOID(oid);
+ if (x9 == null)
+ {
+ x9 = ECNamedCurveTable.getByOID(oid);
+ }
+ dParams = new ECNamedDomainParameters(oid, x9);
+ }
+ else
+ {
+ x9 = X9ECParameters.getInstance(params.getParameters());
+ dParams = new ECDomainParameters(
+ x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
+ }
+
+ ECPrivateKey ec = ECPrivateKey.getInstance(keyInfo.parsePrivateKey());
+ BigInteger d = ec.getKey();
+
+ return new ECPrivateKeyParameters(d, dParams);
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (algOID.equals(EdECObjectIdentifiers.id_X25519))
+ {
+ return new X25519PrivateKeyParameters(getRawKey(keyInfo, X25519PrivateKeyParameters.KEY_SIZE), 0);
+ }
+ else if (algOID.equals(EdECObjectIdentifiers.id_X448))
+ {
+ return new X448PrivateKeyParameters(getRawKey(keyInfo, X448PrivateKeyParameters.KEY_SIZE), 0);
+ }
+ else if (algOID.equals(EdECObjectIdentifiers.id_Ed25519))
+ {
+ return new Ed25519PrivateKeyParameters(getRawKey(keyInfo, Ed25519PrivateKeyParameters.KEY_SIZE), 0);
+ }
+ else if (algOID.equals(EdECObjectIdentifiers.id_Ed448))
+ {
+ return new Ed448PrivateKeyParameters(getRawKey(keyInfo, Ed448PrivateKeyParameters.KEY_SIZE), 0);
+ }
+ else if (
+ algOID.equals(CryptoProObjectIdentifiers.gostR3410_2001) ||
+ algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512) ||
+ algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256))
+ {
+ GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(keyInfo.getPrivateKeyAlgorithm().getParameters());
+ ECGOST3410Parameters ecSpec = null;
+ BigInteger d = null;
+ ASN1Primitive p = keyInfo.getPrivateKeyAlgorithm().getParameters().toASN1Primitive();
+ if (p instanceof ASN1Sequence && (ASN1Sequence.getInstance(p).size() == 2 || ASN1Sequence.getInstance(p).size() == 3))
+ {
+
+ X9ECParameters ecP = ECGOST3410NamedCurves.getByOIDX9(gostParams.getPublicKeyParamSet());
+
+ ecSpec = new ECGOST3410Parameters(
+ new ECNamedDomainParameters(
+ gostParams.getPublicKeyParamSet(), ecP),
+ gostParams.getPublicKeyParamSet(),
+ gostParams.getDigestParamSet(),
+ gostParams.getEncryptionParamSet());
+ ASN1OctetString privEnc = keyInfo.getPrivateKey();
+
+ if (privEnc.getOctets().length == 32 || privEnc.getOctets().length == 64)
+ {
+ d = new BigInteger(1, Arrays.reverse(privEnc.getOctets()));
+ }
+ else
+ {
+ ASN1Encodable privKey = keyInfo.parsePrivateKey();
+ if (privKey instanceof ASN1Integer)
+ {
+ d = ASN1Integer.getInstance(privKey).getPositiveValue();
+ }
+ else
+ {
+ byte[] dVal = Arrays.reverse(ASN1OctetString.getInstance(privKey).getOctets());
+ d = new BigInteger(1, dVal);
+ }
+ }
+ }
+ else
+ {
+ X962Parameters params = X962Parameters.getInstance(keyInfo.getPrivateKeyAlgorithm().getParameters());
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters());
+ X9ECParameters ecP = ECNamedCurveTable.getByOID(oid);
+
+ ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(oid, ecP),
+ gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(),
+ gostParams.getEncryptionParamSet());
+ }
+ else if (params.isImplicitlyCA())
+ {
+ ecSpec = null;
+ }
+ else
+ {
+ X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
+ ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(algOID, ecP),
+ gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(),
+ gostParams.getEncryptionParamSet());
+ }
+
+ ASN1Encodable privKey = keyInfo.parsePrivateKey();
+ if (privKey instanceof ASN1Integer)
+ {
+ ASN1Integer derD = ASN1Integer.getInstance(privKey);
+
+ d = derD.getValue();
+ }
+ else
+ {
+ ECPrivateKey ec = ECPrivateKey.getInstance(privKey);
+
+ d = ec.getKey();
+ }
+
+ }
+
+ return new ECPrivateKeyParameters(
+ d,
+ new ECGOST3410Parameters(
+ ecSpec,
+ gostParams.getPublicKeyParamSet(),
+ gostParams.getDigestParamSet(),
+ gostParams.getEncryptionParamSet()));
+
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ else
+ {
+ throw new RuntimeException("algorithm identifier in private key not recognised");
+ }
+ }
+
+ private static byte[] getRawKey(PrivateKeyInfo keyInfo, int expectedSize)
+ throws IOException
+ {
+ byte[] result = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets();
+ if (expectedSize != result.length)
+ {
+ throw new RuntimeException("private key encoding has incorrect length");
+ }
+ return result;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PublicKeyFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PublicKeyFactory.java
new file mode 100644
index 00000000..9e1f295f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PublicKeyFactory.java
@@ -0,0 +1,566 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
+// import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters;
+// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
+// import org.bouncycastle.asn1.oiw.ElGamalParameter;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.DHParameter;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.RSAPublicKey;
+// import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers;
+// import org.bouncycastle.asn1.ua.DSTU4145BinaryField;
+// import org.bouncycastle.asn1.ua.DSTU4145ECBinary;
+// import org.bouncycastle.asn1.ua.DSTU4145NamedCurves;
+// import org.bouncycastle.asn1.ua.DSTU4145Params;
+// import org.bouncycastle.asn1.ua.DSTU4145PointEncoder;
+// import org.bouncycastle.asn1.ua.UAObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.DSAParameter;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x9.DHPublicKey;
+import com.android.internal.org.bouncycastle.asn1.x9.DomainParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable;
+import com.android.internal.org.bouncycastle.asn1.x9.ValidationParams;
+import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECPoint;
+import com.android.internal.org.bouncycastle.asn1.x9.X9IntegerConverter;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves;
+import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPublicKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHValidationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPublicKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+// import org.bouncycastle.crypto.params.ECGOST3410Parameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECNamedDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPublicKeyParameters;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
+// import org.bouncycastle.crypto.params.Ed448PublicKeyParameters;
+// import org.bouncycastle.crypto.params.ElGamalParameters;
+// import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.RSAKeyParameters;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.params.X25519PublicKeyParameters;
+// import org.bouncycastle.crypto.params.X448PublicKeyParameters;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Factory to create asymmetric public key parameters for asymmetric ciphers from range of
+ * ASN.1 encoded SubjectPublicKeyInfo objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PublicKeyFactory
+{
+ private static Map converters = new HashMap();
+
+ static
+ {
+ converters.put(PKCSObjectIdentifiers.rsaEncryption, new RSAConverter());
+ converters.put(PKCSObjectIdentifiers.id_RSASSA_PSS, new RSAConverter());
+ converters.put(X509ObjectIdentifiers.id_ea_rsa, new RSAConverter());
+ converters.put(X9ObjectIdentifiers.dhpublicnumber, new DHPublicNumberConverter());
+ converters.put(PKCSObjectIdentifiers.dhKeyAgreement, new DHAgreementConverter());
+ converters.put(X9ObjectIdentifiers.id_dsa, new DSAConverter());
+ converters.put(OIWObjectIdentifiers.dsaWithSHA1, new DSAConverter());
+ // Android-removed: Unsupported algorithm
+ // converters.put(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalConverter());
+ converters.put(X9ObjectIdentifiers.id_ecPublicKey, new ECConverter());
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ converters.put(CryptoProObjectIdentifiers.gostR3410_2001, new GOST3410_2001Converter());
+ converters.put(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256, new GOST3410_2012Converter());
+ converters.put(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512, new GOST3410_2012Converter());
+ converters.put(UAObjectIdentifiers.dstu4145be, new DSTUConverter());
+ converters.put(UAObjectIdentifiers.dstu4145le, new DSTUConverter());
+ converters.put(EdECObjectIdentifiers.id_X25519, new X25519Converter());
+ converters.put(EdECObjectIdentifiers.id_X448, new X448Converter());
+ converters.put(EdECObjectIdentifiers.id_Ed25519, new Ed25519Converter());
+ converters.put(EdECObjectIdentifiers.id_Ed448, new Ed448Converter());
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+
+ /**
+ * Create a public key from a SubjectPublicKeyInfo encoding
+ *
+ * @param keyInfoData the SubjectPublicKeyInfo encoding
+ * @return the appropriate key parameter
+ * @throws IOException on an error decoding the key
+ */
+ public static AsymmetricKeyParameter createKey(byte[] keyInfoData)
+ throws IOException
+ {
+ return createKey(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(keyInfoData)));
+ }
+
+ /**
+ * Create a public key from a SubjectPublicKeyInfo encoding read from a stream
+ *
+ * @param inStr the stream to read the SubjectPublicKeyInfo encoding from
+ * @return the appropriate key parameter
+ * @throws IOException on an error decoding the key
+ */
+ public static AsymmetricKeyParameter createKey(InputStream inStr)
+ throws IOException
+ {
+ return createKey(SubjectPublicKeyInfo.getInstance(new ASN1InputStream(inStr).readObject()));
+ }
+
+ /**
+ * Create a public key from the passed in SubjectPublicKeyInfo
+ *
+ * @param keyInfo the SubjectPublicKeyInfo containing the key data
+ * @return the appropriate key parameter
+ * @throws IOException on an error decoding the key
+ */
+ public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ return createKey(keyInfo, null);
+ }
+
+ /**
+ * Create a public key from the passed in SubjectPublicKeyInfo
+ *
+ * @param keyInfo the SubjectPublicKeyInfo containing the key data
+ * @param defaultParams default parameters that might be needed.
+ * @return the appropriate key parameter
+ * @throws IOException on an error decoding the key
+ */
+ public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ throws IOException
+ {
+ AlgorithmIdentifier algID = keyInfo.getAlgorithm();
+
+ SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)converters.get(algID.getAlgorithm());
+ if (null == converter)
+ {
+ throw new IOException("algorithm identifier in public key not recognised: " + algID.getAlgorithm());
+ }
+
+ return converter.getPublicKeyParameters(keyInfo, defaultParams);
+ }
+
+ private static abstract class SubjectPublicKeyInfoConverter
+ {
+ abstract AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ throws IOException;
+ }
+
+ private static class RSAConverter
+ extends SubjectPublicKeyInfoConverter
+ {
+ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ throws IOException
+ {
+ RSAPublicKey pubKey = RSAPublicKey.getInstance(keyInfo.parsePublicKey());
+
+ return new RSAKeyParameters(false, pubKey.getModulus(), pubKey.getPublicExponent());
+ }
+ }
+
+ private static class DHPublicNumberConverter
+ extends SubjectPublicKeyInfoConverter
+ {
+ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ throws IOException
+ {
+ DHPublicKey dhPublicKey = DHPublicKey.getInstance(keyInfo.parsePublicKey());
+
+ BigInteger y = dhPublicKey.getY();
+
+ DomainParameters dhParams = DomainParameters.getInstance(keyInfo.getAlgorithm().getParameters());
+
+ BigInteger p = dhParams.getP();
+ BigInteger g = dhParams.getG();
+ BigInteger q = dhParams.getQ();
+
+ BigInteger j = null;
+ if (dhParams.getJ() != null)
+ {
+ j = dhParams.getJ();
+ }
+
+ DHValidationParameters validation = null;
+ ValidationParams dhValidationParms = dhParams.getValidationParams();
+ if (dhValidationParms != null)
+ {
+ byte[] seed = dhValidationParms.getSeed();
+ BigInteger pgenCounter = dhValidationParms.getPgenCounter();
+
+ // TODO Check pgenCounter size?
+
+ validation = new DHValidationParameters(seed, pgenCounter.intValue());
+ }
+
+ return new DHPublicKeyParameters(y, new DHParameters(p, g, q, j, validation));
+ }
+ }
+
+ private static class DHAgreementConverter
+ extends SubjectPublicKeyInfoConverter
+ {
+ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ throws IOException
+ {
+ DHParameter params = DHParameter.getInstance(keyInfo.getAlgorithm().getParameters());
+ ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey();
+
+ BigInteger lVal = params.getL();
+ int l = lVal == null ? 0 : lVal.intValue();
+ DHParameters dhParams = new DHParameters(params.getP(), params.getG(), null, l);
+
+ return new DHPublicKeyParameters(derY.getValue(), dhParams);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
+ private static class ElGamalConverter
+ extends SubjectPublicKeyInfoConverter
+ {
+ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ throws IOException
+ {
+ ElGamalParameter params = ElGamalParameter.getInstance(keyInfo.getAlgorithm().getParameters());
+ ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey();
+
+ return new ElGamalPublicKeyParameters(derY.getValue(), new ElGamalParameters(
+ params.getP(), params.getG()));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithm
+
+ private static class DSAConverter
+ extends SubjectPublicKeyInfoConverter
+ {
+ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ throws IOException
+ {
+ ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey();
+ ASN1Encodable de = keyInfo.getAlgorithm().getParameters();
+
+ DSAParameters parameters = null;
+ if (de != null)
+ {
+ DSAParameter params = DSAParameter.getInstance(de.toASN1Primitive());
+ parameters = new DSAParameters(params.getP(), params.getQ(), params.getG());
+ }
+
+ return new DSAPublicKeyParameters(derY.getValue(), parameters);
+ }
+ }
+
+ private static class ECConverter
+ extends SubjectPublicKeyInfoConverter
+ {
+ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ {
+ X962Parameters params = X962Parameters.getInstance(keyInfo.getAlgorithm().getParameters());
+ ECDomainParameters dParams;
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
+
+ X9ECParameters x9 = CustomNamedCurves.getByOID(oid);
+ if (x9 == null)
+ {
+ x9 = ECNamedCurveTable.getByOID(oid);
+ }
+ dParams = new ECNamedDomainParameters(oid, x9);
+ }
+ else if (params.isImplicitlyCA())
+ {
+ dParams = (ECDomainParameters)defaultParams;
+ }
+ else
+ {
+ X9ECParameters x9 = X9ECParameters.getInstance(params.getParameters());
+ dParams = new ECDomainParameters(x9);
+ }
+
+ DERBitString bits = keyInfo.getPublicKeyData();
+ byte[] data = bits.getBytes();
+ ASN1OctetString key = new DEROctetString(data);
+
+ //
+ // extra octet string - the old extra embedded octet string
+ //
+ if (data[0] == 0x04 && data[1] == data.length - 2
+ && (data[2] == 0x02 || data[2] == 0x03))
+ {
+ int qLength = new X9IntegerConverter().getByteLength(dParams.getCurve());
+
+ if (qLength >= data.length - 3)
+ {
+ try
+ {
+ key = (ASN1OctetString)ASN1Primitive.fromByteArray(data);
+ }
+ catch (IOException ex)
+ {
+ throw new IllegalArgumentException("error recovering public key");
+ }
+ }
+ }
+
+ X9ECPoint derQ = new X9ECPoint(dParams.getCurve(), key);
+
+ return new ECPublicKeyParameters(derQ.getPoint(), dParams);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ private static class GOST3410_2001Converter
+ extends SubjectPublicKeyInfoConverter
+ {
+ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ {
+ AlgorithmIdentifier algID = keyInfo.getAlgorithm();
+// ASN1ObjectIdentifier algOid = algID.getAlgorithm();
+ GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(algID.getParameters());
+ ASN1ObjectIdentifier publicKeyParamSet = gostParams.getPublicKeyParamSet();
+
+ ECGOST3410Parameters ecDomainParameters = new ECGOST3410Parameters(
+ new ECNamedDomainParameters(publicKeyParamSet, ECGOST3410NamedCurves.getByOIDX9(publicKeyParamSet)),
+ publicKeyParamSet,
+ gostParams.getDigestParamSet(),
+ gostParams.getEncryptionParamSet());
+
+ ASN1OctetString key;
+ try
+ {
+ key = (ASN1OctetString)keyInfo.parsePublicKey();
+ }
+ catch (IOException ex)
+ {
+ throw new IllegalArgumentException("error recovering GOST3410_2001 public key");
+ }
+
+ int fieldSize = 32;
+ int keySize = 2 * fieldSize;
+
+ byte[] keyEnc = key.getOctets();
+ if (keyEnc.length != keySize)
+ {
+ throw new IllegalArgumentException("invalid length for GOST3410_2001 public key");
+ }
+
+ byte[] x9Encoding = new byte[1 + keySize];
+ x9Encoding[0] = 0x04;
+ for (int i = 1; i <= fieldSize; ++i)
+ {
+ x9Encoding[i] = keyEnc[fieldSize - i];
+ x9Encoding[i + fieldSize] = keyEnc[keySize - i];
+ }
+
+ ECPoint q = ecDomainParameters.getCurve().decodePoint(x9Encoding);
+
+ return new ECPublicKeyParameters(q, ecDomainParameters);
+ }
+ }
+
+ private static class GOST3410_2012Converter
+ extends SubjectPublicKeyInfoConverter
+ {
+ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ {
+ AlgorithmIdentifier algID = keyInfo.getAlgorithm();
+ ASN1ObjectIdentifier algOid = algID.getAlgorithm();
+ GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(algID.getParameters());
+ ASN1ObjectIdentifier publicKeyParamSet = gostParams.getPublicKeyParamSet();
+
+ ECGOST3410Parameters ecDomainParameters = new ECGOST3410Parameters(
+ new ECNamedDomainParameters(publicKeyParamSet, ECGOST3410NamedCurves.getByOIDX9(publicKeyParamSet)),
+ publicKeyParamSet,
+ gostParams.getDigestParamSet(),
+ gostParams.getEncryptionParamSet());
+
+ ASN1OctetString key;
+ try
+ {
+ key = (ASN1OctetString)keyInfo.parsePublicKey();
+ }
+ catch (IOException ex)
+ {
+ throw new IllegalArgumentException("error recovering GOST3410_2012 public key");
+ }
+
+ int fieldSize = 32;
+ if (algOid.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512))
+ {
+ fieldSize = 64;
+ }
+ int keySize = 2 * fieldSize;
+
+ byte[] keyEnc = key.getOctets();
+ if (keyEnc.length != keySize)
+ {
+ throw new IllegalArgumentException("invalid length for GOST3410_2012 public key");
+ }
+
+ byte[] x9Encoding = new byte[1 + keySize];
+ x9Encoding[0] = 0x04;
+ for (int i = 1; i <= fieldSize; ++i)
+ {
+ x9Encoding[i] = keyEnc[fieldSize - i];
+ x9Encoding[i + fieldSize] = keyEnc[keySize - i];
+ }
+
+ ECPoint q = ecDomainParameters.getCurve().decodePoint(x9Encoding);
+
+ return new ECPublicKeyParameters(q, ecDomainParameters);
+ }
+ }
+
+ private static class DSTUConverter
+ extends SubjectPublicKeyInfoConverter
+ {
+ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ throws IOException
+ {
+ AlgorithmIdentifier algID = keyInfo.getAlgorithm();
+ ASN1ObjectIdentifier algOid = algID.getAlgorithm();
+ DSTU4145Params dstuParams = DSTU4145Params.getInstance(algID.getParameters());
+
+ ASN1OctetString key;
+ try
+ {
+ key = (ASN1OctetString)keyInfo.parsePublicKey();
+ }
+ catch (IOException ex)
+ {
+ throw new IllegalArgumentException("error recovering DSTU public key");
+ }
+
+ byte[] keyEnc = Arrays.clone(key.getOctets());
+
+ if (algOid.equals(UAObjectIdentifiers.dstu4145le))
+ {
+ reverseBytes(keyEnc);
+ }
+
+ ECDomainParameters ecDomain;
+ if (dstuParams.isNamedCurve())
+ {
+ ecDomain = DSTU4145NamedCurves.getByOID(dstuParams.getNamedCurve());
+ }
+ else
+ {
+ DSTU4145ECBinary binary = dstuParams.getECBinary();
+ byte[] b_bytes = binary.getB();
+ if (algOid.equals(UAObjectIdentifiers.dstu4145le))
+ {
+ reverseBytes(b_bytes);
+ }
+ BigInteger b = new BigInteger(1, b_bytes);
+ DSTU4145BinaryField field = binary.getField();
+ ECCurve curve = new ECCurve.F2m(field.getM(), field.getK1(), field.getK2(), field.getK3(), binary.getA(), b);
+ byte[] g_bytes = binary.getG();
+ if (algOid.equals(UAObjectIdentifiers.dstu4145le))
+ {
+ reverseBytes(g_bytes);
+ }
+ ECPoint g = DSTU4145PointEncoder.decodePoint(curve, g_bytes);
+ ecDomain = new ECDomainParameters(curve, g, binary.getN());
+ }
+
+ ECPoint q = DSTU4145PointEncoder.decodePoint(ecDomain.getCurve(), keyEnc);
+
+ return new ECPublicKeyParameters(q, ecDomain);
+ }
+
+ private void reverseBytes(byte[] bytes)
+ {
+ byte tmp;
+
+ for (int i = 0; i < bytes.length / 2; i++)
+ {
+ tmp = bytes[i];
+ bytes[i] = bytes[bytes.length - 1 - i];
+ bytes[bytes.length - 1 - i] = tmp;
+ }
+ }
+ }
+
+ private static class X25519Converter
+ extends SubjectPublicKeyInfoConverter
+ {
+ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ {
+ return new X25519PublicKeyParameters(getRawKey(keyInfo, defaultParams, X25519PublicKeyParameters.KEY_SIZE), 0);
+ }
+ }
+
+ private static class X448Converter
+ extends SubjectPublicKeyInfoConverter
+ {
+ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ {
+ return new X448PublicKeyParameters(getRawKey(keyInfo, defaultParams, X448PublicKeyParameters.KEY_SIZE), 0);
+ }
+ }
+
+ private static class Ed25519Converter
+ extends SubjectPublicKeyInfoConverter
+ {
+ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ {
+ return new Ed25519PublicKeyParameters(getRawKey(keyInfo, defaultParams, Ed25519PublicKeyParameters.KEY_SIZE), 0);
+ }
+ }
+
+ private static class Ed448Converter
+ extends SubjectPublicKeyInfoConverter
+ {
+ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
+ {
+ return new Ed448PublicKeyParameters(getRawKey(keyInfo, defaultParams, Ed448PublicKeyParameters.KEY_SIZE), 0);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ private static byte[] getRawKey(SubjectPublicKeyInfo keyInfo, Object defaultParams, int expectedSize)
+ {
+ /*
+ * TODO[RFC 8422]
+ * - Require defaultParams == null?
+ * - Require keyInfo.getAlgorithm().getParameters() == null?
+ */
+ byte[] result = keyInfo.getPublicKeyData().getOctets();
+ if (expectedSize != result.length)
+ {
+ throw new RuntimeException("public key encoding has incorrect length");
+ }
+ return result;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/SSHNamedCurves.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/SSHNamedCurves.java
new file mode 100644
index 00000000..9853bf21
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/SSHNamedCurves.java
@@ -0,0 +1,134 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.crypto.util;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.nist.NISTNamedCurves;
+import com.android.internal.org.bouncycastle.asn1.sec.SECObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECNamedDomainParameters;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SSHNamedCurves
+{
+ private static final Map<ASN1ObjectIdentifier, String> oidToName;
+ private static final Map<String, ASN1ObjectIdentifier> oidMap =
+ Collections.unmodifiableMap(new HashMap<String, ASN1ObjectIdentifier>()
+ {
+ {
+ put("nistp256", SECObjectIdentifiers.secp256r1);
+ put("nistp384", SECObjectIdentifiers.secp384r1);
+ put("nistp521", SECObjectIdentifiers.secp521r1);
+ put("nistk163", SECObjectIdentifiers.sect163k1);
+ put("nistp192", SECObjectIdentifiers.secp192r1);
+ put("nistp224", SECObjectIdentifiers.secp224r1);
+ put("nistk233", SECObjectIdentifiers.sect233k1);
+ put("nistb233", SECObjectIdentifiers.sect233r1);
+ put("nistk283", SECObjectIdentifiers.sect283k1);
+ put("nistk409", SECObjectIdentifiers.sect409k1);
+ put("nistb409", SECObjectIdentifiers.sect409r1);
+ put("nistt571", SECObjectIdentifiers.sect571k1);
+ }
+ });
+
+ private static final Map<String, String> curveNameToSSHName = Collections.unmodifiableMap(new HashMap<String, String>()
+ {
+ {
+ String[][] curves = {
+ {"secp256r1", "nistp256"},
+ {"secp384r1", "nistp384"},
+ {"secp521r1", "nistp521"},
+ {"sect163k1", "nistk163"},
+ {"secp192r1", "nistp192"},
+ {"secp224r1", "nistp224"},
+ {"sect233k1", "nistk233"},
+ {"sect233r1", "nistb233"},
+ {"sect283k1", "nistk283"},
+ {"sect409k1", "nistk409"},
+ {"sect409r1", "nistb409"},
+ {"sect571k1", "nistt571"}
+ };
+ for (int i = 0; i != curves.length; i++)
+ {
+ String[] item = curves[i];
+ put(item[0], item[1]);
+ }
+ }
+ });
+ private static HashMap<ECCurve, String> curveMap = new HashMap<ECCurve, String>()
+ {
+ {
+ Enumeration<Object> e = CustomNamedCurves.getNames();
+ while (e.hasMoreElements())
+ {
+ String name = (String)e.nextElement();
+ X9ECParameters parameters = CustomNamedCurves.getByName(name);
+ put(parameters.getCurve(), name);
+ }
+
+ }
+ };
+
+ static
+ {
+ oidToName = Collections.unmodifiableMap(new HashMap<ASN1ObjectIdentifier, String>()
+ {
+ {
+ for (Iterator it = oidMap.keySet().iterator(); it.hasNext();)
+ {
+ String key = (String)it.next();
+ put(oidMap.get(key), key);
+ }
+ }
+ });
+
+
+ }
+
+ public static ASN1ObjectIdentifier getByName(String sshName)
+ {
+ return (ASN1ObjectIdentifier)oidMap.get(sshName);
+ }
+
+ public static X9ECParameters getParameters(String sshName)
+ {
+ return NISTNamedCurves.getByOID((ASN1ObjectIdentifier)oidMap.get(Strings.toLowerCase(sshName)));
+ }
+
+ public static X9ECParameters getParameters(ASN1ObjectIdentifier oid)
+ {
+ return NISTNamedCurves.getByOID(oid);
+ }
+
+ public static String getName(ASN1ObjectIdentifier oid)
+ {
+ return (String)oidToName.get(oid);
+ }
+
+ public static String getNameForParameters(ECDomainParameters parameters)
+ {
+ if (parameters instanceof ECNamedDomainParameters)
+ {
+ return getName(((ECNamedDomainParameters)parameters).getName());
+ }
+
+
+ return getNameForParameters(parameters.getCurve());
+ }
+
+ public static String getNameForParameters(ECCurve curve)
+ {
+ return (String)curveNameToSSHName.get(curveMap.get(curve));
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/iana/AEADAlgorithm.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/iana/AEADAlgorithm.java
new file mode 100644
index 00000000..e6ee5997
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/iana/AEADAlgorithm.java
@@ -0,0 +1,59 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.iana;
+
+/**
+ * RFC 5116
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AEADAlgorithm
+{
+ public static final int AEAD_AES_128_GCM = 1;
+ public static final int AEAD_AES_256_GCM = 2;
+ public static final int AEAD_AES_128_CCM = 3;
+ public static final int AEAD_AES_256_CCM = 4;
+
+ /*
+ * RFC 5282
+ */
+ public static final int AEAD_AES_128_GCM_8 = 5;
+ public static final int AEAD_AES_256_GCM_8 = 6;
+ public static final int AEAD_AES_128_GCM_12 = 7;
+ public static final int AEAD_AES_256_GCM_12 = 8;
+ public static final int AEAD_AES_128_CCM_SHORT = 9;
+ public static final int AEAD_AES_256_CCM_SHORT = 10;
+ public static final int AEAD_AES_128_CCM_SHORT_8 = 11;
+ public static final int AEAD_AES_256_CCM_SHORT_8 = 12;
+ public static final int AEAD_AES_128_CCM_SHORT_12 = 13;
+ public static final int AEAD_AES_256_CCM_SHORT_12 = 14;
+
+ /*
+ * RFC 5297
+ */
+ public static final int AEAD_AES_SIV_CMAC_256 = 15;
+ public static final int AEAD_AES_SIV_CMAC_384 = 16;
+ public static final int AEAD_AES_SIV_CMAC_512 = 17;
+
+ /*
+ * RFC 6655
+ */
+ public static final int AEAD_AES_128_CCM_8 = 18;
+ public static final int AEAD_AES_256_CCM_8 = 19;
+
+ /*
+ * RFC 7253
+ */
+ public static final int AEAD_AES_128_OCB_TAGLEN128 = 20;
+ public static final int AEAD_AES_128_OCB_TAGLEN96 = 21;
+ public static final int AEAD_AES_128_OCB_TAGLEN64 = 22;
+ public static final int AEAD_AES_192_OCB_TAGLEN128 = 23;
+ public static final int AEAD_AES_192_OCB_TAGLEN96 = 24;
+ public static final int AEAD_AES_192_OCB_TAGLEN64 = 25;
+ public static final int AEAD_AES_256_OCB_TAGLEN128 = 26;
+ public static final int AEAD_AES_256_OCB_TAGLEN96 = 27;
+ public static final int AEAD_AES_256_OCB_TAGLEN64 = 28;
+
+ /*
+ * RFC 7539
+ */
+ public static final int AEAD_CHACHA20_POLY1305 = 29;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/AesCcmCiphertext.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/AesCcmCiphertext.java
new file mode 100644
index 00000000..cf8cea8a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/AesCcmCiphertext.java
@@ -0,0 +1,61 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * AesCcmCiphertext ::= SEQUENCE {
+ * nonce OCTET STRING (SIZE (12))
+ * ccmCiphertext Opaque -- 16 bytes longer than plaintext
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AesCcmCiphertext
+ extends ASN1Object
+{
+ private final byte[] nonce;
+ private final SequenceOfOctetString opaque;
+
+ private AesCcmCiphertext(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("sequence not length 2");
+ }
+
+ nonce = Utils.octetStringFixed(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets(), 12);
+ opaque = SequenceOfOctetString.getInstance(seq.getObjectAt(1));
+ }
+
+ public static AesCcmCiphertext getInstance(Object o)
+ {
+ if (o instanceof AesCcmCiphertext)
+ {
+ return (AesCcmCiphertext)o;
+ }
+ else if (o != null)
+ {
+ return new AesCcmCiphertext(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(new DEROctetString(nonce));
+ v.add(opaque);
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/BitmapSspRange.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/BitmapSspRange.java
new file mode 100644
index 00000000..6b52a8d9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/BitmapSspRange.java
@@ -0,0 +1,74 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * BitmapSspRange ::= SEQUENCE {
+ * sspValue OCTET STRING (SIZE(1..32)),
+ * sspBitmask OCTET STRING (SIZE(1..32))
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BitmapSspRange
+ extends ASN1Object
+{
+ private final byte[] sspValue;
+ private final byte[] sspBitmask;
+
+ private BitmapSspRange(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("expected sequence with sspValue and sspBitmask");
+ }
+
+ sspValue = Utils.octetStringFixed(
+ ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets());
+ sspBitmask = Utils.octetStringFixed(
+ ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets());
+ }
+
+ public static BitmapSspRange getInstance(Object o)
+ {
+ if (o instanceof BitmapSspRange)
+ {
+ return (BitmapSspRange)o;
+ }
+ else if (o != null)
+ {
+ return new BitmapSspRange(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public byte[] getSspValue()
+ {
+ return Arrays.clone(sspValue);
+ }
+
+ public byte[] getSspBitmask()
+ {
+ return Arrays.clone(sspBitmask);
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector avec = new ASN1EncodableVector();
+
+ avec.add(new DEROctetString(sspValue));
+ avec.add(new DEROctetString(sspBitmask));
+
+ return new DERSequence(avec);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/CertificateBase.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/CertificateBase.java
new file mode 100644
index 00000000..f3dae006
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/CertificateBase.java
@@ -0,0 +1,68 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * CertificateBase ::= SEQUENCE {
+ * version Uint8(3),
+ * type CertificateType,
+ * issuer IssuerIdentifier,
+ * toBeSigned ToBeSignedCertificate,
+ * signature Signature OPTIONAL
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertificateBase
+ extends ASN1Object
+{
+ private CertificateType type;
+ private byte[] version;
+
+ protected CertificateBase(ASN1Sequence seq)
+ {
+
+ }
+
+ public static CertificateBase getInstance(Object o)
+ {
+ if (o instanceof ImplicitCertificate)
+ {
+ return (ImplicitCertificate)o;
+ }
+ if (o instanceof ExplicitCertificate)
+ {
+ return (ExplicitCertificate)o;
+ }
+
+ if (o != null)
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(o);
+
+ if (seq.getObjectAt(1).equals(CertificateType.Implicit))
+ {
+ return ImplicitCertificate.getInstance(seq);
+ }
+ if (seq.getObjectAt(1).equals(CertificateType.Explicit))
+ {
+ return ExplicitCertificate.getInstance(seq);
+ }
+ throw new IllegalArgumentException("unknown certificate type");
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/CertificateType.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/CertificateType.java
new file mode 100644
index 00000000..6754738c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/CertificateType.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * CertificateType ::= ENUMERATED {
+ * explicit,
+ * implicit,
+ * ...
+ * }
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertificateType
+{
+
+ public static final CertificateType Explicit = new CertificateType(0);
+ public static final CertificateType Implicit = new CertificateType(1);
+ private final ASN1Enumerated enumerated;
+
+ protected CertificateType(int ordinal)
+ {
+ enumerated = new ASN1Enumerated(ordinal);
+ }
+
+ private CertificateType(ASN1Enumerated enumerated)
+ {
+ this.enumerated = enumerated;
+ }
+
+ public CertificateType getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+ else if (src instanceof CertificateType)
+ {
+ return (CertificateType)src;
+ }
+ else
+ {
+ return new CertificateType(ASN1Enumerated.getInstance(src));
+ }
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return enumerated;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/CircularRegion.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/CircularRegion.java
new file mode 100644
index 00000000..b2bdff34
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/CircularRegion.java
@@ -0,0 +1,43 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * CircularRegion ::= SEQUENCE {
+ * center TwoDLocation,
+ * radius Uint16
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CircularRegion
+ extends ASN1Object
+{
+ private CircularRegion(ASN1Sequence seq)
+ {
+
+ }
+
+ public static CircularRegion getInstance(Object o)
+ {
+ if (o instanceof CircularRegion)
+ {
+ return (CircularRegion)o;
+ }
+ else if (o != null)
+ {
+ return new CircularRegion(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Duration.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Duration.java
new file mode 100644
index 00000000..5bc66d1d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Duration.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * Duration ::= CHOICE {
+ * microseconds Uint16,
+ * milliseconds Uint16,
+ * seconds Uint16,
+ * minutes Uint16,
+ * hours Uint16,
+ * sixtyHours Uint16,
+ * years Uint16
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Duration
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EncryptedData.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EncryptedData.java
new file mode 100644
index 00000000..e890086e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EncryptedData.java
@@ -0,0 +1,35 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * EncryptedData ::= SEQUENCE {
+ * recipients SequenceOfRecipientInfo,
+ * ciphertext SymmetricCiphertext
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EncryptedData
+{
+ private EncryptedData(ASN1Sequence seq)
+ {
+
+ }
+
+ public static EncryptedData getInstance(Object o)
+ {
+ if (o instanceof EncryptedData)
+ {
+ return (EncryptedData)o;
+ }
+ else if (o != null)
+ {
+ return new EncryptedData(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EndEntityType.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EndEntityType.java
new file mode 100644
index 00000000..dac4a9e5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EndEntityType.java
@@ -0,0 +1,56 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+
+/**
+ * <pre>
+ * EndEntityType ::= BIT STRING { app(0), enrol(1) } (SIZE (8)) (ALL EXCEPT ())
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EndEntityType
+ extends ASN1Object
+{
+ public static final int app = (1 << 7);
+ public static final int enrol = (1 << 6);
+
+ private final ASN1BitString type;
+
+ public EndEntityType(int type)
+ {
+ if (type != app && type != enrol)
+ {
+ throw new IllegalArgumentException("value out of range");
+ }
+
+ this.type = new DERBitString(type);
+ }
+
+ private EndEntityType(DERBitString str)
+ {
+ this.type = str;
+ }
+
+ public static EndEntityType getInstance(Object src)
+ {
+ if (src instanceof EndEntityType)
+ {
+ return (EndEntityType)src;
+ }
+ else if (src != null)
+ {
+ return new EndEntityType(DERBitString.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return type;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EtsiTs103097Module.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EtsiTs103097Module.java
new file mode 100644
index 00000000..f387be4e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/EtsiTs103097Module.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EtsiTs103097Module
+{
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ExplicitCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ExplicitCertificate.java
new file mode 100644
index 00000000..814436d6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ExplicitCertificate.java
@@ -0,0 +1,16 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ExplicitCertificate
+ extends CertificateBase
+{
+ private ExplicitCertificate(ASN1Sequence seq)
+ {
+ super(seq);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/GeographicRegion.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/GeographicRegion.java
new file mode 100644
index 00000000..1177ceac
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/GeographicRegion.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * GeographicRegion ::= CHOICE {
+ * circularRegion CircularRegion,
+ * rectangularRegion SequenceOfRectangularRegion,
+ * polygonalRegion PolygonalRegion,
+ * identifiedRegion SequenceOfIdentifiedRegion,
+ * ...
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GeographicRegion
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/GroupLinkageValue.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/GroupLinkageValue.java
new file mode 100644
index 00000000..86a9a392
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/GroupLinkageValue.java
@@ -0,0 +1,69 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * GroupLinkageValue ::= SEQUENCE {
+ * jValue OCTET STRING (SIZE(4))
+ * value OCTET STRING (SIZE(9))
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GroupLinkageValue
+ extends ASN1Object
+{
+ private byte[] jValue;
+ private byte[] value;
+
+ private GroupLinkageValue(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("sequence not length 2");
+ }
+
+ jValue = Utils.octetStringFixed(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets(), 4);
+ value = Utils.octetStringFixed(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets(), 9);
+ }
+
+ public static GroupLinkageValue getInstance(Object src)
+ {
+ if (src instanceof GroupLinkageValue)
+ {
+ return (GroupLinkageValue)src;
+ }
+ else if (src != null)
+ {
+ return new GroupLinkageValue(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public byte[] getJValue()
+ {
+ return jValue;
+ }
+
+ public byte[] getValue()
+ {
+ return value;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector avec = new ASN1EncodableVector();
+ avec.add(new DEROctetString(jValue));
+ avec.add(new DEROctetString(value));
+ return new DERSequence(avec);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/HashAlgorithm.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/HashAlgorithm.java
new file mode 100644
index 00000000..037a0bf4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/HashAlgorithm.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * CertificateType ::= ENUMERATED {
+ * explicit,
+ * implicit,
+ * ...
+ * }
+ * @hide This class is not part of the Android public SDK API
+ */
+public class HashAlgorithm
+{
+
+ public static final HashAlgorithm sha256 = new HashAlgorithm(0);
+ public static final HashAlgorithm sha384 = new HashAlgorithm(1);
+ private final ASN1Enumerated enumerated;
+
+ protected HashAlgorithm(int ordinal)
+ {
+ enumerated = new ASN1Enumerated(ordinal);
+ }
+
+ private HashAlgorithm(ASN1Enumerated enumerated)
+ {
+ this.enumerated = enumerated;
+ }
+
+ public HashAlgorithm getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+ else if (src instanceof HashAlgorithm)
+ {
+ return (HashAlgorithm)src;
+ }
+ else
+ {
+ return new HashAlgorithm(ASN1Enumerated.getInstance(src));
+ }
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return enumerated;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/HashedData.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/HashedData.java
new file mode 100644
index 00000000..da684920
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/HashedData.java
@@ -0,0 +1,48 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+
+/**
+ * <pre>
+ * HashedData ::= CHOICE {
+ * sha256HashedData OCTET STRING (SIZE(32))
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class HashedData
+ extends ASN1Object
+ implements ASN1Choice
+{
+ private ASN1OctetString hashData;
+
+ public HashedData(byte[] digest)
+ {
+ this.hashData = new DEROctetString(digest);
+ }
+
+ private HashedData(ASN1OctetString hashData)
+ {
+ this.hashData = hashData;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return hashData;
+ }
+
+ public ASN1OctetString getHashData()
+ {
+ return hashData;
+ }
+
+ public void setHashData(ASN1OctetString hashData)
+ {
+ this.hashData = hashData;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/HeaderInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/HeaderInfo.java
new file mode 100644
index 00000000..2a3bb8b1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/HeaderInfo.java
@@ -0,0 +1,54 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * HeaderInfo ::= SEQUENCE {
+ * psid Psid,
+ * generationTime Time64 OPTIONAL,
+ * expiryTime Time64 OPTIONAL,
+ * generationLocation ThreeDLocation OPTIONAL,
+ * p2pcdLearningRequest HashedId3 OPTIONAL,
+ * missingCrlIdentifier MissingCrlIdentifier OPTIONAL,
+ * ...,
+ * inlineP2pcdRequest SequenceOfHashedId3 OPTIONAL,
+ * requestedCertificate Certificate OPTIONAL
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class HeaderInfo
+ extends ASN1Object
+{
+ private HeaderInfo(ASN1Sequence seq)
+ {
+
+ }
+
+ public static HeaderInfo getInstance(Object o)
+ {
+ if (o instanceof HeaderInfo)
+ {
+ return (HeaderInfo)o;
+ }
+ else if (o != null)
+ {
+ return new HeaderInfo(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/IValue.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/IValue.java
new file mode 100644
index 00000000..5ca0cec8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/IValue.java
@@ -0,0 +1,54 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * <pre>
+ * Uint16 ::= INTEGER (0..65535)
+ *
+ * IValue ::= Uint16
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class IValue
+ extends ASN1Object
+{
+ private final BigInteger value;
+
+ private IValue(ASN1Integer value)
+ {
+ int i = BigIntegers.intValueExact(value.getValue());
+
+ if (i < 0 || i > 65535)
+ {
+ throw new IllegalArgumentException("value out of range");
+ }
+
+ this.value = value.getValue();
+ }
+
+ public static IValue getInstance(Object src)
+ {
+ if (src instanceof IValue)
+ {
+ return (IValue)src;
+ }
+ else if (src != null)
+ {
+ return new IValue(ASN1Integer.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new ASN1Integer(value);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Ieee1609Dot2Content.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Ieee1609Dot2Content.java
new file mode 100644
index 00000000..32f38c99
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Ieee1609Dot2Content.java
@@ -0,0 +1,48 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * Ieee1609Dot2Content ::= CHOICE {
+ * unsecuredData Opaque,
+ * signedData SignedData,
+ * encryptedData EncryptedData,
+ * signedCertificateRequest Opaque,
+ * ...
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Ieee1609Dot2Content
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public static Ieee1609Dot2Content getInstance(Object src)
+ {
+ if (src instanceof Ieee1609Dot2Content)
+ {
+ return (Ieee1609Dot2Content)src;
+ }
+ else if (src != null)
+ {
+ // TODO: need choice processing here
+ return getInstance(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Ieee1609Dot2Data.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Ieee1609Dot2Data.java
new file mode 100644
index 00000000..49680370
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Ieee1609Dot2Data.java
@@ -0,0 +1,59 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * Ieee1609Dot2Data ::= SEQUENCE {
+ * protocolVersion Uint8(3),
+ * content Ieee1609Dot2Content
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Ieee1609Dot2Data
+ extends ASN1Object
+{
+ private final BigInteger protcolVersion;
+ private final Ieee1609Dot2Content content;
+
+ private Ieee1609Dot2Data(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("sequence not length 2");
+ }
+
+ protcolVersion = ASN1Integer.getInstance(seq.getObjectAt(0)).getValue();
+ content = Ieee1609Dot2Content.getInstance(seq.getObjectAt(1));
+ }
+
+ public static Ieee1609Dot2Data getInstance(Object src)
+ {
+ if (src instanceof Ieee1609Dot2Data)
+ {
+ return (Ieee1609Dot2Data)src;
+ }
+ else if (src != null)
+ {
+ return new Ieee1609Dot2Data(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ImplicitCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ImplicitCertificate.java
new file mode 100644
index 00000000..bb9fcd27
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ImplicitCertificate.java
@@ -0,0 +1,16 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ImplicitCertificate
+ extends CertificateBase
+{
+ private ImplicitCertificate(ASN1Sequence seq)
+ {
+ super(seq);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/IssuerIdentifier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/IssuerIdentifier.java
new file mode 100644
index 00000000..fa4dae01
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/IssuerIdentifier.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * IssuerIdentifier ::= CHOICE {
+ * sha256AndDigest HashedId8,
+ * self HashAlgorithm,
+ * ...,
+ * sha384AndDigest HashedId8
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class IssuerIdentifier
+ extends ASN1Object
+ implements ASN1Choice
+{
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Latitude.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Latitude.java
new file mode 100644
index 00000000..5b26e3fc
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Latitude.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * Latitude ::= NinetyDegreeInt
+ *
+ * NinetyDegreeInt ::= INTEGER {
+ * min (-900000000),
+ * max (900000000),
+ * unknown (900000001)
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Latitude
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/LinkageData.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/LinkageData.java
new file mode 100644
index 00000000..5c8768fc
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/LinkageData.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * LinkageData ::= SEQUENCE {
+ * iCert IValue,
+ * linkage-value LinkageValue,
+ * group-linkage-value GroupLinkageValue OPTIONAL
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class LinkageData
+ extends ASN1Object
+{
+ private final IValue iCert;
+ private final LinkageValue linkageValue;
+ private final GroupLinkageValue groupLinkageValue;
+
+ private LinkageData(ASN1Sequence seq)
+ {
+ if (seq.size() != 2 && seq.size() != 3)
+ {
+ throw new IllegalArgumentException("sequence must be size 2 or 3");
+ }
+
+ this.iCert = IValue.getInstance(seq.getObjectAt(2));
+ this.linkageValue = LinkageValue.getInstance(seq.getObjectAt(2));
+ this.groupLinkageValue = GroupLinkageValue.getInstance(seq.getObjectAt(2));
+ }
+
+ public static LinkageData getInstance(Object src)
+ {
+ if (src instanceof LinkageData)
+ {
+ return (LinkageData)src;
+ }
+ else if (src != null)
+ {
+ // TODO: need choice processing here
+ return new LinkageData(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/LinkageValue.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/LinkageValue.java
new file mode 100644
index 00000000..7ad6b8c3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/LinkageValue.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * LinkageValue ::= OCTET STRING (SIZE(9))
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class LinkageValue
+ extends ASN1Object
+{
+ private final byte[] value;
+
+ private LinkageValue(ASN1OctetString octs)
+ {
+ this.value = Arrays.clone(Utils.octetStringFixed(octs.getOctets(), 9));
+ }
+
+ public static LinkageValue getInstance(Object src)
+ {
+ if (src instanceof LinkageValue)
+ {
+ return (LinkageValue)src;
+ }
+ else if (src != null)
+ {
+ return new LinkageValue(ASN1OctetString.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new DEROctetString(Arrays.clone(value));
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Longitude.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Longitude.java
new file mode 100644
index 00000000..68d3bc1e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Longitude.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * Latitude ::= OneEightyDegreeInt
+ *
+ * NinetyDegreeInt ::= INTEGER {
+ * min (-17999999999),
+ * max (1800000000),
+ * unknown (1800000001)
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Longitude
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PKRecipientInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PKRecipientInfo.java
new file mode 100644
index 00000000..e42e48d9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PKRecipientInfo.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * PKRecipientInfo ::= SEQUENCE {
+ * recipientId HashedId8,
+ * encKey EncryptedDataEncryptionKey
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKRecipientInfo
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PolygonalRegion.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PolygonalRegion.java
new file mode 100644
index 00000000..41fc43e9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PolygonalRegion.java
@@ -0,0 +1,20 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * SEQUENCE SIZE(3..MAX) OF TwoDLocation
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PolygonalRegion
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PsidGroupPermissions.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PsidGroupPermissions.java
new file mode 100644
index 00000000..72173fc6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PsidGroupPermissions.java
@@ -0,0 +1,61 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * PsidGroupPermissions ::= SEQUENCE {
+ * subjectPermissions SubjectPermissions,
+ * minChainLength INTEGER DEFAULT 1,
+ * chainLengthRange INTEGER DEFAULT 0,
+ * eeType EndEntityType DEFAULT (app)
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PsidGroupPermissions
+ extends ASN1Object
+{
+ private final SubjectPermissions subjectPermissions;
+ private final BigInteger minChainLength;
+ private final BigInteger chainLengthRange;
+ private final Object eeType;
+
+ private PsidGroupPermissions(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("sequence not length 2");
+ }
+
+ this.subjectPermissions = SubjectPermissions.getInstance(seq.getObjectAt(0));
+ this.minChainLength = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue();
+ this.chainLengthRange = ASN1Integer.getInstance(seq.getObjectAt(2)).getValue();
+ this.eeType = EndEntityType.getInstance(seq.getObjectAt(3));
+ }
+
+ public static PsidGroupPermissions getInstance(Object src)
+ {
+ if (src instanceof PsidGroupPermissions)
+ {
+ return (PsidGroupPermissions)src;
+ }
+ else if (src != null)
+ {
+ return new PsidGroupPermissions(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PsidSspRange.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PsidSspRange.java
new file mode 100644
index 00000000..df80e9f5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/PsidSspRange.java
@@ -0,0 +1,91 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * PsidSspRange ::= SEQUENCE {
+ * psid Psid,
+ * sspRange SspRange OPTIONAL
+ * }
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PsidSspRange
+ extends ASN1Object
+{
+ private ASN1Integer psid;
+ private SspRange sspRange;
+
+ public PsidSspRange()
+ {
+
+ }
+
+ public static PsidSspRange getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+ else if (src instanceof PsidSspRange)
+ {
+ return (PsidSspRange)src;
+ }
+ else
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(src);
+ PsidSspRange psidSspRange = new PsidSspRange();
+ if (seq.size() < 1 || seq.size() > 2)
+ {
+ throw new IllegalStateException("expected sequences with one or optionally two items");
+ }
+
+ if (seq.size() == 1)
+ {
+ psidSspRange.psid = (ASN1Integer)seq.getObjectAt(0);
+ }
+ if (seq.size() == 2)
+ {
+ psidSspRange.sspRange = SspRange.getInstance(seq.getObjectAt(1));
+ }
+ return psidSspRange;
+ }
+ }
+
+
+ public ASN1Integer getPsid()
+ {
+ return psid;
+ }
+
+ public void setPsid(ASN1Integer psid)
+ {
+ this.psid = psid;
+ }
+
+ public SspRange getSspRange()
+ {
+ return sspRange;
+ }
+
+ public void setSspRange(SspRange sspRange)
+ {
+ this.sspRange = sspRange;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector avec = new ASN1EncodableVector();
+ avec.add(psid);
+ if (sspRange != null)
+ {
+ avec.add(sspRange);
+ }
+ return new DERSequence(avec);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/RecipientInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/RecipientInfo.java
new file mode 100644
index 00000000..797e9405
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/RecipientInfo.java
@@ -0,0 +1,18 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+/**
+ * <pre>
+ * RecipientInfo ::= CHOICE {
+ * pskRecipInfo PreSharedKeyReicpientInfo,
+ * symmRecipInfo SymmRecipientInfo,
+ * certRecipInfo PKRecipientInfo,
+ * signedDataRecipInfo PKRecipientInfo,
+ * rekRecipInfo PKRecipientInfo
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RecipientInfo
+{
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/RectangularRegion.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/RectangularRegion.java
new file mode 100644
index 00000000..5ffdc569
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/RectangularRegion.java
@@ -0,0 +1,43 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * RectangularRegion ::= SEQUENCE {
+ * northWest TwoDLocation,
+ * southEast TwoDLocation
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RectangularRegion
+ extends ASN1Object
+{
+ private RectangularRegion(ASN1Sequence seq)
+ {
+
+ }
+
+ public static RectangularRegion getInstance(Object o)
+ {
+ if (o instanceof RectangularRegion)
+ {
+ return (RectangularRegion)o;
+ }
+ else if (o != null)
+ {
+ return new RectangularRegion(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfCertificate.java
new file mode 100644
index 00000000..57b3b774
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfCertificate.java
@@ -0,0 +1,24 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SequenceOfCertificate ::= SEQUENCE OF Certificate
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SequenceOfCertificate
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfOctetString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfOctetString.java
new file mode 100644
index 00000000..1f0e5cc6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfOctetString.java
@@ -0,0 +1,70 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * <pre>
+ * SequenceOfOctetString ::= SEQUENCE (SIZE(0..MAX)) OF OCTET STRING (SIZE(0..MAX))
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SequenceOfOctetString
+ extends ASN1Object
+{
+ private byte[][] octetStrings;
+
+ private SequenceOfOctetString(ASN1Sequence seq)
+ {
+ this.octetStrings = toByteArrays(seq);
+ }
+
+ public static SequenceOfOctetString getInstance(Object o)
+ {
+ if (o instanceof SequenceOfOctetString)
+ {
+ return (SequenceOfOctetString)o;
+ }
+ else if (o != null)
+ {
+ return new SequenceOfOctetString(ASN1Sequence.getInstance(o));
+ }
+
+ return null;
+ }
+
+ public int size()
+ {
+ return octetStrings.length;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (int i = 0; i != octetStrings.length; i++)
+ {
+ v.add(new DEROctetString(Arrays.clone(octetStrings[i])));
+ }
+
+ return new DERSequence(v);
+ }
+
+ static byte[][] toByteArrays(ASN1Sequence seq)
+ {
+ byte[][] octetStrings = new byte[seq.size()][];
+ for (int i = 0; i != seq.size(); i++)
+ {
+ octetStrings[i] = ASN1OctetString.getInstance(seq.getObjectAt(i)).getOctets();
+ }
+
+ return octetStrings;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfPsidGroupPermissions.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfPsidGroupPermissions.java
new file mode 100644
index 00000000..8bf45874
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfPsidGroupPermissions.java
@@ -0,0 +1,24 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SEQUENCE OF PsidGroupPermissions
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SequenceOfPsidGroupPermissions
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfRecipientInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfRecipientInfo.java
new file mode 100644
index 00000000..b0dfb064
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfRecipientInfo.java
@@ -0,0 +1,24 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SequenceOfRecipientInfo ::= SEQUENCE OF RecipientInfo
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SequenceOfRecipientInfo
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfRectangularRegion.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfRectangularRegion.java
new file mode 100644
index 00000000..2befd63a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SequenceOfRectangularRegion.java
@@ -0,0 +1,34 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SequenceOfRectangularRegion ::= SEQUENCE OF RectangularRegion
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SequenceOfRectangularRegion
+ extends ASN1Object
+{
+ private final RectangularRegion[] sequence;
+
+ private SequenceOfRectangularRegion(ASN1Sequence seq)
+ {
+ this.sequence = new RectangularRegion[seq.size()];
+
+ for (int i = 0; i != seq.size(); i++)
+ {
+ sequence[i] = RectangularRegion.getInstance(seq.getObjectAt(i));
+ }
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return new DERSequence(sequence);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ServiceSpecificPermissions.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ServiceSpecificPermissions.java
new file mode 100644
index 00000000..5a58bf47
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ServiceSpecificPermissions.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ServiceSpecificPermissions
+{
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Signature.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Signature.java
new file mode 100644
index 00000000..5c81647c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Signature.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * Signature ::= CHOICE {
+ * ecdsaNistP256Signature EcdsaP256Signature,
+ * ecdsaBrainpoolP256r1Signature EcdsaP256Signature,
+ * ...
+ * ecdsaBrainpoolP384r1Signature EcdsaP384Signature
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Signature
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SignedData.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SignedData.java
new file mode 100644
index 00000000..b0331060
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SignedData.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SignedData ::= SEQUENCE {
+ * hashId HashAlgorithm,
+ * tbsData ToBeSignedData,
+ * signer SignerIdentifier,
+ * signature Signature
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignedData
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SignedDataPayload.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SignedDataPayload.java
new file mode 100644
index 00000000..d625bc9e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SignedDataPayload.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SignedDataPayload ::= SEQUENCE {
+ * data Ieee1609Dot2Data OPTIONAL,
+ * extDataHash HashedData OPTIONAL,
+ * ...
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignedDataPayload
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SignerIdentifier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SignerIdentifier.java
new file mode 100644
index 00000000..10e821c4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SignerIdentifier.java
@@ -0,0 +1,31 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SignerIdentifier ::= CHOICE {
+ * digest HashedId8,
+ * certificate SequenceOfCertificate,
+ * self NULL,
+ * ...
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignerIdentifier
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SspRange.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SspRange.java
new file mode 100644
index 00000000..4bacbe4b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SspRange.java
@@ -0,0 +1,142 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import java.io.IOException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Null;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+
+/**
+ * <pre>
+ * SspRange ::= CHOICE {
+ * opaque SequenceOfOctetString,
+ * all NULL,
+ * ...
+ * bitmapSspRange BitmapSspRange
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SspRange
+ extends ASN1Object
+{
+ private final boolean isAll;
+ private final SequenceOfOctetString opaque;
+ private final BitmapSspRange bitmapSspRange;
+
+ private SspRange()
+ {
+ isAll = true;
+ opaque = null;
+ bitmapSspRange = null;
+ }
+
+ private SspRange(SequenceOfOctetString seq)
+ {
+ this.isAll = false;
+ if (seq.size() != 2)
+ {
+ opaque = seq;
+ bitmapSspRange = null;
+ }
+ else
+ {
+ // ambiguous
+ opaque = SequenceOfOctetString.getInstance(seq);
+
+ BitmapSspRange bitMapRange;
+ try
+ {
+ bitMapRange = BitmapSspRange.getInstance(seq);
+ }
+ catch (IllegalArgumentException e)
+ {
+ bitMapRange = null;
+ }
+
+ bitmapSspRange = bitMapRange;
+ }
+ }
+
+ public SspRange(BitmapSspRange range)
+ {
+ this.isAll = false;
+ this.bitmapSspRange = range;
+ this.opaque = null;
+ }
+
+ public static SspRange getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+
+ if (src instanceof SspRange)
+ {
+ return (SspRange)src;
+ }
+
+ if (src instanceof ASN1Null)
+ {
+ return new SspRange();
+ }
+
+ if (src instanceof ASN1Sequence)
+ {
+ return new SspRange(SequenceOfOctetString.getInstance(src));
+ }
+
+ if (src instanceof byte[])
+ {
+ try
+ {
+ return getInstance(ASN1Primitive.fromByteArray((byte[])src));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to parse encoded general name");
+ }
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance: " + src.getClass().getName());
+ }
+
+ public boolean isAll()
+ {
+ return isAll;
+ }
+
+ public boolean maybeOpaque()
+ {
+ return opaque != null;
+ }
+
+ public BitmapSspRange getBitmapSspRange()
+ {
+ return bitmapSspRange;
+ }
+
+ public SequenceOfOctetString getOpaque()
+ {
+ return opaque;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ if (isAll)
+ {
+ return DERNull.INSTANCE;
+ }
+
+ if (bitmapSspRange != null)
+ {
+ return bitmapSspRange.toASN1Primitive();
+ }
+
+ return opaque.toASN1Primitive();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SubjectPermissions.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SubjectPermissions.java
new file mode 100644
index 00000000..782b0d69
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SubjectPermissions.java
@@ -0,0 +1,41 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * SubjectPermissions ::= CHOICE {
+ * explicit SequenceOfPsidSspRange,
+ * all NULL,
+ * ...
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SubjectPermissions
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public static SubjectPermissions getInstance(Object src)
+ {
+ if (src instanceof SubjectPermissions)
+ {
+ return (SubjectPermissions)src;
+ }
+ else if (src != null)
+ {
+ // TODO: ....
+ return null;
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SymmAlgorithm.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SymmAlgorithm.java
new file mode 100644
index 00000000..9bf2ae15
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SymmAlgorithm.java
@@ -0,0 +1,57 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SymmAlgorithm
+ extends ASN1Object
+{
+ public static SymmAlgorithm aes128Ccm = new SymmAlgorithm(new ASN1Enumerated(0));
+ private ASN1Enumerated symmAlgorithm;
+
+ private SymmAlgorithm(ASN1Enumerated symmAlgorithm)
+ {
+ this.symmAlgorithm = symmAlgorithm;
+ }
+
+ public SymmAlgorithm(int ordinal)
+ {
+ this.symmAlgorithm = new ASN1Enumerated(ordinal);
+ }
+
+ public SymmAlgorithm getInstance(Object src)
+ {
+ if (src == null)
+ {
+ return null;
+ }
+ else if (src instanceof SymmAlgorithm)
+ {
+ return (SymmAlgorithm)src;
+ }
+ else
+ {
+ return new SymmAlgorithm(ASN1Enumerated.getInstance(src));
+ }
+ }
+
+ public ASN1Enumerated getSymmAlgorithm()
+ {
+ return symmAlgorithm;
+ }
+
+ public void setSymmAlgorithm(ASN1Enumerated symmAlgorithm)
+ {
+ this.symmAlgorithm = symmAlgorithm;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return symmAlgorithm.toASN1Primitive();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SymmRecipientInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SymmRecipientInfo.java
new file mode 100644
index 00000000..135829da
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/SymmRecipientInfo.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * SymmRecipientInfo ::= SEQUENCE {
+ * recipientId HashedId8,
+ * encKey SymmetricCiphertext
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SymmRecipientInfo
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ToBeSignedCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ToBeSignedCertificate.java
new file mode 100644
index 00000000..7f34af27
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ToBeSignedCertificate.java
@@ -0,0 +1,56 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+
+/**
+ * <pre>
+ * ToBeSignedCertificate ::= SEQUENCE {
+ * id CertificateId,
+ * cracaId HashedId3,
+ * crlSeries CrlSeries,
+ * validityPeriod ValidityPeriod,
+ * region GeographicRegion OPTIONAL,
+ * assuranceLevel SubjectAssurance OPTIONAL,
+ * appPermissions SequenceOfPsidSep OPTIONAL,
+ * certIssuePermissions SequenceOfPsidGroupPermissions OPTIONAL,
+ * certRequestPermissions NULL OPTIONAL,
+ * encryptionKey PublicEncryptionKey OPTIONAL,
+ * verifyKeyIndicator VerificationKeyIndicator,
+ * ...
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ToBeSignedCertificate
+ extends ASN1Object
+{
+// private final CertificateId certificateId;
+
+ private ToBeSignedCertificate(ASN1Sequence seq)
+ {
+ //TODO: this.certificateId = CertificateId.
+ }
+
+ public static ToBeSignedCertificate getInstance(Object src)
+ {
+ if (src instanceof ToBeSignedCertificate)
+ {
+ return (ToBeSignedCertificate)src;
+ }
+ else if (src != null)
+ {
+ // TODO: need choice processing here
+ return new ToBeSignedCertificate(ASN1Sequence.getInstance(src));
+ }
+
+ return null;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ToBeSignedData.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ToBeSignedData.java
new file mode 100644
index 00000000..050fd37c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ToBeSignedData.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * ToBeSignedData ::= SEQUENCE {
+ * payload SignedDataPayload,
+ * headerInfo HeaderInfo
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ToBeSignedData
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/TwoDLocation.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/TwoDLocation.java
new file mode 100644
index 00000000..b581b13a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/TwoDLocation.java
@@ -0,0 +1,23 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * TwoDLocation ::= SEQUENCE {
+ * latitude Latitude,
+ * longitude Longitude
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TwoDLocation
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Utils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Utils.java
new file mode 100644
index 00000000..f3ab4d46
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/Utils.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+class Utils
+{
+ /**
+ * <pre>
+ * OCTET STRING (SIZE(n))
+ * </pre>
+ */
+ static byte[] octetStringFixed(byte[] octets, int n)
+ {
+ if (octets.length != n)
+ {
+ throw new IllegalArgumentException("octet string out of range");
+ }
+
+ return octets;
+ }
+
+ /**
+ * <pre>
+ * OCTET STRING (SIZE(1..32))
+ * </pre>
+ */
+ static byte[] octetStringFixed(byte[] octets)
+ {
+ if (octets.length < 1 || octets.length > 32)
+ {
+ throw new IllegalArgumentException("octet string out of range");
+ }
+
+ return Arrays.clone(octets);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ValidityPeriod.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ValidityPeriod.java
new file mode 100644
index 00000000..e062e0ca
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/ValidityPeriod.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+
+/**
+ * <pre>
+ * ValidityPeriod ::= SEQUENCE {
+ * start Time32,
+ * duration Duration
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ValidityPeriod
+ extends ASN1Object
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ return new DERSequence(v);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/VerificationKeyIndicator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/VerificationKeyIndicator.java
new file mode 100644
index 00000000..bbab2d6c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/its/asn1/VerificationKeyIndicator.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.its.asn1;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * <pre>
+ * VerificationKeyIndicator ::= CHOICE {
+ * verificationKey PublicVerificationKey,
+ * reconstructionValue EccP256CurvePoint,
+ * ...
+ * }
+ * </pre>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class VerificationKeyIndicator
+ extends ASN1Object
+ implements ASN1Choice
+{
+ public ASN1Primitive toASN1Primitive()
+ {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePrivateKey.java
new file mode 100644
index 00000000..594a05b4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePrivateKey.java
@@ -0,0 +1,105 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import java.io.IOException;
+import java.security.PrivateKey;
+import java.util.ArrayList;
+import java.util.Collections;
+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.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * A composite private key class.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CompositePrivateKey
+ implements PrivateKey
+{
+ private final List<PrivateKey> keys;
+
+ /**
+ * Create a composite key containing a single private key.
+ *
+ * @param keys the private keys the composite private key wraps.
+ */
+ public CompositePrivateKey(PrivateKey... keys)
+ {
+ if (keys == null || keys.length == 0)
+ {
+ throw new IllegalArgumentException("at least one public key must be provided");
+ }
+
+ List<PrivateKey> keyList = new ArrayList<PrivateKey>(keys.length);
+ for (int i = 0; i != keys.length; i++)
+ {
+ keyList.add(keys[i]);
+ }
+ this.keys = Collections.unmodifiableList(keyList);
+ }
+
+ /**
+ * Return a list of the component private keys making up this composite.
+ *
+ * @return an immutable list of private keys.
+ */
+ public List<PrivateKey> getPrivateKeys()
+ {
+ return keys;
+ }
+
+ public String getAlgorithm()
+ {
+ return "Composite";
+ }
+
+ public String getFormat()
+ {
+ return "PKCS#8";
+ }
+
+ public byte[] getEncoded()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (int i = 0; i != keys.size(); i++)
+ {
+ v.add(PrivateKeyInfo.getInstance(keys.get(i).getEncoded()));
+ }
+
+ try
+ {
+ return new PrivateKeyInfo(
+ new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to encode composite key: " + e.getMessage());
+ }
+ }
+
+ public int hashCode()
+ {
+ return keys.hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (o instanceof CompositePrivateKey)
+ {
+ return keys.equals(((CompositePrivateKey)o).keys);
+ }
+
+ return false;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePublicKey.java
new file mode 100644
index 00000000..e9af6e53
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/CompositePublicKey.java
@@ -0,0 +1,105 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import java.io.IOException;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.Collections;
+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.DERSequence;
+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;
+
+/**
+ * A composite key class.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CompositePublicKey
+ implements PublicKey
+{
+ private final List<PublicKey> keys;
+
+ /**
+ * Create a composite key containing a single public key.
+ *
+ * @param keys the public keys the composite key wraps.
+ */
+ public CompositePublicKey(PublicKey... keys)
+ {
+ if (keys == null || keys.length == 0)
+ {
+ throw new IllegalArgumentException("at least one public key must be provided");
+ }
+
+ List<PublicKey> keyList = new ArrayList<PublicKey>(keys.length);
+ for (int i = 0; i != keys.length; i++)
+ {
+ keyList.add(keys[i]);
+ }
+ this.keys = Collections.unmodifiableList(keyList);
+ }
+
+ /**
+ * Return a list of the component private keys making up this composite.
+ *
+ * @return an immutable list of private keys.
+ */
+ public List<PublicKey> getPublicKeys()
+ {
+ return keys;
+ }
+
+ public String getAlgorithm()
+ {
+ return "Composite";
+ }
+
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ public byte[] getEncoded()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (int i = 0; i != keys.size(); i++)
+ {
+ v.add(SubjectPublicKeyInfo.getInstance(keys.get(i).getEncoded()));
+ }
+
+ try
+ {
+ return new SubjectPublicKeyInfo(
+ new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite), new DERSequence(v)).getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to encode composite key: " + e.getMessage());
+ }
+ }
+
+ public int hashCode()
+ {
+ return keys.hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (o instanceof CompositePublicKey)
+ {
+ return keys.equals(((CompositePublicKey)o).keys);
+ }
+
+ return false;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PBKDFKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PBKDFKey.java
new file mode 100644
index 00000000..c3e1a0f5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PBKDFKey.java
@@ -0,0 +1,13 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import javax.crypto.SecretKey;
+
+/**
+ * Base interface for keys associated with various password based key derivation functions (PBKDF).
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PBKDFKey
+ extends SecretKey
+{
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKCS12Key.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKCS12Key.java
new file mode 100644
index 00000000..a6f6c710
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKCS12Key.java
@@ -0,0 +1,89 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import com.android.internal.org.bouncycastle.crypto.PBEParametersGenerator;
+
+/**
+ * A password based key for use with PKCS#12.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS12Key
+ implements PBKDFKey
+{
+ private final char[] password;
+ private final boolean useWrongZeroLengthConversion;
+ /**
+ * Basic constructor for a password based key - secret key generation parameters will be passed separately..
+ *
+ * @param password password to use.
+ */
+ public PKCS12Key(char[] password)
+ {
+ this(password, false);
+ }
+
+ /**
+ * Unfortunately there seems to be some confusion about how to handle zero length
+ * passwords.
+ *
+ * @param password password to use.
+ * @param useWrongZeroLengthConversion use the incorrect encoding approach (add pad bytes)
+ */
+ public PKCS12Key(char[] password, boolean useWrongZeroLengthConversion)
+ {
+ if (password == null)
+ {
+ password = new char[0];
+ }
+
+ this.password = new char[password.length];
+ this.useWrongZeroLengthConversion = useWrongZeroLengthConversion;
+
+ System.arraycopy(password, 0, this.password, 0, password.length);
+ }
+
+ /**
+ * Return a reference to the char[] array holding the password.
+ *
+ * @return a reference to the password array.
+ */
+ public char[] getPassword()
+ {
+ return password;
+ }
+
+ /**
+ * Return the password based key derivation function this key is for,
+ *
+ * @return the string "PKCS12"
+ */
+ public String getAlgorithm()
+ {
+ return "PKCS12";
+ }
+
+ /**
+ * Return the format encoding.
+ *
+ * @return the string "PKCS12", representing the char[] to byte[] conversion.
+ */
+ public String getFormat()
+ {
+ return "PKCS12";
+ }
+
+ /**
+ * Return the password converted to bytes.
+ *
+ * @return the password converted to a byte array.
+ */
+ public byte[] getEncoded()
+ {
+ if (useWrongZeroLengthConversion && password.length == 0)
+ {
+ return new byte[2];
+ }
+
+ return PBEParametersGenerator.PKCS12PasswordToBytes(password);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKCS12KeyWithParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKCS12KeyWithParameters.java
new file mode 100644
index 00000000..33dfa813
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKCS12KeyWithParameters.java
@@ -0,0 +1,71 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import javax.crypto.interfaces.PBEKey;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * A password based key for use with PKCS#12 with full PBE parameters.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS12KeyWithParameters
+ extends PKCS12Key
+ implements PBEKey
+{
+ private final byte[] salt;
+ private final int iterationCount;
+
+ /**
+ * Basic constructor for a password based key with generation parameters.
+ *
+ * @param password password to use.
+ * @param salt salt for generation algorithm
+ * @param iterationCount iteration count for generation algorithm.
+ */
+ public PKCS12KeyWithParameters(char[] password, byte[] salt, int iterationCount)
+ {
+ super(password);
+
+ this.salt = Arrays.clone(salt);
+ this.iterationCount = iterationCount;
+ }
+
+
+ /**
+ * Basic constructor for a password based key with generation parameters, specifying the wrong conversion for
+ * zero length passwords.
+ *
+ * @param password password to use.
+ * @param salt salt for generation algorithm
+ * @param iterationCount iteration count for generation algorithm.
+ * @param useWrongZeroLengthConversion use the incorrect encoding approach (add pad bytes)
+ */
+ public PKCS12KeyWithParameters(char[] password, boolean useWrongZeroLengthConversion, byte[] salt, int iterationCount)
+ {
+ super(password, useWrongZeroLengthConversion);
+
+ this.salt = Arrays.clone(salt);
+ this.iterationCount = iterationCount;
+ }
+
+ /**
+ * Return the salt to use in the key derivation function.
+ *
+ * @return the salt to use in the KDF.
+ */
+ public byte[] getSalt()
+ {
+ return salt;
+ }
+
+ /**
+ * Return the iteration count to use in the key derivation function.
+ *
+ * @return the iteration count to use in the KDF.
+ */
+ public int getIterationCount()
+ {
+ return iterationCount;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKCS12StoreParameter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKCS12StoreParameter.java
new file mode 100644
index 00000000..615cbbb1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKCS12StoreParameter.java
@@ -0,0 +1,64 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import java.io.OutputStream;
+import java.security.KeyStore;
+import java.security.KeyStore.LoadStoreParameter;
+import java.security.KeyStore.ProtectionParameter;
+
+/**
+ * LoadStoreParameter to allow for additional config with PKCS12 files.
+ * <p>
+ * Note: if you want a straight DER encoding of a PKCS#12 file you should use this.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS12StoreParameter
+ implements LoadStoreParameter
+{
+ private final OutputStream out;
+ private final ProtectionParameter protectionParameter;
+ private final boolean forDEREncoding;
+
+ public PKCS12StoreParameter(OutputStream out, char[] password)
+ {
+ this(out, password, false);
+ }
+
+ public PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter)
+ {
+ this(out, protectionParameter, false);
+ }
+
+ public PKCS12StoreParameter(OutputStream out, char[] password, boolean forDEREncoding)
+ {
+ this(out, new KeyStore.PasswordProtection(password), forDEREncoding);
+ }
+
+ public PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter, boolean forDEREncoding)
+ {
+ this.out = out;
+ this.protectionParameter = protectionParameter;
+ this.forDEREncoding = forDEREncoding;
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return out;
+ }
+
+ public ProtectionParameter getProtectionParameter()
+ {
+ return protectionParameter;
+ }
+
+ /**
+ * Return whether the KeyStore used with this parameter should be DER encoded on saving.
+ *
+ * @return true for straight DER encoding, false otherwise,
+ */
+ public boolean isForDEREncoding()
+ {
+ return forDEREncoding;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCRLStore.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCRLStore.java
new file mode 100644
index 00000000..add2781d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCRLStore.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import java.security.cert.CRL;
+import java.util.Collection;
+
+import com.android.internal.org.bouncycastle.util.Selector;
+import com.android.internal.org.bouncycastle.util.Store;
+import com.android.internal.org.bouncycastle.util.StoreException;
+
+/**
+ * Generic interface for a PKIX based CRL store.
+ *
+ * @param <T> the CRL type.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PKIXCRLStore<T extends CRL>
+ extends Store<T>
+{
+ /**
+ * Return the matches associated with the passed in selector.
+ *
+ * @param selector the selector defining the match criteria.
+ * @return a collection of matches with the selector, an empty selector if there are none.
+ * @throws StoreException in the event of an issue doing a match.
+ */
+ Collection<T> getMatches(Selector<T> selector)
+ throws StoreException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java
new file mode 100644
index 00000000..86c38259
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java
@@ -0,0 +1,350 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import java.math.BigInteger;
+import java.security.cert.CRL;
+import java.security.cert.CRLSelector;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLSelector;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Selector;
+
+/**
+ * This class is a Selector implementation for X.509 certificate revocation
+ * lists.
+ *
+ * @see com.android.internal.org.bouncycastle.util.Selector
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKIXCRLStoreSelector<T extends CRL>
+ implements Selector<T>
+{
+ /**
+ * Builder for a PKIXCRLStoreSelector.
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Builder
+ {
+ private final CRLSelector baseSelector;
+
+ private boolean deltaCRLIndicator = false;
+ private boolean completeCRLEnabled = false;
+ private BigInteger maxBaseCRLNumber = null;
+ private byte[] issuingDistributionPoint = null;
+ private boolean issuingDistributionPointEnabled = false;
+
+ /**
+ * Constructor initializing a builder with a CertSelector.
+ *
+ * @param crlSelector the CertSelector to copy the match details from.
+ */
+ public Builder(CRLSelector crlSelector)
+ {
+ this.baseSelector = (CRLSelector)crlSelector.clone();
+ }
+
+
+ /**
+ * If set to <code>true</code> only complete CRLs are returned.
+ * <p>
+ * {@link #setCompleteCRLEnabled(boolean)} and
+ * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other.
+ *
+ * @param completeCRLEnabled <code>true</code> if only complete CRLs
+ * should be returned.
+ */
+ public Builder setCompleteCRLEnabled(boolean completeCRLEnabled)
+ {
+ this.completeCRLEnabled = completeCRLEnabled;
+
+ return this;
+ }
+
+ /**
+ * If this is set to <code>true</code> the CRL reported contains the delta
+ * CRL indicator CRL extension.
+ * <p>
+ * {@link #setCompleteCRLEnabled(boolean)} and
+ * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other.
+ *
+ * @param deltaCRLIndicator <code>true</code> if the delta CRL indicator
+ * extension must be in the CRL.
+ */
+ public Builder setDeltaCRLIndicatorEnabled(boolean deltaCRLIndicator)
+ {
+ this.deltaCRLIndicator = deltaCRLIndicator;
+
+ return this;
+ }
+
+ /**
+ * Sets the maximum base CRL number. Setting to <code>null</code> disables
+ * this cheack.
+ * <p>
+ * This is only meaningful for delta CRLs. Complete CRLs must have a CRL
+ * number which is greater or equal than the base number of the
+ * corresponding CRL.
+ *
+ * @param maxBaseCRLNumber The maximum base CRL number to set.
+ */
+ public void setMaxBaseCRLNumber(BigInteger maxBaseCRLNumber)
+ {
+ this.maxBaseCRLNumber = maxBaseCRLNumber;
+ }
+
+ /**
+ * Enables or disables the issuing distribution point check.
+ *
+ * @param issuingDistributionPointEnabled <code>true</code> to enable the
+ * issuing distribution point check.
+ */
+ public void setIssuingDistributionPointEnabled(
+ boolean issuingDistributionPointEnabled)
+ {
+ this.issuingDistributionPointEnabled = issuingDistributionPointEnabled;
+ }
+
+ /**
+ * Sets the issuing distribution point.
+ * <p>
+ * The issuing distribution point extension is a CRL extension which
+ * identifies the scope and the distribution point of a CRL. The scope
+ * contains among others information about revocation reasons contained in
+ * the CRL. Delta CRLs and complete CRLs must have matching issuing
+ * distribution points.
+ * <p>
+ * The byte array is cloned to protect against subsequent modifications.
+ * <p>
+ * You must also enable or disable this criteria with
+ * {@link #setIssuingDistributionPointEnabled(boolean)}.
+ *
+ * @param issuingDistributionPoint The issuing distribution point to set.
+ * This is the DER encoded OCTET STRING extension value.
+ * @see #getIssuingDistributionPoint()
+ */
+ public void setIssuingDistributionPoint(byte[] issuingDistributionPoint)
+ {
+ this.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint);
+ }
+
+ /**
+ * Build a selector.
+ *
+ * @return a new PKIXCRLStoreSelector
+ */
+ public PKIXCRLStoreSelector<? extends CRL> build()
+ {
+ return new PKIXCRLStoreSelector(this);
+ }
+ }
+
+ private final CRLSelector baseSelector;
+ private final boolean deltaCRLIndicator;
+ private final boolean completeCRLEnabled;
+ private final BigInteger maxBaseCRLNumber;
+ private final byte[] issuingDistributionPoint;
+ private final boolean issuingDistributionPointEnabled;
+
+ private PKIXCRLStoreSelector(Builder baseBuilder)
+ {
+ this.baseSelector = baseBuilder.baseSelector;
+ this.deltaCRLIndicator = baseBuilder.deltaCRLIndicator;
+ this.completeCRLEnabled = baseBuilder.completeCRLEnabled;
+ this.maxBaseCRLNumber = baseBuilder.maxBaseCRLNumber;
+ this.issuingDistributionPoint = baseBuilder.issuingDistributionPoint;
+ this.issuingDistributionPointEnabled = baseBuilder.issuingDistributionPointEnabled;
+ }
+
+
+ /**
+ * Returns if the issuing distribution point criteria should be applied.
+ * Defaults to <code>false</code>.
+ * <p>
+ * You may also set the issuing distribution point criteria if not a missing
+ * issuing distribution point should be assumed.
+ *
+ * @return Returns if the issuing distribution point check is enabled.
+ */
+ public boolean isIssuingDistributionPointEnabled()
+ {
+ return issuingDistributionPointEnabled;
+ }
+
+
+
+ public boolean match(CRL obj)
+ {
+ if (!(obj instanceof X509CRL))
+ {
+ return baseSelector.match(obj);
+ }
+
+ X509CRL crl = (X509CRL)obj;
+ ASN1Integer dci = null;
+ try
+ {
+ byte[] bytes = crl
+ .getExtensionValue(Extension.deltaCRLIndicator.getId());
+ if (bytes != null)
+ {
+ dci = ASN1Integer.getInstance(ASN1OctetString.getInstance(bytes).getOctets());
+ }
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ if (isDeltaCRLIndicatorEnabled())
+ {
+ if (dci == null)
+ {
+ return false;
+ }
+ }
+ if (isCompleteCRLEnabled())
+ {
+ if (dci != null)
+ {
+ return false;
+ }
+ }
+ if (dci != null)
+ {
+
+ if (maxBaseCRLNumber != null)
+ {
+ if (dci.getPositiveValue().compareTo(maxBaseCRLNumber) == 1)
+ {
+ return false;
+ }
+ }
+ }
+ if (issuingDistributionPointEnabled)
+ {
+ byte[] idp = crl
+ .getExtensionValue(Extension.issuingDistributionPoint
+ .getId());
+ if (issuingDistributionPoint == null)
+ {
+ if (idp != null)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (!Arrays.areEqual(idp, issuingDistributionPoint))
+ {
+ return false;
+ }
+ }
+
+ }
+ return baseSelector.match(obj);
+ }
+
+ /**
+ * Returns if this selector must match CRLs with the delta CRL indicator
+ * extension set. Defaults to <code>false</code>.
+ *
+ * @return Returns <code>true</code> if only CRLs with the delta CRL
+ * indicator extension are selected.
+ */
+ public boolean isDeltaCRLIndicatorEnabled()
+ {
+ return deltaCRLIndicator;
+ }
+
+ public Object clone()
+ {
+ return this;
+ }
+
+ /**
+ * If <code>true</code> only complete CRLs are returned. Defaults to
+ * <code>false</code>.
+ *
+ * @return <code>true</code> if only complete CRLs are returned.
+ */
+ public boolean isCompleteCRLEnabled()
+ {
+ return completeCRLEnabled;
+ }
+
+ /**
+ * Get the maximum base CRL number. Defaults to <code>null</code>.
+ *
+ * @return Returns the maximum base CRL number.
+ */
+ public BigInteger getMaxBaseCRLNumber()
+ {
+ return maxBaseCRLNumber;
+ }
+
+
+ /**
+ * Returns the issuing distribution point. Defaults to <code>null</code>,
+ * which is a missing issuing distribution point extension.
+ * <p>
+ * The internal byte array is cloned before it is returned.
+ * <p>
+ * The criteria must be enable with Builder.setIssuingDistributionPointEnabled(boolean)}.
+ *
+ * @return Returns the issuing distribution point.
+ */
+ public byte[] getIssuingDistributionPoint()
+ {
+ return Arrays.clone(issuingDistributionPoint);
+ }
+
+ public X509Certificate getCertificateChecking()
+ {
+ if (baseSelector instanceof X509CRLSelector)
+ {
+ return ((X509CRLSelector)baseSelector).getCertificateChecking();
+ }
+
+ return null;
+ }
+
+ public static Collection<? extends CRL> getCRLs(final PKIXCRLStoreSelector selector, CertStore certStore)
+ throws CertStoreException
+ {
+ return certStore.getCRLs(new SelectorClone(selector));
+ }
+
+ private static class SelectorClone
+ extends X509CRLSelector
+ {
+ private final PKIXCRLStoreSelector selector;
+
+ SelectorClone(PKIXCRLStoreSelector selector)
+ {
+ this.selector = selector;
+
+ if (selector.baseSelector instanceof X509CRLSelector)
+ {
+ X509CRLSelector baseSelector = (X509CRLSelector)selector.baseSelector;
+
+ this.setCertificateChecking(baseSelector.getCertificateChecking());
+ this.setDateAndTime(baseSelector.getDateAndTime());
+ this.setIssuers(baseSelector.getIssuers());
+ this.setMinCRLNumber(baseSelector.getMinCRL());
+ this.setMaxCRLNumber(baseSelector.getMaxCRL());
+ }
+ }
+
+ public boolean match(CRL crl)
+ {
+ return (selector == null) ? (crl != null) : selector.match(crl);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertRevocationChecker.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertRevocationChecker.java
new file mode 100644
index 00000000..08539558
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertRevocationChecker.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.Certificate;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PKIXCertRevocationChecker
+{
+ void setParameter(String name, Object value);
+
+ void initialize(PKIXCertRevocationCheckerParameters params)
+ throws CertPathValidatorException;
+
+ void check(Certificate cert)
+ throws CertPathValidatorException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertRevocationCheckerParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertRevocationCheckerParameters.java
new file mode 100644
index 00000000..9588ecf7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertRevocationCheckerParameters.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import java.security.PublicKey;
+import java.security.cert.CertPath;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKIXCertRevocationCheckerParameters
+{
+ private final PKIXExtendedParameters paramsPKIX;
+ private final Date validDate;
+ private final CertPath certPath;
+ private final int index;
+ private final X509Certificate signingCert;
+ private final PublicKey workingPublicKey;
+
+ public PKIXCertRevocationCheckerParameters(PKIXExtendedParameters paramsPKIX, Date validDate, CertPath certPath, int index, X509Certificate signingCert, PublicKey workingPublicKey)
+ {
+ this.paramsPKIX = paramsPKIX;
+ this.validDate = validDate;
+ this.certPath = certPath;
+ this.index = index;
+ this.signingCert = signingCert;
+ this.workingPublicKey = workingPublicKey;
+ }
+
+ public PKIXExtendedParameters getParamsPKIX()
+ {
+ return paramsPKIX;
+ }
+
+ public Date getValidDate()
+ {
+ return new Date(validDate.getTime());
+ }
+
+ public CertPath getCertPath()
+ {
+ return certPath;
+ }
+
+ public int getIndex()
+ {
+ return index;
+ }
+
+ public X509Certificate getSigningCert()
+ {
+ return signingCert;
+ }
+
+ public PublicKey getWorkingPublicKey()
+ {
+ return workingPublicKey;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertStore.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertStore.java
new file mode 100644
index 00000000..113e098a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertStore.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import java.security.cert.Certificate;
+import java.util.Collection;
+
+import com.android.internal.org.bouncycastle.util.Selector;
+import com.android.internal.org.bouncycastle.util.Store;
+import com.android.internal.org.bouncycastle.util.StoreException;
+
+/**
+ * Generic interface for a PKIX based certificate store.
+ *
+ * @param <T> the certificate type.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PKIXCertStore<T extends Certificate>
+ extends Store<T>
+{
+ /**
+ * Return the matches associated with the passed in selector.
+ *
+ * @param selector the selector defining the match criteria.
+ * @return a collection of matches with the selector, an empty selector if there are none.
+ * @throws StoreException in the event of an issue doing a match.
+ */
+ Collection<T> getMatches(Selector<T> selector)
+ throws StoreException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertStoreSelector.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertStoreSelector.java
new file mode 100644
index 00000000..d0a75cdd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertStoreSelector.java
@@ -0,0 +1,137 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import java.io.IOException;
+import java.security.cert.CertSelector;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.X509CertSelector;
+import java.util.Collection;
+
+import com.android.internal.org.bouncycastle.util.Selector;
+
+/**
+ * This class is a Selector implementation for certificates.
+ *
+ * @see com.android.internal.org.bouncycastle.util.Selector
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKIXCertStoreSelector<T extends Certificate>
+ implements Selector<T>
+{
+ /**
+ * Builder for a PKIXCertStoreSelector.
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Builder
+ {
+ private final CertSelector baseSelector;
+
+ /**
+ * Constructor initializing a builder with a CertSelector.
+ *
+ * @param certSelector the CertSelector to copy the match details from.
+ */
+ public Builder(CertSelector certSelector)
+ {
+ this.baseSelector = (CertSelector)certSelector.clone();
+ }
+
+ /**
+ * Build a selector.
+ *
+ * @return a new PKIXCertStoreSelector
+ */
+ public PKIXCertStoreSelector<? extends Certificate> build()
+ {
+ return new PKIXCertStoreSelector(baseSelector);
+ }
+ }
+
+ private final CertSelector baseSelector;
+
+ private PKIXCertStoreSelector(CertSelector baseSelector)
+ {
+ this.baseSelector = baseSelector;
+ }
+
+ /**
+ * Return the specific certificate this selector is designed to match.
+ *
+ * @return a specific certificate where the selector has been configured explicitly.
+ */
+ public Certificate getCertificate()
+ {
+ if (baseSelector instanceof X509CertSelector)
+ {
+ return ((X509CertSelector)baseSelector).getCertificate();
+ }
+
+ return null;
+ }
+
+ public boolean match(Certificate cert)
+ {
+ return baseSelector.match(cert);
+ }
+
+ public Object clone()
+ {
+ return new PKIXCertStoreSelector(baseSelector);
+ }
+
+ public static Collection<? extends Certificate> getCertificates(final PKIXCertStoreSelector selector, CertStore certStore)
+ throws CertStoreException
+ {
+ return certStore.getCertificates(new SelectorClone(selector));
+ }
+
+ private static class SelectorClone
+ extends X509CertSelector
+ {
+ private final PKIXCertStoreSelector selector;
+
+ SelectorClone(PKIXCertStoreSelector selector)
+ {
+ this.selector = selector;
+
+ if (selector.baseSelector instanceof X509CertSelector)
+ {
+ X509CertSelector baseSelector = (X509CertSelector)selector.baseSelector;
+
+ this.setAuthorityKeyIdentifier(baseSelector.getAuthorityKeyIdentifier());
+ this.setBasicConstraints(baseSelector.getBasicConstraints());
+ this.setCertificate(baseSelector.getCertificate());
+ this.setCertificateValid(baseSelector.getCertificateValid());
+ this.setKeyUsage(baseSelector.getKeyUsage());
+ this.setMatchAllSubjectAltNames(baseSelector.getMatchAllSubjectAltNames());
+ this.setPrivateKeyValid(baseSelector.getPrivateKeyValid());
+ this.setSerialNumber(baseSelector.getSerialNumber());
+ this.setSubjectKeyIdentifier(baseSelector.getSubjectKeyIdentifier());
+ this.setSubjectPublicKey(baseSelector.getSubjectPublicKey());
+
+ try
+ {
+ this.setExtendedKeyUsage(baseSelector.getExtendedKeyUsage());
+ this.setIssuer(baseSelector.getIssuerAsBytes());
+ this.setNameConstraints(baseSelector.getNameConstraints());
+ this.setPathToNames(baseSelector.getPathToNames());
+ this.setPolicy(baseSelector.getPolicy());
+ this.setSubject(baseSelector.getSubjectAsBytes());
+ this.setSubjectAlternativeNames(baseSelector.getSubjectAlternativeNames());
+ this.setSubjectPublicKeyAlgID(baseSelector.getSubjectPublicKeyAlgID());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("base selector invalid: " + e.getMessage(), e);
+ }
+ }
+ }
+
+ public boolean match(Certificate certificate)
+ {
+ return (selector == null) ? (certificate != null) : selector.match(certificate);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXExtendedBuilderParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXExtendedBuilderParameters.java
new file mode 100644
index 00000000..9708b7e8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXExtendedBuilderParameters.java
@@ -0,0 +1,144 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import java.security.InvalidParameterException;
+import java.security.cert.CertPathParameters;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This class contains extended parameters for PKIX certification path builders.
+ *
+ * @see PKIXBuilderParameters
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKIXExtendedBuilderParameters
+ implements CertPathParameters
+{
+ /**
+ * Builder for a PKIXExtendedBuilderParameters object.
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Builder
+ {
+ private final PKIXExtendedParameters baseParameters;
+
+ private int maxPathLength = 5;
+ private Set<X509Certificate> excludedCerts = new HashSet<X509Certificate>();
+
+ public Builder(PKIXBuilderParameters baseParameters)
+ {
+ this.baseParameters = new PKIXExtendedParameters.Builder(baseParameters).build();
+ this.maxPathLength = baseParameters.getMaxPathLength();
+ }
+
+ public Builder(PKIXExtendedParameters baseParameters)
+ {
+ this.baseParameters = baseParameters;
+ }
+
+ /**
+ * Adds excluded certificates which are not used for building a
+ * certification path.
+ * <p>
+ * The given set is cloned to protect it against subsequent modifications.
+ *
+ * @param excludedCerts The excluded certificates to set.
+ */
+ public Builder addExcludedCerts(Set<X509Certificate> excludedCerts)
+ {
+ this.excludedCerts.addAll(excludedCerts);
+
+ return this;
+ }
+
+ /**
+ * Sets the maximum number of intermediate non-self-issued certificates in a
+ * certification path. The PKIX <code>CertPathBuilder</code> must not
+ * build paths longer then this length.
+ * <p>
+ * A value of 0 implies that the path can only contain a single certificate.
+ * A value of -1 does not limit the length. The default length is 5.
+ *
+ * <p>
+ *
+ * The basic constraints extension of a CA certificate overrides this value
+ * if smaller.
+ *
+ * @param maxPathLength the maximum number of non-self-issued intermediate
+ * certificates in the certification path
+ * @throws InvalidParameterException if <code>maxPathLength</code> is set
+ * to a value less than -1
+ *
+ * @see #getMaxPathLength
+ */
+ public Builder setMaxPathLength(int maxPathLength)
+ {
+ if (maxPathLength < -1)
+ {
+ throw new InvalidParameterException("The maximum path "
+ + "length parameter can not be less than -1.");
+ }
+ this.maxPathLength = maxPathLength;
+
+ return this;
+ }
+
+ public PKIXExtendedBuilderParameters build()
+ {
+ return new PKIXExtendedBuilderParameters(this);
+ }
+ }
+
+ private final PKIXExtendedParameters baseParameters;
+ private final Set<X509Certificate> excludedCerts;
+ private final int maxPathLength;
+
+ private PKIXExtendedBuilderParameters(Builder builder)
+ {
+ this.baseParameters = builder.baseParameters;
+ this.excludedCerts = Collections.unmodifiableSet(builder.excludedCerts);
+ this.maxPathLength = builder.maxPathLength;
+ }
+
+ public PKIXExtendedParameters getBaseParameters()
+ {
+ return baseParameters;
+ }
+
+ /**
+ * Excluded certificates are not used for building a certification path.
+ * <p>
+ * The returned set is immutable.
+ *
+ * @return Returns the excluded certificates.
+ */
+ public Set getExcludedCerts()
+ {
+ return excludedCerts;
+ }
+
+ /**
+ * Returns the value of the maximum number of intermediate non-self-issued
+ * certificates in the certification path.
+ *
+ * @return the maximum number of non-self-issued intermediate certificates
+ * in the certification path, or -1 if no limit exists.
+ */
+ public int getMaxPathLength()
+ {
+ return maxPathLength;
+ }
+
+ /**
+ * @return this object
+ */
+ public Object clone()
+ {
+ return this;
+ }
+}
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXExtendedParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXExtendedParameters.java
new file mode 100644
index 00000000..ab85a390
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXExtendedParameters.java
@@ -0,0 +1,356 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce;
+
+import java.security.cert.CertPathParameters;
+import java.security.cert.CertSelector;
+import java.security.cert.CertStore;
+import java.security.cert.PKIXParameters;
+import java.security.cert.TrustAnchor;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralName;
+
+/**
+ * This class extends the PKIXParameters with a validity model parameter.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKIXExtendedParameters
+ implements CertPathParameters
+{
+ /**
+ * This is the default PKIX validity model. Actually there are two variants of this: The PKIX
+ * model and the modified PKIX model. The PKIX model verifies that all involved certificates
+ * must have been valid at the current time. The modified PKIX model verifies that all involved
+ * certificates were valid at the signing time. Both are indirectly chosen with the
+ * {@link PKIXParameters#setDate(Date)} method, so this methods sets the Date when <em>all</em>
+ * certificates must have been valid.
+ */
+ public static final int PKIX_VALIDITY_MODEL = 0;
+
+ /**
+ * This model uses the following validity model. Each certificate must have been valid at the
+ * moment when it was used. That means the end certificate must have been valid at the time the
+ * signature was done. The CA certificate which signed the end certificate must have been valid,
+ * when the end certificate was signed. The CA (or Root CA) certificate must have been valid
+ * when the CA certificate was signed, and so on. So the {@link PKIXParameters#setDate(Date)}
+ * method sets the time, when the <em>end certificate</em> must have been valid. It is used e.g.
+ * in the German signature law.
+ */
+ public static final int CHAIN_VALIDITY_MODEL = 1;
+
+ /**
+ * Builder for a PKIXExtendedParameters object.
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Builder
+ {
+ private final PKIXParameters baseParameters;
+ private final Date validityDate;
+ private final Date date;
+
+ private PKIXCertStoreSelector targetConstraints;
+ private List<PKIXCertStore> extraCertStores = new ArrayList<PKIXCertStore>();
+ private Map<GeneralName, PKIXCertStore> namedCertificateStoreMap = new HashMap<GeneralName, PKIXCertStore>();
+ private List<PKIXCRLStore> extraCRLStores = new ArrayList<PKIXCRLStore>();
+ private Map<GeneralName, PKIXCRLStore> namedCRLStoreMap = new HashMap<GeneralName, PKIXCRLStore>();
+ private boolean revocationEnabled;
+ private int validityModel = PKIX_VALIDITY_MODEL;
+ private boolean useDeltas = false;
+ private Set<TrustAnchor> trustAnchors;
+
+ public Builder(PKIXParameters baseParameters)
+ {
+ this.baseParameters = (PKIXParameters)baseParameters.clone();
+ CertSelector constraints = baseParameters.getTargetCertConstraints();
+ if (constraints != null)
+ {
+ this.targetConstraints = new PKIXCertStoreSelector.Builder(constraints).build();
+ }
+ this.validityDate = baseParameters.getDate();
+ this.date = (validityDate == null) ? new Date() : validityDate;
+ this.revocationEnabled = baseParameters.isRevocationEnabled();
+ this.trustAnchors = baseParameters.getTrustAnchors();
+ }
+
+ public Builder(PKIXExtendedParameters baseParameters)
+ {
+ this.baseParameters = baseParameters.baseParameters;
+ this.validityDate = baseParameters.validityDate;
+ this.date = baseParameters.date;
+ this.targetConstraints = baseParameters.targetConstraints;
+ this.extraCertStores = new ArrayList<PKIXCertStore>(baseParameters.extraCertStores);
+ this.namedCertificateStoreMap = new HashMap<GeneralName, PKIXCertStore>(baseParameters.namedCertificateStoreMap);
+ this.extraCRLStores = new ArrayList<PKIXCRLStore>(baseParameters.extraCRLStores);
+ this.namedCRLStoreMap = new HashMap<GeneralName, PKIXCRLStore>(baseParameters.namedCRLStoreMap);
+ this.useDeltas = baseParameters.useDeltas;
+ this.validityModel = baseParameters.validityModel;
+ this.revocationEnabled = baseParameters.isRevocationEnabled();
+ this.trustAnchors = baseParameters.getTrustAnchors();
+ }
+
+ public Builder addCertificateStore(PKIXCertStore store)
+ {
+ extraCertStores.add(store);
+
+ return this;
+ }
+
+ public Builder addNamedCertificateStore(GeneralName issuerAltName, PKIXCertStore store)
+ {
+ namedCertificateStoreMap.put(issuerAltName, store);
+
+ return this;
+ }
+
+ public Builder addCRLStore(PKIXCRLStore store)
+ {
+ extraCRLStores.add(store);
+
+ return this;
+ }
+
+ public Builder addNamedCRLStore(GeneralName issuerAltName, PKIXCRLStore store)
+ {
+ namedCRLStoreMap.put(issuerAltName, store);
+
+ return this;
+ }
+
+ public Builder setTargetConstraints(PKIXCertStoreSelector selector)
+ {
+ targetConstraints = selector;
+
+ return this;
+ }
+
+ /**
+ * Sets if delta CRLs should be used for checking the revocation status.
+ *
+ * @param useDeltas <code>true</code> if delta CRLs should be used.
+ */
+ public Builder setUseDeltasEnabled(boolean useDeltas)
+ {
+ this.useDeltas = useDeltas;
+
+ return this;
+ }
+
+ /**
+ * @param validityModel The validity model to set.
+ * @see #CHAIN_VALIDITY_MODEL
+ * @see #PKIX_VALIDITY_MODEL
+ */
+ public Builder setValidityModel(int validityModel)
+ {
+ this.validityModel = validityModel;
+
+ return this;
+ }
+
+ /**
+ * Set the trustAnchor to be used with these parameters.
+ *
+ * @param trustAnchor the trust anchor end-entity and CRLs must be based on.
+ * @return the current builder.
+ */
+ public Builder setTrustAnchor(TrustAnchor trustAnchor)
+ {
+ this.trustAnchors = Collections.singleton(trustAnchor);
+
+ return this;
+ }
+
+ /**
+ * Set the set of trustAnchors to be used with these parameters.
+ *
+ * @param trustAnchors a set of trustAnchors, one of which a particular end-entity and it's associated CRLs must be based on.
+ * @return the current builder.
+ */
+ public Builder setTrustAnchors(Set<TrustAnchor> trustAnchors)
+ {
+ this.trustAnchors = trustAnchors;
+
+ return this;
+ }
+
+ /**
+ * Flag whether or not revocation checking is to be enabled.
+ *
+ * @param revocationEnabled true if revocation checking to be enabled, false otherwise.
+ */
+ public void setRevocationEnabled(boolean revocationEnabled)
+ {
+ this.revocationEnabled = revocationEnabled;
+ }
+
+ public PKIXExtendedParameters build()
+ {
+ return new PKIXExtendedParameters(this);
+ }
+ }
+
+ private final PKIXParameters baseParameters;
+ private final PKIXCertStoreSelector targetConstraints;
+ private final Date validityDate;
+ private final Date date;
+ private final List<PKIXCertStore> extraCertStores;
+ private final Map<GeneralName, PKIXCertStore> namedCertificateStoreMap;
+ private final List<PKIXCRLStore> extraCRLStores;
+ private final Map<GeneralName, PKIXCRLStore> namedCRLStoreMap;
+ private final boolean revocationEnabled;
+ private final boolean useDeltas;
+ private final int validityModel;
+ private final Set<TrustAnchor> trustAnchors;
+
+ private PKIXExtendedParameters(Builder builder)
+ {
+ this.baseParameters = builder.baseParameters;
+ this.validityDate = builder.validityDate;
+ this.date = builder.date;
+ this.extraCertStores = Collections.unmodifiableList(builder.extraCertStores);
+ this.namedCertificateStoreMap = Collections.unmodifiableMap(new HashMap<GeneralName, PKIXCertStore>(builder.namedCertificateStoreMap));
+ this.extraCRLStores = Collections.unmodifiableList(builder.extraCRLStores);
+ this.namedCRLStoreMap = Collections.unmodifiableMap(new HashMap<GeneralName, PKIXCRLStore>(builder.namedCRLStoreMap));
+ this.targetConstraints = builder.targetConstraints;
+ this.revocationEnabled = builder.revocationEnabled;
+ this.useDeltas = builder.useDeltas;
+ this.validityModel = builder.validityModel;
+ this.trustAnchors = Collections.unmodifiableSet(builder.trustAnchors);
+ }
+
+ public List<PKIXCertStore> getCertificateStores()
+ {
+ return extraCertStores;
+ }
+
+
+ public Map<GeneralName, PKIXCertStore> getNamedCertificateStoreMap()
+ {
+ return namedCertificateStoreMap;
+ }
+
+ public List<PKIXCRLStore> getCRLStores()
+ {
+ return extraCRLStores;
+ }
+
+ public Map<GeneralName, PKIXCRLStore> getNamedCRLStoreMap()
+ {
+ return namedCRLStoreMap;
+ }
+
+ /**
+ * Returns the time at which to check the validity of the certification path. If {@code null},
+ * the current time is used.
+ *
+ * @return the {@code Date}, or {@code null} if not set
+ */
+ public Date getValidityDate()
+ {
+ return null == validityDate ? null : new Date(validityDate.getTime());
+ }
+
+ /**
+ * @deprecated Use 'getValidityDate' instead (which can return null).
+ */
+ public Date getDate()
+ {
+ return new Date(date.getTime());
+ }
+
+ /**
+ * Defaults to <code>false</code>.
+ *
+ * @return Returns if delta CRLs should be used.
+ */
+ public boolean isUseDeltasEnabled()
+ {
+ return useDeltas;
+ }
+
+ /**
+ * @return Returns the validity model.
+ * @see #CHAIN_VALIDITY_MODEL
+ * @see #PKIX_VALIDITY_MODEL
+ */
+ public int getValidityModel()
+ {
+ return validityModel;
+ }
+
+ public Object clone()
+ {
+ return this;
+ }
+
+ /**
+ * Returns the required constraints on the target certificate.
+ * The constraints are returned as an instance of
+ * <code>Selector</code>. If <code>null</code>, no constraints are
+ * defined.
+ *
+ * @return a <code>Selector</code> specifying the constraints on the
+ * target certificate or attribute certificate (or <code>null</code>)
+ * @see PKIXCertStoreSelector
+ */
+ public PKIXCertStoreSelector getTargetConstraints()
+ {
+ return targetConstraints;
+ }
+
+ public Set getTrustAnchors()
+ {
+ return trustAnchors;
+ }
+
+ public Set getInitialPolicies()
+ {
+ return baseParameters.getInitialPolicies();
+ }
+
+ public String getSigProvider()
+ {
+ return baseParameters.getSigProvider();
+ }
+
+ public boolean isExplicitPolicyRequired()
+ {
+ return baseParameters.isExplicitPolicyRequired();
+ }
+
+ public boolean isAnyPolicyInhibited()
+ {
+ return baseParameters.isAnyPolicyInhibited();
+ }
+
+ public boolean isPolicyMappingInhibited()
+ {
+ return baseParameters.isPolicyMappingInhibited();
+ }
+
+ public List getCertPathCheckers()
+ {
+ return baseParameters.getCertPathCheckers();
+ }
+
+ public List<CertStore> getCertStores()
+ {
+ return baseParameters.getCertStores();
+ }
+
+ public boolean isRevocationEnabled()
+ {
+ return revocationEnabled;
+ }
+
+ public boolean getPolicyQualifiersRejected()
+ {
+ return baseParameters.getPolicyQualifiersRejected();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/interfaces/BCX509Certificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/interfaces/BCX509Certificate.java
new file mode 100644
index 00000000..178ff26b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/interfaces/BCX509Certificate.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.interfaces;
+
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.TBSCertificate;
+
+/**
+ * Interface exposing some additional methods on a BC native certificate object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface BCX509Certificate
+{
+ /**
+ * Return the certificate issuer as an X500Name.
+ *
+ * @return the issuer.
+ */
+ X500Name getIssuerX500Name();
+
+ /**
+ * Return the ASN.1 class representing the TBSCertificate for this certificate.
+ *
+ * @return the issuer.
+ */
+ TBSCertificate getTBSCertificateNative();
+
+ /**
+ * Return the certificate subject as an X500Name.
+ *
+ * @return the issuer.
+ */
+ X500Name getSubjectX500Name();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/DigestUpdatingOutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/DigestUpdatingOutputStream.java
new file mode 100644
index 00000000..49233e44
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/DigestUpdatingOutputStream.java
@@ -0,0 +1,35 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.MessageDigest;
+
+class DigestUpdatingOutputStream
+ extends OutputStream
+{
+ private MessageDigest digest;
+
+ DigestUpdatingOutputStream(MessageDigest digest)
+ {
+ this.digest = digest;
+ }
+
+ public void write(byte[] bytes, int off, int len)
+ throws IOException
+ {
+ digest.update(bytes, off, len);
+ }
+
+ public void write(byte[] bytes)
+ throws IOException
+ {
+ digest.update(bytes);
+ }
+
+ public void write(int b)
+ throws IOException
+ {
+ digest.update((byte)b);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/MacUpdatingOutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/MacUpdatingOutputStream.java
new file mode 100644
index 00000000..49ab8d4e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/MacUpdatingOutputStream.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.crypto.Mac;
+
+class MacUpdatingOutputStream
+ extends OutputStream
+{
+ private Mac mac;
+
+ MacUpdatingOutputStream(Mac mac)
+ {
+ this.mac = mac;
+ }
+
+ public void write(byte[] bytes, int off, int len)
+ throws IOException
+ {
+ mac.update(bytes, off, len);
+ }
+
+ public void write(byte[] bytes)
+ throws IOException
+ {
+ mac.update(bytes);
+ }
+
+ public void write(int b)
+ throws IOException
+ {
+ mac.update((byte)b);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/OutputStreamFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/OutputStreamFactory.java
new file mode 100644
index 00000000..ea73d46f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/OutputStreamFactory.java
@@ -0,0 +1,48 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.io;
+
+import java.io.OutputStream;
+import java.security.MessageDigest;
+import java.security.Signature;
+
+import javax.crypto.Mac;
+
+/**
+ * Utility class for creating OutputStreams from different JCA/JCE operators.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OutputStreamFactory
+{
+ /**
+ * Create an OutputStream that wraps a signature.
+ *
+ * @param signature the signature to be updated as the stream is written to.
+ * @return an OutputStream.
+ */
+ public static OutputStream createStream(Signature signature)
+ {
+ return new SignatureUpdatingOutputStream(signature);
+ }
+
+ /**
+ * Create an OutputStream that wraps a digest.
+ *
+ * @param digest the digest to be updated as the stream is written to.
+ * @return an OutputStream.
+ */
+ public static OutputStream createStream(MessageDigest digest)
+ {
+ return new DigestUpdatingOutputStream(digest);
+ }
+
+ /**
+ * Create an OutputStream that wraps a mac.
+ *
+ * @param mac the signature to be updated as the stream is written to.
+ * @return an OutputStream.
+ */
+ public static OutputStream createStream(Mac mac)
+ {
+ return new MacUpdatingOutputStream(mac);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java
new file mode 100644
index 00000000..8127e4dd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/io/SignatureUpdatingOutputStream.java
@@ -0,0 +1,57 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.Signature;
+import java.security.SignatureException;
+
+class SignatureUpdatingOutputStream
+ extends OutputStream
+{
+ private Signature sig;
+
+ SignatureUpdatingOutputStream(Signature sig)
+ {
+ this.sig = sig;
+ }
+
+ public void write(byte[] bytes, int off, int len)
+ throws IOException
+ {
+ try
+ {
+ sig.update(bytes, off, len);
+ }
+ catch (SignatureException e)
+ {
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ public void write(byte[] bytes)
+ throws IOException
+ {
+ try
+ {
+ sig.update(bytes);
+ }
+ catch (SignatureException e)
+ {
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ public void write(int b)
+ throws IOException
+ {
+ try
+ {
+ sig.update((byte)b);
+ }
+ catch (SignatureException e)
+ {
+ throw new IOException(e.getMessage());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/DH.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/DH.java
new file mode 100644
index 00000000..3529d216
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/DH.java
@@ -0,0 +1,109 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dh.KeyFactorySpi;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DH
+{
+ private static final String PREFIX = "com.android.internal.org.bouncycastle.jcajce.provider.asymmetric" + ".dh.";
+
+ private static final Map<String, String> generalDhAttributes = new HashMap<String, String>();
+
+ static
+ {
+ generalDhAttributes.put("SupportedKeyClasses", "javax.crypto.interfaces.DHPublicKey|javax.crypto.interfaces.DHPrivateKey");
+ generalDhAttributes.put("SupportedKeyFormats", "PKCS#8|X.509");
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("KeyPairGenerator.DH", PREFIX + "KeyPairGeneratorSpi");
+ provider.addAlgorithm("Alg.Alias.KeyPairGenerator.DIFFIEHELLMAN", "DH");
+
+ provider.addAttributes("KeyAgreement.DH", generalDhAttributes);
+ provider.addAlgorithm("KeyAgreement.DH", PREFIX + "KeyAgreementSpi");
+ provider.addAlgorithm("Alg.Alias.KeyAgreement.DIFFIEHELLMAN", "DH");
+ // BEGIN Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("KeyAgreement", PKCSObjectIdentifiers.id_alg_ESDH, PREFIX + "KeyAgreementSpi$DHwithRFC2631KDF");
+ // provider.addAlgorithm("KeyAgreement", PKCSObjectIdentifiers.id_alg_SSDH, PREFIX + "KeyAgreementSpi$DHwithRFC2631KDF");
+ // END Android-removed: Unsupported algorithms
+
+ provider.addAlgorithm("KeyFactory.DH", PREFIX + "KeyFactorySpi");
+ provider.addAlgorithm("Alg.Alias.KeyFactory.DIFFIEHELLMAN", "DH");
+
+ provider.addAlgorithm("AlgorithmParameters.DH", PREFIX + "AlgorithmParametersSpi");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.DIFFIEHELLMAN", "DH");
+
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator.DIFFIEHELLMAN", "DH");
+
+ provider.addAlgorithm("AlgorithmParameterGenerator.DH", PREFIX + "AlgorithmParameterGeneratorSpi");
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("Cipher.IES", PREFIX + "IESCipher$IES");
+ provider.addAlgorithm("Cipher.IESwithAES-CBC", PREFIX + "IESCipher$IESwithAESCBC");
+ provider.addAlgorithm("Cipher.IESWITHAES-CBC", PREFIX + "IESCipher$IESwithAESCBC");
+ provider.addAlgorithm("Cipher.IESWITHDESEDE-CBC", PREFIX + "IESCipher$IESwithDESedeCBC");
+
+ provider.addAlgorithm("Cipher.DHIES", PREFIX + "IESCipher$IES");
+ provider.addAlgorithm("Cipher.DHIESwithAES-CBC", PREFIX + "IESCipher$IESwithAESCBC");
+ provider.addAlgorithm("Cipher.DHIESWITHAES-CBC", PREFIX + "IESCipher$IESwithAESCBC");
+ provider.addAlgorithm("Cipher.DHIESWITHDESEDE-CBC", PREFIX + "IESCipher$IESwithDESedeCBC");
+
+ provider.addAlgorithm("KeyAgreement.DHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHwithSHA1KDF");
+ provider.addAlgorithm("KeyAgreement.DHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHwithSHA224KDF");
+ provider.addAlgorithm("KeyAgreement.DHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHwithSHA256KDF");
+ provider.addAlgorithm("KeyAgreement.DHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHwithSHA384KDF");
+ provider.addAlgorithm("KeyAgreement.DHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHwithSHA512KDF");
+
+ provider.addAlgorithm("KeyAgreement.DHUWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1KDF");
+ provider.addAlgorithm("KeyAgreement.DHUWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224KDF");
+ provider.addAlgorithm("KeyAgreement.DHUWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256KDF");
+ provider.addAlgorithm("KeyAgreement.DHUWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384KDF");
+ provider.addAlgorithm("KeyAgreement.DHUWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512KDF");
+
+ provider.addAlgorithm("KeyAgreement.DHUWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1CKDF");
+ provider.addAlgorithm("KeyAgreement.DHUWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224CKDF");
+ provider.addAlgorithm("KeyAgreement.DHUWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256CKDF");
+ provider.addAlgorithm("KeyAgreement.DHUWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384CKDF");
+ provider.addAlgorithm("KeyAgreement.DHUWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512CKDF");
+
+ provider.addAlgorithm("KeyAgreement.MQVWITHSHA1KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1KDF");
+ provider.addAlgorithm("KeyAgreement.MQVWITHSHA224KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224KDF");
+ provider.addAlgorithm("KeyAgreement.MQVWITHSHA256KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256KDF");
+ provider.addAlgorithm("KeyAgreement.MQVWITHSHA384KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384KDF");
+ provider.addAlgorithm("KeyAgreement.MQVWITHSHA512KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512KDF");
+
+ provider.addAlgorithm("KeyAgreement.MQVWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1CKDF");
+ provider.addAlgorithm("KeyAgreement.MQVWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224CKDF");
+ provider.addAlgorithm("KeyAgreement.MQVWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256CKDF");
+ provider.addAlgorithm("KeyAgreement.MQVWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384CKDF");
+ provider.addAlgorithm("KeyAgreement.MQVWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512CKDF");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ registerOid(provider, PKCSObjectIdentifiers.dhKeyAgreement, "DH", new KeyFactorySpi());
+ registerOid(provider, X9ObjectIdentifiers.dhpublicnumber, "DH", new KeyFactorySpi());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/DSA.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/DSA.java
new file mode 100644
index 00000000..869ed54a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/DSA.java
@@ -0,0 +1,107 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric;
+
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dsa.DSAUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dsa.KeyFactorySpi;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DSA
+{
+ private static final String PREFIX = "com.android.internal.org.bouncycastle.jcajce.provider.asymmetric" + ".dsa.";
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("AlgorithmParameters.DSA", PREFIX + "AlgorithmParametersSpi");
+
+ provider.addAlgorithm("AlgorithmParameterGenerator.DSA", PREFIX + "AlgorithmParameterGeneratorSpi");
+
+ provider.addAlgorithm("KeyPairGenerator.DSA", PREFIX + "KeyPairGeneratorSpi");
+ provider.addAlgorithm("KeyFactory.DSA", PREFIX + "KeyFactorySpi");
+
+ // BEGIN Android-changed: Change primary ID from DSA to SHA1withDSA
+ // provider.addAlgorithm("Signature.DSA", PREFIX + "DSASigner$stdDSA");
+ provider.addAlgorithm("Signature.SHA1withDSA", PREFIX + "DSASigner$stdDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.DSA", "SHA1withDSA");
+ // END Android-changed: Change primary ID from DSA to SHA1withDSA
+ provider.addAlgorithm("Signature.NONEWITHDSA", PREFIX + "DSASigner$noneDSA");
+
+ provider.addAlgorithm("Alg.Alias.Signature.RAWDSA", "NONEWITHDSA");
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("Signature.DETDSA", PREFIX + "DSASigner$detDSA");
+ provider.addAlgorithm("Signature.SHA1WITHDETDSA", PREFIX + "DSASigner$detDSA");
+ provider.addAlgorithm("Signature.SHA224WITHDETDSA", PREFIX + "DSASigner$detDSA224");
+ provider.addAlgorithm("Signature.SHA256WITHDETDSA", PREFIX + "DSASigner$detDSA256");
+ provider.addAlgorithm("Signature.SHA384WITHDETDSA", PREFIX + "DSASigner$detDSA384");
+ provider.addAlgorithm("Signature.SHA512WITHDETDSA", PREFIX + "DSASigner$detDSA512");
+
+ provider.addAlgorithm("Signature.DDSA", PREFIX + "DSASigner$detDSA");
+ provider.addAlgorithm("Signature.SHA1WITHDDSA", PREFIX + "DSASigner$detDSA");
+ provider.addAlgorithm("Signature.SHA224WITHDDSA", PREFIX + "DSASigner$detDSA224");
+ provider.addAlgorithm("Signature.SHA256WITHDDSA", PREFIX + "DSASigner$detDSA256");
+ provider.addAlgorithm("Signature.SHA384WITHDDSA", PREFIX + "DSASigner$detDSA384");
+ provider.addAlgorithm("Signature.SHA512WITHDDSA", PREFIX + "DSASigner$detDSA512");
+ provider.addAlgorithm("Signature.SHA3-224WITHDDSA", PREFIX + "DSASigner$detDSASha3_224");
+ provider.addAlgorithm("Signature.SHA3-256WITHDDSA", PREFIX + "DSASigner$detDSASha3_256");
+ provider.addAlgorithm("Signature.SHA3-384WITHDDSA", PREFIX + "DSASigner$detDSASha3_384");
+ provider.addAlgorithm("Signature.SHA3-512WITHDDSA", PREFIX + "DSASigner$detDSASha3_512");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ addSignatureAlgorithm(provider, "SHA224", "DSA", PREFIX + "DSASigner$dsa224", NISTObjectIdentifiers.dsa_with_sha224);
+ addSignatureAlgorithm(provider, "SHA256", "DSA", PREFIX + "DSASigner$dsa256", NISTObjectIdentifiers.dsa_with_sha256);
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ addSignatureAlgorithm(provider, "SHA384", "DSA", PREFIX + "DSASigner$dsa384", NISTObjectIdentifiers.dsa_with_sha384);
+ addSignatureAlgorithm(provider, "SHA512", "DSA", PREFIX + "DSASigner$dsa512", NISTObjectIdentifiers.dsa_with_sha512);
+
+ addSignatureAlgorithm(provider, "SHA3-224", "DSA", PREFIX + "DSASigner$dsaSha3_224", NISTObjectIdentifiers.id_dsa_with_sha3_224);
+ addSignatureAlgorithm(provider, "SHA3-256", "DSA", PREFIX + "DSASigner$dsaSha3_256", NISTObjectIdentifiers.id_dsa_with_sha3_256);
+ addSignatureAlgorithm(provider, "SHA3-384", "DSA", PREFIX + "DSASigner$dsaSha3_384", NISTObjectIdentifiers.id_dsa_with_sha3_384);
+ addSignatureAlgorithm(provider, "SHA3-512", "DSA", PREFIX + "DSASigner$dsaSha3_512", NISTObjectIdentifiers.id_dsa_with_sha3_512);
+ */
+ // END Android-removed: Unsupported algorithms
+
+ // BEGIN Android-changed: Change primary ID from DSA to SHA1withDSA
+ provider.addAlgorithm("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.SHA1withDSA", "SHA1withDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.SHA1WITHDSA", "SHA1withDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.10040.4.1", "SHA1withDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.10040.4.3", "SHA1withDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.DSAwithSHA1", "SHA1withDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.DSAWITHSHA1", "SHA1withDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.SHA1WithDSA", "SHA1withDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.DSAWithSHA1", "SHA1withDSA");
+ // END Android-changed: Change primary ID from DSA to SHA1withDSA
+
+ AsymmetricKeyInfoConverter keyFact = new KeyFactorySpi();
+
+ for (int i = 0; i != DSAUtil.dsaOids.length; i++)
+ {
+ // BEGIN Android-changed: Change primary ID from DSA to SHA1withDSA
+ provider.addAlgorithm("Alg.Alias.Signature." + DSAUtil.dsaOids[i], "SHA1withDSA");
+ // END Android-changed: Change primary ID from DSA to SHA1withDSA
+
+ registerOid(provider, DSAUtil.dsaOids[i], "DSA", keyFact);
+ registerOidAlgorithmParameterGenerator(provider, DSAUtil.dsaOids[i], "DSA");
+ }
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/EC.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/EC.java
new file mode 100644
index 00000000..fa92c48c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/EC.java
@@ -0,0 +1,285 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric;
+
+import java.util.HashMap;
+import java.util.Map;
+
+// BEGIN Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
+// import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+// import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
+// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+// END Android-removed: Unsupported algorithms
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+// BEGIN Android-removed: Unsupported algorithms
+// import org.bouncycastle.util.Properties;
+// END Android-removed: Unsupported algorithms
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EC
+{
+ private static final String PREFIX = "com.android.internal.org.bouncycastle.jcajce.provider.asymmetric" + ".ec.";
+
+ private static final Map<String, String> generalEcAttributes = new HashMap<String, String>();
+
+ static
+ {
+ generalEcAttributes.put("SupportedKeyClasses", "java.security.interfaces.ECPublicKey|java.security.interfaces.ECPrivateKey");
+ generalEcAttributes.put("SupportedKeyFormats", "PKCS#8|X.509");
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("AlgorithmParameters.EC", PREFIX + "AlgorithmParametersSpi");
+
+ provider.addAttributes("KeyAgreement.ECDH", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECDH", PREFIX + "KeyAgreementSpi$DH");
+ provider.addAttributes("KeyAgreement.ECDHC", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECDHC", PREFIX + "KeyAgreementSpi$DHC");
+ provider.addAttributes("KeyAgreement.ECCDH", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDH", PREFIX + "KeyAgreementSpi$DHC");
+
+ provider.addAttributes("KeyAgreement.ECCDHU", generalEcAttributes);
+ provider.addAlgorithm("KeyAgreement.ECCDHU", PREFIX + "KeyAgreementSpi$DHUC");
+
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo");
+
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA224KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo");
+
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo");
+
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo");
+
+ provider.addAlgorithm("KeyAgreement.ECDHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512KDF", PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo");
+
+ provider.addAlgorithm("KeyAgreement", X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo");
+
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo");
+
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo");
+
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo");
+
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement", SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo");
+
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA1CKDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA256CKDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA384CKDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA512CKDF");
+
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1CKDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224CKDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256CKDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384CKDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512CKDF");
+
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA1KDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA224KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA224KDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA256KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA256KDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA384KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA384KDF");
+ provider.addAlgorithm("KeyAgreement.ECCDHUWITHSHA512KDF", PREFIX + "KeyAgreementSpi$DHUwithSHA512KDF");
+
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA1KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA1KDF");
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA224KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA224KDF");
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA256KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA256KDF");
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA384KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA384KDF");
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHSHA512KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithSHA512KDF");
+
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA1, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA1KDF");
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA224, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA224KDF");
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA256, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA256KDF");
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA384, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA384KDF");
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_SHA512, PREFIX + "KeyAgreementSpi$ECKAEGwithSHA512KDF");
+
+ provider.addAlgorithm("KeyAgreement", BSIObjectIdentifiers.ecka_eg_X963kdf_RIPEMD160, PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF");
+ provider.addAlgorithm("KeyAgreement.ECKAEGWITHRIPEMD160KDF", PREFIX + "KeyAgreementSpi$ECKAEGwithRIPEMD160KDF");
+
+ registerOid(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC", new KeyFactorySpi.EC());
+
+ registerOid(provider, X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC());
+ registerOid(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV());
+
+ registerOid(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme, "EC", new KeyFactorySpi.EC());
+ registerOid(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme, "EC", new KeyFactorySpi.EC());
+
+ registerOid(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme, "EC", new KeyFactorySpi.EC());
+ registerOid(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme, "EC", new KeyFactorySpi.EC());
+
+ registerOid(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme, "EC", new KeyFactorySpi.EC());
+ registerOid(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme, "EC", new KeyFactorySpi.EC());
+
+ registerOid(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme, "EC", new KeyFactorySpi.EC());
+ registerOid(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme, "EC", new KeyFactorySpi.EC());
+
+ registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC");
+
+ registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC");
+ registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, "EC");
+
+ registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme, "EC");
+ registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme, "EC");
+
+ registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme, "EC");
+ registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme, "EC");
+
+ registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme, "EC");
+ registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme, "EC");
+
+ registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme, "EC");
+ registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme, "EC");
+
+ if (!Properties.isOverrideSet("org.bouncycastle.ec.disable_mqv"))
+ {
+ provider.addAlgorithm("KeyAgreement.ECMQV", PREFIX + "KeyAgreementSpi$MQV");
+
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1CKDF");
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224CKDF");
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256CKDF");
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384CKDF");
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512CKDF");
+
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1KDF");
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224KDF");
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256KDF");
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384KDF");
+ provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512KDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512KDF");
+
+ provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA1KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA224KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA256KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA384KDFAndSharedInfo");
+ provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA512KDFAndSharedInfo");
+
+ registerOid(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC());
+
+ registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "EC");
+
+ registerOid(provider, SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV());
+ registerOidAlgorithmParameters(provider, SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, "EC");
+
+ registerOid(provider, SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV());
+ registerOidAlgorithmParameters(provider, SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, "EC");
+
+ registerOid(provider, SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV());
+ registerOidAlgorithmParameters(provider, SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, "EC");
+
+ registerOid(provider, SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV());
+ registerOidAlgorithmParameters(provider, SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, "EC");
+
+ provider.addAlgorithm("KeyFactory.ECMQV", PREFIX + "KeyFactorySpi$ECMQV");
+ provider.addAlgorithm("KeyPairGenerator.ECMQV", PREFIX + "KeyPairGeneratorSpi$ECMQV");
+ }
+
+ provider.addAlgorithm("KeyFactory.EC", PREFIX + "KeyFactorySpi$EC");
+ provider.addAlgorithm("KeyFactory.ECDSA", PREFIX + "KeyFactorySpi$ECDSA");
+ provider.addAlgorithm("KeyFactory.ECDH", PREFIX + "KeyFactorySpi$ECDH");
+ provider.addAlgorithm("KeyFactory.ECDHC", PREFIX + "KeyFactorySpi$ECDHC");
+
+ provider.addAlgorithm("KeyPairGenerator.EC", PREFIX + "KeyPairGeneratorSpi$EC");
+ provider.addAlgorithm("KeyPairGenerator.ECDSA", PREFIX + "KeyPairGeneratorSpi$ECDSA");
+ provider.addAlgorithm("KeyPairGenerator.ECDH", PREFIX + "KeyPairGeneratorSpi$ECDH");
+ provider.addAlgorithm("KeyPairGenerator.ECDHWITHSHA1KDF", PREFIX + "KeyPairGeneratorSpi$ECDH");
+ provider.addAlgorithm("KeyPairGenerator.ECDHC", PREFIX + "KeyPairGeneratorSpi$ECDHC");
+ provider.addAlgorithm("KeyPairGenerator.ECIES", PREFIX + "KeyPairGeneratorSpi$ECDH");
+
+ provider.addAlgorithm("Cipher.ECIES", PREFIX + "IESCipher$ECIES");
+
+ provider.addAlgorithm("Cipher.ECIESwithAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC");
+ provider.addAlgorithm("Cipher.ECIESWITHAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC");
+ provider.addAlgorithm("Cipher.ECIESwithDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC");
+ provider.addAlgorithm("Cipher.ECIESWITHDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC");
+
+ provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA");
+
+ provider.addAlgorithm("Signature.SHA1withECDSA", PREFIX + "SignatureSpi$ecDSA");
+ provider.addAlgorithm("Signature.NONEwithECDSA", PREFIX + "SignatureSpi$ecDSAnone");
+
+ provider.addAlgorithm("Alg.Alias.Signature.ECDSA", "SHA1withECDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.ECDSAwithSHA1", "SHA1withECDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.SHA1WITHECDSA", "SHA1withECDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.ECDSAWITHSHA1", "SHA1withECDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.SHA1WithECDSA", "SHA1withECDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.ECDSAWithSHA1", "SHA1withECDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.1.2.840.10045.4.1", "SHA1withECDSA");
+ provider.addAlgorithm("Alg.Alias.Signature." + TeleTrusTObjectIdentifiers.ecSignWithSha1, "ECDSA");
+
+ provider.addAlgorithm("Signature.ECDDSA", PREFIX + "SignatureSpi$ecDetDSA");
+ provider.addAlgorithm("Signature.SHA1WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA");
+ provider.addAlgorithm("Signature.SHA224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA224");
+ provider.addAlgorithm("Signature.SHA256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA256");
+ provider.addAlgorithm("Signature.SHA384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA384");
+ provider.addAlgorithm("Signature.SHA512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA512");
+ provider.addAlgorithm("Signature.SHA3-224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_224");
+ provider.addAlgorithm("Signature.SHA3-256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_256");
+ provider.addAlgorithm("Signature.SHA3-384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_384");
+ provider.addAlgorithm("Signature.SHA3-512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_512");
+
+ provider.addAlgorithm("Alg.Alias.Signature.DETECDSA", "ECDDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.SHA1WITHDETECDSA", "SHA1WITHECDDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.SHA224WITHDETECDSA", "SHA224WITHECDDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.SHA256WITHDETECDSA", "SHA256WITHECDDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.SHA384WITHDETECDSA", "SHA384WITHECDDSA");
+ provider.addAlgorithm("Alg.Alias.Signature.SHA512WITHDETECDSA", "SHA512WITHECDDSA");
+
+ addSignatureAlgorithm(provider, "SHA224", "ECDSA", PREFIX + "SignatureSpi$ecDSA224", X9ObjectIdentifiers.ecdsa_with_SHA224);
+ addSignatureAlgorithm(provider, "SHA256", "ECDSA", PREFIX + "SignatureSpi$ecDSA256", X9ObjectIdentifiers.ecdsa_with_SHA256);
+ addSignatureAlgorithm(provider, "SHA384", "ECDSA", PREFIX + "SignatureSpi$ecDSA384", X9ObjectIdentifiers.ecdsa_with_SHA384);
+ addSignatureAlgorithm(provider, "SHA512", "ECDSA", PREFIX + "SignatureSpi$ecDSA512", X9ObjectIdentifiers.ecdsa_with_SHA512);
+ addSignatureAlgorithm(provider, "SHA3-224", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_224", NISTObjectIdentifiers.id_ecdsa_with_sha3_224);
+ addSignatureAlgorithm(provider, "SHA3-256", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_256", NISTObjectIdentifiers.id_ecdsa_with_sha3_256);
+ addSignatureAlgorithm(provider, "SHA3-384", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_384", NISTObjectIdentifiers.id_ecdsa_with_sha3_384);
+ addSignatureAlgorithm(provider, "SHA3-512", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_512", NISTObjectIdentifiers.id_ecdsa_with_sha3_512);
+
+ addSignatureAlgorithm(provider, "RIPEMD160", "ECDSA", PREFIX + "SignatureSpi$ecDSARipeMD160",TeleTrusTObjectIdentifiers.ecSignWithRipemd160);
+
+ provider.addAlgorithm("Signature.SHA1WITHECNR", PREFIX + "SignatureSpi$ecNR");
+ provider.addAlgorithm("Signature.SHA224WITHECNR", PREFIX + "SignatureSpi$ecNR224");
+ provider.addAlgorithm("Signature.SHA256WITHECNR", PREFIX + "SignatureSpi$ecNR256");
+ provider.addAlgorithm("Signature.SHA384WITHECNR", PREFIX + "SignatureSpi$ecNR384");
+ provider.addAlgorithm("Signature.SHA512WITHECNR", PREFIX + "SignatureSpi$ecNR512");
+
+ addSignatureAlgorithm(provider, "SHA1", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1);
+ addSignatureAlgorithm(provider, "SHA224", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA224", EACObjectIdentifiers.id_TA_ECDSA_SHA_224);
+ addSignatureAlgorithm(provider, "SHA256", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA256", EACObjectIdentifiers.id_TA_ECDSA_SHA_256);
+ addSignatureAlgorithm(provider, "SHA384", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA384", EACObjectIdentifiers.id_TA_ECDSA_SHA_384);
+ addSignatureAlgorithm(provider, "SHA512", "CVC-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA512", EACObjectIdentifiers.id_TA_ECDSA_SHA_512);
+
+ addSignatureAlgorithm(provider, "SHA1", "PLAIN-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA", BSIObjectIdentifiers.ecdsa_plain_SHA1);
+ addSignatureAlgorithm(provider, "SHA224", "PLAIN-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA224", BSIObjectIdentifiers.ecdsa_plain_SHA224);
+ addSignatureAlgorithm(provider, "SHA256", "PLAIN-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA256", BSIObjectIdentifiers.ecdsa_plain_SHA256);
+ addSignatureAlgorithm(provider, "SHA384", "PLAIN-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA384", BSIObjectIdentifiers.ecdsa_plain_SHA384);
+ addSignatureAlgorithm(provider, "SHA512", "PLAIN-ECDSA", PREFIX + "SignatureSpi$ecCVCDSA512", BSIObjectIdentifiers.ecdsa_plain_SHA512);
+ addSignatureAlgorithm(provider, "RIPEMD160", "PLAIN-ECDSA", PREFIX + "SignatureSpi$ecPlainDSARP160", BSIObjectIdentifiers.ecdsa_plain_RIPEMD160);
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/RSA.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
new file mode 100644
index 00000000..40c585ec
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
@@ -0,0 +1,311 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+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.teletrust.TeleTrusTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RSA
+{
+ private static final String PREFIX = "com.android.internal.org.bouncycastle.jcajce.provider.asymmetric" + ".rsa.";
+
+ private static final Map<String, String> generalRsaAttributes = new HashMap<String, String>();
+
+ static
+ {
+ generalRsaAttributes.put("SupportedKeyClasses", "javax.crypto.interfaces.RSAPublicKey|javax.crypto.interfaces.RSAPrivateKey");
+ generalRsaAttributes.put("SupportedKeyFormats", "PKCS#8|X.509");
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("AlgorithmParameters.OAEP", PREFIX + "AlgorithmParametersSpi$OAEP");
+ provider.addAlgorithm("AlgorithmParameters.PSS", PREFIX + "AlgorithmParametersSpi$PSS");
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.RSAPSS", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.RSASSA-PSS", "PSS");
+
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA224withRSA/PSS", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA256withRSA/PSS", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA384withRSA/PSS", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA512withRSA/PSS", "PSS");
+
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA224WITHRSAANDMGF1", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA256WITHRSAANDMGF1", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA384WITHRSAANDMGF1", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA512WITHRSAANDMGF1", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA3-224WITHRSAANDMGF1", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA3-256WITHRSAANDMGF1", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA3-384WITHRSAANDMGF1", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA3-512WITHRSAANDMGF1", "PSS");
+
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.RAWRSAPSS", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.NONEWITHRSAPSS", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.NONEWITHRSASSA-PSS", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.NONEWITHRSAANDMGF1", "PSS");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ provider.addAttributes("Cipher.RSA", generalRsaAttributes);
+ provider.addAlgorithm("Cipher.RSA", PREFIX + "CipherSpi$NoPadding");
+ // Android-changed: Use an alias for RSA/RAW instead of a concrete implementation
+ provider.addAlgorithm("Alg.Alias.Cipher.RSA/RAW", "RSA");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("Cipher.RSA/PKCS1", PREFIX + "CipherSpi$PKCS1v1_5Padding");
+ provider.addAlgorithm("Cipher", PKCSObjectIdentifiers.rsaEncryption, PREFIX + "CipherSpi$PKCS1v1_5Padding");
+ provider.addAlgorithm("Cipher", X509ObjectIdentifiers.id_ea_rsa, PREFIX + "CipherSpi$PKCS1v1_5Padding");
+ provider.addAlgorithm("Cipher.RSA/1", PREFIX + "CipherSpi$PKCS1v1_5Padding_PrivateOnly");
+ provider.addAlgorithm("Cipher.RSA/2", PREFIX + "CipherSpi$PKCS1v1_5Padding_PublicOnly");
+ provider.addAlgorithm("Cipher.RSA/OAEP", PREFIX + "CipherSpi$OAEPPadding");
+ provider.addAlgorithm("Cipher", PKCSObjectIdentifiers.id_RSAES_OAEP, PREFIX + "CipherSpi$OAEPPadding");
+ provider.addAlgorithm("Cipher.RSA/ISO9796-1", PREFIX + "CipherSpi$ISO9796d1Padding");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ provider.addAlgorithm("Alg.Alias.Cipher.RSA//RAW", "RSA");
+ provider.addAlgorithm("Alg.Alias.Cipher.RSA//NOPADDING", "RSA");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("Alg.Alias.Cipher.RSA//PKCS1PADDING", "RSA/PKCS1");
+ provider.addAlgorithm("Alg.Alias.Cipher.RSA//OAEPPADDING", "RSA/OAEP");
+ provider.addAlgorithm("Alg.Alias.Cipher.RSA//ISO9796-1PADDING", "RSA/ISO9796-1");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ provider.addAlgorithm("KeyFactory.RSA", PREFIX + "KeyFactorySpi");
+ provider.addAlgorithm("KeyPairGenerator.RSA", PREFIX + "KeyPairGeneratorSpi");
+
+ // BEGIN Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("KeyFactory.RSASSA-PSS", PREFIX + "KeyFactorySpi");
+ // provider.addAlgorithm("KeyPairGenerator.RSASSA-PSS", PREFIX + "KeyPairGeneratorSpi$PSS");
+ // END Android-removed: Unsupported algorithms
+
+ AsymmetricKeyInfoConverter keyFact = new KeyFactorySpi();
+
+ registerOid(provider, PKCSObjectIdentifiers.rsaEncryption, "RSA", keyFact);
+ registerOid(provider, X509ObjectIdentifiers.id_ea_rsa, "RSA", keyFact);
+ registerOid(provider, PKCSObjectIdentifiers.id_RSAES_OAEP, "RSA", keyFact);
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ registerOid(provider, PKCSObjectIdentifiers.id_RSASSA_PSS, "RSA", keyFact);
+
+ registerOidAlgorithmParameters(provider, PKCSObjectIdentifiers.rsaEncryption, "RSA");
+ registerOidAlgorithmParameters(provider, X509ObjectIdentifiers.id_ea_rsa, "RSA");
+ registerOidAlgorithmParameters(provider, PKCSObjectIdentifiers.id_RSAES_OAEP, "OAEP");
+ registerOidAlgorithmParameters(provider, PKCSObjectIdentifiers.id_RSASSA_PSS, "PSS");
+
+ provider.addAlgorithm("Signature.RSASSA-PSS", PREFIX + "PSSSignatureSpi$PSSwithRSA");
+ provider.addAlgorithm("Signature." + PKCSObjectIdentifiers.id_RSASSA_PSS, PREFIX + "PSSSignatureSpi$PSSwithRSA");
+ provider.addAlgorithm("Signature.OID." + PKCSObjectIdentifiers.id_RSASSA_PSS, PREFIX + "PSSSignatureSpi$PSSwithRSA");
+
+ provider.addAlgorithm("Signature.RSA", PREFIX + "DigestSignatureSpi$noneRSA");
+ provider.addAlgorithm("Signature.RAWRSASSA-PSS", PREFIX + "PSSSignatureSpi$nonePSS");
+
+ provider.addAlgorithm("Alg.Alias.Signature.RAWRSA", "RSA");
+ provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSA", "RSA");
+ provider.addAlgorithm("Alg.Alias.Signature.RAWRSAPSS", "RAWRSASSA-PSS");
+ provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSAPSS", "RAWRSASSA-PSS");
+ provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSASSA-PSS", "RAWRSASSA-PSS");
+ provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSAANDMGF1", "RAWRSASSA-PSS");
+ provider.addAlgorithm("Alg.Alias.Signature.RSAPSS", "RSASSA-PSS");
+
+ addPSSSignature(provider, "SHA224", PREFIX + "PSSSignatureSpi$SHA224withRSA");
+ addPSSSignature(provider, "SHA256", PREFIX + "PSSSignatureSpi$SHA256withRSA");
+ addPSSSignature(provider, "SHA384", PREFIX + "PSSSignatureSpi$SHA384withRSA");
+ addPSSSignature(provider, "SHA512", PREFIX + "PSSSignatureSpi$SHA512withRSA");
+ addPSSSignature(provider, "SHA512(224)", PREFIX + "PSSSignatureSpi$SHA512_224withRSA");
+ addPSSSignature(provider, "SHA512(256)", PREFIX + "PSSSignatureSpi$SHA512_256withRSA");
+
+ addPSSSignature(provider, "SHA3-224", PREFIX + "PSSSignatureSpi$SHA3_224withRSA");
+ addPSSSignature(provider, "SHA3-256", PREFIX + "PSSSignatureSpi$SHA3_256withRSA");
+ addPSSSignature(provider, "SHA3-384", PREFIX + "PSSSignatureSpi$SHA3_384withRSA");
+ addPSSSignature(provider, "SHA3-512", PREFIX + "PSSSignatureSpi$SHA3_512withRSA");
+
+ if (provider.hasAlgorithm("MessageDigest", "MD2"))
+ {
+ addDigestSignature(provider, "MD2", PREFIX + "DigestSignatureSpi$MD2", PKCSObjectIdentifiers.md2WithRSAEncryption);
+ }
+
+ if (provider.hasAlgorithm("MessageDigest", "MD4"))
+ {
+ addDigestSignature(provider, "MD4", PREFIX + "DigestSignatureSpi$MD4", PKCSObjectIdentifiers.md4WithRSAEncryption);
+ }
+
+ if (provider.hasAlgorithm("MessageDigest", "MD5"))
+ {
+ addDigestSignature(provider, "MD5", PREFIX + "DigestSignatureSpi$MD5", PKCSObjectIdentifiers.md5WithRSAEncryption);
+ addISO9796Signature(provider, "MD5", PREFIX + "ISOSignatureSpi$MD5WithRSAEncryption");
+ }
+
+ if (provider.hasAlgorithm("MessageDigest", "SHA1"))
+ {
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1withRSA/PSS", "PSS");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1WITHRSAANDMGF1", "PSS");
+
+ addPSSSignature(provider, "SHA1", PREFIX + "PSSSignatureSpi$SHA1withRSA");
+ addDigestSignature(provider, "SHA1", PREFIX + "DigestSignatureSpi$SHA1", PKCSObjectIdentifiers.sha1WithRSAEncryption);
+ addISO9796Signature(provider, "SHA1", PREFIX + "ISOSignatureSpi$SHA1WithRSAEncryption");
+
+ provider.addAlgorithm("Alg.Alias.Signature." + OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
+
+ addX931Signature(provider, "SHA1", PREFIX + "X931SignatureSpi$SHA1WithRSAEncryption");
+ }
+
+ addDigestSignature(provider, "SHA224", PREFIX + "DigestSignatureSpi$SHA224", PKCSObjectIdentifiers.sha224WithRSAEncryption);
+ addDigestSignature(provider, "SHA256", PREFIX + "DigestSignatureSpi$SHA256", PKCSObjectIdentifiers.sha256WithRSAEncryption);
+ addDigestSignature(provider, "SHA384", PREFIX + "DigestSignatureSpi$SHA384", PKCSObjectIdentifiers.sha384WithRSAEncryption);
+ addDigestSignature(provider, "SHA512", PREFIX + "DigestSignatureSpi$SHA512", PKCSObjectIdentifiers.sha512WithRSAEncryption);
+ addDigestSignature(provider, "SHA512(224)", PREFIX + "DigestSignatureSpi$SHA512_224", PKCSObjectIdentifiers.sha512_224WithRSAEncryption);
+ addDigestSignature(provider, "SHA512(256)", PREFIX + "DigestSignatureSpi$SHA512_256", PKCSObjectIdentifiers.sha512_256WithRSAEncryption);
+
+ addDigestSignature(provider, "SHA3-224", PREFIX + "DigestSignatureSpi$SHA3_224", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224);
+ addDigestSignature(provider, "SHA3-256", PREFIX + "DigestSignatureSpi$SHA3_256", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256);
+ addDigestSignature(provider, "SHA3-384", PREFIX + "DigestSignatureSpi$SHA3_384", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384);
+ addDigestSignature(provider, "SHA3-512", PREFIX + "DigestSignatureSpi$SHA3_512", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512);
+
+ addISO9796Signature(provider, "SHA224", PREFIX + "ISOSignatureSpi$SHA224WithRSAEncryption");
+ addISO9796Signature(provider, "SHA256", PREFIX + "ISOSignatureSpi$SHA256WithRSAEncryption");
+ addISO9796Signature(provider, "SHA384", PREFIX + "ISOSignatureSpi$SHA384WithRSAEncryption");
+ addISO9796Signature(provider, "SHA512", PREFIX + "ISOSignatureSpi$SHA512WithRSAEncryption");
+ addISO9796Signature(provider, "SHA512(224)", PREFIX + "ISOSignatureSpi$SHA512_224WithRSAEncryption");
+ addISO9796Signature(provider, "SHA512(256)", PREFIX + "ISOSignatureSpi$SHA512_256WithRSAEncryption");
+
+ addX931Signature(provider, "SHA224", PREFIX + "X931SignatureSpi$SHA224WithRSAEncryption");
+ addX931Signature(provider, "SHA256", PREFIX + "X931SignatureSpi$SHA256WithRSAEncryption");
+ addX931Signature(provider, "SHA384", PREFIX + "X931SignatureSpi$SHA384WithRSAEncryption");
+ addX931Signature(provider, "SHA512", PREFIX + "X931SignatureSpi$SHA512WithRSAEncryption");
+ addX931Signature(provider, "SHA512(224)", PREFIX + "X931SignatureSpi$SHA512_224WithRSAEncryption");
+ addX931Signature(provider, "SHA512(256)", PREFIX + "X931SignatureSpi$SHA512_256WithRSAEncryption");
+
+ if (provider.hasAlgorithm("MessageDigest", "RIPEMD128"))
+ {
+ addDigestSignature(provider, "RIPEMD128", PREFIX + "DigestSignatureSpi$RIPEMD128", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
+ addDigestSignature(provider, "RMD128", PREFIX + "DigestSignatureSpi$RIPEMD128", null);
+
+ addX931Signature(provider, "RMD128", PREFIX + "X931SignatureSpi$RIPEMD128WithRSAEncryption");
+ addX931Signature(provider, "RIPEMD128", PREFIX + "X931SignatureSpi$RIPEMD128WithRSAEncryption");
+ }
+
+ if (provider.hasAlgorithm("MessageDigest", "RIPEMD160"))
+ {
+ addDigestSignature(provider, "RIPEMD160", PREFIX + "DigestSignatureSpi$RIPEMD160", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
+ addDigestSignature(provider, "RMD160", PREFIX + "DigestSignatureSpi$RIPEMD160", null);
+ provider.addAlgorithm("Alg.Alias.Signature.RIPEMD160WithRSA/ISO9796-2", "RIPEMD160withRSA/ISO9796-2");
+ provider.addAlgorithm("Signature.RIPEMD160withRSA/ISO9796-2", PREFIX + "ISOSignatureSpi$RIPEMD160WithRSAEncryption");
+
+ addX931Signature(provider, "RMD160", PREFIX + "X931SignatureSpi$RIPEMD160WithRSAEncryption");
+ addX931Signature(provider, "RIPEMD160", PREFIX + "X931SignatureSpi$RIPEMD160WithRSAEncryption");
+ }
+
+ if (provider.hasAlgorithm("MessageDigest", "RIPEMD256"))
+ {
+ addDigestSignature(provider, "RIPEMD256", PREFIX + "DigestSignatureSpi$RIPEMD256", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
+ addDigestSignature(provider, "RMD256", PREFIX + "DigestSignatureSpi$RIPEMD256", null);
+ }
+
+ if (provider.hasAlgorithm("MessageDigest", "WHIRLPOOL"))
+ {
+ addISO9796Signature(provider, "Whirlpool", PREFIX + "ISOSignatureSpi$WhirlpoolWithRSAEncryption");
+ addISO9796Signature(provider, "WHIRLPOOL", PREFIX + "ISOSignatureSpi$WhirlpoolWithRSAEncryption");
+ addX931Signature(provider, "Whirlpool", PREFIX + "X931SignatureSpi$WhirlpoolWithRSAEncryption");
+ addX931Signature(provider, "WHIRLPOOL", PREFIX + "X931SignatureSpi$WhirlpoolWithRSAEncryption");
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+
+ private void addDigestSignature(
+ ConfigurableProvider provider,
+ String digest,
+ String className,
+ ASN1ObjectIdentifier oid)
+ {
+ String mainName = digest + "WITHRSA";
+ String jdk11Variation1 = digest + "withRSA";
+ String jdk11Variation2 = digest + "WithRSA";
+ String alias = digest + "/" + "RSA";
+ String longName = digest + "WITHRSAENCRYPTION";
+ String longJdk11Variation1 = digest + "withRSAEncryption";
+ String longJdk11Variation2 = digest + "WithRSAEncryption";
+
+ provider.addAlgorithm("Signature." + mainName, className);
+ provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation1, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation2, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature." + longName, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature." + longJdk11Variation1, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature." + longJdk11Variation2, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature." + alias, mainName);
+
+ if (oid != null)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
+ }
+ }
+
+ private void addISO9796Signature(
+ ConfigurableProvider provider,
+ String digest,
+ String className)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/ISO9796-2", digest + "WITHRSA/ISO9796-2");
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/ISO9796-2", digest + "WITHRSA/ISO9796-2");
+ provider.addAlgorithm("Signature." + digest + "WITHRSA/ISO9796-2", className);
+ }
+
+ private void addPSSSignature(
+ ConfigurableProvider provider,
+ String digest,
+ String className)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/PSS", digest + "WITHRSAANDMGF1");
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/PSS", digest + "WITHRSAANDMGF1");
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSAandMGF1", digest + "WITHRSAANDMGF1");
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSAAndMGF1", digest + "WITHRSAANDMGF1");
+ // BEGIN Android-removed: unsupported algorithms
+ // provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSASSA-PSS", digest + "WITHRSAANDMGF1");
+ // provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSASSA-PSS", digest + "WITHRSAANDMGF1");
+ // provider.addAlgorithm("Alg.Alias.Signature." + digest + "WITHRSASSA-PSS", digest + "WITHRSAANDMGF1");
+ provider.addAlgorithm("Signature." + digest + "WITHRSAANDMGF1", className);
+ }
+
+ private void addX931Signature(
+ ConfigurableProvider provider,
+ String digest,
+ String className)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/X9.31", digest + "WITHRSA/X9.31");
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/X9.31", digest + "WITHRSA/X9.31");
+ provider.addAlgorithm("Signature." + digest + "WITHRSA/X9.31", className);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/X509.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/X509.java
new file mode 100644
index 00000000..88db097f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/X509.java
@@ -0,0 +1,40 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric;
+
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+
+/**
+ * For some reason the class path project thinks that such a KeyFactory will exist.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509
+{
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("KeyFactory.X.509", "org.bouncycastle.jcajce.provider.asymmetric.x509.KeyFactory");
+ provider.addAlgorithm("Alg.Alias.KeyFactory.X509", "X.509");
+
+ //
+ // certificate factories.
+ //
+ provider.addAlgorithm("CertificateFactory.X.509", "org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory");
+ provider.addAlgorithm("Alg.Alias.CertificateFactory.X509", "X.509");
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java
new file mode 100644
index 00000000..603c969d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java
@@ -0,0 +1,78 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dh;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.spec.DHGenParameterSpec;
+import javax.crypto.spec.DHParameterSpec;
+
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.generators.DHParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.BaseAlgorithmParameterGeneratorSpi;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PrimeCertaintyCalculator;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AlgorithmParameterGeneratorSpi
+ extends BaseAlgorithmParameterGeneratorSpi
+{
+ protected SecureRandom random;
+ protected int strength = 2048;
+
+ private int l = 0;
+
+ protected void engineInit(
+ int strength,
+ SecureRandom random)
+ {
+ this.strength = strength;
+ this.random = random;
+ }
+
+ protected void engineInit(
+ AlgorithmParameterSpec genParamSpec,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ if (!(genParamSpec instanceof DHGenParameterSpec))
+ {
+ throw new InvalidAlgorithmParameterException("DH parameter generator requires a DHGenParameterSpec for initialisation");
+ }
+ DHGenParameterSpec spec = (DHGenParameterSpec)genParamSpec;
+
+ this.strength = spec.getPrimeSize();
+ this.l = spec.getExponentSize();
+ this.random = random;
+ }
+
+ protected AlgorithmParameters engineGenerateParameters()
+ {
+ DHParametersGenerator pGen = new DHParametersGenerator();
+
+ int certainty = PrimeCertaintyCalculator.getDefaultCertainty(strength);
+
+ pGen.init(strength, certainty, CryptoServicesRegistrar.getSecureRandom(random));
+
+ DHParameters p = pGen.generateParameters();
+
+ AlgorithmParameters params;
+
+ try
+ {
+ params = createParametersInstance("DH");
+ params.init(new DHParameterSpec(p.getP(), p.getG(), l));
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.getMessage());
+ }
+
+ return params;
+ }
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParametersSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParametersSpi.java
new file mode 100644
index 00000000..d8d88834
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParametersSpi.java
@@ -0,0 +1,146 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dh;
+
+import java.io.IOException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import javax.crypto.spec.DHParameterSpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.pkcs.DHParameter;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AlgorithmParametersSpi
+ extends java.security.AlgorithmParametersSpi
+{
+ DHParameterSpec currentSpec;
+
+ protected boolean isASN1FormatString(String format)
+ {
+ return format == null || format.equals("ASN.1");
+ }
+
+ protected AlgorithmParameterSpec engineGetParameterSpec(
+ Class paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec == null)
+ {
+ throw new NullPointerException("argument to getParameterSpec must not be null");
+ }
+
+ return localEngineGetParameterSpec(paramSpec);
+ }
+
+
+
+
+ /**
+ * Return the PKCS#3 ASN.1 structure DHParameter.
+ * <p>
+ * <pre>
+ * DHParameter ::= SEQUENCE {
+ * prime INTEGER, -- p
+ * base INTEGER, -- g
+ * privateValueLength INTEGER OPTIONAL}
+ * </pre>
+ */
+ protected byte[] engineGetEncoded()
+ {
+ DHParameter dhP = new DHParameter(currentSpec.getP(), currentSpec.getG(), currentSpec.getL());
+
+ try
+ {
+ return dhP.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Error encoding DHParameters");
+ }
+ }
+
+ protected byte[] engineGetEncoded(
+ String format)
+ {
+ if (isASN1FormatString(format))
+ {
+ return engineGetEncoded();
+ }
+
+ return null;
+ }
+
+ protected AlgorithmParameterSpec localEngineGetParameterSpec(
+ Class paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec == DHParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
+ {
+ return currentSpec;
+ }
+
+ throw new InvalidParameterSpecException("unknown parameter spec passed to DH parameters object.");
+ }
+
+ protected void engineInit(
+ AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (!(paramSpec instanceof DHParameterSpec))
+ {
+ throw new InvalidParameterSpecException("DHParameterSpec required to initialise a Diffie-Hellman algorithm parameters object");
+ }
+
+ this.currentSpec = (DHParameterSpec)paramSpec;
+ }
+
+ protected void engineInit(
+ byte[] params)
+ throws IOException
+ {
+ try
+ {
+ DHParameter dhP = DHParameter.getInstance(params);
+
+ if (dhP.getL() != null)
+ {
+ currentSpec = new DHParameterSpec(dhP.getP(), dhP.getG(), dhP.getL().intValue());
+ }
+ else
+ {
+ currentSpec = new DHParameterSpec(dhP.getP(), dhP.getG());
+ }
+ }
+ catch (ClassCastException e)
+ {
+ throw new IOException("Not a valid DH Parameter encoding.");
+ }
+ catch (ArrayIndexOutOfBoundsException e)
+ {
+ throw new IOException("Not a valid DH Parameter encoding.");
+ }
+ }
+
+ protected void engineInit(
+ byte[] params,
+ String format)
+ throws IOException
+ {
+ if (isASN1FormatString(format))
+ {
+ engineInit(params);
+ }
+ else
+ {
+ throw new IOException("Unknown parameter format " + format);
+ }
+ }
+
+ protected String engineToString()
+ {
+ return "Diffie-Hellman Parameters";
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java
new file mode 100644
index 00000000..943380ca
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java
@@ -0,0 +1,271 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dh;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPrivateKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.pkcs.DHParameter;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x9.DomainParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.ValidationParams;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHValidationParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
+import com.android.internal.org.bouncycastle.jcajce.spec.DHDomainParameterSpec;
+import com.android.internal.org.bouncycastle.jcajce.spec.DHExtendedPrivateKeySpec;
+import com.android.internal.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
+
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCDHPrivateKey
+ implements DHPrivateKey, PKCS12BagAttributeCarrier
+{
+ static final long serialVersionUID = 311058815616901812L;
+
+ private BigInteger x;
+
+ private transient DHParameterSpec dhSpec;
+ private transient PrivateKeyInfo info;
+ private transient DHPrivateKeyParameters dhPrivateKey;
+
+ private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
+ protected BCDHPrivateKey()
+ {
+ }
+
+ BCDHPrivateKey(
+ DHPrivateKey key)
+ {
+ this.x = key.getX();
+ this.dhSpec = key.getParams();
+ }
+
+ BCDHPrivateKey(
+ DHPrivateKeySpec spec)
+ {
+ this.x = spec.getX();
+ if (spec instanceof DHExtendedPrivateKeySpec)
+ {
+ this.dhSpec = ((DHExtendedPrivateKeySpec)spec).getParams();
+ }
+ else
+ {
+ this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
+ }
+ }
+
+ public BCDHPrivateKey(
+ PrivateKeyInfo info)
+ throws IOException
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(info.getPrivateKeyAlgorithm().getParameters());
+ ASN1Integer derX = (ASN1Integer)info.parsePrivateKey();
+ ASN1ObjectIdentifier id = info.getPrivateKeyAlgorithm().getAlgorithm();
+
+ this.info = info;
+ this.x = derX.getValue();
+
+ if (id.equals(PKCSObjectIdentifiers.dhKeyAgreement))
+ {
+ DHParameter params = DHParameter.getInstance(seq);
+
+ if (params.getL() != null)
+ {
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue());
+ this.dhPrivateKey = new DHPrivateKeyParameters(x,
+ new DHParameters(params.getP(), params.getG(), null, params.getL().intValue()));
+ }
+ else
+ {
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
+ this.dhPrivateKey = new DHPrivateKeyParameters(x,
+ new DHParameters(params.getP(), params.getG()));
+ }
+ }
+ else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
+ {
+ DomainParameters params = DomainParameters.getInstance(seq);
+
+ this.dhSpec = new DHDomainParameterSpec(params.getP(), params.getQ(), params.getG(), params.getJ(), 0);
+ this.dhPrivateKey = new DHPrivateKeyParameters(x,
+ new DHParameters(params.getP(), params.getG(), params.getQ(), params.getJ(), null));
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown algorithm type: " + id);
+ }
+
+
+ }
+
+ BCDHPrivateKey(
+ DHPrivateKeyParameters params)
+ {
+ this.x = params.getX();
+ this.dhSpec = new DHDomainParameterSpec(params.getParameters());
+ }
+
+ public String getAlgorithm()
+ {
+ return "DH";
+ }
+
+ /**
+ * return the encoding format we produce in getEncoded().
+ *
+ * @return the string "PKCS#8"
+ */
+ public String getFormat()
+ {
+ return "PKCS#8";
+ }
+
+ /**
+ * Return a PKCS8 representation of the key. The sequence returned
+ * represents a full PrivateKeyInfo object.
+ *
+ * @return a PKCS8 representation of the key.
+ */
+ public byte[] getEncoded()
+ {
+ try
+ {
+ if (info != null)
+ {
+ return info.getEncoded(ASN1Encoding.DER);
+ }
+
+ PrivateKeyInfo info;
+ if (dhSpec instanceof DHDomainParameterSpec && ((DHDomainParameterSpec)dhSpec).getQ() != null)
+ {
+ DHParameters params = ((DHDomainParameterSpec)dhSpec).getDomainParameters();
+ DHValidationParameters validationParameters = params.getValidationParameters();
+ ValidationParams vParams = null;
+ if (validationParameters != null)
+ {
+ vParams = new ValidationParams(validationParameters.getSeed(), validationParameters.getCounter());
+ }
+ info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.dhpublicnumber, new DomainParameters(params.getP(), params.getG(), params.getQ(), params.getJ(), vParams).toASN1Primitive()), new ASN1Integer(getX()));
+ }
+ else
+ {
+ info = new PrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL()).toASN1Primitive()), new ASN1Integer(getX()));
+ }
+ return info.getEncoded(ASN1Encoding.DER);
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+
+ public String toString()
+ {
+ return DHUtil.privateKeyToString("DH", x, new DHParameters(dhSpec.getP(), dhSpec.getG()));
+ }
+
+ public DHParameterSpec getParams()
+ {
+ return dhSpec;
+ }
+
+ public BigInteger getX()
+ {
+ return x;
+ }
+
+ DHPrivateKeyParameters engineGetKeyParameters()
+ {
+ if (dhPrivateKey != null)
+ {
+ return dhPrivateKey;
+ }
+
+ if (dhSpec instanceof DHDomainParameterSpec)
+ {
+ return new DHPrivateKeyParameters(x, ((DHDomainParameterSpec)dhSpec).getDomainParameters());
+ }
+ return new DHPrivateKeyParameters(x, new DHParameters(dhSpec.getP(), dhSpec.getG(), null, dhSpec.getL()));
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof DHPrivateKey))
+ {
+ return false;
+ }
+
+ DHPrivateKey other = (DHPrivateKey)o;
+
+ return this.getX().equals(other.getX())
+ && this.getParams().getG().equals(other.getParams().getG())
+ && this.getParams().getP().equals(other.getParams().getP())
+ && this.getParams().getL() == other.getParams().getL();
+ }
+
+ public int hashCode()
+ {
+ return this.getX().hashCode() ^ this.getParams().getG().hashCode()
+ ^ this.getParams().getP().hashCode() ^ this.getParams().getL();
+ }
+
+ public void setBagAttribute(
+ ASN1ObjectIdentifier oid,
+ ASN1Encodable attribute)
+ {
+ attrCarrier.setBagAttribute(oid, attribute);
+ }
+
+ public ASN1Encodable getBagAttribute(
+ ASN1ObjectIdentifier oid)
+ {
+ return attrCarrier.getBagAttribute(oid);
+ }
+
+ public Enumeration getBagAttributeKeys()
+ {
+ return attrCarrier.getBagAttributeKeys();
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt());
+ this.info = null;
+ this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ out.writeObject(dhSpec.getP());
+ out.writeObject(dhSpec.getG());
+ out.writeInt(dhSpec.getL());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java
new file mode 100644
index 00000000..0326ea11
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java
@@ -0,0 +1,285 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dh;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPublicKeySpec;
+
+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.pkcs.DHParameter;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x9.DomainParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.ValidationParams;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPublicKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHValidationParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
+import com.android.internal.org.bouncycastle.jcajce.spec.DHDomainParameterSpec;
+import com.android.internal.org.bouncycastle.jcajce.spec.DHExtendedPublicKeySpec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCDHPublicKey
+ implements DHPublicKey
+{
+ static final long serialVersionUID = -216691575254424324L;
+
+ private BigInteger y;
+
+ private transient DHPublicKeyParameters dhPublicKey;
+ private transient DHParameterSpec dhSpec;
+ private transient SubjectPublicKeyInfo info;
+
+ BCDHPublicKey(
+ DHPublicKeySpec spec)
+ {
+ this.y = spec.getY();
+ if (spec instanceof DHExtendedPublicKeySpec)
+ {
+ this.dhSpec = ((DHExtendedPublicKeySpec)spec).getParams();
+ }
+ else
+ {
+ this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
+
+ }
+
+ if (dhSpec instanceof DHDomainParameterSpec)
+ {
+ DHDomainParameterSpec dhSp = (DHDomainParameterSpec)dhSpec;
+ this.dhPublicKey = new DHPublicKeyParameters(y, dhSp.getDomainParameters());
+ }
+ else
+ {
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(spec.getP(), spec.getG()));
+ }
+ }
+
+ BCDHPublicKey(
+ DHPublicKey key)
+ {
+ this.y = key.getY();
+ this.dhSpec = key.getParams();
+ if (dhSpec instanceof DHDomainParameterSpec)
+ {
+ DHDomainParameterSpec dhSp = (DHDomainParameterSpec)dhSpec;
+ this.dhPublicKey = new DHPublicKeyParameters(y, dhSp.getDomainParameters());
+ }
+ else
+ {
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
+ }
+ }
+
+ BCDHPublicKey(
+ DHPublicKeyParameters params)
+ {
+ this.y = params.getY();
+ this.dhSpec = new DHDomainParameterSpec(params.getParameters());
+ this.dhPublicKey = params;
+ }
+
+ BCDHPublicKey(
+ BigInteger y,
+ DHParameterSpec dhSpec)
+ {
+ this.y = y;
+ this.dhSpec = dhSpec;
+
+ if (dhSpec instanceof DHDomainParameterSpec)
+ {
+ this.dhPublicKey = new DHPublicKeyParameters(y, ((DHDomainParameterSpec)dhSpec).getDomainParameters());
+ }
+ else
+ {
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
+ }
+ }
+
+ public BCDHPublicKey(
+ SubjectPublicKeyInfo info)
+ {
+ this.info = info;
+
+ ASN1Integer derY;
+ try
+ {
+ derY = (ASN1Integer)info.parsePublicKey();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("invalid info structure in DH public key");
+ }
+
+ this.y = derY.getValue();
+
+ ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithm().getParameters());
+ ASN1ObjectIdentifier id = info.getAlgorithm().getAlgorithm();
+
+ // we need the PKCS check to handle older keys marked with the X9 oid.
+ if (id.equals(PKCSObjectIdentifiers.dhKeyAgreement) || isPKCSParam(seq))
+ {
+ DHParameter params = DHParameter.getInstance(seq);
+
+ if (params.getL() != null)
+ {
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue());
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG(), null, dhSpec.getL()));
+ }
+ else
+ {
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
+ }
+
+ }
+ else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
+ {
+ DomainParameters params = DomainParameters.getInstance(seq);
+
+ ValidationParams validationParams = params.getValidationParams();
+ if (validationParams != null)
+ {
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(params.getP(), params.getG(), params.getQ(), params.getJ(),
+ new DHValidationParameters(validationParams.getSeed(), validationParams.getPgenCounter().intValue())));
+ }
+ else
+ {
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(params.getP(), params.getG(), params.getQ(), params.getJ(), null));
+ }
+ this.dhSpec = new DHDomainParameterSpec(dhPublicKey.getParameters());
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown algorithm type: " + id);
+ }
+ }
+
+ public String getAlgorithm()
+ {
+ return "DH";
+ }
+
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ public byte[] getEncoded()
+ {
+ if (info != null)
+ {
+ return KeyUtil.getEncodedSubjectPublicKeyInfo(info);
+ }
+
+ if (dhSpec instanceof DHDomainParameterSpec && ((DHDomainParameterSpec)dhSpec).getQ() != null)
+ {
+ DHParameters params = ((DHDomainParameterSpec)dhSpec).getDomainParameters();
+ DHValidationParameters validationParameters = params.getValidationParameters();
+ ValidationParams vParams = null;
+ if (validationParameters != null)
+ {
+ vParams = new ValidationParams(validationParameters.getSeed(), validationParameters.getCounter());
+ }
+ return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.dhpublicnumber, new DomainParameters(params.getP(), params.getG(), params.getQ(), params.getJ(), vParams).toASN1Primitive()), new ASN1Integer(y));
+ }
+ return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL()).toASN1Primitive()), new ASN1Integer(y));
+ }
+
+ public String toString()
+ {
+ return DHUtil.publicKeyToString("DH", y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
+ }
+
+ public DHParameterSpec getParams()
+ {
+ return dhSpec;
+ }
+
+ public BigInteger getY()
+ {
+ return y;
+ }
+
+ public DHPublicKeyParameters engineGetKeyParameters()
+ {
+ return dhPublicKey;
+ }
+
+ private boolean isPKCSParam(ASN1Sequence seq)
+ {
+ if (seq.size() == 2)
+ {
+ return true;
+ }
+
+ if (seq.size() > 3)
+ {
+ return false;
+ }
+
+ ASN1Integer l = ASN1Integer.getInstance(seq.getObjectAt(2));
+ ASN1Integer p = ASN1Integer.getInstance(seq.getObjectAt(0));
+
+ if (l.getValue().compareTo(BigInteger.valueOf(p.getValue().bitLength())) > 0)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ return this.getY().hashCode() ^ this.getParams().getG().hashCode()
+ ^ this.getParams().getP().hashCode() ^ this.getParams().getL();
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof DHPublicKey))
+ {
+ return false;
+ }
+
+ DHPublicKey other = (DHPublicKey)o;
+
+ return this.getY().equals(other.getY())
+ && this.getParams().getG().equals(other.getParams().getG())
+ && this.getParams().getP().equals(other.getParams().getP())
+ && this.getParams().getL() == other.getParams().getL();
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt());
+ this.info = null;
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ out.writeObject(dhSpec.getP());
+ out.writeObject(dhSpec.getG());
+ out.writeInt(dhSpec.getL());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/DHUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/DHUtil.java
new file mode 100644
index 00000000..72bd708d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/DHUtil.java
@@ -0,0 +1,46 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dh;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Fingerprint;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+class DHUtil
+{
+ static String privateKeyToString(String algorithm, BigInteger x, DHParameters dhParams)
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ BigInteger y = dhParams.getG().modPow(x, dhParams.getP());
+
+ buf.append(algorithm);
+ buf.append(" Private Key [").append(generateKeyFingerprint(y, dhParams)).append("]").append(nl);
+ buf.append(" Y: ").append(y.toString(16)).append(nl);
+
+ return buf.toString();
+ }
+
+ static String publicKeyToString(String algorithm, BigInteger y, DHParameters dhParams)
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append(algorithm);
+ buf.append(" Public Key [").append(generateKeyFingerprint(y, dhParams)).append("]").append(nl);
+ buf.append(" Y: ").append(y.toString(16)).append(nl);
+
+ return buf.toString();
+ }
+
+ private static String generateKeyFingerprint(BigInteger y, DHParameters dhParams)
+ {
+ return new Fingerprint(
+ Arrays.concatenate(
+ y.toByteArray(),
+ dhParams.getP().toByteArray(), dhParams.getG().toByteArray())).toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java
new file mode 100644
index 00000000..97a1e6c1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java
@@ -0,0 +1,730 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dh;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import com.android.internal.org.bouncycastle.crypto.BasicAgreement;
+import com.android.internal.org.bouncycastle.crypto.DerivationFunction;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.agreement.DHUnifiedAgreement;
+// import org.bouncycastle.crypto.agreement.MQVBasicAgreement;
+// import org.bouncycastle.crypto.agreement.kdf.ConcatenationKDFGenerator;
+// import org.bouncycastle.crypto.agreement.kdf.DHKEKGenerator;
+// import org.bouncycastle.crypto.generators.KDF2BytesGenerator;
+// import org.bouncycastle.crypto.params.DHMQVPrivateParameters;
+// import org.bouncycastle.crypto.params.DHMQVPublicParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPublicKeyParameters;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.params.DHUPrivateParameters;
+// import org.bouncycastle.crypto.params.DHUPublicParameters;
+// import org.bouncycastle.crypto.util.DigestFactory;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.BaseAgreementSpi;
+import com.android.internal.org.bouncycastle.jcajce.spec.DHDomainParameterSpec;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jcajce.spec.DHUParameterSpec;
+// import org.bouncycastle.jcajce.spec.MQVParameterSpec;
+import com.android.internal.org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec;
+
+/**
+ * Diffie-Hellman key agreement. There's actually a better way of doing this
+ * if you are using long term public keys, see the light-weight version for
+ * details.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyAgreementSpi
+ extends BaseAgreementSpi
+{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+
+ // Android-removed: Unsupported algorithms
+ // private final DHUnifiedAgreement unifiedAgreement;
+ private final BasicAgreement mqvAgreement;
+
+ // Android-removed: Unsupported algorithms
+ // private DHUParameterSpec dheParameters;
+ // private MQVParameterSpec mqvParameters;
+
+ private BigInteger x;
+ private BigInteger p;
+ private BigInteger g;
+
+ private byte[] result;
+
+ public KeyAgreementSpi()
+ {
+ this("Diffie-Hellman", null);
+ }
+
+ public KeyAgreementSpi(
+ String kaAlgorithm,
+ DerivationFunction kdf)
+ {
+ super(kaAlgorithm, kdf);
+ // Android-removed: Unsupported algorithm
+ // this.unifiedAgreement = null;
+ this.mqvAgreement = null;
+ }
+
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
+ public KeyAgreementSpi(
+ String kaAlgorithm,
+ DHUnifiedAgreement unifiedAgreement,
+ DerivationFunction kdf)
+ {
+ super(kaAlgorithm, kdf);
+ this.unifiedAgreement = unifiedAgreement;
+ this.mqvAgreement = null;
+ }
+ */
+ // END Android-removed: Unsupported algorithm
+
+ public KeyAgreementSpi(
+ String kaAlgorithm,
+ BasicAgreement mqvAgreement,
+ DerivationFunction kdf)
+ {
+ super(kaAlgorithm, kdf);
+ // Android-removed: Unsupported algorithm
+ // this.unifiedAgreement = null;
+ this.mqvAgreement = mqvAgreement;
+ }
+
+ protected byte[] bigIntToBytes(
+ BigInteger r)
+ {
+ //
+ // RFC 2631 (2.1.2) specifies that the secret should be padded with leading zeros if necessary
+ // must be the same length as p
+ //
+ int expectedLength = (p.bitLength() + 7) / 8;
+
+ byte[] tmp = r.toByteArray();
+
+ if (tmp.length == expectedLength)
+ {
+ return tmp;
+ }
+
+ if (tmp[0] == 0 && tmp.length == expectedLength + 1)
+ {
+ byte[] rv = new byte[tmp.length - 1];
+
+ System.arraycopy(tmp, 1, rv, 0, rv.length);
+ return rv;
+ }
+
+ // tmp must be shorter than expectedLength
+ // pad to the left with zeros.
+ byte[] rv = new byte[expectedLength];
+
+ System.arraycopy(tmp, 0, rv, rv.length - tmp.length, tmp.length);
+
+ return rv;
+ }
+
+ protected Key engineDoPhase(
+ Key key,
+ boolean lastPhase)
+ throws InvalidKeyException, IllegalStateException
+ {
+ if (x == null)
+ {
+ throw new IllegalStateException("Diffie-Hellman not initialised.");
+ }
+
+ if (!(key instanceof DHPublicKey))
+ {
+ throw new InvalidKeyException("DHKeyAgreement doPhase requires DHPublicKey");
+ }
+ DHPublicKey pubKey = (DHPublicKey)key;
+
+ if (!pubKey.getParams().getG().equals(g) || !pubKey.getParams().getP().equals(p))
+ {
+ throw new InvalidKeyException("DHPublicKey not for this KeyAgreement!");
+ }
+
+ BigInteger peerY = ((DHPublicKey)key).getY();
+ if (peerY == null || peerY.compareTo(TWO) < 0
+ || peerY.compareTo(p.subtract(ONE)) >= 0)
+ {
+ throw new InvalidKeyException("Invalid DH PublicKey");
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ if (unifiedAgreement != null)
+ {
+ if (!lastPhase)
+ {
+ throw new IllegalStateException("unified Diffie-Hellman can use only two key pairs");
+ }
+
+ DHPublicKeyParameters staticKey = generatePublicKeyParameter((PublicKey)key);
+ DHPublicKeyParameters ephemKey = generatePublicKeyParameter(dheParameters.getOtherPartyEphemeralKey());
+
+ DHUPublicParameters pKey = new DHUPublicParameters(staticKey, ephemKey);
+
+ result = unifiedAgreement.calculateAgreement(pKey);
+
+ return null;
+ }
+ else if (mqvAgreement != null)
+ {
+ if (!lastPhase)
+ {
+ throw new IllegalStateException("MQV Diffie-Hellman can use only two key pairs");
+ }
+
+ DHPublicKeyParameters staticKey = generatePublicKeyParameter((PublicKey)key);
+ DHPublicKeyParameters ephemKey = generatePublicKeyParameter(mqvParameters.getOtherPartyEphemeralKey());
+
+ DHMQVPublicParameters pKey = new DHMQVPublicParameters(staticKey, ephemKey);
+
+ result = bigIntToBytes(mqvAgreement.calculateAgreement(pKey));
+
+ return null;
+ }
+ else
+ {
+ */
+ // END Android-removed: Unsupported algorithms
+ BigInteger res = peerY.modPow(x, p);
+ if (res.compareTo(ONE) == 0)
+ {
+ throw new InvalidKeyException("Shared key can't be 1");
+ }
+
+ result = bigIntToBytes(res);
+
+ if (lastPhase)
+ {
+ return null;
+ }
+
+ return new BCDHPublicKey(res, pubKey.getParams());
+ /*
+ }
+ */
+ }
+
+ protected byte[] engineGenerateSecret()
+ throws IllegalStateException
+ {
+ if (x == null)
+ {
+ throw new IllegalStateException("Diffie-Hellman not initialised.");
+ }
+
+ return super.engineGenerateSecret();
+ }
+
+ protected int engineGenerateSecret(
+ byte[] sharedSecret,
+ int offset)
+ throws IllegalStateException, ShortBufferException
+ {
+ if (x == null)
+ {
+ throw new IllegalStateException("Diffie-Hellman not initialised.");
+ }
+
+ return super.engineGenerateSecret(sharedSecret, offset);
+ }
+
+ protected SecretKey engineGenerateSecret(
+ String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ if (x == null)
+ {
+ throw new IllegalStateException("Diffie-Hellman not initialised.");
+ }
+
+ // for JSSE compatibility
+ if (algorithm.equals("TlsPremasterSecret"))
+ {
+ return new SecretKeySpec(trimZeroes(result), algorithm);
+ }
+
+ return super.engineGenerateSecret(algorithm);
+ }
+
+ protected void engineInit(
+ Key key,
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ if (!(key instanceof DHPrivateKey))
+ {
+ throw new InvalidKeyException("DHKeyAgreement requires DHPrivateKey for initialisation");
+ }
+ DHPrivateKey privKey = (DHPrivateKey)key;
+
+ if (params != null)
+ {
+ if (params instanceof DHParameterSpec) // p, g override.
+ {
+ DHParameterSpec p = (DHParameterSpec)params;
+
+ this.p = p.getP();
+ this.g = p.getG();
+ // Android-removed: Unsupported algorithm
+ // this.dheParameters = null;
+ this.ukmParameters = null;
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (params instanceof DHUParameterSpec)
+ {
+ if (unifiedAgreement == null)
+ {
+ throw new InvalidAlgorithmParameterException("agreement algorithm not DHU based");
+ }
+ this.p = privKey.getParams().getP();
+ this.g = privKey.getParams().getG();
+ this.dheParameters = (DHUParameterSpec)params;
+ this.ukmParameters = ((DHUParameterSpec)params).getUserKeyingMaterial();
+
+ if (dheParameters.getEphemeralPublicKey() != null)
+ {
+ unifiedAgreement.init(new DHUPrivateParameters(generatePrivateKeyParameter(privKey),
+ generatePrivateKeyParameter(dheParameters.getEphemeralPrivateKey()),
+ generatePublicKeyParameter(dheParameters.getEphemeralPublicKey())));
+ }
+ else
+ {
+ unifiedAgreement.init(new DHUPrivateParameters(generatePrivateKeyParameter(privKey),
+ generatePrivateKeyParameter(dheParameters.getEphemeralPrivateKey())));
+ }
+ }
+ else if (params instanceof MQVParameterSpec)
+ {
+ if (mqvAgreement == null)
+ {
+ throw new InvalidAlgorithmParameterException("agreement algorithm not MQV based");
+ }
+ this.p = privKey.getParams().getP();
+ this.g = privKey.getParams().getG();
+ this.mqvParameters = (MQVParameterSpec)params;
+ this.ukmParameters = ((MQVParameterSpec)params).getUserKeyingMaterial();
+
+ if (mqvParameters.getEphemeralPublicKey() != null)
+ {
+ mqvAgreement.init(new DHMQVPrivateParameters(generatePrivateKeyParameter(privKey),
+ generatePrivateKeyParameter(mqvParameters.getEphemeralPrivateKey()),
+ generatePublicKeyParameter(mqvParameters.getEphemeralPublicKey())));
+ }
+ else
+ {
+ mqvAgreement.init(new DHMQVPrivateParameters(generatePrivateKeyParameter(privKey),
+ generatePrivateKeyParameter(mqvParameters.getEphemeralPrivateKey())));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ else if (params instanceof UserKeyingMaterialSpec)
+ {
+ if (kdf == null)
+ {
+ throw new InvalidAlgorithmParameterException("no KDF specified for UserKeyingMaterialSpec");
+ }
+ this.p = privKey.getParams().getP();
+ this.g = privKey.getParams().getG();
+ // Android-removed: Unsupported algorithm
+ // this.dheParameters = null;
+ this.ukmParameters = ((UserKeyingMaterialSpec)params).getUserKeyingMaterial();
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("DHKeyAgreement only accepts DHParameterSpec");
+ }
+ }
+ else
+ {
+ this.p = privKey.getParams().getP();
+ this.g = privKey.getParams().getG();
+ }
+
+ this.x = privKey.getX();
+ this.result = bigIntToBytes(x);
+ }
+
+ protected void engineInit(
+ Key key,
+ SecureRandom random)
+ throws InvalidKeyException
+ {
+ if (!(key instanceof DHPrivateKey))
+ {
+ throw new InvalidKeyException("DHKeyAgreement requires DHPrivateKey");
+ }
+
+ DHPrivateKey privKey = (DHPrivateKey)key;
+
+ this.p = privKey.getParams().getP();
+ this.g = privKey.getParams().getG();
+ this.x = privKey.getX();
+ this.result = bigIntToBytes(x);
+ }
+
+ protected byte[] calcSecret()
+ {
+ return result;
+ }
+
+ private DHPrivateKeyParameters generatePrivateKeyParameter(PrivateKey privKey)
+ throws InvalidKeyException
+ {
+ if (privKey instanceof DHPrivateKey)
+ {
+ if (privKey instanceof BCDHPrivateKey)
+ {
+ return ((BCDHPrivateKey)privKey).engineGetKeyParameters();
+ }
+ else
+ {
+ DHPrivateKey pub = (DHPrivateKey)privKey;
+
+ DHParameterSpec params = pub.getParams();
+ return new DHPrivateKeyParameters(pub.getX(),
+ new DHParameters(params.getP(), params.getG(), null, params.getL()));
+ }
+ }
+ else
+ {
+ throw new InvalidKeyException("private key not a DHPrivateKey");
+ }
+ }
+
+ private DHPublicKeyParameters generatePublicKeyParameter(PublicKey pubKey)
+ throws InvalidKeyException
+ {
+ if (pubKey instanceof DHPublicKey)
+ {
+ if (pubKey instanceof BCDHPublicKey)
+ {
+ return ((BCDHPublicKey)pubKey).engineGetKeyParameters();
+ }
+ else
+ {
+ DHPublicKey pub = (DHPublicKey)pubKey;
+
+ DHParameterSpec params = pub.getParams();
+
+ if (params instanceof DHDomainParameterSpec)
+ {
+ return new DHPublicKeyParameters(pub.getY(), ((DHDomainParameterSpec)params).getDomainParameters());
+ }
+ return new DHPublicKeyParameters(pub.getY(),
+ new DHParameters(params.getP(), params.getG(), null, params.getL()));
+ }
+ }
+ else
+ {
+ throw new InvalidKeyException("public key not a DHPublicKey");
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class DHwithRFC2631KDF
+ extends KeyAgreementSpi
+ {
+ public DHwithRFC2631KDF()
+ {
+ super("DHwithRFC2631KDF", new DHKEKGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class DHwithSHA1KDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA1KDF()
+ {
+ super("DHwithSHA1CKDF", new KDF2BytesGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class DHwithSHA224KDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA224KDF()
+ {
+ super("DHwithSHA224CKDF", new KDF2BytesGenerator(DigestFactory.createSHA224()));
+ }
+ }
+
+ public static class DHwithSHA256KDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA256KDF()
+ {
+ super("DHwithSHA256CKDF", new KDF2BytesGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ public static class DHwithSHA384KDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA384KDF()
+ {
+ super("DHwithSHA384KDF", new KDF2BytesGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ public static class DHwithSHA512KDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA512KDF()
+ {
+ super("DHwithSHA512KDF", new KDF2BytesGenerator(DigestFactory.createSHA512()));
+ }
+ }
+
+ public static class DHwithSHA1CKDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA1CKDF()
+ {
+ super("DHwithSHA1CKDF", new ConcatenationKDFGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class DHwithSHA224CKDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA224CKDF()
+ {
+ super("DHwithSHA224CKDF", new ConcatenationKDFGenerator(DigestFactory.createSHA224()));
+ }
+ }
+
+ public static class DHwithSHA256CKDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA256CKDF()
+ {
+ super("DHwithSHA256CKDF", new ConcatenationKDFGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ public static class DHwithSHA384CKDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA384CKDF()
+ {
+ super("DHwithSHA384CKDF", new ConcatenationKDFGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ public static class DHwithSHA512CKDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA512CKDF()
+ {
+ super("DHwithSHA512CKDF", new ConcatenationKDFGenerator(DigestFactory.createSHA512()));
+ }
+ }
+
+ public static class DHUwithSHA1KDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA1KDF()
+ {
+ super("DHUwithSHA1KDF", new DHUnifiedAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class DHUwithSHA224KDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA224KDF()
+ {
+ super("DHUwithSHA224KDF", new DHUnifiedAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA224()));
+ }
+ }
+
+ public static class DHUwithSHA256KDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA256KDF()
+ {
+ super("DHUwithSHA256KDF", new DHUnifiedAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ public static class DHUwithSHA384KDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA384KDF()
+ {
+ super("DHUwithSHA384KDF", new DHUnifiedAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ public static class DHUwithSHA512KDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA512KDF()
+ {
+ super("DHUwithSHA512KDF", new DHUnifiedAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA512()));
+ }
+ }
+
+ public static class DHUwithSHA1CKDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA1CKDF()
+ {
+ super("DHUwithSHA1CKDF", new DHUnifiedAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class DHUwithSHA224CKDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA224CKDF()
+ {
+ super("DHUwithSHA224CKDF", new DHUnifiedAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA224()));
+ }
+ }
+
+ public static class DHUwithSHA256CKDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA256CKDF()
+ {
+ super("DHUwithSHA256CKDF", new DHUnifiedAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ public static class DHUwithSHA384CKDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA384CKDF()
+ {
+ super("DHUwithSHA384CKDF", new DHUnifiedAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ public static class DHUwithSHA512CKDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA512CKDF()
+ {
+ super("DHUwithSHA512CKDF", new DHUnifiedAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA512()));
+ }
+ }
+
+ public static class MQVwithSHA1KDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA1KDF()
+ {
+ super("MQVwithSHA1KDF", new MQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class MQVwithSHA224KDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA224KDF()
+ {
+ super("MQVwithSHA224KDF", new MQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA224()));
+ }
+ }
+
+ public static class MQVwithSHA256KDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA256KDF()
+ {
+ super("MQVwithSHA256KDF", new MQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ public static class MQVwithSHA384KDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA384KDF()
+ {
+ super("MQVwithSHA384KDF", new MQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ public static class MQVwithSHA512KDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA512KDF()
+ {
+ super("MQVwithSHA512KDF", new MQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA512()));
+ }
+ }
+
+ public static class MQVwithSHA1CKDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA1CKDF()
+ {
+ super("MQVwithSHA1CKDF", new MQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class MQVwithSHA224CKDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA224CKDF()
+ {
+ super("MQVwithSHA224CKDF", new MQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA224()));
+ }
+ }
+
+ public static class MQVwithSHA256CKDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA256CKDF()
+ {
+ super("MQVwithSHA256CKDF", new MQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ public static class MQVwithSHA384CKDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA384CKDF()
+ {
+ super("MQVwithSHA384CKDF", new MQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ public static class MQVwithSHA512CKDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA512CKDF()
+ {
+ super("MQVwithSHA512CKDF", new MQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA512()));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyFactorySpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyFactorySpi.java
new file mode 100644
index 00000000..b0f69040
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyFactorySpi.java
@@ -0,0 +1,140 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dh;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHPrivateKeySpec;
+import javax.crypto.spec.DHPublicKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ExtendedInvalidKeySpecException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyFactorySpi
+ extends BaseKeyFactorySpi
+{
+ public KeyFactorySpi()
+ {
+ }
+
+ protected KeySpec engineGetKeySpec(
+ Key key,
+ Class spec)
+ throws InvalidKeySpecException
+ {
+ if (spec.isAssignableFrom(DHPrivateKeySpec.class) && key instanceof DHPrivateKey)
+ {
+ DHPrivateKey k = (DHPrivateKey)key;
+
+ return new DHPrivateKeySpec(k.getX(), k.getParams().getP(), k.getParams().getG());
+ }
+ else if (spec.isAssignableFrom(DHPublicKeySpec.class) && key instanceof DHPublicKey)
+ {
+ DHPublicKey k = (DHPublicKey)key;
+
+ return new DHPublicKeySpec(k.getY(), k.getParams().getP(), k.getParams().getG());
+ }
+
+ return super.engineGetKeySpec(key, spec);
+ }
+
+ protected Key engineTranslateKey(
+ Key key)
+ throws InvalidKeyException
+ {
+ if (key instanceof DHPublicKey)
+ {
+ return new BCDHPublicKey((DHPublicKey)key);
+ }
+ else if (key instanceof DHPrivateKey)
+ {
+ return new BCDHPrivateKey((DHPrivateKey)key);
+ }
+
+ throw new InvalidKeyException("key type unknown");
+ }
+
+ protected PrivateKey engineGeneratePrivate(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof DHPrivateKeySpec)
+ {
+ return new BCDHPrivateKey((DHPrivateKeySpec)keySpec);
+ }
+
+ return super.engineGeneratePrivate(keySpec);
+ }
+
+ protected PublicKey engineGeneratePublic(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof DHPublicKeySpec)
+ {
+ try
+ {
+ return new BCDHPublicKey((DHPublicKeySpec)keySpec);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ExtendedInvalidKeySpecException(e.getMessage(), e);
+ }
+ }
+
+ return super.engineGeneratePublic(keySpec);
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm();
+
+ if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement))
+ {
+ return new BCDHPrivateKey(keyInfo);
+ }
+ else if (algOid.equals(X9ObjectIdentifiers.dhpublicnumber))
+ {
+ return new BCDHPrivateKey(keyInfo);
+ }
+ else
+ {
+ throw new IOException("algorithm identifier " + algOid + " in key not recognised");
+ }
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm();
+
+ if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement))
+ {
+ return new BCDHPublicKey(keyInfo);
+ }
+ else if (algOid.equals(X9ObjectIdentifiers.dhpublicnumber))
+ {
+ return new BCDHPublicKey(keyInfo);
+ }
+ else
+ {
+ throw new IOException("algorithm identifier " + algOid + " in key not recognised");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java
new file mode 100644
index 00000000..dfe68930
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java
@@ -0,0 +1,153 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dh;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPair;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Hashtable;
+
+import javax.crypto.spec.DHParameterSpec;
+
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator;
+import com.android.internal.org.bouncycastle.crypto.generators.DHParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.params.DHKeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPublicKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PrimeCertaintyCalculator;
+import com.android.internal.org.bouncycastle.jcajce.spec.DHDomainParameterSpec;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.util.Integers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyPairGeneratorSpi
+ extends java.security.KeyPairGenerator
+{
+ private static Hashtable params = new Hashtable();
+ private static Object lock = new Object();
+
+ DHKeyGenerationParameters param;
+ DHBasicKeyPairGenerator engine = new DHBasicKeyPairGenerator();
+ int strength = 2048;
+ SecureRandom random = CryptoServicesRegistrar.getSecureRandom();
+ boolean initialised = false;
+
+ public KeyPairGeneratorSpi()
+ {
+ super("DH");
+ }
+
+ public void initialize(
+ int strength,
+ SecureRandom random)
+ {
+ this.strength = strength;
+ this.random = random;
+ this.initialised = false;
+ }
+
+ public void initialize(
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ if (!(params instanceof DHParameterSpec))
+ {
+ throw new InvalidAlgorithmParameterException("parameter object not a DHParameterSpec");
+ }
+ DHParameterSpec dhParams = (DHParameterSpec)params;
+
+ try
+ {
+ param = convertParams(random, dhParams);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new InvalidAlgorithmParameterException(e.getMessage(), e);
+ }
+
+ engine.init(param);
+ initialised = true;
+ }
+
+ private DHKeyGenerationParameters convertParams(SecureRandom random, DHParameterSpec dhParams)
+ {
+ // BEGIN Android-removed: Don't special-case DHDomainParameterSpec
+ // When DHDomainParameterSpec is special-cased here, it supplies a value for q that
+ // ultimately results in a smaller value of x, which runs afoul of the Wycheproof test
+ // com.google.security.wycheproof.DhTest.testKeyPairGenerator(). See the docs in DhTest
+ // for more details of why that requirement is made.
+ //
+ // While we believe this code would be safe (and likely somewhat faster), in the interest
+ // of being conservative we've disabled it to preserve the old behavior that also passes
+ // the Wycheproof test.
+ /*
+ if (dhParams instanceof DHDomainParameterSpec)
+ {
+ return new DHKeyGenerationParameters(random, ((DHDomainParameterSpec)dhParams).getDomainParameters());
+ }
+ */
+ // END Android-removed: Don't special-case DHDomainParameterSpec
+ return new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL()));
+ }
+
+ public KeyPair generateKeyPair()
+ {
+ if (!initialised)
+ {
+ Integer paramStrength = Integers.valueOf(strength);
+
+ if (params.containsKey(paramStrength))
+ {
+ param = (DHKeyGenerationParameters)params.get(paramStrength);
+ }
+ else
+ {
+ DHParameterSpec dhParams = BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(strength);
+
+ if (dhParams != null)
+ {
+ param = convertParams(random, dhParams);
+ }
+ else
+ {
+ synchronized (lock)
+ {
+ // we do the check again in case we were blocked by a generator for
+ // our key size.
+ if (params.containsKey(paramStrength))
+ {
+ param = (DHKeyGenerationParameters)params.get(paramStrength);
+ }
+ else
+ {
+
+ DHParametersGenerator pGen = new DHParametersGenerator();
+
+ pGen.init(strength, PrimeCertaintyCalculator.getDefaultCertainty(strength), random);
+
+ param = new DHKeyGenerationParameters(random, pGen.generateParameters());
+
+ params.put(paramStrength, param);
+ }
+ }
+ }
+ }
+
+ engine.init(param);
+
+ initialised = true;
+ }
+
+ AsymmetricCipherKeyPair pair = engine.generateKeyPair();
+ DHPublicKeyParameters pub = (DHPublicKeyParameters)pair.getPublic();
+ DHPrivateKeyParameters priv = (DHPrivateKeyParameters)pair.getPrivate();
+
+ return new KeyPair(new BCDHPublicKey(pub), new BCDHPrivateKey(priv));
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java
new file mode 100644
index 00000000..e8a2fb1b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParameterGeneratorSpi.java
@@ -0,0 +1,115 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dsa;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.digests.SHA256Digest;
+import com.android.internal.org.bouncycastle.crypto.generators.DSAParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameterGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.BaseAlgorithmParameterGeneratorSpi;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PrimeCertaintyCalculator;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AlgorithmParameterGeneratorSpi
+ extends BaseAlgorithmParameterGeneratorSpi
+{
+ protected SecureRandom random;
+ // Android-changed: Change default strength to 1024
+ // In 1.57, the default strength was changed to 2048. We keep it at 1024 for app
+ // compatibility, particularly because the default digest (SHA-1) doesn't have
+ // a sufficiently long digest to work with 2048-bit keys.
+ protected int strength = 1024;
+ protected DSAParameterGenerationParameters params;
+
+ protected void engineInit(
+ int strength,
+ SecureRandom random)
+ {
+ if (strength < 512 || strength > 3072)
+ {
+ throw new InvalidParameterException("strength must be from 512 - 3072");
+ }
+
+ if (strength <= 1024 && strength % 64 != 0)
+ {
+ throw new InvalidParameterException("strength must be a multiple of 64 below 1024 bits.");
+ }
+
+ if (strength > 1024 && strength % 1024 != 0)
+ {
+ throw new InvalidParameterException("strength must be a multiple of 1024 above 1024 bits.");
+ }
+
+ this.strength = strength;
+ this.random = random;
+ }
+
+ protected void engineInit(
+ AlgorithmParameterSpec genParamSpec,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for DSA parameter generation.");
+ }
+
+ protected AlgorithmParameters engineGenerateParameters()
+ {
+ DSAParametersGenerator pGen;
+
+ if (strength <= 1024)
+ {
+ pGen = new DSAParametersGenerator();
+ }
+ else
+ {
+ pGen = new DSAParametersGenerator(new SHA256Digest());
+ }
+
+ if (random == null)
+ {
+ random = CryptoServicesRegistrar.getSecureRandom();
+ }
+
+ int certainty = PrimeCertaintyCalculator.getDefaultCertainty(strength);
+
+ if (strength == 1024)
+ {
+ params = new DSAParameterGenerationParameters(1024, 160, certainty, random);
+ pGen.init(params);
+ }
+ else if (strength > 1024)
+ {
+ params = new DSAParameterGenerationParameters(strength, 256, certainty, random);
+ pGen.init(params);
+ }
+ else
+ {
+ pGen.init(strength, certainty, random);
+ }
+
+ DSAParameters p = pGen.generateParameters();
+
+ AlgorithmParameters params;
+
+ try
+ {
+ params = createParametersInstance("DSA");
+ params.init(new DSAParameterSpec(p.getP(), p.getQ(), p.getG()));
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.getMessage());
+ }
+
+ return params;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.java
new file mode 100644
index 00000000..3e34e06e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.java
@@ -0,0 +1,135 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dsa;
+
+import java.io.IOException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.x509.DSAParameter;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AlgorithmParametersSpi
+ extends java.security.AlgorithmParametersSpi
+{
+ DSAParameterSpec currentSpec;
+
+ protected boolean isASN1FormatString(String format)
+ {
+ return format == null || format.equals("ASN.1");
+ }
+
+ protected AlgorithmParameterSpec engineGetParameterSpec(
+ Class paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec == null)
+ {
+ throw new NullPointerException("argument to getParameterSpec must not be null");
+ }
+
+ return localEngineGetParameterSpec(paramSpec);
+ }
+
+ /**
+ * Return the X.509 ASN.1 structure DSAParameter.
+ * <pre>
+ * DSAParameter ::= SEQUENCE {
+ * prime INTEGER, -- p
+ * subprime INTEGER, -- q
+ * base INTEGER, -- g}
+ * </pre>
+ */
+ protected byte[] engineGetEncoded()
+ {
+ DSAParameter dsaP = new DSAParameter(currentSpec.getP(), currentSpec.getQ(), currentSpec.getG());
+
+ try
+ {
+ return dsaP.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Error encoding DSAParameters");
+ }
+ }
+
+ protected byte[] engineGetEncoded(
+ String format)
+ {
+ if (isASN1FormatString(format))
+ {
+ return engineGetEncoded();
+ }
+
+ return null;
+ }
+
+ protected AlgorithmParameterSpec localEngineGetParameterSpec(
+ Class paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec == DSAParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
+ {
+ return currentSpec;
+ }
+
+ throw new InvalidParameterSpecException("unknown parameter spec passed to DSA parameters object.");
+ }
+
+ protected void engineInit(
+ AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (!(paramSpec instanceof DSAParameterSpec))
+ {
+ throw new InvalidParameterSpecException("DSAParameterSpec required to initialise a DSA algorithm parameters object");
+ }
+
+ this.currentSpec = (DSAParameterSpec)paramSpec;
+ }
+
+ protected void engineInit(
+ byte[] params)
+ throws IOException
+ {
+ try
+ {
+ DSAParameter dsaP = DSAParameter.getInstance(ASN1Primitive.fromByteArray(params));
+
+ currentSpec = new DSAParameterSpec(dsaP.getP(), dsaP.getQ(), dsaP.getG());
+ }
+ catch (ClassCastException e)
+ {
+ throw new IOException("Not a valid DSA Parameter encoding.");
+ }
+ catch (ArrayIndexOutOfBoundsException e)
+ {
+ throw new IOException("Not a valid DSA Parameter encoding.");
+ }
+ }
+
+ protected void engineInit(
+ byte[] params,
+ String format)
+ throws IOException
+ {
+ if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509"))
+ {
+ engineInit(params);
+ }
+ else
+ {
+ throw new IOException("Unknown parameter format " + format);
+ }
+ }
+
+ protected String engineToString()
+ {
+ return "DSA Parameters";
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPrivateKey.java
new file mode 100644
index 00000000..8b9db67b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPrivateKey.java
@@ -0,0 +1,185 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dsa;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.DSAPrivateKeySpec;
+import java.util.Enumeration;
+
+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.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.DSAParameter;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
+import com.android.internal.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCDSAPrivateKey
+ implements DSAPrivateKey, PKCS12BagAttributeCarrier
+{
+ private static final long serialVersionUID = -4677259546958385734L;
+
+ private BigInteger x;
+ private transient DSAParams dsaSpec;
+
+ private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
+ protected BCDSAPrivateKey()
+ {
+ }
+
+ BCDSAPrivateKey(
+ DSAPrivateKey key)
+ {
+ this.x = key.getX();
+ this.dsaSpec = key.getParams();
+ }
+
+ BCDSAPrivateKey(
+ DSAPrivateKeySpec spec)
+ {
+ this.x = spec.getX();
+ this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG());
+ }
+
+ public BCDSAPrivateKey(
+ PrivateKeyInfo info)
+ throws IOException
+ {
+ DSAParameter params = DSAParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters());
+ ASN1Integer derX = (ASN1Integer)info.parsePrivateKey();
+
+ this.x = derX.getValue();
+ this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG());
+ }
+
+ BCDSAPrivateKey(
+ DSAPrivateKeyParameters params)
+ {
+ this.x = params.getX();
+ this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG());
+ }
+
+ public String getAlgorithm()
+ {
+ return "DSA";
+ }
+
+ /**
+ * return the encoding format we produce in getEncoded().
+ *
+ * @return the string "PKCS#8"
+ */
+ public String getFormat()
+ {
+ return "PKCS#8";
+ }
+
+ /**
+ * Return a PKCS8 representation of the key. The sequence returned
+ * represents a full PrivateKeyInfo object.
+ *
+ * @return a PKCS8 representation of the key.
+ */
+ public byte[] getEncoded()
+ {
+ return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG()).toASN1Primitive()), new ASN1Integer(getX()));
+ }
+
+ public DSAParams getParams()
+ {
+ return dsaSpec;
+ }
+
+ public BigInteger getX()
+ {
+ return x;
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof DSAPrivateKey))
+ {
+ return false;
+ }
+
+ DSAPrivateKey other = (DSAPrivateKey)o;
+
+ return this.getX().equals(other.getX())
+ && this.getParams().getG().equals(other.getParams().getG())
+ && this.getParams().getP().equals(other.getParams().getP())
+ && this.getParams().getQ().equals(other.getParams().getQ());
+ }
+
+ public int hashCode()
+ {
+ return this.getX().hashCode() ^ this.getParams().getG().hashCode()
+ ^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode();
+ }
+
+ public void setBagAttribute(
+ ASN1ObjectIdentifier oid,
+ ASN1Encodable attribute)
+ {
+ attrCarrier.setBagAttribute(oid, attribute);
+ }
+
+ public ASN1Encodable getBagAttribute(
+ ASN1ObjectIdentifier oid)
+ {
+ return attrCarrier.getBagAttribute(oid);
+ }
+
+ public Enumeration getBagAttributeKeys()
+ {
+ return attrCarrier.getBagAttributeKeys();
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ this.dsaSpec = new DSAParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject());
+ this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ out.writeObject(dsaSpec.getP());
+ out.writeObject(dsaSpec.getQ());
+ out.writeObject(dsaSpec.getG());
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ BigInteger y = getParams().getG().modPow(x, getParams().getP());
+
+ buf.append("DSA Private Key [").append(DSAUtil.generateKeyFingerprint(y, getParams())).append("]").append(nl);
+ buf.append(" Y: ").append(y.toString(16)).append(nl);
+
+ return buf.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java
new file mode 100644
index 00000000..f7d7b5bc
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java
@@ -0,0 +1,222 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dsa;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPublicKey;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.DSAPublicKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.DSAParameter;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPublicKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCDSAPublicKey
+ implements DSAPublicKey
+{
+ private static final long serialVersionUID = 1752452449903495175L;
+ private static BigInteger ZERO = BigInteger.valueOf(0);
+
+ private BigInteger y;
+
+ private transient DSAPublicKeyParameters lwKeyParams;
+ private transient DSAParams dsaSpec;
+
+ BCDSAPublicKey(
+ DSAPublicKeySpec spec)
+ {
+ this.y = spec.getY();
+ this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG());
+ this.lwKeyParams = new DSAPublicKeyParameters(y, DSAUtil.toDSAParameters(dsaSpec));
+ }
+
+ BCDSAPublicKey(
+ DSAPublicKey key)
+ {
+ this.y = key.getY();
+ this.dsaSpec = key.getParams();
+ this.lwKeyParams = new DSAPublicKeyParameters(y, DSAUtil.toDSAParameters(dsaSpec));
+ }
+
+ BCDSAPublicKey(
+ DSAPublicKeyParameters params)
+ {
+ this.y = params.getY();
+ if (params.getParameters() != null)
+ {
+ this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG());
+ }
+ else
+ {
+ this.dsaSpec = null;
+ }
+ this.lwKeyParams = params;
+ }
+
+ public BCDSAPublicKey(
+ SubjectPublicKeyInfo info)
+ {
+ ASN1Integer derY;
+
+ try
+ {
+ derY = (ASN1Integer)info.parsePublicKey();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("invalid info structure in DSA public key");
+ }
+
+ this.y = derY.getValue();
+
+ if (isNotNull(info.getAlgorithm().getParameters()))
+ {
+ DSAParameter params = DSAParameter.getInstance(info.getAlgorithm().getParameters());
+
+ this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG());
+ }
+ else
+ {
+ this.dsaSpec = null;
+ }
+
+ this.lwKeyParams = new DSAPublicKeyParameters(y, DSAUtil.toDSAParameters(dsaSpec));
+ }
+
+ private boolean isNotNull(ASN1Encodable parameters)
+ {
+ return parameters != null && !DERNull.INSTANCE.equals(parameters.toASN1Primitive());
+ }
+
+ public String getAlgorithm()
+ {
+ return "DSA";
+ }
+
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ DSAPublicKeyParameters engineGetKeyParameters()
+ {
+ return lwKeyParams;
+ }
+
+ public byte[] getEncoded()
+ {
+ if (dsaSpec == null)
+ {
+ return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa), new ASN1Integer(y));
+ }
+
+ return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG()).toASN1Primitive()), new ASN1Integer(y));
+ }
+
+ public DSAParams getParams()
+ {
+ return dsaSpec;
+ }
+
+ public BigInteger getY()
+ {
+ return y;
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append("DSA Public Key [").append(DSAUtil.generateKeyFingerprint(y, getParams())).append("]").append(nl);
+ buf.append(" Y: ").append(this.getY().toString(16)).append(nl);
+
+ return buf.toString();
+ }
+
+ public int hashCode()
+ {
+ if (dsaSpec != null)
+ {
+ return this.getY().hashCode() ^ this.getParams().getG().hashCode()
+ ^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode();
+ }
+ else
+ {
+ return this.getY().hashCode();
+ }
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof DSAPublicKey))
+ {
+ return false;
+ }
+
+ DSAPublicKey other = (DSAPublicKey)o;
+
+ if (this.dsaSpec != null)
+ {
+ return this.getY().equals(other.getY())
+ && other.getParams() != null
+ && this.getParams().getG().equals(other.getParams().getG())
+ && this.getParams().getP().equals(other.getParams().getP())
+ && this.getParams().getQ().equals(other.getParams().getQ());
+ }
+ else
+ {
+ return this.getY().equals(other.getY()) && other.getParams() == null;
+ }
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ BigInteger p = (BigInteger)in.readObject();
+ if (p.equals(ZERO))
+ {
+ this.dsaSpec = null;
+ }
+ else
+ {
+ this.dsaSpec = new DSAParameterSpec(p, (BigInteger)in.readObject(), (BigInteger)in.readObject());
+ }
+ this.lwKeyParams = new DSAPublicKeyParameters(y, DSAUtil.toDSAParameters(dsaSpec));
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ if (dsaSpec == null)
+ {
+ out.writeObject(ZERO);
+ }
+ else
+ {
+ out.writeObject(dsaSpec.getP());
+ out.writeObject(dsaSpec.getQ());
+ out.writeObject(dsaSpec.getG());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
new file mode 100644
index 00000000..cc30d173
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
@@ -0,0 +1,400 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dsa;
+
+import java.math.BigInteger;
+import java.security.AlgorithmParameters;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+import java.security.spec.AlgorithmParameterSpec;
+
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DSAExt;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.digests.NullDigest;
+// Android-added: Check DSA keys when generated
+import com.android.internal.org.bouncycastle.crypto.params.DSAKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+import com.android.internal.org.bouncycastle.crypto.signers.DSAEncoding;
+// Android-removed: Unsupported algorithm
+// import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
+import com.android.internal.org.bouncycastle.crypto.signers.StandardDSAEncoding;
+// Android-changed: Use Android digests
+// import org.bouncycastle.crypto.util.DigestFactory;
+import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DSASigner
+ extends SignatureSpi
+ implements PKCSObjectIdentifiers, X509ObjectIdentifiers
+{
+ private Digest digest;
+ private DSAExt signer;
+ private DSAEncoding encoding = StandardDSAEncoding.INSTANCE;
+ private SecureRandom random;
+
+ protected DSASigner(
+ Digest digest,
+ DSAExt signer)
+ {
+ this.digest = digest;
+ this.signer = signer;
+ }
+
+ protected void engineInitVerify(
+ PublicKey publicKey)
+ throws InvalidKeyException
+ {
+ CipherParameters param = DSAUtil.generatePublicKeyParameter(publicKey);
+
+ digest.reset();
+ signer.init(false, param);
+ }
+
+ protected void engineInitSign(
+ PrivateKey privateKey,
+ SecureRandom random)
+ throws InvalidKeyException
+ {
+ this.random = random;
+ engineInitSign(privateKey);
+ }
+
+ protected void engineInitSign(
+ PrivateKey privateKey)
+ throws InvalidKeyException
+ {
+ CipherParameters param = DSAUtil.generatePrivateKeyParameter(privateKey);
+
+ // Android-added: Check DSA keys when generated
+ DSAParameters dsaParam = ((DSAKeyParameters) param).getParameters();
+ checkKey(dsaParam);
+
+ if (random != null)
+ {
+ param = new ParametersWithRandom(param, random);
+ }
+
+ digest.reset();
+ signer.init(true, param);
+ }
+
+ protected void engineUpdate(
+ byte b)
+ throws SignatureException
+ {
+ digest.update(b);
+ }
+
+ protected void engineUpdate(
+ byte[] b,
+ int off,
+ int len)
+ throws SignatureException
+ {
+ digest.update(b, off, len);
+ }
+
+ protected byte[] engineSign()
+ throws SignatureException
+ {
+ byte[] hash = new byte[digest.getDigestSize()];
+
+ digest.doFinal(hash, 0);
+
+ try
+ {
+ BigInteger[] sig = signer.generateSignature(hash);
+
+ return encoding.encode(signer.getOrder(), sig[0], sig[1]);
+ }
+ catch (Exception e)
+ {
+ throw new SignatureException(e.toString());
+ }
+ }
+
+ protected boolean engineVerify(
+ byte[] sigBytes)
+ throws SignatureException
+ {
+ byte[] hash = new byte[digest.getDigestSize()];
+
+ digest.doFinal(hash, 0);
+
+ BigInteger[] sig;
+
+ try
+ {
+ sig = encoding.decode(signer.getOrder(), sigBytes);
+ }
+ catch (Exception e)
+ {
+ throw new SignatureException("error decoding signature bytes.");
+ }
+
+ return signer.verifySignature(hash, sig[0], sig[1]);
+ }
+
+ protected AlgorithmParameters engineGetParameters()
+ {
+ return null;
+ }
+
+ protected void engineSetParameter(
+ AlgorithmParameterSpec params)
+ {
+ throw new UnsupportedOperationException("engineSetParameter unsupported");
+ }
+
+ // BEGIN Android-added: Check DSA keys when generated
+ protected void checkKey(DSAParameters params) throws InvalidKeyException {
+ int valueL = params.getP().bitLength();
+ int valueN = params.getQ().bitLength();
+ int digestSize = digest.getDigestSize();
+
+ // The checks are consistent with DSAParametersGenerator's init method.
+ if ((valueL < 1024 || valueL > 3072) || valueL % 1024 != 0) {
+ throw new InvalidKeyException("valueL values must be between 1024 and 3072 and a multiple of 1024");
+ } else if (valueL == 1024 && valueN != 160) {
+ throw new InvalidKeyException("valueN must be 160 for valueL = 1024");
+ } else if (valueL == 2048 && (valueN != 224 && valueN != 256)) {
+ throw new InvalidKeyException("valueN must be 224 or 256 for valueL = 2048");
+ } else if (valueL == 3072 && valueN != 256) {
+ throw new InvalidKeyException("valueN must be 256 for valueL = 3072");
+ }
+ if (!(digest instanceof NullDigest) && valueN > digestSize * 8) {
+ throw new InvalidKeyException("Key is too strong for this signature algorithm");
+ }
+ }
+
+ // END Android-added: Check DSA keys when generated
+ /**
+ * @deprecated replaced with #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
+ */
+ protected void engineSetParameter(
+ String param,
+ Object value)
+ {
+ throw new UnsupportedOperationException("engineSetParameter unsupported");
+ }
+
+ /**
+ * @deprecated
+ */
+ protected Object engineGetParameter(
+ String param)
+ {
+ throw new UnsupportedOperationException("engineGetParameter unsupported");
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class stdDSA
+ extends DSASigner
+ {
+ public stdDSA()
+ {
+ // Android-changed: Use Android digests
+ // super(DigestFactory.createSHA1(), new org.bouncycastle.crypto.signers.DSASigner());
+ super(AndroidDigestFactory.getSHA1(), new com.android.internal.org.bouncycastle.crypto.signers.DSASigner());
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
+ static public class detDSA
+ extends DSASigner
+ {
+ public detDSA()
+ {
+ super(DigestFactory.createSHA1(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA1())));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithm
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class dsa224
+ extends DSASigner
+ {
+ public dsa224()
+ {
+ // Android-changed: Use Android digests
+ // super(DigestFactory.createSHA224(), new org.bouncycastle.crypto.signers.DSASigner());
+ super(AndroidDigestFactory.getSHA224(), new com.android.internal.org.bouncycastle.crypto.signers.DSASigner());
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
+ static public class detDSA224
+ extends DSASigner
+ {
+ public detDSA224()
+ {
+ super(DigestFactory.createSHA224(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA224())));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithm
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class dsa256
+ extends DSASigner
+ {
+ public dsa256()
+ {
+ // Android-changed: Use Android digests
+ // super(DigestFactory.createSHA256(), new org.bouncycastle.crypto.signers.DSASigner());
+ super(AndroidDigestFactory.getSHA256(), new com.android.internal.org.bouncycastle.crypto.signers.DSASigner());
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ static public class detDSA256
+ extends DSASigner
+ {
+ public detDSA256()
+ {
+ super(DigestFactory.createSHA256(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA256())));
+ }
+ }
+
+ static public class dsa384
+ extends DSASigner
+ {
+ public dsa384()
+ {
+ super(DigestFactory.createSHA384(), new org.bouncycastle.crypto.signers.DSASigner());
+ }
+ }
+
+ static public class detDSA384
+ extends DSASigner
+ {
+ public detDSA384()
+ {
+ super(DigestFactory.createSHA384(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA384())));
+ }
+ }
+
+ static public class dsa512
+ extends DSASigner
+ {
+ public dsa512()
+ {
+ super(DigestFactory.createSHA512(), new org.bouncycastle.crypto.signers.DSASigner());
+ }
+ }
+
+ static public class detDSA512
+ extends DSASigner
+ {
+ public detDSA512()
+ {
+ super(DigestFactory.createSHA512(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA512())));
+ }
+ }
+
+ static public class dsaSha3_224
+ extends DSASigner
+ {
+ public dsaSha3_224()
+ {
+ super(DigestFactory.createSHA3_224(), new org.bouncycastle.crypto.signers.DSASigner());
+ }
+ }
+
+ static public class detDSASha3_224
+ extends DSASigner
+ {
+ public detDSASha3_224()
+ {
+ super(DigestFactory.createSHA3_224(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_224())));
+ }
+ }
+
+ static public class dsaSha3_256
+ extends DSASigner
+ {
+ public dsaSha3_256()
+ {
+ super(DigestFactory.createSHA3_256(), new org.bouncycastle.crypto.signers.DSASigner());
+ }
+ }
+
+ static public class detDSASha3_256
+ extends DSASigner
+ {
+ public detDSASha3_256()
+ {
+ super(DigestFactory.createSHA3_256(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_256())));
+ }
+ }
+
+ static public class dsaSha3_384
+ extends DSASigner
+ {
+ public dsaSha3_384()
+ {
+ super(DigestFactory.createSHA3_384(), new org.bouncycastle.crypto.signers.DSASigner());
+ }
+ }
+
+ static public class detDSASha3_384
+ extends DSASigner
+ {
+ public detDSASha3_384()
+ {
+ super(DigestFactory.createSHA3_384(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_384())));
+ }
+ }
+
+ static public class dsaSha3_512
+ extends DSASigner
+ {
+ public dsaSha3_512()
+ {
+ super(DigestFactory.createSHA3_512(), new org.bouncycastle.crypto.signers.DSASigner());
+ }
+ }
+
+ static public class detDSASha3_512
+ extends DSASigner
+ {
+ public detDSASha3_512()
+ {
+ super(DigestFactory.createSHA3_512(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_512())));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class noneDSA
+ extends DSASigner
+ {
+ public noneDSA()
+ {
+ super(new NullDigest(), new com.android.internal.org.bouncycastle.crypto.signers.DSASigner());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSAUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSAUtil.java
new file mode 100644
index 00000000..823298cb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSAUtil.java
@@ -0,0 +1,113 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dsa;
+
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.interfaces.DSAPublicKey;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Fingerprint;
+
+/**
+ * utility class for converting jce/jca DSA objects
+ * objects into their org.bouncycastle.crypto counterparts.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DSAUtil
+{
+ public static final ASN1ObjectIdentifier[] dsaOids =
+ {
+ X9ObjectIdentifiers.id_dsa,
+ OIWObjectIdentifiers.dsaWithSHA1,
+ X9ObjectIdentifiers.id_dsa_with_sha1
+ };
+
+ /**
+ * Return true if the passed in OID could be associated with a DSA key.
+ *
+ * @param algOid algorithm OID from a key.
+ * @return true if it's for a DSA key, false otherwise.
+ */
+ public static boolean isDsaOid(
+ ASN1ObjectIdentifier algOid)
+ {
+ for (int i = 0; i != dsaOids.length; i++)
+ {
+ if (algOid.equals(dsaOids[i]))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ static DSAParameters toDSAParameters(DSAParams spec)
+ {
+ if (spec != null)
+ {
+ return new DSAParameters(spec.getP(), spec.getQ(), spec.getG());
+ }
+
+ return null;
+ }
+
+ static public AsymmetricKeyParameter generatePublicKeyParameter(
+ PublicKey key)
+ throws InvalidKeyException
+ {
+ if (key instanceof BCDSAPublicKey)
+ {
+ return ((BCDSAPublicKey)key).engineGetKeyParameters();
+ }
+
+ if (key instanceof DSAPublicKey)
+ {
+ return new BCDSAPublicKey((DSAPublicKey)key).engineGetKeyParameters();
+ }
+
+ try
+ {
+ byte[] bytes = key.getEncoded();
+
+ BCDSAPublicKey bckey = new BCDSAPublicKey(SubjectPublicKeyInfo.getInstance(bytes));
+
+ return bckey.engineGetKeyParameters();
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeyException("can't identify DSA public key: " + key.getClass().getName());
+ }
+ }
+
+ static public AsymmetricKeyParameter generatePrivateKeyParameter(
+ PrivateKey key)
+ throws InvalidKeyException
+ {
+ if (key instanceof DSAPrivateKey)
+ {
+ DSAPrivateKey k = (DSAPrivateKey)key;
+
+ return new DSAPrivateKeyParameters(k.getX(),
+ new DSAParameters(k.getParams().getP(), k.getParams().getQ(), k.getParams().getG()));
+ }
+
+ throw new InvalidKeyException("can't identify DSA private key.");
+ }
+
+ static String generateKeyFingerprint(BigInteger y, DSAParams params)
+ {
+ return new Fingerprint(Arrays.concatenate(y.toByteArray(), params.getP().toByteArray(), params.getQ().toByteArray(), params.getG().toByteArray())).toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java
new file mode 100644
index 00000000..87c56f95
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java
@@ -0,0 +1,238 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dsa;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.interfaces.DSAPublicKey;
+import java.security.spec.DSAPrivateKeySpec;
+import java.security.spec.DSAPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPublicKeyParameters;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.util.OpenSSHPrivateKeyUtil;
+// import org.bouncycastle.crypto.util.OpenSSHPublicKeyUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec;
+// import org.bouncycastle.jce.spec.OpenSSHPublicKeySpec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyFactorySpi
+ extends BaseKeyFactorySpi
+{
+ public KeyFactorySpi()
+ {
+ }
+
+ protected KeySpec engineGetKeySpec(
+ Key key,
+ Class spec)
+ throws InvalidKeySpecException
+ {
+ if (spec.isAssignableFrom(DSAPublicKeySpec.class) && key instanceof DSAPublicKey)
+ {
+ DSAPublicKey k = (DSAPublicKey)key;
+
+ return new DSAPublicKeySpec(k.getY(), k.getParams().getP(), k.getParams().getQ(), k.getParams().getG());
+ }
+ else if (spec.isAssignableFrom(DSAPrivateKeySpec.class) && key instanceof java.security.interfaces.DSAPrivateKey)
+ {
+ java.security.interfaces.DSAPrivateKey k = (java.security.interfaces.DSAPrivateKey)key;
+
+ return new DSAPrivateKeySpec(k.getX(), k.getParams().getP(), k.getParams().getQ(), k.getParams().getG());
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (spec.isAssignableFrom(OpenSSHPublicKeySpec.class) && key instanceof java.security.interfaces.DSAPublicKey)
+ {
+ DSAPublicKey k = (DSAPublicKey)key;
+ try
+ {
+ return new OpenSSHPublicKeySpec(OpenSSHPublicKeyUtil.encodePublicKey(new DSAPublicKeyParameters(k.getY(), new DSAParameters(k.getParams().getP(), k.getParams().getQ(), k.getParams().getG()))));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ else if (spec.isAssignableFrom(OpenSSHPrivateKeySpec.class) && key instanceof java.security.interfaces.DSAPrivateKey)
+ {
+ DSAPrivateKey k = (DSAPrivateKey)key;
+ try
+ {
+ return new OpenSSHPrivateKeySpec(OpenSSHPrivateKeyUtil.encodePrivateKey(new DSAPrivateKeyParameters(k.getX(), new DSAParameters(k.getParams().getP(), k.getParams().getQ(), k.getParams().getG()))));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPublicKeySpec.class) && key instanceof java.security.interfaces.DSAPublicKey)
+ {
+ DSAPublicKey k = (DSAPublicKey)key;
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPublicKeySpec(OpenSSHPublicKeyUtil.encodePublicKey(new DSAPublicKeyParameters(k.getY(), new DSAParameters(k.getParams().getP(), k.getParams().getQ(), k.getParams().getG()))));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec.class) && key instanceof java.security.interfaces.DSAPrivateKey)
+ {
+ DSAPrivateKey k = (DSAPrivateKey)key;
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec(OpenSSHPrivateKeyUtil.encodePrivateKey(new DSAPrivateKeyParameters(k.getX(), new DSAParameters(k.getParams().getP(), k.getParams().getQ(), k.getParams().getG()))));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ return super.engineGetKeySpec(key, spec);
+ }
+
+ protected Key engineTranslateKey(
+ Key key)
+ throws InvalidKeyException
+ {
+ if (key instanceof DSAPublicKey)
+ {
+ return new BCDSAPublicKey((DSAPublicKey)key);
+ }
+ else if (key instanceof DSAPrivateKey)
+ {
+ return new BCDSAPrivateKey((DSAPrivateKey)key);
+ }
+
+ throw new InvalidKeyException("key type unknown");
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm();
+
+ if (DSAUtil.isDsaOid(algOid))
+ {
+ return new BCDSAPrivateKey(keyInfo);
+ }
+ else
+ {
+ throw new IOException("algorithm identifier " + algOid + " in key not recognised");
+ }
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm();
+
+ if (DSAUtil.isDsaOid(algOid))
+ {
+ return new BCDSAPublicKey(keyInfo);
+ }
+ else
+ {
+ throw new IOException("algorithm identifier " + algOid + " in key not recognised");
+ }
+ }
+
+ protected PrivateKey engineGeneratePrivate(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof DSAPrivateKeySpec)
+ {
+ return new BCDSAPrivateKey((DSAPrivateKeySpec)keySpec);
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (keySpec instanceof OpenSSHPrivateKeySpec)
+ {
+ CipherParameters params = OpenSSHPrivateKeyUtil.parsePrivateKeyBlob(((OpenSSHPrivateKeySpec)keySpec).getEncoded());
+ if (params instanceof DSAPrivateKeyParameters)
+ {
+ return engineGeneratePrivate(
+ new DSAPrivateKeySpec(
+ ((DSAPrivateKeyParameters)params).getX(),
+ ((DSAPrivateKeyParameters)params).getParameters().getP(),
+ ((DSAPrivateKeyParameters)params).getParameters().getQ(),
+ ((DSAPrivateKeyParameters)params).getParameters().getG()));
+ }
+ else
+ {
+ throw new IllegalArgumentException("openssh private key is not dsa privare key");
+ }
+
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ return super.engineGeneratePrivate(keySpec);
+ }
+
+ protected PublicKey engineGeneratePublic(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof DSAPublicKeySpec)
+ {
+ try
+ {
+ return new BCDSAPublicKey((DSAPublicKeySpec)keySpec);
+ }
+ catch (final Exception e)
+ {
+ throw new InvalidKeySpecException("invalid KeySpec: " + e.getMessage())
+ {
+ public Throwable getCause()
+ {
+ return e;
+ }
+ };
+ }
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (keySpec instanceof OpenSSHPublicKeySpec)
+ {
+ CipherParameters parameters = OpenSSHPublicKeyUtil.parsePublicKey(((OpenSSHPublicKeySpec)keySpec).getEncoded());
+
+ if (parameters instanceof DSAPublicKeyParameters)
+ {
+ return engineGeneratePublic(
+ new DSAPublicKeySpec(((DSAPublicKeyParameters)parameters).getY(),
+ ((DSAPublicKeyParameters)parameters).getParameters().getP(),
+ ((DSAPublicKeyParameters)parameters).getParameters().getQ(),
+ ((DSAPublicKeyParameters)parameters).getParameters().getG()));
+ }
+
+ throw new IllegalArgumentException("openssh public key is not dsa public key");
+
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ return super.engineGeneratePublic(keySpec);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java
new file mode 100644
index 00000000..5541f662
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java
@@ -0,0 +1,180 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dsa;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.KeyPair;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.util.Hashtable;
+
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.digests.SHA256Digest;
+import com.android.internal.org.bouncycastle.crypto.generators.DSAKeyPairGenerator;
+import com.android.internal.org.bouncycastle.crypto.generators.DSAParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.params.DSAKeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameterGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPublicKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PrimeCertaintyCalculator;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.util.Integers;
+import com.android.internal.org.bouncycastle.util.Properties;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyPairGeneratorSpi
+ extends java.security.KeyPairGenerator
+{
+ private static Hashtable params = new Hashtable();
+ private static Object lock = new Object();
+
+ DSAKeyGenerationParameters param;
+ DSAKeyPairGenerator engine = new DSAKeyPairGenerator();
+ // Android-changed: Change default strength to 1024
+ // In 1.57, the default strength was changed to 2048. We keep it at 1024 for app
+ // compatibility, particularly because the default digest (SHA-1) doesn't have
+ // a sufficiently long digest to work with 2048-bit keys.
+ int strength = 1024;
+
+ SecureRandom random = CryptoServicesRegistrar.getSecureRandom();
+ boolean initialised = false;
+
+ public KeyPairGeneratorSpi()
+ {
+ super("DSA");
+ }
+
+ public void initialize(
+ int strength,
+ SecureRandom random)
+ {
+ if (strength < 512 || strength > 4096 || ((strength < 1024) && strength % 64 != 0) || (strength >= 1024 && strength % 1024 != 0))
+ {
+ throw new InvalidParameterException("strength must be from 512 - 4096 and a multiple of 1024 above 1024");
+ }
+
+ // Android-added: Treat null SecureRandom as default
+ if (random == null) {
+ random = new SecureRandom();
+ }
+
+ DSAParameterSpec spec = BouncyCastleProvider.CONFIGURATION.getDSADefaultParameters(strength);
+
+ if (spec != null)
+ {
+ param = new DSAKeyGenerationParameters(random, new DSAParameters(spec.getP(), spec.getQ(), spec.getG()));
+
+ engine.init(param);
+ this.initialised = true;
+ }
+ else
+ {
+ this.strength = strength;
+ this.random = random;
+ this.initialised = false;
+ }
+ }
+
+ public void initialize(
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ if (!(params instanceof DSAParameterSpec))
+ {
+ throw new InvalidAlgorithmParameterException("parameter object not a DSAParameterSpec");
+ }
+ DSAParameterSpec dsaParams = (DSAParameterSpec)params;
+
+ // Android-added: Treat null SecureRandom as default
+ if (random == null) {
+ random = new SecureRandom();
+ }
+
+ param = new DSAKeyGenerationParameters(random, new DSAParameters(dsaParams.getP(), dsaParams.getQ(), dsaParams.getG()));
+
+ engine.init(param);
+ initialised = true;
+ }
+
+ public KeyPair generateKeyPair()
+ {
+ if (!initialised)
+ {
+ Integer paramStrength = Integers.valueOf(strength);
+
+ if (params.containsKey(paramStrength))
+ {
+ param = (DSAKeyGenerationParameters)params.get(paramStrength);
+ }
+ else
+ {
+ synchronized (lock)
+ {
+ // we do the check again in case we were blocked by a generator for
+ // our key size.
+ if (params.containsKey(paramStrength))
+ {
+ param = (DSAKeyGenerationParameters)params.get(paramStrength);
+ }
+ else
+ {
+ DSAParametersGenerator pGen;
+ DSAParameterGenerationParameters dsaParams;
+
+ int certainty = PrimeCertaintyCalculator.getDefaultCertainty(strength);
+
+ // Typical combination of keysize and size of q.
+ // keysize = 1024, q's size = 160
+ // keysize = 2048, q's size = 224
+ // keysize = 2048, q's size = 256
+ // keysize = 3072, q's size = 256
+ // For simplicity if keysize is greater than 1024 then we choose q's size to be 256.
+ // For legacy keysize that is less than 1024-bit, we just use the 186-2 style parameters
+ if (strength == 1024)
+ {
+ pGen = new DSAParametersGenerator();
+ if (Properties.isOverrideSet("com.android.internal.org.bouncycastle.dsa.FIPS186-2for1024bits"))
+ {
+ pGen.init(strength, certainty, random);
+ }
+ else
+ {
+ dsaParams = new DSAParameterGenerationParameters(1024, 160, certainty, random);
+ pGen.init(dsaParams);
+ }
+ }
+ else if (strength > 1024)
+ {
+ dsaParams = new DSAParameterGenerationParameters(strength, 256, certainty, random);
+ pGen = new DSAParametersGenerator(new SHA256Digest());
+ pGen.init(dsaParams);
+ }
+ else
+ {
+ pGen = new DSAParametersGenerator();
+ pGen.init(strength, certainty, random);
+ }
+ param = new DSAKeyGenerationParameters(random, pGen.generateParameters());
+
+ params.put(paramStrength, param);
+ }
+ }
+ }
+
+ engine.init(param);
+ initialised = true;
+ }
+
+ AsymmetricCipherKeyPair pair = engine.generateKeyPair();
+ DSAPublicKeyParameters pub = (DSAPublicKeyParameters)pair.getPublic();
+ DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)pair.getPrivate();
+
+ return new KeyPair(new BCDSAPublicKey(pub), new BCDSAPrivateKey(priv));
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
new file mode 100644
index 00000000..e9fe33f4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
@@ -0,0 +1,189 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.ec;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable;
+import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECPoint;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveSpec;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AlgorithmParametersSpi
+ extends java.security.AlgorithmParametersSpi
+{
+ private ECParameterSpec ecParameterSpec;
+ private String curveName;
+
+ protected boolean isASN1FormatString(String format)
+ {
+ return format == null || format.equals("ASN.1");
+ }
+
+ @Override
+ protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec)
+ throws InvalidParameterSpecException
+ {
+ if (algorithmParameterSpec instanceof ECGenParameterSpec)
+ {
+ ECGenParameterSpec ecGenParameterSpec = (ECGenParameterSpec)algorithmParameterSpec;
+ X9ECParameters params = ECUtils.getDomainParametersFromGenSpec(ecGenParameterSpec);
+
+ if (params == null)
+ {
+ throw new InvalidParameterSpecException("EC curve name not recognized: " + ecGenParameterSpec.getName());
+ }
+ curveName = ecGenParameterSpec.getName();
+ ECParameterSpec baseSpec = EC5Util.convertToSpec(params);
+ ecParameterSpec = new ECNamedCurveSpec(curveName,
+ baseSpec.getCurve(), baseSpec.getGenerator(), baseSpec.getOrder(), BigInteger.valueOf(baseSpec.getCofactor()));
+ }
+ else if (algorithmParameterSpec instanceof ECParameterSpec)
+ {
+ if (algorithmParameterSpec instanceof ECNamedCurveSpec)
+ {
+ curveName = ((ECNamedCurveSpec)algorithmParameterSpec).getName();
+ }
+ else
+ {
+ curveName = null;
+ }
+ ecParameterSpec = (ECParameterSpec)algorithmParameterSpec;
+ }
+ else
+ {
+ throw new InvalidParameterSpecException("AlgorithmParameterSpec class not recognized: " + algorithmParameterSpec.getClass().getName());
+ }
+ }
+
+ @Override
+ protected void engineInit(byte[] bytes)
+ throws IOException
+ {
+ engineInit(bytes, "ASN.1");
+ }
+
+ @Override
+ protected void engineInit(byte[] bytes, String format)
+ throws IOException
+ {
+ if (isASN1FormatString(format))
+ {
+ X962Parameters params = X962Parameters.getInstance(bytes);
+
+ ECCurve curve = EC5Util.getCurve(BouncyCastleProvider.CONFIGURATION, params);
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier curveId = ASN1ObjectIdentifier.getInstance(params.getParameters());
+
+ curveName = ECNamedCurveTable.getName(curveId);
+ if (curveName == null)
+ {
+ curveName = curveId.getId();
+ }
+ }
+
+ ecParameterSpec = EC5Util.convertToSpec(params, curve);
+ }
+ else
+ {
+ throw new IOException("Unknown encoded parameters format in AlgorithmParameters object: " + format);
+ }
+ }
+
+ @Override
+ protected <T extends AlgorithmParameterSpec> T engineGetParameterSpec(Class<T> paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (ECParameterSpec.class.isAssignableFrom(paramSpec) || paramSpec == AlgorithmParameterSpec.class)
+ {
+ return (T)ecParameterSpec;
+ }
+ else if (ECGenParameterSpec.class.isAssignableFrom(paramSpec))
+ {
+ if (curveName != null)
+ {
+ ASN1ObjectIdentifier namedCurveOid = ECUtil.getNamedCurveOid(curveName);
+
+ if (namedCurveOid != null)
+ {
+ return (T)new ECGenParameterSpec(namedCurveOid.getId());
+ }
+ return (T)new ECGenParameterSpec(curveName);
+ }
+ else
+ {
+ ASN1ObjectIdentifier namedCurveOid = ECUtil.getNamedCurveOid(EC5Util.convertSpec(ecParameterSpec));
+
+ if (namedCurveOid != null)
+ {
+ return (T)new ECGenParameterSpec(namedCurveOid.getId());
+ }
+ }
+ }
+ throw new InvalidParameterSpecException("EC AlgorithmParameters cannot convert to " + paramSpec.getName());
+ }
+
+ @Override
+ protected byte[] engineGetEncoded()
+ throws IOException
+ {
+ return engineGetEncoded("ASN.1");
+ }
+
+ @Override
+ protected byte[] engineGetEncoded(String format)
+ throws IOException
+ {
+ if (isASN1FormatString(format))
+ {
+ X962Parameters params;
+
+ if (ecParameterSpec == null) // implicitly CA
+ {
+ params = new X962Parameters(DERNull.INSTANCE);
+ }
+ else if (curveName != null)
+ {
+ params = new X962Parameters(ECUtil.getNamedCurveOid(curveName));
+ }
+ else
+ {
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec ecSpec = EC5Util.convertSpec(ecParameterSpec);
+ X9ECParameters ecP = new X9ECParameters(
+ ecSpec.getCurve(),
+ new X9ECPoint(ecSpec.getG(), false),
+ ecSpec.getN(),
+ ecSpec.getH(),
+ ecSpec.getSeed());
+
+ params = new X962Parameters(ecP);
+ }
+
+ return params.getEncoded();
+ }
+
+ throw new IOException("Unknown parameters format in AlgorithmParameters object: " + format);
+ }
+
+ @Override
+ protected String engineToString()
+ {
+ return "EC Parameters";
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
new file mode 100644
index 00000000..051e0b62
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
@@ -0,0 +1,409 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.ec;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.interfaces.ECPrivateKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPrivateKeySpec;
+import java.security.spec.EllipticCurve;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
+import com.android.internal.org.bouncycastle.jce.interfaces.ECPointEncoder;
+import com.android.internal.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCECPrivateKey
+ implements ECPrivateKey, com.android.internal.org.bouncycastle.jce.interfaces.ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder
+{
+ static final long serialVersionUID = 994553197664784084L;
+
+ private String algorithm = "EC";
+ private boolean withCompression;
+
+ private transient BigInteger d;
+ private transient ECParameterSpec ecSpec;
+ private transient ProviderConfiguration configuration;
+ private transient DERBitString publicKey;
+
+ private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
+ protected BCECPrivateKey()
+ {
+ }
+
+ public BCECPrivateKey(
+ ECPrivateKey key,
+ ProviderConfiguration configuration)
+ {
+ this.d = key.getS();
+ this.algorithm = key.getAlgorithm();
+ this.ecSpec = key.getParams();
+ this.configuration = configuration;
+ }
+
+ public BCECPrivateKey(
+ String algorithm,
+ com.android.internal.org.bouncycastle.jce.spec.ECPrivateKeySpec spec,
+ ProviderConfiguration configuration)
+ {
+ this.algorithm = algorithm;
+ this.d = spec.getD();
+
+ if (spec.getParams() != null) // can be null if implicitlyCA
+ {
+ ECCurve curve = spec.getParams().getCurve();
+ EllipticCurve ellipticCurve;
+
+ ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed());
+
+ this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams());
+ }
+ else
+ {
+ this.ecSpec = null;
+ }
+
+ this.configuration = configuration;
+ }
+
+
+ public BCECPrivateKey(
+ String algorithm,
+ ECPrivateKeySpec spec,
+ ProviderConfiguration configuration)
+ {
+ this.algorithm = algorithm;
+ this.d = spec.getS();
+ this.ecSpec = spec.getParams();
+ this.configuration = configuration;
+ }
+
+ public BCECPrivateKey(
+ String algorithm,
+ BCECPrivateKey key)
+ {
+ this.algorithm = algorithm;
+ this.d = key.d;
+ this.ecSpec = key.ecSpec;
+ this.withCompression = key.withCompression;
+ this.attrCarrier = key.attrCarrier;
+ this.publicKey = key.publicKey;
+ this.configuration = key.configuration;
+ }
+
+ public BCECPrivateKey(
+ String algorithm,
+ ECPrivateKeyParameters params,
+ BCECPublicKey pubKey,
+ ECParameterSpec spec,
+ ProviderConfiguration configuration)
+ {
+ this.algorithm = algorithm;
+ this.d = params.getD();
+ this.configuration = configuration;
+
+ if (spec == null)
+ {
+ ECDomainParameters dp = params.getParameters();
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed());
+
+ this.ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ EC5Util.convertPoint(dp.getG()),
+ dp.getN(),
+ dp.getH().intValue());
+ }
+ else
+ {
+ this.ecSpec = spec;
+ }
+
+ this.publicKey = getPublicKeyDetails(pubKey);
+ }
+
+ public BCECPrivateKey(
+ String algorithm,
+ ECPrivateKeyParameters params,
+ BCECPublicKey pubKey,
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec spec,
+ ProviderConfiguration configuration)
+ {
+ this.algorithm = algorithm;
+ this.d = params.getD();
+ this.configuration = configuration;
+
+ if (spec == null)
+ {
+ ECDomainParameters dp = params.getParameters();
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed());
+
+ this.ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ EC5Util.convertPoint(dp.getG()),
+ dp.getN(),
+ dp.getH().intValue());
+ }
+ else
+ {
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed());
+
+ this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec);
+ }
+
+ try
+ {
+ this.publicKey = getPublicKeyDetails(pubKey);
+ }
+ catch (Exception e)
+ {
+ this.publicKey = null; // not all curves are encodable
+ }
+ }
+
+ public BCECPrivateKey(
+ String algorithm,
+ ECPrivateKeyParameters params,
+ ProviderConfiguration configuration)
+ {
+ this.algorithm = algorithm;
+ this.d = params.getD();
+ this.ecSpec = null;
+ this.configuration = configuration;
+ }
+
+ BCECPrivateKey(
+ String algorithm,
+ PrivateKeyInfo info,
+ ProviderConfiguration configuration)
+ throws IOException
+ {
+ this.algorithm = algorithm;
+ this.configuration = configuration;
+ populateFromPrivKeyInfo(info);
+ }
+
+ private void populateFromPrivKeyInfo(PrivateKeyInfo info)
+ throws IOException
+ {
+ X962Parameters params = X962Parameters.getInstance(info.getPrivateKeyAlgorithm().getParameters());
+
+ ECCurve curve = EC5Util.getCurve(configuration, params);
+ ecSpec = EC5Util.convertToSpec(params, curve);
+
+ ASN1Encodable privKey = info.parsePrivateKey();
+ if (privKey instanceof ASN1Integer)
+ {
+ ASN1Integer derD = ASN1Integer.getInstance(privKey);
+
+ this.d = derD.getValue();
+ }
+ else
+ {
+ com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey ec = com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(privKey);
+
+ this.d = ec.getKey();
+ this.publicKey = ec.getPublicKey();
+ }
+ }
+
+ public String getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ /**
+ * return the encoding format we produce in getEncoded().
+ *
+ * @return the string "PKCS#8"
+ */
+ public String getFormat()
+ {
+ return "PKCS#8";
+ }
+
+ /**
+ * Return a PKCS8 representation of the key. The sequence returned
+ * represents a full PrivateKeyInfo object.
+ *
+ * @return a PKCS8 representation of the key.
+ */
+ public byte[] getEncoded()
+ {
+ X962Parameters params = ECUtils.getDomainParametersFromName(ecSpec, withCompression);
+
+ int orderBitLength;
+ if (ecSpec == null)
+ {
+ orderBitLength = ECUtil.getOrderBitLength(configuration, null, this.getS());
+ }
+ else
+ {
+ orderBitLength = ECUtil.getOrderBitLength(configuration, ecSpec.getOrder(), this.getS());
+ }
+
+ PrivateKeyInfo info;
+ com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey keyStructure;
+
+ if (publicKey != null)
+ {
+ keyStructure = new com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), publicKey, params);
+ }
+ else
+ {
+ keyStructure = new com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params);
+ }
+
+ try
+ {
+ info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), keyStructure);
+
+ return info.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ public ECParameterSpec getParams()
+ {
+ return ecSpec;
+ }
+
+ public com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec getParameters()
+ {
+ if (ecSpec == null)
+ {
+ return null;
+ }
+
+ return EC5Util.convertSpec(ecSpec);
+ }
+
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec()
+ {
+ if (ecSpec != null)
+ {
+ return EC5Util.convertSpec(ecSpec);
+ }
+
+ return configuration.getEcImplicitlyCa();
+ }
+
+ public BigInteger getS()
+ {
+ return d;
+ }
+
+ public BigInteger getD()
+ {
+ return d;
+ }
+
+ public void setBagAttribute(
+ ASN1ObjectIdentifier oid,
+ ASN1Encodable attribute)
+ {
+ attrCarrier.setBagAttribute(oid, attribute);
+ }
+
+ public ASN1Encodable getBagAttribute(
+ ASN1ObjectIdentifier oid)
+ {
+ return attrCarrier.getBagAttribute(oid);
+ }
+
+ public Enumeration getBagAttributeKeys()
+ {
+ return attrCarrier.getBagAttributeKeys();
+ }
+
+ public void setPointFormat(String style)
+ {
+ withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof BCECPrivateKey))
+ {
+ return false;
+ }
+
+ BCECPrivateKey other = (BCECPrivateKey)o;
+
+ return getD().equals(other.getD()) && (engineGetSpec().equals(other.engineGetSpec()));
+ }
+
+ public int hashCode()
+ {
+ return getD().hashCode() ^ engineGetSpec().hashCode();
+ }
+
+ public String toString()
+ {
+ return ECUtil.privateKeyToString("EC", d, engineGetSpec());
+ }
+
+ private DERBitString getPublicKeyDetails(BCECPublicKey pub)
+ {
+ try
+ {
+ SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded()));
+
+ return info.getPublicKeyData();
+ }
+ catch (IOException e)
+ { // should never happen
+ return null;
+ }
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ byte[] enc = (byte[])in.readObject();
+
+ this.configuration = BouncyCastleProvider.CONFIGURATION;
+
+ populateFromPrivKeyInfo(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc)));
+
+ this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ out.writeObject(this.getEncoded());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
new file mode 100644
index 00000000..13e42f84
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
@@ -0,0 +1,349 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.ec;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.EllipticCurve;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECPoint;
+import com.android.internal.org.bouncycastle.asn1.x9.X9IntegerConverter;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
+import com.android.internal.org.bouncycastle.jce.interfaces.ECPointEncoder;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.util.Properties;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCECPublicKey
+ implements ECPublicKey, com.android.internal.org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder
+{
+ static final long serialVersionUID = 2422789860422731812L;
+
+ private String algorithm = "EC";
+ private boolean withCompression;
+
+ private transient ECPublicKeyParameters ecPublicKey;
+ private transient ECParameterSpec ecSpec;
+ private transient ProviderConfiguration configuration;
+
+ public BCECPublicKey(
+ String algorithm,
+ BCECPublicKey key)
+ {
+ this.algorithm = algorithm;
+ this.ecPublicKey = key.ecPublicKey;
+ this.ecSpec = key.ecSpec;
+ this.withCompression = key.withCompression;
+ this.configuration = key.configuration;
+ }
+
+ public BCECPublicKey(
+ String algorithm,
+ ECPublicKeySpec spec,
+ ProviderConfiguration configuration)
+ {
+ this.algorithm = algorithm;
+ this.ecSpec = spec.getParams();
+ this.ecPublicKey = new ECPublicKeyParameters(EC5Util.convertPoint(ecSpec, spec.getW()), EC5Util.getDomainParameters(configuration, spec.getParams()));
+ this.configuration = configuration;
+ }
+
+ public BCECPublicKey(
+ String algorithm,
+ com.android.internal.org.bouncycastle.jce.spec.ECPublicKeySpec spec,
+ ProviderConfiguration configuration)
+ {
+ this.algorithm = algorithm;
+
+ if (spec.getParams() != null) // can be null if implictlyCa
+ {
+ ECCurve curve = spec.getParams().getCurve();
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed());
+
+ // this may seem a little long-winded but it's how we pick up the custom curve.
+ this.ecPublicKey = new ECPublicKeyParameters(
+ spec.getQ(), ECUtil.getDomainParameters(configuration, spec.getParams()));
+ this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams());
+ }
+ else
+ {
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec s = configuration.getEcImplicitlyCa();
+
+ this.ecPublicKey = new ECPublicKeyParameters(s.getCurve().createPoint(spec.getQ().getAffineXCoord().toBigInteger(), spec.getQ().getAffineYCoord().toBigInteger()), EC5Util.getDomainParameters(configuration, (ECParameterSpec)null));
+ this.ecSpec = null;
+ }
+
+ this.configuration = configuration;
+ }
+
+ public BCECPublicKey(
+ String algorithm,
+ ECPublicKeyParameters params,
+ ECParameterSpec spec,
+ ProviderConfiguration configuration)
+ {
+ ECDomainParameters dp = params.getParameters();
+
+ this.algorithm = algorithm;
+ this.ecPublicKey = params;
+
+ if (spec == null)
+ {
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed());
+
+ this.ecSpec = createSpec(ellipticCurve, dp);
+ }
+ else
+ {
+ this.ecSpec = spec;
+ }
+
+ this.configuration = configuration;
+ }
+
+ public BCECPublicKey(
+ String algorithm,
+ ECPublicKeyParameters params,
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec spec,
+ ProviderConfiguration configuration)
+ {
+ ECDomainParameters dp = params.getParameters();
+
+ this.algorithm = algorithm;
+
+ if (spec == null)
+ {
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed());
+
+ this.ecSpec = createSpec(ellipticCurve, dp);
+ }
+ else
+ {
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed());
+
+ this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec);
+ }
+
+ this.ecPublicKey = params;
+ this.configuration = configuration;
+ }
+
+ /*
+ * called for implicitCA
+ */
+ public BCECPublicKey(
+ String algorithm,
+ ECPublicKeyParameters params,
+ ProviderConfiguration configuration)
+ {
+ this.algorithm = algorithm;
+ this.ecPublicKey = params;
+ this.ecSpec = null;
+ this.configuration = configuration;
+ }
+
+ public BCECPublicKey(
+ ECPublicKey key,
+ ProviderConfiguration configuration)
+ {
+ this.algorithm = key.getAlgorithm();
+ this.ecSpec = key.getParams();
+ this.ecPublicKey = new ECPublicKeyParameters(EC5Util.convertPoint(this.ecSpec, key.getW()), EC5Util.getDomainParameters(configuration, key.getParams()));
+ this.configuration = configuration;
+ }
+
+ BCECPublicKey(
+ String algorithm,
+ SubjectPublicKeyInfo info,
+ ProviderConfiguration configuration)
+ {
+ this.algorithm = algorithm;
+ this.configuration = configuration;
+ populateFromPubKeyInfo(info);
+ }
+
+ private ECParameterSpec createSpec(EllipticCurve ellipticCurve, ECDomainParameters dp)
+ {
+ return new ECParameterSpec(
+ ellipticCurve,
+ EC5Util.convertPoint(dp.getG()),
+ dp.getN(),
+ dp.getH().intValue());
+ }
+
+ private void populateFromPubKeyInfo(SubjectPublicKeyInfo info)
+ {
+ X962Parameters params = X962Parameters.getInstance(info.getAlgorithm().getParameters());
+ ECCurve curve = EC5Util.getCurve(configuration, params);
+ ecSpec = EC5Util.convertToSpec(params, curve);
+
+ DERBitString bits = info.getPublicKeyData();
+ byte[] data = bits.getBytes();
+ ASN1OctetString key = new DEROctetString(data);
+
+ //
+ // extra octet string - one of our old certs...
+ //
+ if (data[0] == 0x04 && data[1] == data.length - 2
+ && (data[2] == 0x02 || data[2] == 0x03))
+ {
+ int qLength = new X9IntegerConverter().getByteLength(curve);
+
+ if (qLength >= data.length - 3)
+ {
+ try
+ {
+ key = (ASN1OctetString) ASN1Primitive.fromByteArray(data);
+ }
+ catch (IOException ex)
+ {
+ throw new IllegalArgumentException("error recovering public key");
+ }
+ }
+ }
+
+ X9ECPoint derQ = new X9ECPoint(curve, key);
+
+ this.ecPublicKey = new ECPublicKeyParameters(derQ.getPoint(), ECUtil.getDomainParameters(configuration, params));
+ }
+
+ public String getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ public byte[] getEncoded()
+ {
+ boolean compress = withCompression || Properties.isOverrideSet("com.android.internal.org.bouncycastle.ec.enable_pc");
+
+ AlgorithmIdentifier algId = new AlgorithmIdentifier(
+ X9ObjectIdentifiers.id_ecPublicKey,
+ ECUtils.getDomainParametersFromName(ecSpec, compress));
+
+ byte[] pubKeyOctets = ecPublicKey.getQ().getEncoded(compress);
+
+ // stored curve is null if ImplicitlyCa
+ return KeyUtil.getEncodedSubjectPublicKeyInfo(algId, pubKeyOctets);
+ }
+
+ public ECParameterSpec getParams()
+ {
+ return ecSpec;
+ }
+
+ public com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec getParameters()
+ {
+ if (ecSpec == null) // implictlyCA
+ {
+ return null;
+ }
+
+ return EC5Util.convertSpec(ecSpec);
+ }
+
+ public ECPoint getW()
+ {
+ return EC5Util.convertPoint(ecPublicKey.getQ());
+ }
+
+ public com.android.internal.org.bouncycastle.math.ec.ECPoint getQ()
+ {
+ com.android.internal.org.bouncycastle.math.ec.ECPoint q = ecPublicKey.getQ();
+
+ if (ecSpec == null)
+ {
+ return q.getDetachedPoint();
+ }
+
+ return q;
+ }
+
+ ECPublicKeyParameters engineGetKeyParameters()
+ {
+ return ecPublicKey;
+ }
+
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec()
+ {
+ if (ecSpec != null)
+ {
+ return EC5Util.convertSpec(ecSpec);
+ }
+
+ return configuration.getEcImplicitlyCa();
+ }
+
+ public String toString()
+ {
+ return ECUtil.publicKeyToString("EC", ecPublicKey.getQ(), engineGetSpec());
+ }
+
+ public void setPointFormat(String style)
+ {
+ withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof BCECPublicKey))
+ {
+ return false;
+ }
+
+ BCECPublicKey other = (BCECPublicKey)o;
+
+ return ecPublicKey.getQ().equals(other.ecPublicKey.getQ()) && (engineGetSpec().equals(other.engineGetSpec()));
+ }
+
+ public int hashCode()
+ {
+ return ecPublicKey.getQ().hashCode() ^ engineGetSpec().hashCode();
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ byte[] enc = (byte[])in.readObject();
+
+ this.configuration = BouncyCastleProvider.CONFIGURATION;
+
+ populateFromPubKeyInfo(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc)));
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ out.writeObject(this.getEncoded());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
new file mode 100644
index 00000000..d07bebfd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
@@ -0,0 +1,98 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.ec;
+
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.PublicKey;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECPoint;
+import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveSpec;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+
+class ECUtils
+{
+ static AsymmetricKeyParameter generatePublicKeyParameter(
+ PublicKey key)
+ throws InvalidKeyException
+ {
+ return (key instanceof BCECPublicKey) ? ((BCECPublicKey)key).engineGetKeyParameters() : ECUtil.generatePublicKeyParameter(key);
+ }
+
+ static X9ECParameters getDomainParametersFromGenSpec(ECGenParameterSpec genSpec)
+ {
+ return getDomainParametersFromName(genSpec.getName());
+ }
+
+ static X9ECParameters getDomainParametersFromName(String curveName)
+ {
+ X9ECParameters domainParameters;
+ try
+ {
+ if (curveName.charAt(0) >= '0' && curveName.charAt(0) <= '2')
+ {
+ ASN1ObjectIdentifier oidID = new ASN1ObjectIdentifier(curveName);
+ domainParameters = ECUtil.getNamedCurveByOid(oidID);
+ }
+ else
+ {
+ if (curveName.indexOf(' ') > 0)
+ {
+ curveName = curveName.substring(curveName.indexOf(' ') + 1);
+ domainParameters = ECUtil.getNamedCurveByName(curveName);
+ }
+ else
+ {
+ domainParameters = ECUtil.getNamedCurveByName(curveName);
+ }
+ }
+ }
+ catch (IllegalArgumentException ex)
+ {
+ domainParameters = ECUtil.getNamedCurveByName(curveName);
+ }
+ return domainParameters;
+ }
+
+ static X962Parameters getDomainParametersFromName(ECParameterSpec ecSpec, boolean withCompression)
+ {
+ X962Parameters params;
+
+ if (ecSpec instanceof ECNamedCurveSpec)
+ {
+ ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName());
+ if (curveOid == null)
+ {
+ curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName());
+ }
+ params = new X962Parameters(curveOid);
+ }
+ else if (ecSpec == null)
+ {
+ params = new X962Parameters(DERNull.INSTANCE);
+ }
+ else
+ {
+ ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve());
+
+ X9ECParameters ecP = new X9ECParameters(
+ curve,
+ new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), withCompression),
+ ecSpec.getOrder(),
+ BigInteger.valueOf(ecSpec.getCofactor()),
+ ecSpec.getCurve().getSeed());
+
+ params = new X962Parameters(ecP);
+ }
+
+ return params;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
new file mode 100644
index 00000000..324623c8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
@@ -0,0 +1,834 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.ec;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import com.android.internal.org.bouncycastle.asn1.x9.X9IntegerConverter;
+import com.android.internal.org.bouncycastle.crypto.BasicAgreement;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DerivationFunction;
+import com.android.internal.org.bouncycastle.crypto.agreement.ECDHBasicAgreement;
+// BEGIN Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.agreement.ECDHCBasicAgreement;
+// import org.bouncycastle.crypto.agreement.ECDHCUnifiedAgreement;
+// import org.bouncycastle.crypto.agreement.ECMQVBasicAgreement;
+// import org.bouncycastle.crypto.agreement.kdf.ConcatenationKDFGenerator;
+// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
+// import org.bouncycastle.crypto.generators.KDF2BytesGenerator;
+// import org.bouncycastle.crypto.params.ECDHUPrivateParameters;
+// import org.bouncycastle.crypto.params.ECDHUPublicParameters;
+// END Android-removed: Unsupported algorithms
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPublicKeyParameters;
+// BEGIN Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.params.MQVPrivateParameters;
+// import org.bouncycastle.crypto.params.MQVPublicParameters;
+// import org.bouncycastle.crypto.util.DigestFactory;
+// END Android-removed: Unsupported algorithms
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.BaseAgreementSpi;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+// BEGIN Android-removed: Unsupported algorithms
+// import org.bouncycastle.jcajce.spec.DHUParameterSpec;
+// import org.bouncycastle.jcajce.spec.MQVParameterSpec;
+// END Android-removed: Unsupported algorithms
+import com.android.internal.org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec;
+import com.android.internal.org.bouncycastle.jce.interfaces.ECPrivateKey;
+import com.android.internal.org.bouncycastle.jce.interfaces.ECPublicKey;
+// BEGIN Android-removed: Unsupported algorithms
+// import org.bouncycastle.jce.interfaces.MQVPrivateKey;
+// import org.bouncycastle.jce.interfaces.MQVPublicKey;
+// END Android-removed: Unsupported algorithms
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * Diffie-Hellman key agreement using elliptic curve keys, ala IEEE P1363
+ * both the simple one, and the simple one with cofactors are supported.
+ * <p>
+ * Also, MQV key agreement per SEC-1
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyAgreementSpi
+ extends BaseAgreementSpi
+{
+ private static final X9IntegerConverter converter = new X9IntegerConverter();
+
+ private String kaAlgorithm;
+
+ private ECDomainParameters parameters;
+ private Object agreement;
+
+ // Android-removed: Unsupported algorithms
+ // private MQVParameterSpec mqvParameters;
+ // private DHUParameterSpec dheParameters;
+ private byte[] result;
+
+ protected KeyAgreementSpi(
+ String kaAlgorithm,
+ BasicAgreement agreement,
+ DerivationFunction kdf)
+ {
+ super(kaAlgorithm, kdf);
+
+ this.kaAlgorithm = kaAlgorithm;
+ this.agreement = agreement;
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ protected KeyAgreementSpi(
+ String kaAlgorithm,
+ ECDHCUnifiedAgreement agreement,
+ DerivationFunction kdf)
+ {
+ super(kaAlgorithm, kdf);
+
+ this.kaAlgorithm = kaAlgorithm;
+ this.agreement = agreement;
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ protected byte[] bigIntToBytes(
+ BigInteger r)
+ {
+ return converter.integerToBytes(r, converter.getByteLength(parameters.getCurve()));
+ }
+
+ protected Key engineDoPhase(
+ Key key,
+ boolean lastPhase)
+ throws InvalidKeyException, IllegalStateException
+ {
+ if (parameters == null)
+ {
+ throw new IllegalStateException(kaAlgorithm + " not initialised.");
+ }
+
+ if (!lastPhase)
+ {
+ throw new IllegalStateException(kaAlgorithm + " can only be between two parties.");
+ }
+
+ CipherParameters pubKey;
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ if (agreement instanceof ECMQVBasicAgreement)
+ {
+ if (!(key instanceof MQVPublicKey))
+ {
+ ECPublicKeyParameters staticKey = (ECPublicKeyParameters)
+ ECUtils.generatePublicKeyParameter((PublicKey)key);
+ ECPublicKeyParameters ephemKey = (ECPublicKeyParameters)
+ ECUtils.generatePublicKeyParameter(mqvParameters.getOtherPartyEphemeralKey());
+
+ pubKey = new MQVPublicParameters(staticKey, ephemKey);
+ }
+ else
+ {
+ MQVPublicKey mqvPubKey = (MQVPublicKey)key;
+ ECPublicKeyParameters staticKey = (ECPublicKeyParameters)
+ ECUtils.generatePublicKeyParameter(mqvPubKey.getStaticKey());
+ ECPublicKeyParameters ephemKey = (ECPublicKeyParameters)
+ ECUtils.generatePublicKeyParameter(mqvPubKey.getEphemeralKey());
+
+ pubKey = new MQVPublicParameters(staticKey, ephemKey);
+ }
+ }
+ else if (agreement instanceof ECDHCUnifiedAgreement)
+ {
+ ECPublicKeyParameters staticKey = (ECPublicKeyParameters)
+ ECUtils.generatePublicKeyParameter((PublicKey)key);
+ ECPublicKeyParameters ephemKey = (ECPublicKeyParameters)
+ ECUtils.generatePublicKeyParameter(dheParameters.getOtherPartyEphemeralKey());
+
+ pubKey = new ECDHUPublicParameters(staticKey, ephemKey);
+ }
+ else
+ */
+ // END Android-removed: Unsupported algorithms
+ {
+ if (!(key instanceof PublicKey))
+ {
+ throw new InvalidKeyException(kaAlgorithm + " key agreement requires "
+ + getSimpleName(ECPublicKey.class) + " for doPhase");
+ }
+
+ pubKey = ECUtils.generatePublicKeyParameter((PublicKey)key);
+ }
+
+ try
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ if (agreement instanceof BasicAgreement)
+ {
+ */
+ // END Android-removed: Unsupported algorithms
+ result = bigIntToBytes(((BasicAgreement)agreement).calculateAgreement(pubKey));
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ }
+ else
+ {
+ result = ((ECDHCUnifiedAgreement)agreement).calculateAgreement(pubKey);
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+ catch (final Exception e)
+ {
+ throw new InvalidKeyException("calculation failed: " + e.getMessage())
+ {
+ public Throwable getCause()
+ {
+ return e;
+ }
+ };
+ }
+
+ return null;
+ }
+
+ protected void engineInit(
+ Key key,
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ // Android-removed: Unsupported algorithms
+ // if (params != null &&
+ // !(params instanceof MQVParameterSpec || params instanceof UserKeyingMaterialSpec || params instanceof DHUParameterSpec))
+ if (params != null && !(params instanceof UserKeyingMaterialSpec))
+ {
+ throw new InvalidAlgorithmParameterException("No algorithm parameters supported");
+ }
+
+ initFromKey(key, params);
+ }
+
+ protected void engineInit(
+ Key key,
+ SecureRandom random)
+ throws InvalidKeyException
+ {
+ try
+ {
+ initFromKey(key, null);
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ // this should never occur.
+ throw new InvalidKeyException(e.getMessage());
+ }
+ }
+
+ private void initFromKey(Key key, AlgorithmParameterSpec parameterSpec)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ if (agreement instanceof ECMQVBasicAgreement)
+ {
+ mqvParameters = null;
+ if (!(key instanceof MQVPrivateKey) && !(parameterSpec instanceof MQVParameterSpec))
+ {
+ throw new InvalidAlgorithmParameterException(kaAlgorithm + " key agreement requires "
+ + getSimpleName(MQVParameterSpec.class) + " for initialisation");
+ }
+
+ ECPrivateKeyParameters staticPrivKey;
+ ECPrivateKeyParameters ephemPrivKey;
+ ECPublicKeyParameters ephemPubKey;
+ if (key instanceof MQVPrivateKey)
+ {
+ MQVPrivateKey mqvPrivKey = (MQVPrivateKey)key;
+ staticPrivKey = (ECPrivateKeyParameters)
+ ECUtil.generatePrivateKeyParameter(mqvPrivKey.getStaticPrivateKey());
+ ephemPrivKey = (ECPrivateKeyParameters)
+ ECUtil.generatePrivateKeyParameter(mqvPrivKey.getEphemeralPrivateKey());
+
+ ephemPubKey = null;
+ if (mqvPrivKey.getEphemeralPublicKey() != null)
+ {
+ ephemPubKey = (ECPublicKeyParameters)
+ ECUtils.generatePublicKeyParameter(mqvPrivKey.getEphemeralPublicKey());
+ }
+ }
+ else
+ {
+ MQVParameterSpec mqvParameterSpec = (MQVParameterSpec)parameterSpec;
+
+ staticPrivKey = (ECPrivateKeyParameters)
+ ECUtil.generatePrivateKeyParameter((PrivateKey)key);
+ ephemPrivKey = (ECPrivateKeyParameters)
+ ECUtil.generatePrivateKeyParameter(mqvParameterSpec.getEphemeralPrivateKey());
+
+ ephemPubKey = null;
+ if (mqvParameterSpec.getEphemeralPublicKey() != null)
+ {
+ ephemPubKey = (ECPublicKeyParameters)
+ ECUtils.generatePublicKeyParameter(mqvParameterSpec.getEphemeralPublicKey());
+ }
+ mqvParameters = mqvParameterSpec;
+ ukmParameters = mqvParameterSpec.getUserKeyingMaterial();
+ }
+
+ MQVPrivateParameters localParams = new MQVPrivateParameters(staticPrivKey, ephemPrivKey, ephemPubKey);
+ this.parameters = staticPrivKey.getParameters();
+
+ // TODO Validate that all the keys are using the same parameters?
+
+ ((ECMQVBasicAgreement)agreement).init(localParams);
+ }
+ else if (parameterSpec instanceof DHUParameterSpec)
+ {
+ if (!(agreement instanceof ECDHCUnifiedAgreement))
+ {
+ throw new InvalidAlgorithmParameterException(kaAlgorithm + " key agreement cannot be used with "
+ + getSimpleName(DHUParameterSpec.class));
+ }
+ DHUParameterSpec dheParameterSpec = (DHUParameterSpec)parameterSpec;
+ ECPrivateKeyParameters staticPrivKey;
+ ECPrivateKeyParameters ephemPrivKey;
+ ECPublicKeyParameters ephemPubKey;
+
+ staticPrivKey = (ECPrivateKeyParameters)
+ ECUtil.generatePrivateKeyParameter((PrivateKey)key);
+ ephemPrivKey = (ECPrivateKeyParameters)
+ ECUtil.generatePrivateKeyParameter(dheParameterSpec.getEphemeralPrivateKey());
+
+ ephemPubKey = null;
+ if (dheParameterSpec.getEphemeralPublicKey() != null)
+ {
+ ephemPubKey = (ECPublicKeyParameters)
+ ECUtils.generatePublicKeyParameter(dheParameterSpec.getEphemeralPublicKey());
+ }
+ dheParameters = dheParameterSpec;
+ ukmParameters = dheParameterSpec.getUserKeyingMaterial();
+
+ ECDHUPrivateParameters localParams = new ECDHUPrivateParameters(staticPrivKey, ephemPrivKey, ephemPubKey);
+ this.parameters = staticPrivKey.getParameters();
+
+ ((ECDHCUnifiedAgreement)agreement).init(localParams);
+ }
+ else
+ */
+ // END Android-removed: Unsupported algorithms
+ {
+ if (!(key instanceof PrivateKey))
+ {
+ throw new InvalidKeyException(kaAlgorithm + " key agreement requires "
+ + getSimpleName(ECPrivateKey.class) + " for initialisation");
+ }
+ if (kdf == null && parameterSpec instanceof UserKeyingMaterialSpec)
+ {
+ throw new InvalidAlgorithmParameterException("no KDF specified for UserKeyingMaterialSpec");
+ }
+ ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)ECUtil.generatePrivateKeyParameter((PrivateKey)key);
+ this.parameters = privKey.getParameters();
+ ukmParameters = (parameterSpec instanceof UserKeyingMaterialSpec) ? ((UserKeyingMaterialSpec)parameterSpec).getUserKeyingMaterial() : null;
+ ((BasicAgreement)agreement).init(privKey);
+ }
+ }
+
+ private static String getSimpleName(Class clazz)
+ {
+ String fullName = clazz.getName();
+
+ return fullName.substring(fullName.lastIndexOf('.') + 1);
+ }
+
+ protected byte[] calcSecret()
+ {
+ return Arrays.clone(result);
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class DH
+ extends KeyAgreementSpi
+ {
+ public DH()
+ {
+ super("ECDH", new ECDHBasicAgreement(), null);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class DHC
+ extends KeyAgreementSpi
+ {
+ public DHC()
+ {
+ super("ECDHC", new ECDHCBasicAgreement(), null);
+ }
+ }
+
+ public static class MQV
+ extends KeyAgreementSpi
+ {
+ public MQV()
+ {
+ super("ECMQV", new ECMQVBasicAgreement(), null);
+ }
+ }
+
+ public static class DHUC
+ extends KeyAgreementSpi
+ {
+ public DHUC()
+ {
+ super("ECCDHU", new ECDHCUnifiedAgreement(), null);
+ }
+ }
+
+ public static class DHwithSHA1KDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA1KDF()
+ {
+ super("ECDHwithSHA1KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class DHwithSHA1KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA1KDFAndSharedInfo()
+ {
+ super("ECDHwithSHA1KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class CDHwithSHA1KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public CDHwithSHA1KDFAndSharedInfo()
+ {
+ super("ECCDHwithSHA1KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class DHwithSHA224KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA224KDFAndSharedInfo()
+ {
+ super("ECDHwithSHA224KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA224()));
+ }
+ }
+
+ public static class CDHwithSHA224KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public CDHwithSHA224KDFAndSharedInfo()
+ {
+ super("ECCDHwithSHA224KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA224()));
+ }
+ }
+
+ public static class DHwithSHA256KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA256KDFAndSharedInfo()
+ {
+ super("ECDHwithSHA256KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ public static class CDHwithSHA256KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public CDHwithSHA256KDFAndSharedInfo()
+ {
+ super("ECCDHwithSHA256KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ public static class DHwithSHA384KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA384KDFAndSharedInfo()
+ {
+ super("ECDHwithSHA384KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ public static class CDHwithSHA384KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public CDHwithSHA384KDFAndSharedInfo()
+ {
+ super("ECCDHwithSHA384KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ public static class DHwithSHA512KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA512KDFAndSharedInfo()
+ {
+ super("ECDHwithSHA512KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA512()));
+ }
+ }
+
+ public static class CDHwithSHA512KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public CDHwithSHA512KDFAndSharedInfo()
+ {
+ super("ECCDHwithSHA512KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA512()));
+ }
+ }
+
+ public static class MQVwithSHA1KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA1KDFAndSharedInfo()
+ {
+ super("ECMQVwithSHA1KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class MQVwithSHA224KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA224KDFAndSharedInfo()
+ {
+ super("ECMQVwithSHA224KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA224()));
+ }
+ }
+
+ public static class MQVwithSHA256KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA256KDFAndSharedInfo()
+ {
+ super("ECMQVwithSHA256KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ public static class MQVwithSHA384KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA384KDFAndSharedInfo()
+ {
+ super("ECMQVwithSHA384KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ public static class MQVwithSHA512KDFAndSharedInfo
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA512KDFAndSharedInfo()
+ {
+ super("ECMQVwithSHA512KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA512()));
+ }
+ }
+
+ public static class DHwithSHA1CKDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA1CKDF()
+ {
+ super("ECDHwithSHA1CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class DHwithSHA256CKDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA256CKDF()
+ {
+ super("ECDHwithSHA256CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ public static class DHwithSHA384CKDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA384CKDF()
+ {
+ super("ECDHwithSHA384CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ public static class DHwithSHA512CKDF
+ extends KeyAgreementSpi
+ {
+ public DHwithSHA512CKDF()
+ {
+ super("ECDHwithSHA512CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA512()));
+ }
+ }
+
+ public static class MQVwithSHA1CKDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA1CKDF()
+ {
+ super("ECMQVwithSHA1CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class MQVwithSHA224CKDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA224CKDF()
+ {
+ super("ECMQVwithSHA224CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA224()));
+ }
+ }
+
+ public static class MQVwithSHA256CKDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA256CKDF()
+ {
+ super("ECMQVwithSHA256CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ public static class MQVwithSHA384CKDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA384CKDF()
+ {
+ super("ECMQVwithSHA384CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ public static class MQVwithSHA512CKDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA512CKDF()
+ {
+ super("ECMQVwithSHA512CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA512()));
+ }
+ }
+
+ public static class MQVwithSHA1KDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA1KDF()
+ {
+ super("ECMQVwithSHA1KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class MQVwithSHA224KDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA224KDF()
+ {
+ super("ECMQVwithSHA224KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA224()));
+ }
+ }
+
+ public static class MQVwithSHA256KDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA256KDF()
+ {
+ super("ECMQVwithSHA256KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ public static class MQVwithSHA384KDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA384KDF()
+ {
+ super("ECMQVwithSHA384KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ public static class MQVwithSHA512KDF
+ extends KeyAgreementSpi
+ {
+ public MQVwithSHA512KDF()
+ {
+ super("ECMQVwithSHA512KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA512()));
+ }
+ }
+
+ public static class DHUwithSHA1CKDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA1CKDF()
+ {
+ super("ECCDHUwithSHA1CKDF", new ECDHCUnifiedAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class DHUwithSHA224CKDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA224CKDF()
+ {
+ super("ECCDHUwithSHA224CKDF", new ECDHCUnifiedAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA224()));
+ }
+ }
+
+ public static class DHUwithSHA256CKDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA256CKDF()
+ {
+ super("ECCDHUwithSHA256CKDF", new ECDHCUnifiedAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ public static class DHUwithSHA384CKDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA384CKDF()
+ {
+ super("ECCDHUwithSHA384CKDF", new ECDHCUnifiedAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ public static class DHUwithSHA512CKDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA512CKDF()
+ {
+ super("ECCDHUwithSHA512CKDF", new ECDHCUnifiedAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA512()));
+ }
+ }
+
+ public static class DHUwithSHA1KDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA1KDF()
+ {
+ super("ECCDHUwithSHA1KDF", new ECDHCUnifiedAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ public static class DHUwithSHA224KDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA224KDF()
+ {
+ super("ECCDHUwithSHA224KDF", new ECDHCUnifiedAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA224()));
+ }
+ }
+
+ public static class DHUwithSHA256KDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA256KDF()
+ {
+ super("ECCDHUwithSHA256KDF", new ECDHCUnifiedAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ public static class DHUwithSHA384KDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA384KDF()
+ {
+ super("ECCDHUwithSHA384KDF", new ECDHCUnifiedAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ public static class DHUwithSHA512KDF
+ extends KeyAgreementSpi
+ {
+ public DHUwithSHA512KDF()
+ {
+ super("ECCDHUwithSHA512KDF", new ECDHCUnifiedAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA512()));
+ }
+ }
+
+ /**
+ * KeyAgreement according to BSI TR-03111 chapter 4.3.1
+ *
+ public static class ECKAEGwithSHA1KDF
+ extends KeyAgreementSpi
+ {
+ public ECKAEGwithSHA1KDF()
+ {
+ super("ECKAEGwithSHA1KDF", new ECDHBasicAgreement(),
+ new KDF2BytesGenerator(DigestFactory.createSHA1()));
+ }
+ }
+
+ /**
+ * KeyAgreement according to BSI TR-03111 chapter 4.3.1
+ *
+ public static class ECKAEGwithRIPEMD160KDF
+ extends KeyAgreementSpi
+ {
+ public ECKAEGwithRIPEMD160KDF()
+ {
+ super("ECKAEGwithRIPEMD160KDF", new ECDHBasicAgreement(),
+ new KDF2BytesGenerator(new RIPEMD160Digest()));
+ }
+ }
+
+ /**
+ * KeyAgreement according to BSI TR-03111 chapter 4.3.1
+ *
+ public static class ECKAEGwithSHA224KDF
+ extends KeyAgreementSpi
+ {
+ public ECKAEGwithSHA224KDF()
+ {
+ super("ECKAEGwithSHA224KDF", new ECDHBasicAgreement(),
+ new KDF2BytesGenerator(DigestFactory.createSHA224()));
+ }
+ }
+
+ /**
+ * KeyAgreement according to BSI TR-03111 chapter 4.3.1
+ *
+ public static class ECKAEGwithSHA256KDF
+ extends KeyAgreementSpi
+ {
+ public ECKAEGwithSHA256KDF()
+ {
+ super("ECKAEGwithSHA256KDF", new ECDHBasicAgreement(),
+ new KDF2BytesGenerator(DigestFactory.createSHA256()));
+ }
+ }
+
+ /**
+ * KeyAgreement according to BSI TR-03111 chapter 4.3.1
+ *
+ public static class ECKAEGwithSHA384KDF
+ extends KeyAgreementSpi
+ {
+ public ECKAEGwithSHA384KDF()
+ {
+ super("ECKAEGwithSHA384KDF", new ECDHBasicAgreement(),
+ new KDF2BytesGenerator(DigestFactory.createSHA384()));
+ }
+ }
+
+ /**
+ * KeyAgreement according to BSI TR-03111 chapter 4.3.1
+ *
+ public static class ECKAEGwithSHA512KDF
+ extends KeyAgreementSpi
+ {
+ public ECKAEGwithSHA512KDF()
+ {
+ super("ECKAEGwithSHA512KDF", new ECDHBasicAgreement(),
+ new KDF2BytesGenerator(DigestFactory.createSHA512()));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
new file mode 100644
index 00000000..87ea4794
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
@@ -0,0 +1,411 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.ec;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPublicKeyParameters;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.util.OpenSSHPublicKeyUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+import com.android.internal.org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec;
+import com.android.internal.org.bouncycastle.jcajce.spec.OpenSSHPublicKeySpec;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec;
+import com.android.internal.org.bouncycastle.jce.spec.ECPrivateKeySpec;
+import com.android.internal.org.bouncycastle.jce.spec.ECPublicKeySpec;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec;
+// import org.bouncycastle.jce.spec.OpenSSHPublicKeySpec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyFactorySpi
+ extends BaseKeyFactorySpi
+ implements AsymmetricKeyInfoConverter
+{
+ String algorithm;
+ ProviderConfiguration configuration;
+
+ KeyFactorySpi(
+ String algorithm,
+ ProviderConfiguration configuration)
+ {
+ this.algorithm = algorithm;
+ this.configuration = configuration;
+ }
+
+ protected Key engineTranslateKey(
+ Key key)
+ throws InvalidKeyException
+ {
+ if (key instanceof ECPublicKey)
+ {
+ return new BCECPublicKey((ECPublicKey)key, configuration);
+ }
+ else if (key instanceof ECPrivateKey)
+ {
+ return new BCECPrivateKey((ECPrivateKey)key, configuration);
+ }
+
+ throw new InvalidKeyException("key type unknown");
+ }
+
+ protected KeySpec engineGetKeySpec(
+ Key key,
+ Class spec)
+ throws InvalidKeySpecException
+ {
+ if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(java.security.spec.ECPublicKeySpec.class)) && key instanceof ECPublicKey)
+ {
+ ECPublicKey k = (ECPublicKey)key;
+ if (k.getParams() != null)
+ {
+ return new java.security.spec.ECPublicKeySpec(k.getW(), k.getParams());
+ }
+ else
+ {
+ ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+
+ return new java.security.spec.ECPublicKeySpec(k.getW(), EC5Util.convertSpec(EC5Util.convertCurve(implicitSpec.getCurve(), implicitSpec.getSeed()), implicitSpec));
+ }
+ }
+ else if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(java.security.spec.ECPrivateKeySpec.class)) && key instanceof ECPrivateKey)
+ {
+ ECPrivateKey k = (ECPrivateKey)key;
+
+ if (k.getParams() != null)
+ {
+ return new java.security.spec.ECPrivateKeySpec(k.getS(), k.getParams());
+ }
+ else
+ {
+ ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+
+ return new java.security.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(EC5Util.convertCurve(implicitSpec.getCurve(), implicitSpec.getSeed()), implicitSpec));
+ }
+ }
+ else if (spec.isAssignableFrom(com.android.internal.org.bouncycastle.jce.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey)
+ {
+ ECPublicKey k = (ECPublicKey)key;
+ if (k.getParams() != null)
+ {
+ return new com.android.internal.org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW()), EC5Util.convertSpec(k.getParams()));
+ }
+ else
+ {
+ ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+
+ return new com.android.internal.org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW()), implicitSpec);
+ }
+ }
+ else if (spec.isAssignableFrom(com.android.internal.org.bouncycastle.jce.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey)
+ {
+ ECPrivateKey k = (ECPrivateKey)key;
+
+ if (k.getParams() != null)
+ {
+ return new com.android.internal.org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(k.getParams()));
+ }
+ else
+ {
+ ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+
+ return new com.android.internal.org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), implicitSpec);
+ }
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (spec.isAssignableFrom(OpenSSHPublicKeySpec.class) && key instanceof ECPublicKey)
+ {
+ if (key instanceof BCECPublicKey)
+ {
+ BCECPublicKey bcPk = (BCECPublicKey)key;
+ ECParameterSpec sc = bcPk.getParameters();
+ try
+ {
+ return new OpenSSHPublicKeySpec(
+ OpenSSHPublicKeyUtil.encodePublicKey(
+ new ECPublicKeyParameters(bcPk.getQ(), new ECDomainParameters(sc.getCurve(), sc.getG(), sc.getN(), sc.getH(), sc.getSeed()))));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid key type: " + key.getClass().getName());
+ }
+ }
+ else if (spec.isAssignableFrom(OpenSSHPrivateKeySpec.class) && key instanceof ECPrivateKey)
+ {
+ if (key instanceof BCECPrivateKey)
+ {
+ try
+ {
+ return new OpenSSHPrivateKeySpec(PrivateKeyInfo.getInstance(key.getEncoded()).parsePrivateKey().toASN1Primitive().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("cannot encoded key: " + e.getMessage());
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid key type: " + key.getClass().getName());
+ }
+
+ }
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPublicKeySpec.class) && key instanceof ECPublicKey)
+ {
+ if (key instanceof BCECPublicKey)
+ {
+ BCECPublicKey bcPk = (BCECPublicKey)key;
+ ECParameterSpec sc = bcPk.getParameters();
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPublicKeySpec(
+ OpenSSHPublicKeyUtil.encodePublicKey(
+ new ECPublicKeyParameters(bcPk.getQ(), new ECDomainParameters(sc.getCurve(), sc.getG(), sc.getN(), sc.getH(), sc.getSeed()))));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid key type: " + key.getClass().getName());
+ }
+ }
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec.class) && key instanceof ECPrivateKey)
+ {
+ if (key instanceof BCECPrivateKey)
+ {
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec(PrivateKeyInfo.getInstance(key.getEncoded()).parsePrivateKey().toASN1Primitive().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("cannot encoded key: " + e.getMessage());
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("invalid key type: " + key.getClass().getName());
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ return super.engineGetKeySpec(key, spec);
+ }
+
+ protected PrivateKey engineGeneratePrivate(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof ECPrivateKeySpec)
+ {
+ return new BCECPrivateKey(algorithm, (ECPrivateKeySpec)keySpec, configuration);
+ }
+ else if (keySpec instanceof java.security.spec.ECPrivateKeySpec)
+ {
+ return new BCECPrivateKey(algorithm, (java.security.spec.ECPrivateKeySpec)keySpec, configuration);
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (keySpec instanceof OpenSSHPrivateKeySpec)
+ {
+ org.bouncycastle.asn1.sec.ECPrivateKey ecKey = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(((OpenSSHPrivateKeySpec)keySpec).getEncoded());
+
+ try
+ {
+ return new BCECPrivateKey(algorithm, new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, ecKey.getParameters()), ecKey), configuration);
+ }
+ catch (IOException e)
+ {
+ throw new InvalidKeySpecException("bad encoding: " + e.getMessage());
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ return super.engineGeneratePrivate(keySpec);
+ }
+
+ protected PublicKey engineGeneratePublic(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ try
+ {
+ if (keySpec instanceof ECPublicKeySpec)
+ {
+ return new BCECPublicKey(algorithm, (ECPublicKeySpec)keySpec, configuration);
+ }
+ else if (keySpec instanceof java.security.spec.ECPublicKeySpec)
+ {
+ return new BCECPublicKey(algorithm, (java.security.spec.ECPublicKeySpec)keySpec, configuration);
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (keySpec instanceof OpenSSHPublicKeySpec)
+ {
+ CipherParameters params = OpenSSHPublicKeyUtil.parsePublicKey(((OpenSSHPublicKeySpec)keySpec).getEncoded());
+ if (params instanceof ECPublicKeyParameters)
+ {
+ ECDomainParameters parameters = ((ECPublicKeyParameters)params).getParameters();
+ return engineGeneratePublic(
+ new ECPublicKeySpec(((ECPublicKeyParameters)params).getQ(),
+ new ECParameterSpec(parameters.getCurve(), parameters.getG(), parameters.getN(), parameters.getH(), parameters.getSeed())
+ ));
+ }
+ else
+ {
+ throw new IllegalArgumentException("openssh key is not ec public key");
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeySpecException("invalid KeySpec: " + e.getMessage(), e);
+ }
+
+ return super.engineGeneratePublic(keySpec);
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm();
+
+ if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey))
+ {
+ return new BCECPrivateKey(algorithm, keyInfo, configuration);
+ }
+ else
+ {
+ throw new IOException("algorithm identifier " + algOid + " in key not recognised");
+ }
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm();
+
+ if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey))
+ {
+ return new BCECPublicKey(algorithm, keyInfo, configuration);
+ }
+ else
+ {
+ throw new IOException("algorithm identifier " + algOid + " in key not recognised");
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class EC
+ extends KeyFactorySpi
+ {
+ public EC()
+ {
+ super("EC", BouncyCastleProvider.CONFIGURATION);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class ECDSA
+ extends KeyFactorySpi
+ {
+ public ECDSA()
+ {
+ super("ECDSA", BouncyCastleProvider.CONFIGURATION);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
+ public static class ECGOST3410
+ extends KeyFactorySpi
+ {
+ public ECGOST3410()
+ {
+ super("ECGOST3410", BouncyCastleProvider.CONFIGURATION);
+ }
+ }
+
+ public static class ECGOST3410_2012
+ extends KeyFactorySpi
+ {
+ public ECGOST3410_2012()
+ {
+ super("ECGOST3410-2012", BouncyCastleProvider.CONFIGURATION);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithm
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class ECDH
+ extends KeyFactorySpi
+ {
+ public ECDH()
+ {
+ super("ECDH", BouncyCastleProvider.CONFIGURATION);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class ECDHC
+ extends KeyFactorySpi
+ {
+ public ECDHC()
+ {
+ super("ECDHC", BouncyCastleProvider.CONFIGURATION);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class ECMQV
+ extends KeyFactorySpi
+ {
+ public ECMQV()
+ {
+ super("ECMQV", BouncyCastleProvider.CONFIGURATION);
+ }
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
new file mode 100644
index 00000000..0892390f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
@@ -0,0 +1,333 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.ec;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.KeyPair;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.util.Hashtable;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.generators.ECKeyPairGenerator;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECKeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec;
+import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveSpec;
+import com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.util.Integers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class KeyPairGeneratorSpi
+ extends java.security.KeyPairGenerator
+{
+ public KeyPairGeneratorSpi(String algorithmName)
+ {
+ super(algorithmName);
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class EC
+ extends KeyPairGeneratorSpi
+ {
+ ECKeyGenerationParameters param;
+ ECKeyPairGenerator engine = new ECKeyPairGenerator();
+ Object ecParams = null;
+ // Android-changed: Use 256-bit keys by default.
+ // 239-bit keys (the Bouncy Castle default) are less widely-supported than 256-bit ones,
+ // so we've changed the default strength to 256 for increased compatibility
+ int strength = 256;
+ SecureRandom random = CryptoServicesRegistrar.getSecureRandom();
+ boolean initialised = false;
+ String algorithm;
+ ProviderConfiguration configuration;
+
+ static private Hashtable ecParameters;
+
+ static {
+ ecParameters = new Hashtable();
+
+ ecParameters.put(Integers.valueOf(192), new ECGenParameterSpec("prime192v1")); // a.k.a P-192
+ ecParameters.put(Integers.valueOf(239), new ECGenParameterSpec("prime239v1"));
+ ecParameters.put(Integers.valueOf(256), new ECGenParameterSpec("prime256v1")); // a.k.a P-256
+
+ ecParameters.put(Integers.valueOf(224), new ECGenParameterSpec("P-224"));
+ ecParameters.put(Integers.valueOf(384), new ECGenParameterSpec("P-384"));
+ ecParameters.put(Integers.valueOf(521), new ECGenParameterSpec("P-521"));
+ }
+
+ public EC()
+ {
+ super("EC");
+ this.algorithm = "EC";
+ this.configuration = BouncyCastleProvider.CONFIGURATION;
+ }
+
+ public EC(
+ String algorithm,
+ ProviderConfiguration configuration)
+ {
+ super(algorithm);
+ this.algorithm = algorithm;
+ this.configuration = configuration;
+ }
+
+ public void initialize(
+ int strength,
+ SecureRandom random)
+ {
+ this.strength = strength;
+ // BEGIN Android-changed: Don't override this.random with null.
+ // Passing null just means to use a default random, which this.random is already
+ // initialized to, so just use that
+ if (random != null) {
+ this.random = random;
+ }
+ // END Android-changed: Don't override this.random with null.
+
+ ECGenParameterSpec ecParams = (ECGenParameterSpec)ecParameters.get(Integers.valueOf(strength));
+ if (ecParams == null)
+ {
+ throw new InvalidParameterException("unknown key size.");
+ }
+
+ try
+ {
+ initialize(ecParams, random);
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ throw new InvalidParameterException("key size not configurable.");
+ }
+ }
+
+ public void initialize(
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ // BEGIN Android-added: Use existing SecureRandom if none is provided.
+ if (random == null) {
+ random = this.random;
+ }
+ // END Android-added: Use existing SecureRandom if none is provided.
+ if (params == null)
+ {
+ ECParameterSpec implicitCA = configuration.getEcImplicitlyCa();
+ if (implicitCA == null)
+ {
+ throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set");
+ }
+
+ this.ecParams = null;
+ this.param = createKeyGenParamsBC(implicitCA, random);
+ }
+ else if (params instanceof ECParameterSpec)
+ {
+ this.ecParams = params;
+ this.param = createKeyGenParamsBC((ECParameterSpec)params, random);
+ }
+ else if (params instanceof java.security.spec.ECParameterSpec)
+ {
+ this.ecParams = params;
+ this.param = createKeyGenParamsJCE((java.security.spec.ECParameterSpec)params, random);
+ }
+ else if (params instanceof ECGenParameterSpec)
+ {
+ initializeNamedCurve(((ECGenParameterSpec)params).getName(), random);
+ }
+ else if (params instanceof ECNamedCurveGenParameterSpec)
+ {
+ initializeNamedCurve(((ECNamedCurveGenParameterSpec)params).getName(), random);
+ }
+ else
+ {
+ String name = ECUtil.getNameFrom(params);
+
+ if (name != null)
+ {
+ initializeNamedCurve(name, random);
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("invalid parameterSpec: " + params);
+ }
+ }
+
+ engine.init(param);
+ initialised = true;
+ }
+
+ public KeyPair generateKeyPair()
+ {
+ if (!initialised)
+ {
+ initialize(strength, new SecureRandom());
+ }
+
+ AsymmetricCipherKeyPair pair = engine.generateKeyPair();
+ ECPublicKeyParameters pub = (ECPublicKeyParameters)pair.getPublic();
+ ECPrivateKeyParameters priv = (ECPrivateKeyParameters)pair.getPrivate();
+
+ if (ecParams instanceof ECParameterSpec)
+ {
+ ECParameterSpec p = (ECParameterSpec)ecParams;
+
+ BCECPublicKey pubKey = new BCECPublicKey(algorithm, pub, p, configuration);
+ return new KeyPair(pubKey,
+ new BCECPrivateKey(algorithm, priv, pubKey, p, configuration));
+ }
+ else if (ecParams == null)
+ {
+ return new KeyPair(new BCECPublicKey(algorithm, pub, configuration),
+ new BCECPrivateKey(algorithm, priv, configuration));
+ }
+ else
+ {
+ java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)ecParams;
+
+ BCECPublicKey pubKey = new BCECPublicKey(algorithm, pub, p, configuration);
+
+ return new KeyPair(pubKey, new BCECPrivateKey(algorithm, priv, pubKey, p, configuration));
+ }
+ }
+
+ protected ECKeyGenerationParameters createKeyGenParamsBC(ECParameterSpec p, SecureRandom r)
+ {
+ return new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN(), p.getH()), r);
+ }
+
+ protected ECKeyGenerationParameters createKeyGenParamsJCE(java.security.spec.ECParameterSpec p, SecureRandom r)
+ {
+ if (p instanceof ECNamedCurveSpec)
+ {
+ X9ECParameters x9P = ECUtils.getDomainParametersFromName(((ECNamedCurveSpec)p).getName());
+
+ if (x9P != null)
+ {
+ ECDomainParameters dp = new ECDomainParameters(x9P.getCurve(), x9P.getG(), x9P.getN(), x9P.getH());
+
+ return new ECKeyGenerationParameters(dp, r);
+ }
+ }
+
+ ECCurve curve = EC5Util.convertCurve(p.getCurve());
+ ECPoint g = EC5Util.convertPoint(curve, p.getGenerator());
+ BigInteger n = p.getOrder();
+ BigInteger h = BigInteger.valueOf(p.getCofactor());
+ ECDomainParameters dp = new ECDomainParameters(curve, g, n, h);
+ return new ECKeyGenerationParameters(dp, r);
+ }
+
+ protected ECNamedCurveSpec createNamedCurveSpec(String curveName)
+ throws InvalidAlgorithmParameterException
+ {
+ // NOTE: Don't bother with custom curves here as the curve will be converted to JCE type shortly
+
+ X9ECParameters p = ECUtils.getDomainParametersFromName(curveName);
+ if (p == null)
+ {
+ try
+ {
+ // Check whether it's actually an OID string (SunJSSE ServerHandshaker setupEphemeralECDHKeys bug)
+ p = ECNamedCurveTable.getByOID(new ASN1ObjectIdentifier(curveName));
+ if (p == null)
+ {
+ Map extraCurves = configuration.getAdditionalECParameters();
+
+ p = (X9ECParameters)extraCurves.get(new ASN1ObjectIdentifier(curveName));
+
+ if (p == null)
+ {
+ throw new InvalidAlgorithmParameterException("unknown curve OID: " + curveName);
+ }
+ }
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
+ }
+ }
+
+ // Work-around for JDK bug -- it won't look up named curves properly if seed is present
+ byte[] seed = null; //p.getSeed();
+
+ return new ECNamedCurveSpec(curveName, p.getCurve(), p.getG(), p.getN(), p.getH(), seed);
+ }
+
+ protected void initializeNamedCurve(String curveName, SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ ECNamedCurveSpec namedCurve = createNamedCurveSpec(curveName);
+ this.ecParams = namedCurve;
+ this.param = createKeyGenParamsJCE(namedCurve, random);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class ECDSA
+ extends EC
+ {
+ public ECDSA()
+ {
+ super("ECDSA", BouncyCastleProvider.CONFIGURATION);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class ECDH
+ extends EC
+ {
+ public ECDH()
+ {
+ super("ECDH", BouncyCastleProvider.CONFIGURATION);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class ECDHC
+ extends EC
+ {
+ public ECDHC()
+ {
+ super("ECDHC", BouncyCastleProvider.CONFIGURATION);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class ECMQV
+ extends EC
+ {
+ public ECMQV()
+ {
+ super("ECMQV", BouncyCastleProvider.CONFIGURATION);
+ }
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
new file mode 100644
index 00000000..87ad7658
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
@@ -0,0 +1,400 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.ec;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.DSAExt;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.digests.NullDigest;
+// BEGIN Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
+// END Android-removed: Unsupported algorithms
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+import com.android.internal.org.bouncycastle.crypto.signers.DSAEncoding;
+import com.android.internal.org.bouncycastle.crypto.signers.ECDSASigner;
+// BEGIN Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.signers.ECNRSigner;
+// import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
+// END Android-removed: Unsupported algorithms
+import com.android.internal.org.bouncycastle.crypto.signers.PlainDSAEncoding;
+import com.android.internal.org.bouncycastle.crypto.signers.StandardDSAEncoding;
+// BEGIN Android-changed: Use Android digests
+// import org.bouncycastle.crypto.util.DigestFactory;
+import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.DSABase;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignatureSpi
+ extends DSABase
+{
+ SignatureSpi(Digest digest, DSAExt signer, DSAEncoding encoding)
+ {
+ super(digest, signer, encoding);
+ }
+
+ protected void engineInitVerify(PublicKey publicKey)
+ throws InvalidKeyException
+ {
+ CipherParameters param = ECUtils.generatePublicKeyParameter(publicKey);
+
+ digest.reset();
+ signer.init(false, param);
+ }
+
+ protected void engineInitSign(
+ PrivateKey privateKey)
+ throws InvalidKeyException
+ {
+ CipherParameters param = ECUtil.generatePrivateKeyParameter(privateKey);
+
+ digest.reset();
+
+ if (appRandom != null)
+ {
+ signer.init(true, new ParametersWithRandom(param, appRandom));
+ }
+ else
+ {
+ signer.init(true, param);
+ }
+ }
+
+ protected AlgorithmParameters engineGetParameters()
+ {
+ return null;
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class ecDSA
+ extends SignatureSpi
+ {
+ public ecDSA()
+ {
+ // Android-changed: Use Android digests
+ // super(DigestFactory.createSHA1(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ super(AndroidDigestFactory.getSHA1(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
+ static public class ecDetDSA
+ extends SignatureSpi
+ {
+ public ecDetDSA()
+ {
+ super(DigestFactory.createSHA1(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA1())), StandardDSAEncoding.INSTANCE);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithm
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class ecDSAnone
+ extends SignatureSpi
+ {
+ public ecDSAnone()
+ {
+ super(new NullDigest(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class ecDSA224
+ extends SignatureSpi
+ {
+ public ecDSA224()
+ {
+ // Android-changed: Use Android digests
+ // super(DigestFactory.createSHA224(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ super(AndroidDigestFactory.getSHA224(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
+ static public class ecDetDSA224
+ extends SignatureSpi
+ {
+ public ecDetDSA224()
+ {
+ super(DigestFactory.createSHA224(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA224())), StandardDSAEncoding.INSTANCE);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithm
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class ecDSA256
+ extends SignatureSpi
+ {
+ public ecDSA256()
+ {
+ // Android-changed: Use Android digests
+ // super(DigestFactory.createSHA256(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ super(AndroidDigestFactory.getSHA256(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
+ static public class ecDetDSA256
+ extends SignatureSpi
+ {
+ public ecDetDSA256()
+ {
+ super(DigestFactory.createSHA256(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA256())), StandardDSAEncoding.INSTANCE);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithm
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class ecDSA384
+ extends SignatureSpi
+ {
+ public ecDSA384()
+ {
+ // Android-changed: Use Android digests
+ // super(DigestFactory.createSHA384(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ super(AndroidDigestFactory.getSHA384(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
+ static public class ecDetDSA384
+ extends SignatureSpi
+ {
+ public ecDetDSA384()
+ {
+ super(DigestFactory.createSHA384(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA384())), StandardDSAEncoding.INSTANCE);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class ecDSA512
+ extends SignatureSpi
+ {
+ public ecDSA512()
+ {
+ // Android-changed: Use Android digests
+ // super(DigestFactory.createSHA512(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ super(AndroidDigestFactory.getSHA512(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ static public class ecDetDSA512
+ extends SignatureSpi
+ {
+ public ecDetDSA512()
+ {
+ super(DigestFactory.createSHA512(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA512())), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecDSASha3_224
+ extends SignatureSpi
+ {
+ public ecDSASha3_224()
+ {
+ super(DigestFactory.createSHA3_224(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecDetDSASha3_224
+ extends SignatureSpi
+ {
+ public ecDetDSASha3_224()
+ {
+ super(DigestFactory.createSHA3_224(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_224())), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecDSASha3_256
+ extends SignatureSpi
+ {
+ public ecDSASha3_256()
+ {
+ super(DigestFactory.createSHA3_256(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecDetDSASha3_256
+ extends SignatureSpi
+ {
+ public ecDetDSASha3_256()
+ {
+ super(DigestFactory.createSHA3_256(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_256())), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecDSASha3_384
+ extends SignatureSpi
+ {
+ public ecDSASha3_384()
+ {
+ super(DigestFactory.createSHA3_384(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecDetDSASha3_384
+ extends SignatureSpi
+ {
+ public ecDetDSASha3_384()
+ {
+ super(DigestFactory.createSHA3_384(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_384())), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecDSASha3_512
+ extends SignatureSpi
+ {
+ public ecDSASha3_512()
+ {
+ super(DigestFactory.createSHA3_512(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecDetDSASha3_512
+ extends SignatureSpi
+ {
+ public ecDetDSASha3_512()
+ {
+ super(DigestFactory.createSHA3_512(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_512())), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecDSARipeMD160
+ extends SignatureSpi
+ {
+ public ecDSARipeMD160()
+ {
+ super(new RIPEMD160Digest(), new ECDSASigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecNR
+ extends SignatureSpi
+ {
+ public ecNR()
+ {
+ super(DigestFactory.createSHA1(), new ECNRSigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecNR224
+ extends SignatureSpi
+ {
+ public ecNR224()
+ {
+ super(DigestFactory.createSHA224(), new ECNRSigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecNR256
+ extends SignatureSpi
+ {
+ public ecNR256()
+ {
+ super(DigestFactory.createSHA256(), new ECNRSigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecNR384
+ extends SignatureSpi
+ {
+ public ecNR384()
+ {
+ super(DigestFactory.createSHA384(), new ECNRSigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecNR512
+ extends SignatureSpi
+ {
+ public ecNR512()
+ {
+ super(DigestFactory.createSHA512(), new ECNRSigner(), StandardDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecCVCDSA
+ extends SignatureSpi
+ {
+ public ecCVCDSA()
+ {
+ super(DigestFactory.createSHA1(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecCVCDSA224
+ extends SignatureSpi
+ {
+ public ecCVCDSA224()
+ {
+ super(DigestFactory.createSHA224(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecCVCDSA256
+ extends SignatureSpi
+ {
+ public ecCVCDSA256()
+ {
+ super(DigestFactory.createSHA256(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecCVCDSA384
+ extends SignatureSpi
+ {
+ public ecCVCDSA384()
+ {
+ super(DigestFactory.createSHA384(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecCVCDSA512
+ extends SignatureSpi
+ {
+ public ecCVCDSA512()
+ {
+ super(DigestFactory.createSHA512(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+
+ static public class ecPlainDSARP160
+ extends SignatureSpi
+ {
+ public ecPlainDSARP160()
+ {
+ super(new RIPEMD160Digest(), new ECDSASigner(), PlainDSAEncoding.INSTANCE);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java
new file mode 100644
index 00000000..8381d956
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java
@@ -0,0 +1,286 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.rsa;
+
+import java.io.IOException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
+
+import javax.crypto.spec.OAEPParameterSpec;
+import javax.crypto.spec.PSource;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.RSAESOAEPparams;
+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.provider.util.DigestFactory;
+import com.android.internal.org.bouncycastle.jcajce.util.MessageDigestUtils;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class AlgorithmParametersSpi
+ extends java.security.AlgorithmParametersSpi
+{
+ protected boolean isASN1FormatString(String format)
+ {
+ return format == null || format.equals("ASN.1");
+ }
+
+ protected AlgorithmParameterSpec engineGetParameterSpec(
+ Class paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec == null)
+ {
+ throw new NullPointerException("argument to getParameterSpec must not be null");
+ }
+
+ return localEngineGetParameterSpec(paramSpec);
+ }
+
+ protected abstract AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec)
+ throws InvalidParameterSpecException;
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class OAEP
+ extends AlgorithmParametersSpi
+ {
+ OAEPParameterSpec currentSpec;
+
+ /**
+ * Return the PKCS#1 ASN.1 structure RSAES-OAEP-params.
+ */
+ protected byte[] engineGetEncoded()
+ {
+ AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(
+ DigestFactory.getOID(currentSpec.getDigestAlgorithm()),
+ DERNull.INSTANCE);
+ MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)currentSpec.getMGFParameters();
+ AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
+ PKCSObjectIdentifiers.id_mgf1,
+ new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE));
+ PSource.PSpecified pSource = (PSource.PSpecified)currentSpec.getPSource();
+ AlgorithmIdentifier pSourceAlgorithm = new AlgorithmIdentifier(
+ PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(pSource.getValue()));
+ RSAESOAEPparams oaepP = new RSAESOAEPparams(hashAlgorithm, maskGenAlgorithm, pSourceAlgorithm);
+
+ try
+ {
+ return oaepP.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Error encoding OAEPParameters");
+ }
+ }
+
+ protected byte[] engineGetEncoded(
+ String format)
+ {
+ if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509"))
+ {
+ return engineGetEncoded();
+ }
+
+ return null;
+ }
+
+ protected AlgorithmParameterSpec localEngineGetParameterSpec(
+ Class paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec == OAEPParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
+ {
+ return currentSpec;
+ }
+
+ throw new InvalidParameterSpecException("unknown parameter spec passed to OAEP parameters object.");
+ }
+
+ protected void engineInit(
+ AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (!(paramSpec instanceof OAEPParameterSpec))
+ {
+ throw new InvalidParameterSpecException("OAEPParameterSpec required to initialise an OAEP algorithm parameters object");
+ }
+
+ this.currentSpec = (OAEPParameterSpec)paramSpec;
+ }
+
+ protected void engineInit(
+ byte[] params)
+ throws IOException
+ {
+ try
+ {
+ RSAESOAEPparams oaepP = RSAESOAEPparams.getInstance(params);
+
+ if (!oaepP.getMaskGenAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1))
+ {
+ throw new IOException("unknown mask generation function: " + oaepP.getMaskGenAlgorithm().getAlgorithm());
+ }
+
+ currentSpec = new OAEPParameterSpec(
+ MessageDigestUtils.getDigestName(oaepP.getHashAlgorithm().getAlgorithm()),
+ OAEPParameterSpec.DEFAULT.getMGFAlgorithm(),
+ new MGF1ParameterSpec(MessageDigestUtils.getDigestName(AlgorithmIdentifier.getInstance(oaepP.getMaskGenAlgorithm().getParameters()).getAlgorithm())),
+ new PSource.PSpecified(ASN1OctetString.getInstance(oaepP.getPSourceAlgorithm().getParameters()).getOctets()));
+ }
+ catch (ClassCastException e)
+ {
+ throw new IOException("Not a valid OAEP Parameter encoding.");
+ }
+ catch (ArrayIndexOutOfBoundsException e)
+ {
+ throw new IOException("Not a valid OAEP Parameter encoding.");
+ }
+ }
+
+ protected void engineInit(
+ byte[] params,
+ String format)
+ throws IOException
+ {
+ if (format.equalsIgnoreCase("X.509")
+ || format.equalsIgnoreCase("ASN.1"))
+ {
+ engineInit(params);
+ }
+ else
+ {
+ throw new IOException("Unknown parameter format " + format);
+ }
+ }
+
+ protected String engineToString()
+ {
+ return "OAEP Parameters";
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PSS
+ extends AlgorithmParametersSpi
+ {
+ PSSParameterSpec currentSpec;
+
+ /**
+ * Return the PKCS#1 ASN.1 structure RSASSA-PSS-params.
+ */
+ protected byte[] engineGetEncoded()
+ throws IOException
+ {
+ PSSParameterSpec pssSpec = currentSpec;
+ AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(
+ DigestFactory.getOID(pssSpec.getDigestAlgorithm()),
+ DERNull.INSTANCE);
+ MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)pssSpec.getMGFParameters();
+ AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
+ PKCSObjectIdentifiers.id_mgf1,
+ new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE));
+ RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField()));
+
+ return pssP.getEncoded("DER");
+ }
+
+ protected byte[] engineGetEncoded(
+ String format)
+ throws IOException
+ {
+ if (format.equalsIgnoreCase("X.509")
+ || format.equalsIgnoreCase("ASN.1"))
+ {
+ return engineGetEncoded();
+ }
+
+ return null;
+ }
+
+ protected AlgorithmParameterSpec localEngineGetParameterSpec(
+ Class paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec == PSSParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
+ {
+ return currentSpec;
+ }
+
+ throw new InvalidParameterSpecException("unknown parameter spec passed to PSS parameters object.");
+ }
+
+ protected void engineInit(
+ AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (!(paramSpec instanceof PSSParameterSpec))
+ {
+ throw new InvalidParameterSpecException("PSSParameterSpec required to initialise an PSS algorithm parameters object");
+ }
+
+ this.currentSpec = (PSSParameterSpec)paramSpec;
+ }
+
+ protected void engineInit(
+ byte[] params)
+ throws IOException
+ {
+ try
+ {
+ RSASSAPSSparams pssP = RSASSAPSSparams.getInstance(params);
+
+ if (!pssP.getMaskGenAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1))
+ {
+ throw new IOException("unknown mask generation function: " + pssP.getMaskGenAlgorithm().getAlgorithm());
+ }
+
+ currentSpec = new PSSParameterSpec(
+ MessageDigestUtils.getDigestName(pssP.getHashAlgorithm().getAlgorithm()),
+ PSSParameterSpec.DEFAULT.getMGFAlgorithm(),
+ new MGF1ParameterSpec(MessageDigestUtils.getDigestName(AlgorithmIdentifier.getInstance(pssP.getMaskGenAlgorithm().getParameters()).getAlgorithm())),
+ pssP.getSaltLength().intValue(),
+ pssP.getTrailerField().intValue());
+ }
+ catch (ClassCastException e)
+ {
+ throw new IOException("Not a valid PSS Parameter encoding.");
+ }
+ catch (ArrayIndexOutOfBoundsException e)
+ {
+ throw new IOException("Not a valid PSS Parameter encoding.");
+ }
+ }
+
+ protected void engineInit(
+ byte[] params,
+ String format)
+ throws IOException
+ {
+ if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509"))
+ {
+ engineInit(params);
+ }
+ else
+ {
+ throw new IOException("Unknown parameter format " + format);
+ }
+ }
+
+ protected String engineToString()
+ {
+ return "PSS Parameters";
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java
new file mode 100644
index 00000000..e81dfec5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java
@@ -0,0 +1,297 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.rsa;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.spec.RSAPrivateCrtKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.pkcs.RSAPrivateKey;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * A provider representation for a RSA private key, with CRT factors included.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCRSAPrivateCrtKey
+ extends BCRSAPrivateKey
+ implements RSAPrivateCrtKey
+{
+ static final long serialVersionUID = 7834723820638524718L;
+
+ private BigInteger publicExponent;
+ private BigInteger primeP;
+ private BigInteger primeQ;
+ private BigInteger primeExponentP;
+ private BigInteger primeExponentQ;
+ private BigInteger crtCoefficient;
+
+ /**
+ * construct a private key from it's org.bouncycastle.crypto equivalent.
+ *
+ * @param key the parameters object representing the private key.
+ */
+ BCRSAPrivateCrtKey(
+ RSAPrivateCrtKeyParameters key)
+ {
+ super(key);
+
+ this.publicExponent = key.getPublicExponent();
+ this.primeP = key.getP();
+ this.primeQ = key.getQ();
+ this.primeExponentP = key.getDP();
+ this.primeExponentQ = key.getDQ();
+ this.crtCoefficient = key.getQInv();
+ }
+
+ BCRSAPrivateCrtKey(
+ AlgorithmIdentifier algorithmIdentifier,
+ RSAPrivateCrtKeyParameters key)
+ {
+ super(algorithmIdentifier, key);
+
+ this.publicExponent = key.getPublicExponent();
+ this.primeP = key.getP();
+ this.primeQ = key.getQ();
+ this.primeExponentP = key.getDP();
+ this.primeExponentQ = key.getDQ();
+ this.crtCoefficient = key.getQInv();
+ }
+
+ /**
+ * construct a private key from an RSAPrivateCrtKeySpec
+ *
+ * @param spec the spec to be used in construction.
+ */
+ BCRSAPrivateCrtKey(
+ RSAPrivateCrtKeySpec spec)
+ {
+ super(new RSAPrivateCrtKeyParameters(spec.getModulus(),
+ spec.getPublicExponent(), spec.getPrivateExponent(),
+ spec.getPrimeP(), spec.getPrimeQ(), spec.getPrimeExponentP(), spec.getPrimeExponentQ(), spec.getCrtCoefficient()));
+
+ this.modulus = spec.getModulus();
+ this.publicExponent = spec.getPublicExponent();
+ this.privateExponent = spec.getPrivateExponent();
+ this.primeP = spec.getPrimeP();
+ this.primeQ = spec.getPrimeQ();
+ this.primeExponentP = spec.getPrimeExponentP();
+ this.primeExponentQ = spec.getPrimeExponentQ();
+ this.crtCoefficient = spec.getCrtCoefficient();
+ }
+
+ /**
+ * construct a private key from another RSAPrivateCrtKey.
+ *
+ * @param key the object implementing the RSAPrivateCrtKey interface.
+ */
+ BCRSAPrivateCrtKey(
+ RSAPrivateCrtKey key)
+ {
+ super(new RSAPrivateCrtKeyParameters(key.getModulus(),
+ key.getPublicExponent(), key.getPrivateExponent(),
+ key.getPrimeP(), key.getPrimeQ(), key.getPrimeExponentP(), key.getPrimeExponentQ(), key.getCrtCoefficient()));
+
+ this.modulus = key.getModulus();
+ this.publicExponent = key.getPublicExponent();
+ this.privateExponent = key.getPrivateExponent();
+ this.primeP = key.getPrimeP();
+ this.primeQ = key.getPrimeQ();
+ this.primeExponentP = key.getPrimeExponentP();
+ this.primeExponentQ = key.getPrimeExponentQ();
+ this.crtCoefficient = key.getCrtCoefficient();
+ }
+
+ /**
+ * construct an RSA key from a private key info object.
+ */
+ BCRSAPrivateCrtKey(
+ PrivateKeyInfo info)
+ throws IOException
+ {
+ this(info.getPrivateKeyAlgorithm(), RSAPrivateKey.getInstance(info.parsePrivateKey()));
+ }
+
+ /**
+ * construct an RSA key from a ASN.1 RSA private key object.
+ */
+ BCRSAPrivateCrtKey(
+ RSAPrivateKey key)
+ {
+ this(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER, key);
+ }
+
+ BCRSAPrivateCrtKey(
+ AlgorithmIdentifier algorithmIdentifier,
+ RSAPrivateKey key)
+ {
+ super(algorithmIdentifier, new RSAPrivateCrtKeyParameters(key.getModulus(),
+ key.getPublicExponent(), key.getPrivateExponent(),
+ key.getPrime1(), key.getPrime2(), key.getExponent1(), key.getExponent2(), key.getCoefficient()));
+
+ this.modulus = key.getModulus();
+ this.publicExponent = key.getPublicExponent();
+ this.privateExponent = key.getPrivateExponent();
+ this.primeP = key.getPrime1();
+ this.primeQ = key.getPrime2();
+ this.primeExponentP = key.getExponent1();
+ this.primeExponentQ = key.getExponent2();
+ this.crtCoefficient = key.getCoefficient();
+ }
+
+ /**
+ * return the encoding format we produce in getEncoded().
+ *
+ * @return the encoding format we produce in getEncoded().
+ */
+ public String getFormat()
+ {
+ return "PKCS#8";
+ }
+
+ /**
+ * Return a PKCS8 representation of the key. The sequence returned
+ * represents a full PrivateKeyInfo object.
+ *
+ * @return a PKCS8 representation of the key.
+ */
+ public byte[] getEncoded()
+ {
+ return KeyUtil.getEncodedPrivateKeyInfo(algorithmIdentifier, new RSAPrivateKey(getModulus(), getPublicExponent(), getPrivateExponent(), getPrimeP(), getPrimeQ(), getPrimeExponentP(), getPrimeExponentQ(), getCrtCoefficient()));
+ }
+
+ /**
+ * return the public exponent.
+ *
+ * @return the public exponent.
+ */
+ public BigInteger getPublicExponent()
+ {
+ return publicExponent;
+ }
+
+ /**
+ * return the prime P.
+ *
+ * @return the prime P.
+ */
+ public BigInteger getPrimeP()
+ {
+ return primeP;
+ }
+
+ /**
+ * return the prime Q.
+ *
+ * @return the prime Q.
+ */
+ public BigInteger getPrimeQ()
+ {
+ return primeQ;
+ }
+
+ /**
+ * return the prime exponent for P.
+ *
+ * @return the prime exponent for P.
+ */
+ public BigInteger getPrimeExponentP()
+ {
+ return primeExponentP;
+ }
+
+ /**
+ * return the prime exponent for Q.
+ *
+ * @return the prime exponent for Q.
+ */
+ public BigInteger getPrimeExponentQ()
+ {
+ return primeExponentQ;
+ }
+
+ /**
+ * return the CRT coefficient.
+ *
+ * @return the CRT coefficient.
+ */
+ public BigInteger getCrtCoefficient()
+ {
+ return crtCoefficient;
+ }
+
+ public int hashCode()
+ {
+ return this.getModulus().hashCode()
+ ^ this.getPublicExponent().hashCode()
+ ^ this.getPrivateExponent().hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (!(o instanceof RSAPrivateCrtKey))
+ {
+ return false;
+ }
+
+ RSAPrivateCrtKey key = (RSAPrivateCrtKey)o;
+
+ return this.getModulus().equals(key.getModulus())
+ && this.getPublicExponent().equals(key.getPublicExponent())
+ && this.getPrivateExponent().equals(key.getPrivateExponent())
+ && this.getPrimeP().equals(key.getPrimeP())
+ && this.getPrimeQ().equals(key.getPrimeQ())
+ && this.getPrimeExponentP().equals(key.getPrimeExponentP())
+ && this.getPrimeExponentQ().equals(key.getPrimeExponentQ())
+ && this.getCrtCoefficient().equals(key.getCrtCoefficient());
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
+ this.rsaPrivateKey = new RSAPrivateCrtKeyParameters(this.getModulus(),
+ this.getPublicExponent(), this.getPrivateExponent(),
+ this.getPrimeP(), this.getPrimeQ(),
+ this.getPrimeExponentP(), this.getPrimeExponentQ(), this.getCrtCoefficient());
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append("RSA Private CRT Key [").append(
+ RSAUtil.generateKeyFingerprint(this.getModulus())).append("]")
+ .append(",[")
+ .append(RSAUtil.generateExponentFingerprint(this.getPublicExponent()))
+ .append("]")
+ .append(nl);
+ buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl);
+ buf.append(" public exponent: ").append(this.getPublicExponent().toString(16)).append(nl);
+
+ return buf.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java
new file mode 100644
index 00000000..7492e8df
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java
@@ -0,0 +1,208 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.rsa;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.RSAPrivateKeySpec;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.crypto.params.RSAKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
+import com.android.internal.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCRSAPrivateKey
+ implements RSAPrivateKey, PKCS12BagAttributeCarrier
+{
+ static final long serialVersionUID = 5110188922551353628L;
+
+ private static BigInteger ZERO = BigInteger.valueOf(0);
+
+ protected BigInteger modulus;
+ protected BigInteger privateExponent;
+ private byte[] algorithmIdentifierEnc = getEncoding(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER);
+
+ protected transient AlgorithmIdentifier algorithmIdentifier = BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER;
+ protected transient RSAKeyParameters rsaPrivateKey;
+ protected transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
+ BCRSAPrivateKey(
+ RSAKeyParameters key)
+ {
+ this.modulus = key.getModulus();
+ this.privateExponent = key.getExponent();
+ this.rsaPrivateKey = key;
+ }
+
+ BCRSAPrivateKey(
+ AlgorithmIdentifier algID,
+ RSAKeyParameters key)
+ {
+ this.algorithmIdentifier = algID;
+ this.algorithmIdentifierEnc = getEncoding(algID);
+
+ this.modulus = key.getModulus();
+ this.privateExponent = key.getExponent();
+ this.rsaPrivateKey = key;
+ }
+
+ BCRSAPrivateKey(
+ RSAPrivateKeySpec spec)
+ {
+ this.modulus = spec.getModulus();
+ this.privateExponent = spec.getPrivateExponent();
+ this.rsaPrivateKey = new RSAKeyParameters(true, modulus, privateExponent);
+ }
+
+ BCRSAPrivateKey(
+ RSAPrivateKey key)
+ {
+ this.modulus = key.getModulus();
+ this.privateExponent = key.getPrivateExponent();
+ this.rsaPrivateKey = new RSAKeyParameters(true, modulus, privateExponent);
+ }
+
+ BCRSAPrivateKey(AlgorithmIdentifier algID, com.android.internal.org.bouncycastle.asn1.pkcs.RSAPrivateKey key)
+ {
+ this.algorithmIdentifier = algID;
+ this.algorithmIdentifierEnc = getEncoding(algID);
+
+ this.modulus = key.getModulus();
+ this.privateExponent = key.getPrivateExponent();
+ this.rsaPrivateKey = new RSAKeyParameters(true, modulus, privateExponent);
+ }
+
+ public BigInteger getModulus()
+ {
+ return modulus;
+ }
+
+ public BigInteger getPrivateExponent()
+ {
+ return privateExponent;
+ }
+
+ public String getAlgorithm()
+ {
+ if (algorithmIdentifier.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ return "RSASSA-PSS";
+ }
+ return "RSA";
+ }
+
+ public String getFormat()
+ {
+ return "PKCS#8";
+ }
+
+ RSAKeyParameters engineGetKeyParameters()
+ {
+ return rsaPrivateKey;
+ }
+
+ public byte[] getEncoded()
+ {
+ return KeyUtil.getEncodedPrivateKeyInfo(algorithmIdentifier, new com.android.internal.org.bouncycastle.asn1.pkcs.RSAPrivateKey(getModulus(), ZERO, getPrivateExponent(), ZERO, ZERO, ZERO, ZERO, ZERO));
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof RSAPrivateKey))
+ {
+ return false;
+ }
+
+ if (o == this)
+ {
+ return true;
+ }
+
+ RSAPrivateKey key = (RSAPrivateKey)o;
+
+ return getModulus().equals(key.getModulus())
+ && getPrivateExponent().equals(key.getPrivateExponent());
+ }
+
+ public int hashCode()
+ {
+ return getModulus().hashCode() ^ getPrivateExponent().hashCode();
+ }
+
+ public void setBagAttribute(
+ ASN1ObjectIdentifier oid,
+ ASN1Encodable attribute)
+ {
+ attrCarrier.setBagAttribute(oid, attribute);
+ }
+
+ public ASN1Encodable getBagAttribute(
+ ASN1ObjectIdentifier oid)
+ {
+ return attrCarrier.getBagAttribute(oid);
+ }
+
+ public Enumeration getBagAttributeKeys()
+ {
+ return attrCarrier.getBagAttributeKeys();
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ if (algorithmIdentifierEnc == null)
+ {
+ algorithmIdentifierEnc = getEncoding(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER);
+ }
+
+ this.algorithmIdentifier = AlgorithmIdentifier.getInstance(algorithmIdentifierEnc);
+
+ this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
+ this.rsaPrivateKey = new RSAKeyParameters(true, modulus, privateExponent);
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append("RSA Private Key [").append(
+ RSAUtil.generateKeyFingerprint(this.getModulus())).append("],[]").append(nl);
+ buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl);
+
+ return buf.toString();
+ }
+
+ private static byte[] getEncoding(AlgorithmIdentifier algorithmIdentifier)
+ {
+ try
+ {
+ return algorithmIdentifier.getEncoded();
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java
new file mode 100644
index 00000000..2c071517
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java
@@ -0,0 +1,203 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.rsa;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.RSAPublicKeySpec;
+
+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;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.crypto.params.RSAKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCRSAPublicKey
+ implements RSAPublicKey
+{
+ static final AlgorithmIdentifier DEFAULT_ALGORITHM_IDENTIFIER = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
+
+ static final long serialVersionUID = 2675817738516720772L;
+
+ private BigInteger modulus;
+ private BigInteger publicExponent;
+
+ private transient AlgorithmIdentifier algorithmIdentifier;
+ private transient RSAKeyParameters rsaPublicKey;
+
+ BCRSAPublicKey(
+ RSAKeyParameters key)
+ {
+ this(DEFAULT_ALGORITHM_IDENTIFIER, key);
+ }
+
+ BCRSAPublicKey(
+ AlgorithmIdentifier algId,
+ RSAKeyParameters key)
+ {
+ this.algorithmIdentifier = algId;
+ this.modulus = key.getModulus();
+ this.publicExponent = key.getExponent();
+ this.rsaPublicKey = key;
+ }
+
+ BCRSAPublicKey(
+ RSAPublicKeySpec spec)
+ {
+ this.algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER;
+ this.modulus = spec.getModulus();
+ this.publicExponent = spec.getPublicExponent();
+ this.rsaPublicKey = new RSAKeyParameters(false, modulus, publicExponent);
+ }
+
+ BCRSAPublicKey(
+ RSAPublicKey key)
+ {
+ this.algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER;
+ this.modulus = key.getModulus();
+ this.publicExponent = key.getPublicExponent();
+ this.rsaPublicKey = new RSAKeyParameters(false, modulus, publicExponent);
+ }
+
+ BCRSAPublicKey(
+ SubjectPublicKeyInfo info)
+ {
+ populateFromPublicKeyInfo(info);
+ }
+
+ private void populateFromPublicKeyInfo(SubjectPublicKeyInfo info)
+ {
+ try
+ {
+ com.android.internal.org.bouncycastle.asn1.pkcs.RSAPublicKey pubKey = com.android.internal.org.bouncycastle.asn1.pkcs.RSAPublicKey.getInstance(info.parsePublicKey());
+
+ this.algorithmIdentifier = info.getAlgorithm();
+ this.modulus = pubKey.getModulus();
+ this.publicExponent = pubKey.getPublicExponent();
+ this.rsaPublicKey = new RSAKeyParameters(false, modulus, publicExponent);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("invalid info structure in RSA public key");
+ }
+ }
+
+ /**
+ * return the modulus.
+ *
+ * @return the modulus.
+ */
+ public BigInteger getModulus()
+ {
+ return modulus;
+ }
+
+ /**
+ * return the public exponent.
+ *
+ * @return the public exponent.
+ */
+ public BigInteger getPublicExponent()
+ {
+ return publicExponent;
+ }
+
+ public String getAlgorithm()
+ {
+ if (algorithmIdentifier.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ return "RSASSA-PSS";
+ }
+ return "RSA";
+ }
+
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ public byte[] getEncoded()
+ {
+ return KeyUtil.getEncodedSubjectPublicKeyInfo(algorithmIdentifier, new com.android.internal.org.bouncycastle.asn1.pkcs.RSAPublicKey(getModulus(), getPublicExponent()));
+ }
+
+ RSAKeyParameters engineGetKeyParameters()
+ {
+ return rsaPublicKey;
+ }
+
+ public int hashCode()
+ {
+ return this.getModulus().hashCode() ^ this.getPublicExponent().hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (!(o instanceof RSAPublicKey))
+ {
+ return false;
+ }
+
+ RSAPublicKey key = (RSAPublicKey)o;
+
+ return getModulus().equals(key.getModulus())
+ && getPublicExponent().equals(key.getPublicExponent());
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append("RSA Public Key [").append(RSAUtil.generateKeyFingerprint(this.getModulus())).append("]")
+ .append(",[")
+ .append(RSAUtil.generateExponentFingerprint(this.getPublicExponent()))
+ .append("]")
+ .append(nl);
+ buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl);
+ buf.append("public exponent: ").append(this.getPublicExponent().toString(16)).append(nl);
+
+ return buf.toString();
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ try
+ {
+ algorithmIdentifier = AlgorithmIdentifier.getInstance(in.readObject());
+ }
+ catch (Exception e)
+ {
+ algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER;
+ }
+ this.rsaPublicKey = new RSAKeyParameters(false, modulus, publicExponent);
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ if (!algorithmIdentifier.equals(DEFAULT_ALGORITHM_IDENTIFIER))
+ {
+ out.writeObject(algorithmIdentifier.getEncoded());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java
new file mode 100644
index 00000000..8a9a86c7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java
@@ -0,0 +1,627 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.rsa;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.MGF1ParameterSpec;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.OAEPParameterSpec;
+import javax.crypto.spec.PSource;
+
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.AsymmetricBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+// Android-removed: Unsupported algorithm
+// import org.bouncycastle.crypto.encodings.ISO9796d1Encoding;
+import com.android.internal.org.bouncycastle.crypto.encodings.OAEPEncoding;
+import com.android.internal.org.bouncycastle.crypto.encodings.PKCS1Encoding;
+import com.android.internal.org.bouncycastle.crypto.engines.RSABlindedEngine;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.BadBlockException;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.DigestFactory;
+// Android-changed: Use default provider for JCA algorithms instead of BC
+// Was: import org.bouncycastle.jcajce.util.BCJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CipherSpi
+ extends BaseCipherSpi
+{
+ // Android-changed: Use default provider for JCA algorithms instead of BC
+ // Was: private final JcaJceHelper helper = new BCJcaJceHelper();
+ private final JcaJceHelper helper = new DefaultJcaJceHelper();
+
+ private AsymmetricBlockCipher cipher;
+ private AlgorithmParameterSpec paramSpec;
+ private AlgorithmParameters engineParams;
+ private boolean publicKeyOnly = false;
+ private boolean privateKeyOnly = false;
+ private ErasableOutputStream bOut = new ErasableOutputStream();
+
+ public CipherSpi(
+ AsymmetricBlockCipher engine)
+ {
+ cipher = engine;
+ }
+
+ public CipherSpi(
+ OAEPParameterSpec pSpec)
+ {
+ try
+ {
+ initFromSpec(pSpec);
+ }
+ catch (NoSuchPaddingException e)
+ {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ }
+
+ public CipherSpi(
+ boolean publicKeyOnly,
+ boolean privateKeyOnly,
+ AsymmetricBlockCipher engine)
+ {
+ this.publicKeyOnly = publicKeyOnly;
+ this.privateKeyOnly = privateKeyOnly;
+ cipher = engine;
+ }
+
+ private void initFromSpec(
+ OAEPParameterSpec pSpec)
+ throws NoSuchPaddingException
+ {
+ MGF1ParameterSpec mgfParams = (MGF1ParameterSpec)pSpec.getMGFParameters();
+ Digest digest = DigestFactory.getDigest(mgfParams.getDigestAlgorithm());
+
+ if (digest == null)
+ {
+ throw new NoSuchPaddingException("no match on OAEP constructor for digest algorithm: "+ mgfParams.getDigestAlgorithm());
+ }
+
+ cipher = new OAEPEncoding(new RSABlindedEngine(), digest, ((PSource.PSpecified)pSpec.getPSource()).getValue());
+ paramSpec = pSpec;
+ }
+
+ protected int engineGetBlockSize()
+ {
+ try
+ {
+ return cipher.getInputBlockSize();
+ }
+ catch (NullPointerException e)
+ {
+ throw new IllegalStateException("RSA Cipher not initialised");
+ }
+ }
+
+ protected int engineGetKeySize(
+ Key key)
+ {
+ if (key instanceof RSAPrivateKey)
+ {
+ RSAPrivateKey k = (RSAPrivateKey)key;
+
+ return k.getModulus().bitLength();
+ }
+ else if (key instanceof RSAPublicKey)
+ {
+ RSAPublicKey k = (RSAPublicKey)key;
+
+ return k.getModulus().bitLength();
+ }
+
+ throw new IllegalArgumentException("not an RSA key!");
+ }
+
+ protected int engineGetOutputSize(
+ int inputLen)
+ {
+ try
+ {
+ return cipher.getOutputBlockSize();
+ }
+ catch (NullPointerException e)
+ {
+ throw new IllegalStateException("RSA Cipher not initialised");
+ }
+ }
+
+ protected AlgorithmParameters engineGetParameters()
+ {
+ if (engineParams == null)
+ {
+ if (paramSpec != null)
+ {
+ try
+ {
+ engineParams = helper.createAlgorithmParameters("OAEP");
+ engineParams.init(paramSpec);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.toString());
+ }
+ }
+ }
+
+ return engineParams;
+ }
+
+ protected void engineSetMode(
+ String mode)
+ throws NoSuchAlgorithmException
+ {
+ String md = Strings.toUpperCase(mode);
+
+ if (md.equals("NONE") || md.equals("ECB"))
+ {
+ return;
+ }
+
+ if (md.equals("1"))
+ {
+ privateKeyOnly = true;
+ publicKeyOnly = false;
+ return;
+ }
+ else if (md.equals("2"))
+ {
+ privateKeyOnly = false;
+ publicKeyOnly = true;
+ return;
+ }
+
+ throw new NoSuchAlgorithmException("can't support mode " + mode);
+ }
+
+ protected void engineSetPadding(
+ String padding)
+ throws NoSuchPaddingException
+ {
+ String pad = Strings.toUpperCase(padding);
+
+ if (pad.equals("NOPADDING"))
+ {
+ cipher = new RSABlindedEngine();
+ }
+ else if (pad.equals("PKCS1PADDING"))
+ {
+ cipher = new PKCS1Encoding(new RSABlindedEngine());
+ }
+ // BEGIN Android-removed: Unsupported algorithm
+ // else if (pad.equals("ISO9796-1PADDING"))
+ // {
+ // cipher = new ISO9796d1Encoding(new RSABlindedEngine());
+ // }
+ // END Android-removed: Unsupported algorithm
+ else if (pad.equals("OAEPWITHMD5ANDMGF1PADDING"))
+ {
+ initFromSpec(new OAEPParameterSpec("MD5", "MGF1", new MGF1ParameterSpec("MD5"), PSource.PSpecified.DEFAULT));
+ }
+ else if (pad.equals("OAEPPADDING"))
+ {
+ initFromSpec(OAEPParameterSpec.DEFAULT);
+ }
+ else if (pad.equals("OAEPWITHSHA1ANDMGF1PADDING") || pad.equals("OAEPWITHSHA-1ANDMGF1PADDING"))
+ {
+ initFromSpec(OAEPParameterSpec.DEFAULT);
+ }
+ else if (pad.equals("OAEPWITHSHA224ANDMGF1PADDING") || pad.equals("OAEPWITHSHA-224ANDMGF1PADDING"))
+ {
+ initFromSpec(new OAEPParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA-224"), PSource.PSpecified.DEFAULT));
+ }
+ else if (pad.equals("OAEPWITHSHA256ANDMGF1PADDING") || pad.equals("OAEPWITHSHA-256ANDMGF1PADDING"))
+ {
+ initFromSpec(new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT));
+ }
+ else if (pad.equals("OAEPWITHSHA384ANDMGF1PADDING") || pad.equals("OAEPWITHSHA-384ANDMGF1PADDING"))
+ {
+ initFromSpec(new OAEPParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT));
+ }
+ else if (pad.equals("OAEPWITHSHA512ANDMGF1PADDING") || pad.equals("OAEPWITHSHA-512ANDMGF1PADDING"))
+ {
+ initFromSpec(new OAEPParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT));
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (pad.equals("OAEPWITHSHA3-224ANDMGF1PADDING"))
+ {
+ initFromSpec(new OAEPParameterSpec("SHA3-224", "MGF1", new MGF1ParameterSpec("SHA3-224"), PSource.PSpecified.DEFAULT));
+ }
+ else if (pad.equals("OAEPWITHSHA3-256ANDMGF1PADDING"))
+ {
+ initFromSpec(new OAEPParameterSpec("SHA3-256", "MGF1", new MGF1ParameterSpec("SHA3-256"), PSource.PSpecified.DEFAULT));
+ }
+ else if (pad.equals("OAEPWITHSHA3-384ANDMGF1PADDING"))
+ {
+ initFromSpec(new OAEPParameterSpec("SHA3-384", "MGF1", new MGF1ParameterSpec("SHA3-384"), PSource.PSpecified.DEFAULT));
+ }
+ else if (pad.equals("OAEPWITHSHA3-512ANDMGF1PADDING"))
+ {
+ initFromSpec(new OAEPParameterSpec("SHA3-512", "MGF1", new MGF1ParameterSpec("SHA3-512"), PSource.PSpecified.DEFAULT));
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ else
+ {
+ throw new NoSuchPaddingException(padding + " unavailable with RSA.");
+ }
+ }
+
+ protected void engineInit(
+ int opmode,
+ Key key,
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ CipherParameters param;
+
+ if (params == null || params instanceof OAEPParameterSpec)
+ {
+ if (key instanceof RSAPublicKey)
+ {
+ if (privateKeyOnly && opmode == Cipher.ENCRYPT_MODE)
+ {
+ throw new InvalidKeyException(
+ "mode 1 requires RSAPrivateKey");
+ }
+
+ param = RSAUtil.generatePublicKeyParameter((RSAPublicKey)key);
+ }
+ else if (key instanceof RSAPrivateKey)
+ {
+ if (publicKeyOnly && opmode == Cipher.ENCRYPT_MODE)
+ {
+ throw new InvalidKeyException(
+ "mode 2 requires RSAPublicKey");
+ }
+
+ param = RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)key);
+ }
+ else
+ {
+ throw new InvalidKeyException("unknown key type passed to RSA");
+ }
+
+ if (params != null)
+ {
+ OAEPParameterSpec spec = (OAEPParameterSpec)params;
+
+ paramSpec = params;
+
+ if (!spec.getMGFAlgorithm().equalsIgnoreCase("MGF1") && !spec.getMGFAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1.getId()))
+ {
+ throw new InvalidAlgorithmParameterException("unknown mask generation function specified");
+ }
+
+ if (!(spec.getMGFParameters() instanceof MGF1ParameterSpec))
+ {
+ throw new InvalidAlgorithmParameterException("unkown MGF parameters");
+ }
+
+ Digest digest = DigestFactory.getDigest(spec.getDigestAlgorithm());
+
+ if (digest == null)
+ {
+ throw new InvalidAlgorithmParameterException("no match on digest algorithm: "+ spec.getDigestAlgorithm());
+ }
+
+ MGF1ParameterSpec mgfParams = (MGF1ParameterSpec)spec.getMGFParameters();
+ Digest mgfDigest = DigestFactory.getDigest(mgfParams.getDigestAlgorithm());
+
+ if (mgfDigest == null)
+ {
+ throw new InvalidAlgorithmParameterException("no match on MGF digest algorithm: "+ mgfParams.getDigestAlgorithm());
+ }
+
+ cipher = new OAEPEncoding(new RSABlindedEngine(), digest, mgfDigest, ((PSource.PSpecified)spec.getPSource()).getValue());
+ }
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("unknown parameter type: " + params.getClass().getName());
+ }
+
+ if (!(cipher instanceof RSABlindedEngine))
+ {
+ if (random != null)
+ {
+ param = new ParametersWithRandom(param, random);
+ }
+ else
+ {
+ param = new ParametersWithRandom(param, CryptoServicesRegistrar.getSecureRandom());
+ }
+ }
+
+ bOut.reset();
+
+ switch (opmode)
+ {
+ case Cipher.ENCRYPT_MODE:
+ case Cipher.WRAP_MODE:
+ cipher.init(true, param);
+ break;
+ case Cipher.DECRYPT_MODE:
+ case Cipher.UNWRAP_MODE:
+ cipher.init(false, param);
+ break;
+ default:
+ throw new InvalidParameterException("unknown opmode " + opmode + " passed to RSA");
+ }
+ }
+
+ protected void engineInit(
+ int opmode,
+ Key key,
+ AlgorithmParameters params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ AlgorithmParameterSpec paramSpec = null;
+
+ if (params != null)
+ {
+ try
+ {
+ paramSpec = params.getParameterSpec(OAEPParameterSpec.class);
+ }
+ catch (InvalidParameterSpecException e)
+ {
+ throw new InvalidAlgorithmParameterException("cannot recognise parameters: " + e.toString(), e);
+ }
+ }
+
+ engineParams = params;
+ engineInit(opmode, key, paramSpec, random);
+ }
+
+ protected void engineInit(
+ int opmode,
+ Key key,
+ SecureRandom random)
+ throws InvalidKeyException
+ {
+ try
+ {
+ engineInit(opmode, key, (AlgorithmParameterSpec)null, random);
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ // this shouldn't happen
+ throw new InvalidKeyException("Eeeek! " + e.toString(), e);
+ }
+ }
+
+ protected byte[] engineUpdate(
+ byte[] input,
+ int inputOffset,
+ int inputLen)
+ {
+ bOut.write(input, inputOffset, inputLen);
+
+ if (cipher instanceof RSABlindedEngine)
+ {
+ if (bOut.size() > cipher.getInputBlockSize() + 1)
+ {
+ throw new ArrayIndexOutOfBoundsException("too much data for RSA block");
+ }
+ }
+ else
+ {
+ if (bOut.size() > cipher.getInputBlockSize())
+ {
+ throw new ArrayIndexOutOfBoundsException("too much data for RSA block");
+ }
+ }
+
+ return null;
+ }
+
+ protected int engineUpdate(
+ byte[] input,
+ int inputOffset,
+ int inputLen,
+ byte[] output,
+ int outputOffset)
+ {
+ bOut.write(input, inputOffset, inputLen);
+
+ if (cipher instanceof RSABlindedEngine)
+ {
+ if (bOut.size() > cipher.getInputBlockSize() + 1)
+ {
+ throw new ArrayIndexOutOfBoundsException("too much data for RSA block");
+ }
+ }
+ else
+ {
+ if (bOut.size() > cipher.getInputBlockSize())
+ {
+ throw new ArrayIndexOutOfBoundsException("too much data for RSA block");
+ }
+ }
+
+ return 0;
+ }
+
+ protected byte[] engineDoFinal(
+ byte[] input,
+ int inputOffset,
+ int inputLen)
+ throws IllegalBlockSizeException, BadPaddingException
+ {
+ if (input != null)
+ {
+ bOut.write(input, inputOffset, inputLen);
+ }
+
+ if (cipher instanceof RSABlindedEngine)
+ {
+ if (bOut.size() > cipher.getInputBlockSize() + 1)
+ {
+ throw new ArrayIndexOutOfBoundsException("too much data for RSA block");
+ }
+ }
+ else
+ {
+ if (bOut.size() > cipher.getInputBlockSize())
+ {
+ throw new ArrayIndexOutOfBoundsException("too much data for RSA block");
+ }
+ }
+
+ return getOutput();
+ }
+
+ protected int engineDoFinal(
+ byte[] input,
+ int inputOffset,
+ int inputLen,
+ byte[] output,
+ int outputOffset)
+ throws IllegalBlockSizeException, BadPaddingException, ShortBufferException
+ {
+ if (outputOffset + engineGetOutputSize(inputLen) > output.length)
+ {
+ throw new ShortBufferException("output buffer too short for input.");
+ }
+
+ if (input != null)
+ {
+ bOut.write(input, inputOffset, inputLen);
+ }
+
+ if (cipher instanceof RSABlindedEngine)
+ {
+ if (bOut.size() > cipher.getInputBlockSize() + 1)
+ {
+ throw new ArrayIndexOutOfBoundsException("too much data for RSA block");
+ }
+ }
+ else
+ {
+ if (bOut.size() > cipher.getInputBlockSize())
+ {
+ throw new ArrayIndexOutOfBoundsException("too much data for RSA block");
+ }
+ }
+
+ byte[] out = getOutput();
+
+ for (int i = 0; i != out.length; i++)
+ {
+ output[outputOffset + i] = out[i];
+ }
+
+ return out.length;
+ }
+
+ private byte[] getOutput()
+ throws BadPaddingException
+ {
+ try
+ {
+ return cipher.processBlock(bOut.getBuf(), 0, bOut.size());
+ }
+ catch (InvalidCipherTextException e)
+ {
+ throw new BadBlockException("unable to decrypt block", e);
+ }
+ catch (ArrayIndexOutOfBoundsException e)
+ {
+ throw new BadBlockException("unable to decrypt block", e);
+ }
+ finally
+ {
+ bOut.erase();
+ }
+ }
+
+ /**
+ * classes that inherit from us.
+ * @hide This class is not part of the Android public SDK API
+ */
+
+ static public class NoPadding
+ extends CipherSpi
+ {
+ public NoPadding()
+ {
+ super(new RSABlindedEngine());
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ static public class PKCS1v1_5Padding
+ extends CipherSpi
+ {
+ public PKCS1v1_5Padding()
+ {
+ super(new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ static public class PKCS1v1_5Padding_PrivateOnly
+ extends CipherSpi
+ {
+ public PKCS1v1_5Padding_PrivateOnly()
+ {
+ super(false, true, new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ static public class PKCS1v1_5Padding_PublicOnly
+ extends CipherSpi
+ {
+ public PKCS1v1_5Padding_PublicOnly()
+ {
+ super(true, false, new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ static public class OAEPPadding
+ extends CipherSpi
+ {
+ public OAEPPadding()
+ {
+ super(OAEPParameterSpec.DEFAULT);
+ }
+ }
+
+ static public class ISO9796d1Padding
+ extends CipherSpi
+ {
+ public ISO9796d1Padding()
+ {
+ super(new ISO9796d1Encoding(new RSABlindedEngine()));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java
new file mode 100644
index 00000000..3ec528d5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java
@@ -0,0 +1,453 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.rsa;
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.DigestInfo;
+import com.android.internal.org.bouncycastle.crypto.AsymmetricBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.digests.MD2Digest;
+// import org.bouncycastle.crypto.digests.MD4Digest;
+// import org.bouncycastle.crypto.digests.NullDigest;
+// import org.bouncycastle.crypto.digests.RIPEMD128Digest;
+// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
+// import org.bouncycastle.crypto.digests.RIPEMD256Digest;
+import com.android.internal.org.bouncycastle.crypto.encodings.PKCS1Encoding;
+import com.android.internal.org.bouncycastle.crypto.engines.RSABlindedEngine;
+// Android-changed: Use Android digests
+// import org.bouncycastle.crypto.util.DigestFactory;
+import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DigestSignatureSpi
+ extends SignatureSpi
+{
+ private Digest digest;
+ private AsymmetricBlockCipher cipher;
+ private AlgorithmIdentifier algId;
+
+ // care - this constructor is actually used by outside organisations
+ protected DigestSignatureSpi(
+ Digest digest,
+ AsymmetricBlockCipher cipher)
+ {
+ this.digest = digest;
+ this.cipher = cipher;
+ this.algId = null;
+ }
+
+ // care - this constructor is actually used by outside organisations
+ protected DigestSignatureSpi(
+ ASN1ObjectIdentifier objId,
+ Digest digest,
+ AsymmetricBlockCipher cipher)
+ {
+ this.digest = digest;
+ this.cipher = cipher;
+ this.algId = new AlgorithmIdentifier(objId, DERNull.INSTANCE);
+ }
+
+ protected void engineInitVerify(
+ PublicKey publicKey)
+ throws InvalidKeyException
+ {
+ if (!(publicKey instanceof RSAPublicKey))
+ {
+ throw new InvalidKeyException("Supplied key (" + getType(publicKey) + ") is not a RSAPublicKey instance");
+ }
+
+ CipherParameters param = RSAUtil.generatePublicKeyParameter((RSAPublicKey)publicKey);
+
+ digest.reset();
+ cipher.init(false, param);
+ }
+
+ protected void engineInitSign(
+ PrivateKey privateKey)
+ throws InvalidKeyException
+ {
+ if (!(privateKey instanceof RSAPrivateKey))
+ {
+ throw new InvalidKeyException("Supplied key (" + getType(privateKey) + ") is not a RSAPrivateKey instance");
+ }
+
+ CipherParameters param = RSAUtil.generatePrivateKeyParameter((RSAPrivateKey)privateKey);
+
+ digest.reset();
+
+ cipher.init(true, param);
+ }
+
+ private String getType(
+ Object o)
+ {
+ if (o == null)
+ {
+ return null;
+ }
+
+ return o.getClass().getName();
+ }
+
+ protected void engineUpdate(
+ byte b)
+ throws SignatureException
+ {
+ digest.update(b);
+ }
+
+ protected void engineUpdate(
+ byte[] b,
+ int off,
+ int len)
+ throws SignatureException
+ {
+ digest.update(b, off, len);
+ }
+
+ protected byte[] engineSign()
+ throws SignatureException
+ {
+ byte[] hash = new byte[digest.getDigestSize()];
+
+ digest.doFinal(hash, 0);
+
+ try
+ {
+ byte[] bytes = derEncode(hash);
+
+ return cipher.processBlock(bytes, 0, bytes.length);
+ }
+ catch (ArrayIndexOutOfBoundsException e)
+ {
+ throw new SignatureException("key too small for signature type");
+ }
+ catch (Exception e)
+ {
+ throw new SignatureException(e.toString());
+ }
+ }
+
+ protected boolean engineVerify(
+ byte[] sigBytes)
+ throws SignatureException
+ {
+ byte[] hash = new byte[digest.getDigestSize()];
+
+ digest.doFinal(hash, 0);
+
+ byte[] sig;
+ byte[] expected;
+
+ try
+ {
+ sig = cipher.processBlock(sigBytes, 0, sigBytes.length);
+
+ expected = derEncode(hash);
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+
+ if (sig.length == expected.length)
+ {
+ return Arrays.constantTimeAreEqual(sig, expected);
+ }
+ else if (sig.length == expected.length - 2) // NULL left out
+ {
+ expected[1] -= 2; // adjust lengths
+ expected[3] -= 2;
+
+ int sigOffset = 4 + expected[3];
+ int expectedOffset = sigOffset + 2;
+ int nonEqual = 0;
+
+ for (int i = 0; i < expected.length - expectedOffset; i++)
+ {
+ nonEqual |= (sig[sigOffset + i] ^ expected[expectedOffset + i]);
+ }
+
+ for (int i = 0; i < sigOffset; i++)
+ {
+ nonEqual |= (sig[i] ^ expected[i]); // check header less NULL
+ }
+
+ return nonEqual == 0;
+ }
+ else
+ {
+ Arrays.constantTimeAreEqual(expected, expected); // keep time "steady".
+
+ return false;
+ }
+ }
+
+ protected void engineSetParameter(
+ AlgorithmParameterSpec params)
+ {
+ throw new UnsupportedOperationException("engineSetParameter unsupported");
+ }
+
+ /**
+ * @deprecated replaced with #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
+ */
+ protected void engineSetParameter(
+ String param,
+ Object value)
+ {
+ throw new UnsupportedOperationException("engineSetParameter unsupported");
+ }
+
+ /**
+ * @deprecated
+ */
+ protected Object engineGetParameter(
+ String param)
+ {
+ return null;
+ }
+
+ protected AlgorithmParameters engineGetParameters()
+ {
+ return null;
+ }
+
+ private byte[] derEncode(
+ byte[] hash)
+ throws IOException
+ {
+ if (algId == null)
+ {
+ // For raw RSA, the DigestInfo must be prepared externally
+ return hash;
+ }
+
+ DigestInfo dInfo = new DigestInfo(algId, hash);
+
+ return dInfo.getEncoded(ASN1Encoding.DER);
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class SHA1
+ extends DigestSignatureSpi
+ {
+ public SHA1()
+ {
+ // Android-changed: Use Android digests
+ // super(OIWObjectIdentifiers.idSHA1, DigestFactory.createSHA1(), new PKCS1Encoding(new RSABlindedEngine()));
+ super(OIWObjectIdentifiers.idSHA1, AndroidDigestFactory.getSHA1(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class SHA224
+ extends DigestSignatureSpi
+ {
+ public SHA224()
+ {
+ // Android-changed: Use Android digests
+ // super(NISTObjectIdentifiers.id_sha224, DigestFactory.createSHA224(), new PKCS1Encoding(new RSABlindedEngine()));
+ super(NISTObjectIdentifiers.id_sha224, AndroidDigestFactory.getSHA224(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class SHA256
+ extends DigestSignatureSpi
+ {
+ public SHA256()
+ {
+ // Android-changed: Use Android digests
+ // super(NISTObjectIdentifiers.id_sha256, DigestFactory.createSHA256(), new PKCS1Encoding(new RSABlindedEngine()));
+ super(NISTObjectIdentifiers.id_sha256, AndroidDigestFactory.getSHA256(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class SHA384
+ extends DigestSignatureSpi
+ {
+ public SHA384()
+ {
+ // Android-changed: Use Android digests
+ // super(NISTObjectIdentifiers.id_sha384, DigestFactory.createSHA384(), new PKCS1Encoding(new RSABlindedEngine()));
+ super(NISTObjectIdentifiers.id_sha384, AndroidDigestFactory.getSHA384(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class SHA512
+ extends DigestSignatureSpi
+ {
+ public SHA512()
+ {
+ // Android-changed: Use Android digests
+ // super(NISTObjectIdentifiers.id_sha512, DigestFactory.createSHA512(), new PKCS1Encoding(new RSABlindedEngine()));
+ super(NISTObjectIdentifiers.id_sha512, AndroidDigestFactory.getSHA512(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ static public class SHA512_224
+ extends DigestSignatureSpi
+ {
+ public SHA512_224()
+ {
+ super(NISTObjectIdentifiers.id_sha512_224, DigestFactory.createSHA512_224(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ static public class SHA512_256
+ extends DigestSignatureSpi
+ {
+ public SHA512_256()
+ {
+ super(NISTObjectIdentifiers.id_sha512_256, DigestFactory.createSHA512_256(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ static public class SHA3_224
+ extends DigestSignatureSpi
+ {
+ public SHA3_224()
+ {
+ super(NISTObjectIdentifiers.id_sha3_224, DigestFactory.createSHA3_224(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ static public class SHA3_256
+ extends DigestSignatureSpi
+ {
+ public SHA3_256()
+ {
+ super(NISTObjectIdentifiers.id_sha3_256, DigestFactory.createSHA3_256(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ static public class SHA3_384
+ extends DigestSignatureSpi
+ {
+ public SHA3_384()
+ {
+ super(NISTObjectIdentifiers.id_sha3_384, DigestFactory.createSHA3_384(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ static public class SHA3_512
+ extends DigestSignatureSpi
+ {
+ public SHA3_512()
+ {
+ super(NISTObjectIdentifiers.id_sha3_512, DigestFactory.createSHA3_512(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ static public class MD2
+ extends DigestSignatureSpi
+ {
+ public MD2()
+ {
+ super(PKCSObjectIdentifiers.md2, new MD2Digest(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ static public class MD4
+ extends DigestSignatureSpi
+ {
+ public MD4()
+ {
+ super(PKCSObjectIdentifiers.md4, new MD4Digest(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class MD5
+ extends DigestSignatureSpi
+ {
+ public MD5()
+ {
+ // Android-changed: Use Android digests
+ // super(PKCSObjectIdentifiers.md5, DigestFactory.createMD5(), new PKCS1Encoding(new RSABlindedEngine()));
+ super(PKCSObjectIdentifiers.md5, AndroidDigestFactory.getMD5(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ static public class RIPEMD160
+ extends DigestSignatureSpi
+ {
+ public RIPEMD160()
+ {
+ super(TeleTrusTObjectIdentifiers.ripemd160, new RIPEMD160Digest(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ static public class RIPEMD128
+ extends DigestSignatureSpi
+ {
+ public RIPEMD128()
+ {
+ super(TeleTrusTObjectIdentifiers.ripemd128, new RIPEMD128Digest(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ static public class RIPEMD256
+ extends DigestSignatureSpi
+ {
+ public RIPEMD256()
+ {
+ super(TeleTrusTObjectIdentifiers.ripemd256, new RIPEMD256Digest(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+
+ static public class noneRSA
+ extends DigestSignatureSpi
+ {
+ public noneRSA()
+ {
+ super(new NullDigest(), new PKCS1Encoding(new RSABlindedEngine()));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java
new file mode 100644
index 00000000..53ccca49
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java
@@ -0,0 +1,295 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.rsa;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.RSAPrivateCrtKeySpec;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.pkcs.RSAPrivateKey;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.params.RSAKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.util.OpenSSHPrivateKeyUtil;
+// import org.bouncycastle.crypto.util.OpenSSHPublicKeyUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ExtendedInvalidKeySpecException;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec;
+// import org.bouncycastle.jce.spec.OpenSSHPublicKeySpec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyFactorySpi
+ extends BaseKeyFactorySpi
+{
+ public KeyFactorySpi()
+ {
+ }
+
+ protected KeySpec engineGetKeySpec(
+ Key key,
+ Class spec)
+ throws InvalidKeySpecException
+ {
+ if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(RSAPublicKeySpec.class)) && key instanceof RSAPublicKey)
+ {
+ RSAPublicKey k = (RSAPublicKey)key;
+
+ return new RSAPublicKeySpec(k.getModulus(), k.getPublicExponent());
+ }
+ else if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(RSAPrivateCrtKeySpec.class)) && key instanceof RSAPrivateCrtKey)
+ {
+ RSAPrivateCrtKey k = (RSAPrivateCrtKey)key;
+
+ return new RSAPrivateCrtKeySpec(
+ k.getModulus(), k.getPublicExponent(),
+ k.getPrivateExponent(),
+ k.getPrimeP(), k.getPrimeQ(),
+ k.getPrimeExponentP(), k.getPrimeExponentQ(),
+ k.getCrtCoefficient());
+ }
+ else if ((spec.isAssignableFrom(KeySpec.class) || spec.isAssignableFrom(RSAPrivateKeySpec.class)) && key instanceof java.security.interfaces.RSAPrivateKey)
+ {
+ java.security.interfaces.RSAPrivateKey k = (java.security.interfaces.RSAPrivateKey)key;
+
+ return new RSAPrivateKeySpec(k.getModulus(), k.getPrivateExponent());
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (spec.isAssignableFrom(OpenSSHPublicKeySpec.class) && key instanceof RSAPublicKey)
+ {
+ try
+ {
+ return new OpenSSHPublicKeySpec(
+ OpenSSHPublicKeyUtil.encodePublicKey(
+ new RSAKeyParameters(
+ false,
+ ((RSAPublicKey)key).getModulus(),
+ ((RSAPublicKey)key).getPublicExponent())
+ )
+ );
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ else if (spec.isAssignableFrom(OpenSSHPrivateKeySpec.class) && key instanceof RSAPrivateCrtKey)
+ {
+ try
+ {
+ return new OpenSSHPrivateKeySpec(OpenSSHPrivateKeyUtil.encodePrivateKey(new RSAPrivateCrtKeyParameters(
+ ((RSAPrivateCrtKey)key).getModulus(),
+ ((RSAPrivateCrtKey)key).getPublicExponent(),
+ ((RSAPrivateCrtKey)key).getPrivateExponent(),
+ ((RSAPrivateCrtKey)key).getPrimeP(),
+ ((RSAPrivateCrtKey)key).getPrimeQ(),
+ ((RSAPrivateCrtKey)key).getPrimeExponentP(),
+ ((RSAPrivateCrtKey)key).getPrimeExponentQ(),
+ ((RSAPrivateCrtKey)key).getCrtCoefficient()
+ )));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPublicKeySpec.class) && key instanceof RSAPublicKey)
+ {
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPublicKeySpec(
+ OpenSSHPublicKeyUtil.encodePublicKey(
+ new RSAKeyParameters(
+ false,
+ ((RSAPublicKey)key).getModulus(),
+ ((RSAPublicKey)key).getPublicExponent())
+ )
+ );
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec.class) && key instanceof RSAPrivateCrtKey)
+ {
+ try
+ {
+ return new org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec(OpenSSHPrivateKeyUtil.encodePrivateKey(new RSAPrivateCrtKeyParameters(
+ ((RSAPrivateCrtKey)key).getModulus(),
+ ((RSAPrivateCrtKey)key).getPublicExponent(),
+ ((RSAPrivateCrtKey)key).getPrivateExponent(),
+ ((RSAPrivateCrtKey)key).getPrimeP(),
+ ((RSAPrivateCrtKey)key).getPrimeQ(),
+ ((RSAPrivateCrtKey)key).getPrimeExponentP(),
+ ((RSAPrivateCrtKey)key).getPrimeExponentQ(),
+ ((RSAPrivateCrtKey)key).getCrtCoefficient()
+ )));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to produce encoding: " + e.getMessage());
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ return super.engineGetKeySpec(key, spec);
+ }
+
+ protected Key engineTranslateKey(
+ Key key)
+ throws InvalidKeyException
+ {
+ if (key instanceof RSAPublicKey)
+ {
+ return new BCRSAPublicKey((RSAPublicKey)key);
+ }
+ else if (key instanceof RSAPrivateCrtKey)
+ {
+ return new BCRSAPrivateCrtKey((RSAPrivateCrtKey)key);
+ }
+ else if (key instanceof java.security.interfaces.RSAPrivateKey)
+ {
+ return new BCRSAPrivateKey((java.security.interfaces.RSAPrivateKey)key);
+ }
+
+ throw new InvalidKeyException("key type unknown");
+ }
+
+ protected PrivateKey engineGeneratePrivate(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof PKCS8EncodedKeySpec)
+ {
+ try
+ {
+ return generatePrivate(PrivateKeyInfo.getInstance(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
+ }
+ catch (Exception e)
+ {
+ //
+ // in case it's just a RSAPrivateKey object... -- openSSL produces these
+ //
+ try
+ {
+ return new BCRSAPrivateCrtKey(
+ RSAPrivateKey.getInstance(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
+ }
+ catch (Exception ex)
+ {
+ throw new ExtendedInvalidKeySpecException("unable to process key spec: " + e.toString(), e);
+ }
+ }
+ }
+ else if (keySpec instanceof RSAPrivateCrtKeySpec)
+ {
+ return new BCRSAPrivateCrtKey((RSAPrivateCrtKeySpec)keySpec);
+ }
+ else if (keySpec instanceof RSAPrivateKeySpec)
+ {
+ return new BCRSAPrivateKey((RSAPrivateKeySpec)keySpec);
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (keySpec instanceof OpenSSHPrivateKeySpec)
+ {
+ CipherParameters parameters = OpenSSHPrivateKeyUtil.parsePrivateKeyBlob(((OpenSSHPrivateKeySpec)keySpec).getEncoded());
+
+ if (parameters instanceof RSAPrivateCrtKeyParameters)
+ {
+ return new BCRSAPrivateCrtKey((RSAPrivateCrtKeyParameters)parameters);
+ }
+
+ throw new InvalidKeySpecException("open SSH public key is not RSA private key");
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ throw new InvalidKeySpecException("unknown KeySpec type: " + keySpec.getClass().getName());
+ }
+
+ protected PublicKey engineGeneratePublic(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof RSAPublicKeySpec)
+ {
+ return new BCRSAPublicKey((RSAPublicKeySpec)keySpec);
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (keySpec instanceof OpenSSHPublicKeySpec)
+ {
+
+ CipherParameters parameters = OpenSSHPublicKeyUtil.parsePublicKey(((OpenSSHPublicKeySpec)keySpec).getEncoded());
+ if (parameters instanceof RSAKeyParameters)
+ {
+ return new BCRSAPublicKey((RSAKeyParameters)parameters);
+ }
+
+ throw new InvalidKeySpecException("Open SSH public key is not RSA public key");
+
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ return super.engineGeneratePublic(keySpec);
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm();
+
+ if (RSAUtil.isRsaOid(algOid))
+ {
+ RSAPrivateKey rsaPrivKey = RSAPrivateKey.getInstance(keyInfo.parsePrivateKey());
+
+ if (rsaPrivKey.getCoefficient().intValue() == 0)
+ {
+ return new BCRSAPrivateKey(keyInfo.getPrivateKeyAlgorithm(), rsaPrivKey);
+ }
+ else
+ {
+ return new BCRSAPrivateCrtKey(keyInfo);
+ }
+ }
+ else
+ {
+ throw new IOException("algorithm identifier " + algOid + " in key not recognised");
+ }
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm();
+
+ if (RSAUtil.isRsaOid(algOid))
+ {
+ return new BCRSAPublicKey(keyInfo);
+ }
+ else
+ {
+ throw new IOException("algorithm identifier " + algOid + " in key not recognised");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java
new file mode 100644
index 00000000..3b0d53e1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java
@@ -0,0 +1,108 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.rsa;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPair;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
+
+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;
+import com.android.internal.org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.generators.RSAKeyPairGenerator;
+import com.android.internal.org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.params.RSAKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PrimeCertaintyCalculator;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyPairGeneratorSpi
+ extends java.security.KeyPairGenerator
+{
+ private static final AlgorithmIdentifier PKCS_ALGID = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
+ private static final AlgorithmIdentifier PSS_ALGID = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS);
+
+ final static BigInteger defaultPublicExponent = BigInteger.valueOf(0x10001);
+
+ RSAKeyGenerationParameters param;
+ RSAKeyPairGenerator engine;
+ AlgorithmIdentifier algId;
+
+ public KeyPairGeneratorSpi(
+ String algorithmName,
+ AlgorithmIdentifier algId)
+ {
+ super(algorithmName);
+
+ this.algId = algId;
+ engine = new RSAKeyPairGenerator();
+ param = new RSAKeyGenerationParameters(defaultPublicExponent,
+ CryptoServicesRegistrar.getSecureRandom(), 2048, PrimeCertaintyCalculator.getDefaultCertainty(2048));
+ engine.init(param);
+ }
+
+ public KeyPairGeneratorSpi()
+ {
+ this("RSA", PKCS_ALGID);
+ }
+
+ public void initialize(
+ int strength,
+ SecureRandom random)
+ {
+ param = new RSAKeyGenerationParameters(defaultPublicExponent,
+ // Android-changed: Replace null random with default implementation.
+ // random, strength, PrimeCertaintyCalculator.getDefaultCertainty(strength));
+ (random != null) ? random : new SecureRandom(), strength, PrimeCertaintyCalculator.getDefaultCertainty(strength));
+
+ engine.init(param);
+ }
+
+ public void initialize(
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ if (!(params instanceof RSAKeyGenParameterSpec))
+ {
+ throw new InvalidAlgorithmParameterException("parameter object not a RSAKeyGenParameterSpec");
+ }
+ RSAKeyGenParameterSpec rsaParams = (RSAKeyGenParameterSpec)params;
+
+ param = new RSAKeyGenerationParameters(
+ rsaParams.getPublicExponent(),
+ // Android-changed: Replace null random with default implementation.
+ // random, rsaParams.getKeysize(), PrimeCertaintyCalculator.getDefaultCertainty(2048));
+ (random != null) ? random : new SecureRandom(), rsaParams.getKeysize(), PrimeCertaintyCalculator.getDefaultCertainty(2048));
+
+ engine.init(param);
+ }
+
+ public KeyPair generateKeyPair()
+ {
+ AsymmetricCipherKeyPair pair = engine.generateKeyPair();
+ RSAKeyParameters pub = (RSAKeyParameters)pair.getPublic();
+ RSAPrivateCrtKeyParameters priv = (RSAPrivateCrtKeyParameters)pair.getPrivate();
+
+ return new KeyPair(new BCRSAPublicKey(algId, pub),
+ new BCRSAPrivateCrtKey(algId, priv));
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PSS
+ extends KeyPairGeneratorSpi
+ {
+ public PSS()
+ {
+ super("RSASSA-PSS", PSS_ALGID);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java
new file mode 100644
index 00000000..98a1710a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java
@@ -0,0 +1,89 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.rsa;
+
+import java.math.BigInteger;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.params.RSAKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import com.android.internal.org.bouncycastle.util.Fingerprint;
+
+/**
+ * utility class for converting java.security RSA objects into their
+ * org.bouncycastle.crypto counterparts.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RSAUtil
+{
+ public static final ASN1ObjectIdentifier[] rsaOids =
+ {
+ PKCSObjectIdentifiers.rsaEncryption,
+ X509ObjectIdentifiers.id_ea_rsa,
+ PKCSObjectIdentifiers.id_RSAES_OAEP,
+ PKCSObjectIdentifiers.id_RSASSA_PSS
+ };
+
+ public static boolean isRsaOid(
+ ASN1ObjectIdentifier algOid)
+ {
+ for (int i = 0; i != rsaOids.length; i++)
+ {
+ if (algOid.equals(rsaOids[i]))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ static RSAKeyParameters generatePublicKeyParameter(
+ RSAPublicKey key)
+ {
+ if (key instanceof BCRSAPublicKey)
+ {
+ return ((BCRSAPublicKey)key).engineGetKeyParameters();
+ }
+
+ return new RSAKeyParameters(false, key.getModulus(), key.getPublicExponent());
+ }
+
+ static RSAKeyParameters generatePrivateKeyParameter(
+ RSAPrivateKey key)
+ {
+ if (key instanceof BCRSAPrivateKey)
+ {
+ return ((BCRSAPrivateKey)key).engineGetKeyParameters();
+ }
+
+ if (key instanceof RSAPrivateCrtKey)
+ {
+ RSAPrivateCrtKey k = (RSAPrivateCrtKey)key;
+
+ return new RSAPrivateCrtKeyParameters(k.getModulus(),
+ k.getPublicExponent(), k.getPrivateExponent(),
+ k.getPrimeP(), k.getPrimeQ(), k.getPrimeExponentP(), k.getPrimeExponentQ(), k.getCrtCoefficient());
+ }
+ else
+ {
+ RSAPrivateKey k = key;
+
+ return new RSAKeyParameters(true, k.getModulus(), k.getPrivateExponent());
+ }
+ }
+
+ static String generateKeyFingerprint(BigInteger modulus)
+ {
+ return new Fingerprint(modulus.toByteArray()).toString();
+ }
+
+ static String generateExponentFingerprint(BigInteger exponent)
+ {
+ return new Fingerprint(exponent.toByteArray(), 32).toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java
new file mode 100644
index 00000000..b89cd733
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java
@@ -0,0 +1,355 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util;
+
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.crypto.KeyAgreementSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.SecretKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.gnu.GNUObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.kisa.KISAObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+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.crypto.DerivationFunction;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.agreement.kdf.DHKDFParameters;
+// import org.bouncycastle.crypto.agreement.kdf.DHKEKGenerator;
+import com.android.internal.org.bouncycastle.crypto.params.DESParameters;
+import com.android.internal.org.bouncycastle.crypto.params.KDFParameters;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Integers;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class BaseAgreementSpi
+ extends KeyAgreementSpi
+{
+ private static final Map<String, ASN1ObjectIdentifier> defaultOids = new HashMap<String, ASN1ObjectIdentifier>();
+ private static final Map<String, Integer> keySizes = new HashMap<String, Integer>();
+ private static final Map<String, String> nameTable = new HashMap<String, String>();
+
+ private static final Hashtable oids = new Hashtable();
+ private static final Hashtable des = new Hashtable();
+
+ static
+ {
+ Integer i64 = Integers.valueOf(64);
+ Integer i128 = Integers.valueOf(128);
+ Integer i192 = Integers.valueOf(192);
+ Integer i256 = Integers.valueOf(256);
+
+ keySizes.put("DES", i64);
+ keySizes.put("DESEDE", i192);
+ keySizes.put("BLOWFISH", i128);
+ keySizes.put("AES", i256);
+
+ keySizes.put(NISTObjectIdentifiers.id_aes128_ECB.getId(), i128);
+ keySizes.put(NISTObjectIdentifiers.id_aes192_ECB.getId(), i192);
+ keySizes.put(NISTObjectIdentifiers.id_aes256_ECB.getId(), i256);
+ keySizes.put(NISTObjectIdentifiers.id_aes128_CBC.getId(), i128);
+ keySizes.put(NISTObjectIdentifiers.id_aes192_CBC.getId(), i192);
+ keySizes.put(NISTObjectIdentifiers.id_aes256_CBC.getId(), i256);
+ keySizes.put(NISTObjectIdentifiers.id_aes128_CFB.getId(), i128);
+ keySizes.put(NISTObjectIdentifiers.id_aes192_CFB.getId(), i192);
+ keySizes.put(NISTObjectIdentifiers.id_aes256_CFB.getId(), i256);
+ keySizes.put(NISTObjectIdentifiers.id_aes128_OFB.getId(), i128);
+ keySizes.put(NISTObjectIdentifiers.id_aes192_OFB.getId(), i192);
+ keySizes.put(NISTObjectIdentifiers.id_aes256_OFB.getId(), i256);
+ keySizes.put(NISTObjectIdentifiers.id_aes128_wrap.getId(), i128);
+ keySizes.put(NISTObjectIdentifiers.id_aes192_wrap.getId(), i192);
+ keySizes.put(NISTObjectIdentifiers.id_aes256_wrap.getId(), i256);
+ keySizes.put(NISTObjectIdentifiers.id_aes128_CCM.getId(), i128);
+ keySizes.put(NISTObjectIdentifiers.id_aes192_CCM.getId(), i192);
+ keySizes.put(NISTObjectIdentifiers.id_aes256_CCM.getId(), i256);
+ keySizes.put(NISTObjectIdentifiers.id_aes128_GCM.getId(), i128);
+ keySizes.put(NISTObjectIdentifiers.id_aes192_GCM.getId(), i192);
+ keySizes.put(NISTObjectIdentifiers.id_aes256_GCM.getId(), i256);
+ keySizes.put(NTTObjectIdentifiers.id_camellia128_wrap.getId(), i128);
+ keySizes.put(NTTObjectIdentifiers.id_camellia192_wrap.getId(), i192);
+ keySizes.put(NTTObjectIdentifiers.id_camellia256_wrap.getId(), i256);
+ keySizes.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap.getId(), i128);
+
+ keySizes.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(), i192);
+ keySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), i192);
+ keySizes.put(OIWObjectIdentifiers.desCBC.getId(), i64);
+
+ // Android-removed: Unsupported algorithms
+ // keySizes.put(CryptoProObjectIdentifiers.gostR28147_gcfb.getId(), i256);
+ // keySizes.put(CryptoProObjectIdentifiers.id_Gost28147_89_None_KeyWrap.getId(), i256);
+ // keySizes.put(CryptoProObjectIdentifiers.id_Gost28147_89_CryptoPro_KeyWrap.getId(), i256);
+
+ keySizes.put(PKCSObjectIdentifiers.id_hmacWithSHA1.getId(), Integers.valueOf(160));
+ keySizes.put(PKCSObjectIdentifiers.id_hmacWithSHA256.getId(), i256);
+ keySizes.put(PKCSObjectIdentifiers.id_hmacWithSHA384.getId(), Integers.valueOf(384));
+ keySizes.put(PKCSObjectIdentifiers.id_hmacWithSHA512.getId(), Integers.valueOf(512));
+
+ defaultOids.put("DESEDE", PKCSObjectIdentifiers.des_EDE3_CBC);
+ defaultOids.put("AES", NISTObjectIdentifiers.id_aes256_CBC);
+ defaultOids.put("CAMELLIA", NTTObjectIdentifiers.id_camellia256_cbc);
+ defaultOids.put("SEED", KISAObjectIdentifiers.id_seedCBC);
+ defaultOids.put("DES", OIWObjectIdentifiers.desCBC);
+
+ nameTable.put(MiscObjectIdentifiers.cast5CBC.getId(), "CAST5");
+ nameTable.put(MiscObjectIdentifiers.as_sys_sec_alg_ideaCBC.getId(), "IDEA");
+ nameTable.put(MiscObjectIdentifiers.cryptlib_algorithm_blowfish_ECB.getId(), "Blowfish");
+ nameTable.put(MiscObjectIdentifiers.cryptlib_algorithm_blowfish_CBC.getId(), "Blowfish");
+ nameTable.put(MiscObjectIdentifiers.cryptlib_algorithm_blowfish_CFB.getId(), "Blowfish");
+ nameTable.put(MiscObjectIdentifiers.cryptlib_algorithm_blowfish_OFB.getId(), "Blowfish");
+ nameTable.put(OIWObjectIdentifiers.desECB.getId(), "DES");
+ nameTable.put(OIWObjectIdentifiers.desCBC.getId(), "DES");
+ nameTable.put(OIWObjectIdentifiers.desCFB.getId(), "DES");
+ nameTable.put(OIWObjectIdentifiers.desOFB.getId(), "DES");
+ nameTable.put(OIWObjectIdentifiers.desEDE.getId(), "DESede");
+ nameTable.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), "DESede");
+ nameTable.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(), "DESede");
+ nameTable.put(PKCSObjectIdentifiers.id_alg_CMSRC2wrap.getId(), "RC2");
+ nameTable.put(PKCSObjectIdentifiers.id_hmacWithSHA1.getId(), "HmacSHA1");
+ nameTable.put(PKCSObjectIdentifiers.id_hmacWithSHA224.getId(), "HmacSHA224");
+ nameTable.put(PKCSObjectIdentifiers.id_hmacWithSHA256.getId(), "HmacSHA256");
+ nameTable.put(PKCSObjectIdentifiers.id_hmacWithSHA384.getId(), "HmacSHA384");
+ nameTable.put(PKCSObjectIdentifiers.id_hmacWithSHA512.getId(), "HmacSHA512");
+ nameTable.put(NTTObjectIdentifiers.id_camellia128_cbc.getId(), "Camellia");
+ nameTable.put(NTTObjectIdentifiers.id_camellia192_cbc.getId(), "Camellia");
+ nameTable.put(NTTObjectIdentifiers.id_camellia256_cbc.getId(), "Camellia");
+ nameTable.put(NTTObjectIdentifiers.id_camellia128_wrap.getId(), "Camellia");
+ nameTable.put(NTTObjectIdentifiers.id_camellia192_wrap.getId(), "Camellia");
+ nameTable.put(NTTObjectIdentifiers.id_camellia256_wrap.getId(), "Camellia");
+ nameTable.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap.getId(), "SEED");
+ nameTable.put(KISAObjectIdentifiers.id_seedCBC.getId(), "SEED");
+ nameTable.put(KISAObjectIdentifiers.id_seedMAC.getId(), "SEED");
+ // Android-removed: Unsupported algorithm
+ // nameTable.put(CryptoProObjectIdentifiers.gostR28147_gcfb.getId(), "GOST28147");
+
+ nameTable.put(NISTObjectIdentifiers.id_aes128_wrap.getId(), "AES");
+ nameTable.put(NISTObjectIdentifiers.id_aes128_CCM.getId(), "AES");
+ nameTable.put(NISTObjectIdentifiers.id_aes128_CCM.getId(), "AES");
+
+ oids.put("DESEDE", PKCSObjectIdentifiers.des_EDE3_CBC);
+ oids.put("AES", NISTObjectIdentifiers.id_aes256_CBC);
+ oids.put("DES", OIWObjectIdentifiers.desCBC);
+
+ des.put("DES", "DES");
+ des.put("DESEDE", "DES");
+ des.put(OIWObjectIdentifiers.desCBC.getId(), "DES");
+ des.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), "DES");
+ des.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(), "DES");
+ }
+
+ protected final String kaAlgorithm;
+ protected final DerivationFunction kdf;
+
+ protected byte[] ukmParameters;
+
+ public BaseAgreementSpi(String kaAlgorithm, DerivationFunction kdf)
+ {
+ this.kaAlgorithm = kaAlgorithm;
+ this.kdf = kdf;
+ }
+
+ protected static String getAlgorithm(String algDetails)
+ {
+ if (algDetails.indexOf('[') > 0)
+ {
+ return algDetails.substring(0, algDetails.indexOf('['));
+ }
+
+ if (algDetails.startsWith(NISTObjectIdentifiers.aes.getId()))
+ {
+ return "AES";
+ }
+ // BEGIN Android-removed: Unsupported algorithm
+ // if (algDetails.startsWith(GNUObjectIdentifiers.Serpent.getId()))
+ // {
+ // return "Serpent";
+ // }
+ // END Android-removed: Unsupported algorithms
+
+ String name = (String)nameTable.get(Strings.toUpperCase(algDetails));
+
+ if (name != null)
+ {
+ return name;
+ }
+
+ return algDetails;
+ }
+
+ protected static int getKeySize(String algDetails)
+ {
+ if (algDetails.indexOf('[') > 0)
+ {
+ return Integer.parseInt(algDetails.substring(algDetails.indexOf('[') + 1, algDetails.indexOf(']')));
+ }
+
+ String algKey = Strings.toUpperCase(algDetails);
+ if (!keySizes.containsKey(algKey))
+ {
+ return -1;
+ }
+
+ return ((Integer)keySizes.get(algKey)).intValue();
+ }
+
+ protected static byte[] trimZeroes(byte[] secret)
+ {
+ if (secret[0] != 0)
+ {
+ return secret;
+ }
+ else
+ {
+ int ind = 0;
+ while (ind < secret.length && secret[ind] == 0)
+ {
+ ind++;
+ }
+
+ byte[] rv = new byte[secret.length - ind];
+
+ System.arraycopy(secret, ind, rv, 0, rv.length);
+
+ return rv;
+ }
+ }
+
+ protected byte[] engineGenerateSecret()
+ throws IllegalStateException
+ {
+ if (kdf != null)
+ {
+ byte[] secret = calcSecret();
+ try
+ {
+ return getSharedSecretBytes(secret, null, secret.length * 8);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new IllegalStateException(e.getMessage());
+ }
+ }
+
+ return calcSecret();
+ }
+
+ protected int engineGenerateSecret(
+ byte[] sharedSecret,
+ int offset)
+ throws IllegalStateException, ShortBufferException
+ {
+ byte[] secret = engineGenerateSecret();
+
+ if (sharedSecret.length - offset < secret.length)
+ {
+ throw new ShortBufferException(kaAlgorithm + " key agreement: need " + secret.length + " bytes");
+ }
+
+ System.arraycopy(secret, 0, sharedSecret, offset, secret.length);
+
+ return secret.length;
+ }
+
+ protected SecretKey engineGenerateSecret(
+ String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ String algKey = Strings.toUpperCase(algorithm);
+ String oidAlgorithm = algorithm;
+
+ if (oids.containsKey(algKey))
+ {
+ oidAlgorithm = ((ASN1ObjectIdentifier)oids.get(algKey)).getId();
+ }
+
+ int keySize = getKeySize(oidAlgorithm);
+
+ byte[] secret = getSharedSecretBytes(calcSecret(), oidAlgorithm, keySize);
+
+ String algName = getAlgorithm(algorithm);
+
+ if (des.containsKey(algName))
+ {
+ DESParameters.setOddParity(secret);
+ }
+
+ return new SecretKeySpec(secret, algName);
+ }
+
+ private byte[] getSharedSecretBytes(byte[] secret, String oidAlgorithm, int keySize)
+ throws NoSuchAlgorithmException
+ {
+ if (kdf != null)
+ {
+ if (keySize < 0)
+ {
+ throw new NoSuchAlgorithmException("unknown algorithm encountered: " + oidAlgorithm);
+ }
+ byte[] keyBytes = new byte[keySize / 8];
+
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
+ if (kdf instanceof DHKEKGenerator)
+ {
+ if (oidAlgorithm == null)
+ {
+ throw new NoSuchAlgorithmException("algorithm OID is null");
+ }
+ ASN1ObjectIdentifier oid;
+ try
+ {
+ oid = new ASN1ObjectIdentifier(oidAlgorithm);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new NoSuchAlgorithmException("no OID for algorithm: " + oidAlgorithm);
+ }
+ DHKDFParameters params = new DHKDFParameters(oid, keySize, secret, ukmParameters);
+
+ kdf.init(params);
+ }
+ else
+ */
+ // END Android-removed: Unsupported algorithm
+ {
+ KDFParameters params = new KDFParameters(secret, ukmParameters);
+
+ kdf.init(params);
+ }
+
+ kdf.generateBytes(keyBytes, 0, keyBytes.length);
+
+ Arrays.clear(secret);
+
+ return keyBytes;
+ }
+ else
+ {
+ if (keySize > 0)
+ {
+ byte[] keyBytes = new byte[keySize / 8];
+
+ System.arraycopy(secret, 0, keyBytes, 0, keyBytes.length);
+
+ Arrays.clear(secret);
+
+ return keyBytes;
+ }
+
+ return secret;
+ }
+ }
+
+ protected abstract byte[] calcSecret();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAlgorithmParameterGeneratorSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAlgorithmParameterGeneratorSpi.java
new file mode 100644
index 00000000..1f2e6706
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAlgorithmParameterGeneratorSpi.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util;
+
+import java.security.AlgorithmParameterGeneratorSpi;
+import java.security.AlgorithmParameters;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+
+import com.android.internal.org.bouncycastle.jcajce.util.BCJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class BaseAlgorithmParameterGeneratorSpi
+ extends AlgorithmParameterGeneratorSpi
+{
+ private final JcaJceHelper helper = new BCJcaJceHelper();
+
+ public BaseAlgorithmParameterGeneratorSpi()
+ {
+ }
+
+ protected final AlgorithmParameters createParametersInstance(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return helper.createAlgorithmParameters(algorithm);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java
new file mode 100644
index 00000000..f9d0692f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java
@@ -0,0 +1,258 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util;
+
+import java.io.ByteArrayOutputStream;
+import java.security.AlgorithmParameters;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherSpi;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEParameterSpec;
+// Android-removed: Unsupported algorithms
+// import javax.crypto.spec.RC2ParameterSpec;
+// import javax.crypto.spec.RC5ParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.Wrapper;
+import com.android.internal.org.bouncycastle.jcajce.util.BCJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class BaseCipherSpi
+ extends CipherSpi
+{
+ //
+ // specs we can handle.
+ //
+ private Class[] availableSpecs =
+ {
+ IvParameterSpec.class,
+ PBEParameterSpec.class,
+ // Android-removed: Unsupported algorithms
+ // RC2ParameterSpec.class,
+ // RC5ParameterSpec.class
+ };
+
+ private final JcaJceHelper helper = new BCJcaJceHelper();
+
+ protected AlgorithmParameters engineParams = null;
+
+ protected Wrapper wrapEngine = null;
+
+ private int ivSize;
+ private byte[] iv;
+
+ protected BaseCipherSpi()
+ {
+ }
+
+ protected int engineGetBlockSize()
+ {
+ return 0;
+ }
+
+ protected byte[] engineGetIV()
+ {
+ return null;
+ }
+
+ protected int engineGetKeySize(
+ Key key)
+ {
+ return key.getEncoded().length;
+ }
+
+ protected int engineGetOutputSize(
+ int inputLen)
+ {
+ return -1;
+ }
+
+ protected AlgorithmParameters engineGetParameters()
+ {
+ return null;
+ }
+
+ protected final AlgorithmParameters createParametersInstance(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return helper.createAlgorithmParameters(algorithm);
+ }
+
+ protected void engineSetMode(
+ String mode)
+ throws NoSuchAlgorithmException
+ {
+ throw new NoSuchAlgorithmException("can't support mode " + mode);
+ }
+
+ protected void engineSetPadding(
+ String padding)
+ throws NoSuchPaddingException
+ {
+ throw new NoSuchPaddingException("Padding " + padding + " unknown.");
+ }
+
+ protected byte[] engineWrap(
+ Key key)
+ throws IllegalBlockSizeException, InvalidKeyException
+ {
+ byte[] encoded = key.getEncoded();
+ if (encoded == null)
+ {
+ throw new InvalidKeyException("Cannot wrap key, null encoding.");
+ }
+
+ try
+ {
+ if (wrapEngine == null)
+ {
+ return engineDoFinal(encoded, 0, encoded.length);
+ }
+ else
+ {
+ return wrapEngine.wrap(encoded, 0, encoded.length);
+ }
+ }
+ catch (BadPaddingException e)
+ {
+ throw new IllegalBlockSizeException(e.getMessage());
+ }
+ }
+
+ protected Key engineUnwrap(
+ byte[] wrappedKey,
+ String wrappedKeyAlgorithm,
+ int wrappedKeyType)
+ throws InvalidKeyException
+ {
+ byte[] encoded;
+ try
+ {
+ if (wrapEngine == null)
+ {
+ encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length);
+ }
+ else
+ {
+ encoded = wrapEngine.unwrap(wrappedKey, 0, wrappedKey.length);
+ }
+ }
+ catch (InvalidCipherTextException e)
+ {
+ throw new InvalidKeyException(e.getMessage());
+ }
+ catch (final BadPaddingException e)
+ {
+ throw new InvalidKeyException("unable to unwrap")
+ {
+ public synchronized Throwable getCause()
+ {
+ return e;
+ }
+ };
+ }
+ catch (IllegalBlockSizeException e2)
+ {
+ throw new InvalidKeyException(e2.getMessage());
+ }
+
+ if (wrappedKeyType == Cipher.SECRET_KEY)
+ {
+ return new SecretKeySpec(encoded, wrappedKeyAlgorithm);
+ }
+ else if (wrappedKeyAlgorithm.equals("") && wrappedKeyType == Cipher.PRIVATE_KEY)
+ {
+ /*
+ * The caller doesn't know the algorithm as it is part of
+ * the encrypted data.
+ */
+ try
+ {
+ PrivateKeyInfo in = PrivateKeyInfo.getInstance(encoded);
+
+ PrivateKey privKey = BouncyCastleProvider.getPrivateKey(in);
+
+ if (privKey != null)
+ {
+ return privKey;
+ }
+ else
+ {
+ throw new InvalidKeyException("algorithm " + in.getPrivateKeyAlgorithm().getAlgorithm() + " not supported");
+ }
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeyException("Invalid key encoding.");
+ }
+ }
+ else
+ {
+ try
+ {
+ KeyFactory kf = helper.createKeyFactory(wrappedKeyAlgorithm);
+
+ if (wrappedKeyType == Cipher.PUBLIC_KEY)
+ {
+ return kf.generatePublic(new X509EncodedKeySpec(encoded));
+ }
+ else if (wrappedKeyType == Cipher.PRIVATE_KEY)
+ {
+ return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded));
+ }
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new InvalidKeyException("Unknown key type " + e.getMessage());
+ }
+ catch (InvalidKeySpecException e)
+ {
+ throw new InvalidKeyException("Unknown key type " + e.getMessage());
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new InvalidKeyException("Unknown key type " + e.getMessage());
+ }
+
+ throw new InvalidKeyException("Unknown key type " + wrappedKeyType);
+ }
+ }
+
+ protected static final class ErasableOutputStream
+ extends ByteArrayOutputStream
+ {
+ public ErasableOutputStream()
+ {
+ }
+
+ public byte[] getBuf()
+ {
+ return buf;
+ }
+
+ public void erase()
+ {
+ Arrays.fill(this.buf, (byte)0);
+ reset();
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java
new file mode 100644
index 00000000..3bebeb52
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java
@@ -0,0 +1,81 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util;
+
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class BaseKeyFactorySpi
+ extends java.security.KeyFactorySpi
+ implements AsymmetricKeyInfoConverter
+{
+ protected PrivateKey engineGeneratePrivate(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof PKCS8EncodedKeySpec)
+ {
+ try
+ {
+ return generatePrivate(PrivateKeyInfo.getInstance(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeySpecException("encoded key spec not recognized: " + e.getMessage());
+ }
+ }
+ else
+ {
+ throw new InvalidKeySpecException("key spec not recognized");
+ }
+ }
+
+ protected PublicKey engineGeneratePublic(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof X509EncodedKeySpec)
+ {
+ try
+ {
+ return generatePublic(SubjectPublicKeyInfo.getInstance(((X509EncodedKeySpec)keySpec).getEncoded()));
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeySpecException("encoded key spec not recognized: " + e.getMessage());
+ }
+ }
+ else
+ {
+ throw new InvalidKeySpecException("key spec not recognized");
+ }
+ }
+
+ protected KeySpec engineGetKeySpec(
+ Key key,
+ Class spec)
+ throws InvalidKeySpecException
+ {
+ if (spec.isAssignableFrom(PKCS8EncodedKeySpec.class) && key.getFormat().equals("PKCS#8"))
+ {
+ return new PKCS8EncodedKeySpec(key.getEncoded());
+ }
+ else if (spec.isAssignableFrom(X509EncodedKeySpec.class) && key.getFormat().equals("X.509"))
+ {
+ return new X509EncodedKeySpec(key.getEncoded());
+ }
+
+ throw new InvalidKeySpecException("not implemented yet " + key + " " + spec);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/DHUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/DHUtil.java
new file mode 100644
index 00000000..d6e9994a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/DHUtil.java
@@ -0,0 +1,57 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util;
+
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.interfaces.DHPublicKey;
+
+import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPublicKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.dh.BCDHPublicKey;
+
+/**
+ * utility class for converting jce/jca DH objects
+ * objects into their org.bouncycastle.crypto counterparts.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHUtil
+{
+ static public AsymmetricKeyParameter generatePublicKeyParameter(
+ PublicKey key)
+ throws InvalidKeyException
+ {
+ if (key instanceof BCDHPublicKey)
+ {
+ return ((BCDHPublicKey)key).engineGetKeyParameters();
+ }
+ if (key instanceof DHPublicKey)
+ {
+ DHPublicKey k = (DHPublicKey)key;
+
+ return new DHPublicKeyParameters(k.getY(),
+ new DHParameters(k.getParams().getP(), k.getParams().getG(), null, k.getParams().getL()));
+ }
+
+ throw new InvalidKeyException("can't identify DH public key.");
+ }
+
+ static public AsymmetricKeyParameter generatePrivateKeyParameter(
+ PrivateKey key)
+ throws InvalidKeyException
+ {
+ if (key instanceof DHPrivateKey)
+ {
+ DHPrivateKey k = (DHPrivateKey)key;
+
+ return new DHPrivateKeyParameters(k.getX(),
+ new DHParameters(k.getParams().getP(), k.getParams().getG(), null, k.getParams().getL()));
+ }
+
+ throw new InvalidKeyException("can't identify DH private key.");
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/DSABase.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/DSABase.java
new file mode 100644
index 00000000..a3ca457e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/DSABase.java
@@ -0,0 +1,114 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util;
+
+import java.math.BigInteger;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+import java.security.spec.AlgorithmParameterSpec;
+
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.DSAExt;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.signers.DSAEncoding;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class DSABase
+ extends SignatureSpi
+ implements PKCSObjectIdentifiers, X509ObjectIdentifiers
+{
+ protected Digest digest;
+ protected DSAExt signer;
+ protected DSAEncoding encoding;
+
+ protected DSABase(
+ Digest digest,
+ DSAExt signer,
+ DSAEncoding encoding)
+ {
+ this.digest = digest;
+ this.signer = signer;
+ this.encoding = encoding;
+ }
+
+ protected void engineUpdate(
+ byte b)
+ throws SignatureException
+ {
+ digest.update(b);
+ }
+
+ protected void engineUpdate(
+ byte[] b,
+ int off,
+ int len)
+ throws SignatureException
+ {
+ digest.update(b, off, len);
+ }
+
+ protected byte[] engineSign()
+ throws SignatureException
+ {
+ byte[] hash = new byte[digest.getDigestSize()];
+ digest.doFinal(hash, 0);
+
+ try
+ {
+ BigInteger[] sig = signer.generateSignature(hash);
+
+ return encoding.encode(signer.getOrder(), sig[0], sig[1]);
+ }
+ catch (Exception e)
+ {
+ throw new SignatureException(e.toString());
+ }
+ }
+
+ protected boolean engineVerify(
+ byte[] sigBytes)
+ throws SignatureException
+ {
+ byte[] hash = new byte[digest.getDigestSize()];
+ digest.doFinal(hash, 0);
+
+ BigInteger[] sig;
+ try
+ {
+ sig = encoding.decode(signer.getOrder(), sigBytes);
+ }
+ catch (Exception e)
+ {
+ throw new SignatureException("error decoding signature bytes.");
+ }
+
+ return signer.verifySignature(hash, sig[0], sig[1]);
+ }
+
+ protected void engineSetParameter(
+ AlgorithmParameterSpec params)
+ {
+ throw new UnsupportedOperationException("engineSetParameter unsupported");
+ }
+
+ /**
+ * @deprecated replaced with "#engineSetParameter(java.security.spec.AlgorithmParameterSpec)"
+ */
+ protected void engineSetParameter(
+ String param,
+ Object value)
+ {
+ throw new UnsupportedOperationException("engineSetParameter unsupported");
+ }
+
+ /**
+ * @deprecated
+ */
+ protected Object engineGetParameter(
+ String param)
+ {
+ throw new UnsupportedOperationException("engineSetParameter unsupported");
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/DSAEncoder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/DSAEncoder.java
new file mode 100644
index 00000000..a1d4040b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/DSAEncoder.java
@@ -0,0 +1,18 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+/**
+ * @deprecated No longer used
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface DSAEncoder
+{
+ byte[] encode(BigInteger r, BigInteger s)
+ throws IOException;
+
+ BigInteger[] decode(byte[] sig)
+ throws IOException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
new file mode 100644
index 00000000..7eaea818
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
@@ -0,0 +1,372 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util;
+
+import java.math.BigInteger;
+import java.security.spec.ECField;
+import java.security.spec.ECFieldF2m;
+import java.security.spec.ECFieldFp;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.EllipticCurve;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
+// import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable;
+import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
+// import org.bouncycastle.jce.ECGOST3410NamedCurveTable;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
+import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveSpec;
+import com.android.internal.org.bouncycastle.math.ec.ECAlgorithms;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.field.FiniteField;
+import com.android.internal.org.bouncycastle.math.field.Polynomial;
+import com.android.internal.org.bouncycastle.math.field.PolynomialExtensionField;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EC5Util
+{
+ private static Map customCurves = new HashMap();
+
+ static
+ {
+ Enumeration e = CustomNamedCurves.getNames();
+ while (e.hasMoreElements())
+ {
+ String name = (String)e.nextElement();
+
+ X9ECParameters curveParams = ECNamedCurveTable.getByName(name);
+ if (curveParams != null) // there may not be a regular curve, may just be a custom curve.
+ {
+ customCurves.put(curveParams.getCurve(), CustomNamedCurves.getByName(name).getCurve());
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported curves
+ /*
+ X9ECParameters x9_25519 = CustomNamedCurves.getByName("Curve25519");
+ ECCurve c_25519 = x9_25519.getCurve();
+
+ customCurves.put(new ECCurve.Fp(
+ c_25519.getField().getCharacteristic(),
+ c_25519.getA().toBigInteger(),
+ c_25519.getB().toBigInteger(),
+ c_25519.getOrder(),
+ c_25519.getCofactor()
+ ), c_25519);
+ */
+ // END Android-removed: Unsupported curves
+ }
+
+ public static ECCurve getCurve(
+ ProviderConfiguration configuration,
+ X962Parameters params)
+ {
+ ECCurve curve;
+ Set acceptableCurves = configuration.getAcceptableNamedCurves();
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters());
+
+ if (acceptableCurves.isEmpty() || acceptableCurves.contains(oid))
+ {
+ X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
+
+ if (ecP == null)
+ {
+ ecP = (X9ECParameters)configuration.getAdditionalECParameters().get(oid);
+ }
+
+ curve = ecP.getCurve();
+ }
+ else
+ {
+ throw new IllegalStateException("named curve not acceptable");
+ }
+ }
+ else if (params.isImplicitlyCA())
+ {
+ curve = configuration.getEcImplicitlyCa().getCurve();
+ }
+ else
+ {
+ ASN1Sequence pSeq = ASN1Sequence.getInstance(params.getParameters());
+ if (acceptableCurves.isEmpty())
+ {
+ if (pSeq.size() > 3)
+ {
+ X9ECParameters ecP = X9ECParameters.getInstance(pSeq);
+
+ curve = ecP.getCurve();
+ }
+ else // GOST parameters
+ {
+ // BEGIN Android-removed: unsupported algorithms
+ /*
+ ASN1ObjectIdentifier gostCurve = ASN1ObjectIdentifier.getInstance(pSeq.getObjectAt(0));
+
+ curve = ECGOST3410NamedCurves.getByOIDX9(gostCurve).getCurve();
+ */
+ // END Android-removed: unsupported algorithms
+ throw new IllegalStateException("GOST is not supported");
+ }
+ }
+ else
+ {
+ throw new IllegalStateException("encoded parameters not acceptable");
+ }
+ }
+
+ return curve;
+ }
+
+ public static ECDomainParameters getDomainParameters(
+ ProviderConfiguration configuration,
+ java.security.spec.ECParameterSpec params)
+ {
+ ECDomainParameters domainParameters;
+
+ if (params == null)
+ {
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec iSpec = configuration.getEcImplicitlyCa();
+
+ domainParameters = new ECDomainParameters(iSpec.getCurve(), iSpec.getG(), iSpec.getN(), iSpec.getH(), iSpec.getSeed());
+ }
+ else
+ {
+ domainParameters = ECUtil.getDomainParameters(configuration, convertSpec(params));
+ }
+
+ return domainParameters;
+ }
+
+ public static ECParameterSpec convertToSpec(
+ X962Parameters params, ECCurve curve)
+ {
+ ECParameterSpec ecSpec;
+ EllipticCurve ellipticCurve;
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
+ X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
+ if (ecP == null)
+ {
+ Map additionalECParameters = BouncyCastleProvider.CONFIGURATION.getAdditionalECParameters();
+ if (!additionalECParameters.isEmpty())
+ {
+ ecP = (X9ECParameters)additionalECParameters.get(oid);
+ }
+ }
+
+ ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
+
+ ecSpec = new ECNamedCurveSpec(
+ ECUtil.getCurveName(oid),
+ ellipticCurve,
+ convertPoint(ecP.getG()),
+ ecP.getN(),
+ ecP.getH());
+ }
+ else if (params.isImplicitlyCA())
+ {
+ ecSpec = null;
+ }
+ else
+ {
+ ASN1Sequence pSeq = ASN1Sequence.getInstance(params.getParameters());
+ if (pSeq.size() > 3)
+ {
+ X9ECParameters ecP = X9ECParameters.getInstance(pSeq);
+
+ ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
+
+ if (ecP.getH() != null)
+ {
+ ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ convertPoint(ecP.getG()),
+ ecP.getN(),
+ ecP.getH().intValue());
+ }
+ else
+ {
+ ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ convertPoint(ecP.getG()),
+ ecP.getN(),
+ 1); // TODO: not strictly correct... need to fix the test data...
+ }
+ }
+ else // GOST parameters
+ {
+ // BEGIN Android-removed: unsupported algorithms
+ /*
+ GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(pSeq);
+
+ ECNamedCurveParameterSpec spec = ECGOST3410NamedCurveTable.getParameterSpec(ECGOST3410NamedCurves.getName(
+ gostParams.getPublicKeyParamSet()));
+
+ curve = spec.getCurve();
+ ellipticCurve = EC5Util.convertCurve(curve, spec.getSeed());
+
+ ecSpec = new ECNamedCurveSpec(
+ ECGOST3410NamedCurves.getName(gostParams.getPublicKeyParamSet()),
+ ellipticCurve,
+ EC5Util.convertPoint(spec.getG()),
+ spec.getN(), spec.getH());
+
+ */
+ // END Android-removed: unsupported algorithms
+ ecSpec = null;
+ }
+ }
+
+ return ecSpec;
+ }
+
+ public static ECParameterSpec convertToSpec(
+ X9ECParameters domainParameters)
+ {
+ return new ECParameterSpec(
+ convertCurve(domainParameters.getCurve(), null), // JDK 1.5 has trouble with this if it's not null...
+ EC5Util.convertPoint(domainParameters.getG()),
+ domainParameters.getN(),
+ domainParameters.getH().intValue());
+ }
+
+ public static ECParameterSpec convertToSpec(
+ ECDomainParameters domainParameters)
+ {
+ return new ECParameterSpec(
+ convertCurve(domainParameters.getCurve(), null), // JDK 1.5 has trouble with this if it's not null...
+ EC5Util.convertPoint(domainParameters.getG()),
+ domainParameters.getN(),
+ domainParameters.getH().intValue());
+ }
+
+ public static EllipticCurve convertCurve(
+ ECCurve curve,
+ byte[] seed)
+ {
+ ECField field = convertField(curve.getField());
+ BigInteger a = curve.getA().toBigInteger(), b = curve.getB().toBigInteger();
+
+ // TODO: the Sun EC implementation doesn't currently handle the seed properly
+ // so at the moment it's set to null. Should probably look at making this configurable
+ return new EllipticCurve(field, a, b, null);
+ }
+
+ public static ECCurve convertCurve(
+ EllipticCurve ec)
+ {
+ ECField field = ec.getField();
+ BigInteger a = ec.getA();
+ BigInteger b = ec.getB();
+
+ if (field instanceof ECFieldFp)
+ {
+ ECCurve.Fp curve = new ECCurve.Fp(((ECFieldFp)field).getP(), a, b);
+
+ if (customCurves.containsKey(curve))
+ {
+ return (ECCurve)customCurves.get(curve);
+ }
+
+ return curve;
+ }
+ else
+ {
+ ECFieldF2m fieldF2m = (ECFieldF2m)field;
+ int m = fieldF2m.getM();
+ int ks[] = ECUtil.convertMidTerms(fieldF2m.getMidTermsOfReductionPolynomial());
+ return new ECCurve.F2m(m, ks[0], ks[1], ks[2], a, b);
+ }
+ }
+
+ public static ECField convertField(FiniteField field)
+ {
+ if (ECAlgorithms.isFpField(field))
+ {
+ return new ECFieldFp(field.getCharacteristic());
+ }
+ else //if (ECAlgorithms.isF2mField(curveField))
+ {
+ Polynomial poly = ((PolynomialExtensionField)field).getMinimalPolynomial();
+ int[] exponents = poly.getExponentsPresent();
+ int[] ks = Arrays.reverse(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
+ return new ECFieldF2m(poly.getDegree(), ks);
+ }
+ }
+
+ public static ECParameterSpec convertSpec(
+ EllipticCurve ellipticCurve,
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec spec)
+ {
+ ECPoint g = convertPoint(spec.getG());
+
+ if (spec instanceof ECNamedCurveParameterSpec)
+ {
+ String name = ((ECNamedCurveParameterSpec)spec).getName();
+
+ return new ECNamedCurveSpec(name, ellipticCurve, g, spec.getN(), spec.getH());
+ }
+ else
+ {
+ return new ECParameterSpec(ellipticCurve, g, spec.getN(), spec.getH().intValue());
+ }
+ }
+
+ public static com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec convertSpec(ECParameterSpec ecSpec)
+ {
+ ECCurve curve = convertCurve(ecSpec.getCurve());
+
+ com.android.internal.org.bouncycastle.math.ec.ECPoint g = convertPoint(curve, ecSpec.getGenerator());
+ BigInteger n = ecSpec.getOrder();
+ BigInteger h = BigInteger.valueOf(ecSpec.getCofactor());
+ byte[] seed = ecSpec.getCurve().getSeed();
+
+ if (ecSpec instanceof ECNamedCurveSpec)
+ {
+ return new com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveParameterSpec(((ECNamedCurveSpec)ecSpec).getName(), curve,
+ g, n, h, seed);
+ }
+ else
+ {
+ return new com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec(curve, g, n, h, seed);
+ }
+ }
+
+ public static com.android.internal.org.bouncycastle.math.ec.ECPoint convertPoint(ECParameterSpec ecSpec, ECPoint point)
+ {
+ return convertPoint(convertCurve(ecSpec.getCurve()), point);
+ }
+
+ public static com.android.internal.org.bouncycastle.math.ec.ECPoint convertPoint(ECCurve curve, ECPoint point)
+ {
+ return curve.createPoint(point.getAffineX(), point.getAffineY());
+ }
+
+ public static ECPoint convertPoint(com.android.internal.org.bouncycastle.math.ec.ECPoint point)
+ {
+ point = point.normalize();
+
+ return new ECPoint(
+ point.getAffineXCoord().toBigInteger(),
+ point.getAffineYCoord().toBigInteger());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
new file mode 100644
index 00000000..5d0ebfe4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
@@ -0,0 +1,451 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util;
+
+import java.lang.reflect.Method;
+import java.math.BigInteger;
+import java.security.AccessController;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.PrivilegedAction;
+import java.security.PublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Enumeration;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable;
+import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves;
+import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECNamedDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
+import com.android.internal.org.bouncycastle.jce.interfaces.ECPrivateKey;
+import com.android.internal.org.bouncycastle.jce.interfaces.ECPublicKey;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
+import com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.ec.FixedPointCombMultiplier;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Fingerprint;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * utility class for converting jce/jca ECDSA, ECDH, and ECDHC
+ * objects into their org.bouncycastle.crypto counterparts.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECUtil
+{
+ /**
+ * Returns a sorted array of middle terms of the reduction polynomial.
+ * @param k The unsorted array of middle terms of the reduction polynomial
+ * of length 1 or 3.
+ * @return the sorted array of middle terms of the reduction polynomial.
+ * This array always has length 3.
+ */
+ static int[] convertMidTerms(
+ int[] k)
+ {
+ int[] res = new int[3];
+
+ if (k.length == 1)
+ {
+ res[0] = k[0];
+ }
+ else
+ {
+ if (k.length != 3)
+ {
+ throw new IllegalArgumentException("Only Trinomials and pentanomials supported");
+ }
+
+ if (k[0] < k[1] && k[0] < k[2])
+ {
+ res[0] = k[0];
+ if (k[1] < k[2])
+ {
+ res[1] = k[1];
+ res[2] = k[2];
+ }
+ else
+ {
+ res[1] = k[2];
+ res[2] = k[1];
+ }
+ }
+ else if (k[1] < k[2])
+ {
+ res[0] = k[1];
+ if (k[0] < k[2])
+ {
+ res[1] = k[0];
+ res[2] = k[2];
+ }
+ else
+ {
+ res[1] = k[2];
+ res[2] = k[0];
+ }
+ }
+ else
+ {
+ res[0] = k[2];
+ if (k[0] < k[1])
+ {
+ res[1] = k[0];
+ res[2] = k[1];
+ }
+ else
+ {
+ res[1] = k[1];
+ res[2] = k[0];
+ }
+ }
+ }
+
+ return res;
+ }
+
+ public static ECDomainParameters getDomainParameters(
+ ProviderConfiguration configuration,
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec params)
+ {
+ ECDomainParameters domainParameters;
+
+ if (params instanceof ECNamedCurveParameterSpec)
+ {
+ ECNamedCurveParameterSpec nParams = (ECNamedCurveParameterSpec)params;
+ ASN1ObjectIdentifier nameOid = ECUtil.getNamedCurveOid(nParams.getName());
+
+ domainParameters = new ECNamedDomainParameters(nameOid, nParams.getCurve(), nParams.getG(), nParams.getN(), nParams.getH(), nParams.getSeed());
+ }
+ else if (params == null)
+ {
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec iSpec = configuration.getEcImplicitlyCa();
+
+ domainParameters = new ECDomainParameters(iSpec.getCurve(), iSpec.getG(), iSpec.getN(), iSpec.getH(), iSpec.getSeed());
+ }
+ else
+ {
+ domainParameters = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH(), params.getSeed());
+ }
+
+ return domainParameters;
+ }
+
+ public static ECDomainParameters getDomainParameters(
+ ProviderConfiguration configuration,
+ X962Parameters params)
+ {
+ ECDomainParameters domainParameters;
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters());
+ X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
+ if (ecP == null)
+ {
+ Map extraCurves = configuration.getAdditionalECParameters();
+
+ ecP = (X9ECParameters)extraCurves.get(oid);
+ }
+ domainParameters = new ECNamedDomainParameters(oid, ecP);
+ }
+ else if (params.isImplicitlyCA())
+ {
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec iSpec = configuration.getEcImplicitlyCa();
+
+ domainParameters = new ECDomainParameters(iSpec.getCurve(), iSpec.getG(), iSpec.getN(), iSpec.getH(), iSpec.getSeed());
+ }
+ else
+ {
+ X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
+
+ domainParameters = new ECDomainParameters(ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed());
+ }
+
+ return domainParameters;
+ }
+
+ public static AsymmetricKeyParameter generatePublicKeyParameter(
+ PublicKey key)
+ throws InvalidKeyException
+ {
+ if (key instanceof ECPublicKey)
+ {
+ ECPublicKey k = (ECPublicKey)key;
+ ECParameterSpec s = k.getParameters();
+
+ return new ECPublicKeyParameters(
+ k.getQ(),
+ new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
+ }
+ else if (key instanceof java.security.interfaces.ECPublicKey)
+ {
+ java.security.interfaces.ECPublicKey pubKey = (java.security.interfaces.ECPublicKey)key;
+ ECParameterSpec s = EC5Util.convertSpec(pubKey.getParams());
+ return new ECPublicKeyParameters(
+ EC5Util.convertPoint(pubKey.getParams(), pubKey.getW()),
+ new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
+ }
+ else
+ {
+ // see if we can build a key from key.getEncoded()
+ try
+ {
+ byte[] bytes = key.getEncoded();
+
+ if (bytes == null)
+ {
+ throw new InvalidKeyException("no encoding for EC public key");
+ }
+
+ PublicKey publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes));
+
+ if (publicKey instanceof java.security.interfaces.ECPublicKey)
+ {
+ return ECUtil.generatePublicKeyParameter(publicKey);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeyException("cannot identify EC public key: " + e.toString());
+ }
+ }
+
+ throw new InvalidKeyException("cannot identify EC public key.");
+ }
+
+ public static AsymmetricKeyParameter generatePrivateKeyParameter(
+ PrivateKey key)
+ throws InvalidKeyException
+ {
+ if (key instanceof ECPrivateKey)
+ {
+ ECPrivateKey k = (ECPrivateKey)key;
+ ECParameterSpec s = k.getParameters();
+
+ if (s == null)
+ {
+ s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+ }
+
+ if (k.getParameters() instanceof ECNamedCurveParameterSpec)
+ {
+ String name = ((ECNamedCurveParameterSpec)k.getParameters()).getName();
+ return new ECPrivateKeyParameters(
+ k.getD(),
+ new ECNamedDomainParameters(ECNamedCurveTable.getOID(name),
+ s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
+ }
+ else
+ {
+ return new ECPrivateKeyParameters(
+ k.getD(),
+ new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
+ }
+ }
+ else if (key instanceof java.security.interfaces.ECPrivateKey)
+ {
+ java.security.interfaces.ECPrivateKey privKey = (java.security.interfaces.ECPrivateKey)key;
+ ECParameterSpec s = EC5Util.convertSpec(privKey.getParams());
+ return new ECPrivateKeyParameters(
+ privKey.getS(),
+ new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
+ }
+ else
+ {
+ // see if we can build a key from key.getEncoded()
+ try
+ {
+ byte[] bytes = key.getEncoded();
+
+ if (bytes == null)
+ {
+ throw new InvalidKeyException("no encoding for EC private key");
+ }
+
+ PrivateKey privateKey = BouncyCastleProvider.getPrivateKey(PrivateKeyInfo.getInstance(bytes));
+
+ if (privateKey instanceof java.security.interfaces.ECPrivateKey)
+ {
+ return ECUtil.generatePrivateKeyParameter(privateKey);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeyException("cannot identify EC private key: " + e.toString());
+ }
+ }
+
+ throw new InvalidKeyException("can't identify EC private key.");
+ }
+
+ public static int getOrderBitLength(ProviderConfiguration configuration, BigInteger order, BigInteger privateValue)
+ {
+ if (order == null) // implicitly CA
+ {
+ ECParameterSpec implicitCA = configuration.getEcImplicitlyCa();
+
+ if (implicitCA == null)
+ {
+ return privateValue.bitLength(); // a guess but better than an exception!
+ }
+
+ return implicitCA.getN().bitLength();
+ }
+ else
+ {
+ return order.bitLength();
+ }
+ }
+
+ public static ASN1ObjectIdentifier getNamedCurveOid(
+ String curveName)
+ {
+ String name = curveName;
+
+ int spacePos = name.indexOf(' ');
+ if (spacePos > 0)
+ {
+ name = name.substring(spacePos + 1);
+ }
+
+ try
+ {
+ if (name.charAt(0) >= '0' && name.charAt(0) <= '2')
+ {
+ return new ASN1ObjectIdentifier(name);
+ }
+ }
+ catch (IllegalArgumentException ex)
+ {
+ }
+
+ return ECNamedCurveTable.getOID(name);
+ }
+
+ public static ASN1ObjectIdentifier getNamedCurveOid(
+ ECParameterSpec ecParameterSpec)
+ {
+ for (Enumeration names = ECNamedCurveTable.getNames(); names.hasMoreElements();)
+ {
+ String name = (String)names.nextElement();
+
+ X9ECParameters params = ECNamedCurveTable.getByName(name);
+
+ if (params.getN().equals(ecParameterSpec.getN())
+ && params.getH().equals(ecParameterSpec.getH())
+ && params.getCurve().equals(ecParameterSpec.getCurve())
+ && params.getG().equals(ecParameterSpec.getG()))
+ {
+ return com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable.getOID(name);
+ }
+ }
+
+ return null;
+ }
+
+ public static X9ECParameters getNamedCurveByOid(
+ ASN1ObjectIdentifier oid)
+ {
+ X9ECParameters params = CustomNamedCurves.getByOID(oid);
+
+ if (params == null)
+ {
+ params = ECNamedCurveTable.getByOID(oid);
+ }
+
+ return params;
+ }
+
+ public static X9ECParameters getNamedCurveByName(
+ String curveName)
+ {
+ X9ECParameters params = CustomNamedCurves.getByName(curveName);
+
+ if (params == null)
+ {
+ params = ECNamedCurveTable.getByName(curveName);
+ }
+
+ return params;
+ }
+
+ public static String getCurveName(
+ ASN1ObjectIdentifier oid)
+ {
+ return ECNamedCurveTable.getName(oid);
+ }
+
+ public static String privateKeyToString(String algorithm, BigInteger d, com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec spec)
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ com.android.internal.org.bouncycastle.math.ec.ECPoint q = new FixedPointCombMultiplier().multiply(spec.getG(), d).normalize();
+
+ buf.append(algorithm);
+ buf.append(" Private Key [").append(ECUtil.generateKeyFingerprint(q, spec)).append("]").append(nl);
+ buf.append(" X: ").append(q.getAffineXCoord().toBigInteger().toString(16)).append(nl);
+ buf.append(" Y: ").append(q.getAffineYCoord().toBigInteger().toString(16)).append(nl);
+
+ return buf.toString();
+ }
+
+ public static String publicKeyToString(String algorithm, com.android.internal.org.bouncycastle.math.ec.ECPoint q, com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec spec)
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append(algorithm);
+ buf.append(" Public Key [").append(ECUtil.generateKeyFingerprint(q, spec)).append("]").append(nl);
+ buf.append(" X: ").append(q.getAffineXCoord().toBigInteger().toString(16)).append(nl);
+ buf.append(" Y: ").append(q.getAffineYCoord().toBigInteger().toString(16)).append(nl);
+
+ return buf.toString();
+ }
+
+ public static String generateKeyFingerprint(ECPoint publicPoint, com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec spec)
+ {
+ ECCurve curve = spec.getCurve();
+ ECPoint g = spec.getG();
+
+ if (curve != null)
+ {
+ return new Fingerprint(Arrays.concatenate(publicPoint.getEncoded(false), curve.getA().getEncoded(), curve.getB().getEncoded(), g.getEncoded(false))).toString();
+ }
+
+ return new Fingerprint(publicPoint.getEncoded(false)).toString();
+ }
+
+ public static String getNameFrom(final AlgorithmParameterSpec paramSpec)
+ {
+ return (String)AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ try
+ {
+ Method m = paramSpec.getClass().getMethod("getName");
+
+ return m.invoke(paramSpec);
+ }
+ catch (Exception e)
+ {
+ // ignore - maybe log?
+ }
+
+ return null;
+ }
+ });
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ExtendedInvalidKeySpecException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ExtendedInvalidKeySpecException.java
new file mode 100644
index 00000000..7461e6ce
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ExtendedInvalidKeySpecException.java
@@ -0,0 +1,25 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util;
+
+import java.security.spec.InvalidKeySpecException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ExtendedInvalidKeySpecException
+ extends InvalidKeySpecException
+{
+ private Throwable cause;
+
+ public ExtendedInvalidKeySpecException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/KeyUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/KeyUtil.java
new file mode 100644
index 00000000..f4d56bb0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/KeyUtil.java
@@ -0,0 +1,76 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyUtil
+{
+ public static byte[] getEncodedSubjectPublicKeyInfo(AlgorithmIdentifier algId, ASN1Encodable keyData)
+ {
+ try
+ {
+ return getEncodedSubjectPublicKeyInfo(new SubjectPublicKeyInfo(algId, keyData));
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+
+ public static byte[] getEncodedSubjectPublicKeyInfo(AlgorithmIdentifier algId, byte[] keyData)
+ {
+ try
+ {
+ return getEncodedSubjectPublicKeyInfo(new SubjectPublicKeyInfo(algId, keyData));
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+
+ public static byte[] getEncodedSubjectPublicKeyInfo(SubjectPublicKeyInfo info)
+ {
+ try
+ {
+ return info.getEncoded(ASN1Encoding.DER);
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+
+ public static byte[] getEncodedPrivateKeyInfo(AlgorithmIdentifier algId, ASN1Encodable privKey)
+ {
+ try
+ {
+ PrivateKeyInfo info = new PrivateKeyInfo(algId, privKey.toASN1Primitive());
+
+ return getEncodedPrivateKeyInfo(info);
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+
+ public static byte[] getEncodedPrivateKeyInfo(PrivateKeyInfo info)
+ {
+ try
+ {
+ return info.getEncoded(ASN1Encoding.DER);
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java
new file mode 100644
index 00000000..5b5d0121
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java
@@ -0,0 +1,127 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OutputStream;
+import com.android.internal.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS12BagAttributeCarrierImpl
+ implements PKCS12BagAttributeCarrier
+{
+ private Hashtable pkcs12Attributes;
+ private Vector pkcs12Ordering;
+
+ PKCS12BagAttributeCarrierImpl(Hashtable attributes, Vector ordering)
+ {
+ this.pkcs12Attributes = attributes;
+ this.pkcs12Ordering = ordering;
+ }
+
+ public PKCS12BagAttributeCarrierImpl()
+ {
+ this(new Hashtable(), new Vector());
+ }
+
+ public void setBagAttribute(
+ ASN1ObjectIdentifier oid,
+ ASN1Encodable attribute)
+ {
+ if (pkcs12Attributes.containsKey(oid))
+ { // preserve original ordering
+ pkcs12Attributes.put(oid, attribute);
+ }
+ else
+ {
+ pkcs12Attributes.put(oid, attribute);
+ pkcs12Ordering.addElement(oid);
+ }
+ }
+
+ public ASN1Encodable getBagAttribute(
+ ASN1ObjectIdentifier oid)
+ {
+ return (ASN1Encodable)pkcs12Attributes.get(oid);
+ }
+
+ public Enumeration getBagAttributeKeys()
+ {
+ return pkcs12Ordering.elements();
+ }
+
+ int size()
+ {
+ return pkcs12Ordering.size();
+ }
+
+ Hashtable getAttributes()
+ {
+ return pkcs12Attributes;
+ }
+
+ Vector getOrdering()
+ {
+ return pkcs12Ordering;
+ }
+
+ public void writeObject(ObjectOutputStream out)
+ throws IOException
+ {
+ if (pkcs12Ordering.size() == 0)
+ {
+ out.writeObject(new Hashtable());
+ out.writeObject(new Vector());
+ }
+ else
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ ASN1OutputStream aOut = ASN1OutputStream.create(bOut);
+
+ Enumeration e = this.getBagAttributeKeys();
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(e.nextElement());
+
+ aOut.writeObject(oid);
+ aOut.writeObject((ASN1Encodable)pkcs12Attributes.get(oid));
+ }
+
+ out.writeObject(bOut.toByteArray());
+ }
+ }
+
+ public void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ Object obj = in.readObject();
+
+ if (obj instanceof Hashtable)
+ {
+ this.pkcs12Attributes = (Hashtable)obj;
+ this.pkcs12Ordering = (Vector)in.readObject();
+ }
+ else
+ {
+ ASN1InputStream aIn = new ASN1InputStream((byte[])obj);
+
+ ASN1ObjectIdentifier oid;
+
+ while ((oid = (ASN1ObjectIdentifier)aIn.readObject()) != null)
+ {
+ this.setBagAttribute(oid, aIn.readObject());
+ }
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/PrimeCertaintyCalculator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/PrimeCertaintyCalculator.java
new file mode 100644
index 00000000..16d6c8c0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/PrimeCertaintyCalculator.java
@@ -0,0 +1,25 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PrimeCertaintyCalculator
+{
+ private PrimeCertaintyCalculator()
+ {
+
+ }
+
+ /**
+ * Return the current wisdom on prime certainty requirements.
+ *
+ * @param keySizeInBits size of the key being generated.
+ * @return a certainty value.
+ */
+ public static int getDefaultCertainty(int keySizeInBits)
+ {
+ // Based on FIPS 186-4 Table C.1
+ return keySizeInBits <= 1024 ? 80 : (96 + 16 * ((keySizeInBits - 1) / 1024));
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java
new file mode 100644
index 00000000..1de0527f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java
@@ -0,0 +1,460 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+// Android-added: Use PushbackInputStream
+import java.io.PushbackInputStream;
+import java.security.cert.CRL;
+import java.security.cert.CRLException;
+import java.security.cert.CertPath;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactorySpi;
+import java.security.cert.CertificateParsingException;
+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.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.SignedData;
+import com.android.internal.org.bouncycastle.asn1.x509.Certificate;
+import com.android.internal.org.bouncycastle.asn1.x509.CertificateList;
+import com.android.internal.org.bouncycastle.jcajce.util.BCJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.util.io.Streams;
+
+/**
+ * class for dealing with X509 certificates.
+ * <p>
+ * At the moment this will deal with "-----BEGIN CERTIFICATE-----" to "-----END CERTIFICATE-----"
+ * base 64 encoded certs, as well as the BER binaries of certificates and some classes of PKCS#7
+ * objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertificateFactory
+ extends CertificateFactorySpi
+{
+ private final JcaJceHelper bcHelper = new BCJcaJceHelper();
+
+ private static final PEMUtil PEM_CERT_PARSER = new PEMUtil("CERTIFICATE");
+ private static final PEMUtil PEM_CRL_PARSER = new PEMUtil("CRL");
+ private static final PEMUtil PEM_PKCS7_PARSER = new PEMUtil("PKCS7");
+
+ private ASN1Set sData = null;
+ private int sDataObjectCount = 0;
+ private InputStream currentStream = null;
+
+ private ASN1Set sCrlData = null;
+ private int sCrlDataObjectCount = 0;
+ private InputStream currentCrlStream = null;
+
+ private java.security.cert.Certificate readDERCertificate(
+ ASN1InputStream dIn)
+ throws IOException, CertificateParsingException
+ {
+ return getCertificate(ASN1Sequence.getInstance(dIn.readObject()));
+ }
+
+ private java.security.cert.Certificate readPEMCertificate(
+ InputStream in)
+ throws IOException, CertificateParsingException
+ {
+ return getCertificate(PEM_CERT_PARSER.readPEMObject(in));
+ }
+
+ private java.security.cert.Certificate getCertificate(ASN1Sequence seq)
+ throws CertificateParsingException
+ {
+ if (seq == null)
+ {
+ return null;
+ }
+
+ if (seq.size() > 1
+ && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier)
+ {
+ if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData))
+ {
+ sData = SignedData.getInstance(ASN1Sequence.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(1), true)).getCertificates();
+
+ return getCertificate();
+ }
+ }
+
+ return new X509CertificateObject(bcHelper,
+ Certificate.getInstance(seq));
+ }
+
+ private java.security.cert.Certificate getCertificate()
+ throws CertificateParsingException
+ {
+ if (sData != null)
+ {
+ while (sDataObjectCount < sData.size())
+ {
+ Object obj = sData.getObjectAt(sDataObjectCount++);
+
+ if (obj instanceof ASN1Sequence)
+ {
+ return new X509CertificateObject(bcHelper,
+ Certificate.getInstance(obj));
+ }
+ }
+ }
+
+ return null;
+ }
+
+
+ protected CRL createCRL(CertificateList c)
+ throws CRLException
+ {
+ return new X509CRLObject(bcHelper, c);
+ }
+
+ private CRL readPEMCRL(
+ InputStream in)
+ throws IOException, CRLException
+ {
+ return getCRL(PEM_CRL_PARSER.readPEMObject(in));
+ }
+
+ private CRL readDERCRL(
+ ASN1InputStream aIn)
+ throws IOException, CRLException
+ {
+ return getCRL(ASN1Sequence.getInstance(aIn.readObject()));
+ }
+
+ private CRL getCRL(ASN1Sequence seq)
+ throws CRLException
+ {
+ if (seq == null)
+ {
+ return null;
+ }
+
+ if (seq.size() > 1
+ && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier)
+ {
+ if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData))
+ {
+ sCrlData = SignedData.getInstance(ASN1Sequence.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(1), true)).getCRLs();
+
+ return getCRL();
+ }
+ }
+
+ return createCRL(
+ CertificateList.getInstance(seq));
+ }
+
+ private CRL getCRL()
+ throws CRLException
+ {
+ if (sCrlData == null || sCrlDataObjectCount >= sCrlData.size())
+ {
+ return null;
+ }
+
+ return createCRL(
+ CertificateList.getInstance(
+ sCrlData.getObjectAt(sCrlDataObjectCount++)));
+ }
+
+ /**
+ * Generates a certificate object and initializes it with the data
+ * read from the input stream inStream.
+ */
+ public java.security.cert.Certificate engineGenerateCertificate(
+ InputStream in)
+ throws CertificateException
+ {
+ if (currentStream == null)
+ {
+ currentStream = in;
+ sData = null;
+ sDataObjectCount = 0;
+ }
+ else if (currentStream != in) // reset if input stream has changed
+ {
+ currentStream = in;
+ sData = null;
+ sDataObjectCount = 0;
+ }
+
+ try
+ {
+ if (sData != null)
+ {
+ if (sDataObjectCount != sData.size())
+ {
+ return getCertificate();
+ }
+ else
+ {
+ sData = null;
+ sDataObjectCount = 0;
+ return null;
+ }
+ }
+
+ InputStream pis;
+
+ if (in.markSupported())
+ {
+ pis = in;
+ }
+ else
+ {
+ // Android-changed: Use PushbackInputStream instead of ByteArrayInputStream.
+ // we want {@code in.available()} to return the number of available bytes if
+ // there is trailing data (otherwise it breaks
+ // libcore.java.security.cert.X509CertificateTest#test_Provider
+ // ). Which is not possible if we read the whole stream at this point.
+ // // pis = new ByteArrayInputStream(Streams.readAll(in));
+ pis = new PushbackInputStream(in);
+ }
+
+ // BEGIN Android-changed: Use PushbackInputStream
+ // pis.mark(1);
+ if (in.markSupported()) {
+ pis.mark(1);
+ }
+ // END Android-changed: Use PushbackInputStream
+
+ int tag = pis.read();
+
+ if (tag == -1)
+ {
+ return null;
+ }
+
+ // BEGIN Android-changed: Use PushbackInputStream
+ // pis.reset
+ if (in.markSupported()) {
+ pis.reset();
+ }
+ else
+ {
+ ((PushbackInputStream) pis).unread(tag);
+ }
+ // END Android-changed: Use PushbackInputStream
+
+ if (tag != 0x30) // assume ascii PEM encoded.
+ {
+ return readPEMCertificate(pis);
+ }
+ else
+ {
+ return readDERCertificate(new ASN1InputStream(pis));
+ }
+ }
+ catch (Exception e)
+ {
+ throw new ExCertificateException("parsing issue: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Returns a (possibly empty) collection view of the certificates
+ * read from the given input stream inStream.
+ */
+ public Collection engineGenerateCertificates(
+ InputStream inStream)
+ throws CertificateException
+ {
+ java.security.cert.Certificate cert;
+ // Android-removed: Don't read entire stream immediately.
+ // we want {@code in.available()} to return the number of available bytes if
+ // there is trailing data (otherwise it breaks
+ // libcore.java.security.cert.X509CertificateTest#test_Provider
+ // ). Which is not possible if we read the whole stream at this point.
+ // BufferedInputStream in = new BufferedInputStream(inStream);
+ List certs = new ArrayList();
+
+ // Android-changed: Read from original stream
+ // while ((cert = engineGenerateCertificate(in)) != null)
+ while ((cert = engineGenerateCertificate(inStream)) != null)
+ {
+ certs.add(cert);
+ }
+
+ return certs;
+ }
+
+ /**
+ * Generates a certificate revocation list (CRL) object and initializes
+ * it with the data read from the input stream inStream.
+ */
+ public CRL engineGenerateCRL(
+ InputStream in)
+ throws CRLException
+ {
+ if (currentCrlStream == null)
+ {
+ currentCrlStream = in;
+ sCrlData = null;
+ sCrlDataObjectCount = 0;
+ }
+ else if (currentCrlStream != in) // reset if input stream has changed
+ {
+ currentCrlStream = in;
+ sCrlData = null;
+ sCrlDataObjectCount = 0;
+ }
+
+ try
+ {
+ if (sCrlData != null)
+ {
+ if (sCrlDataObjectCount != sCrlData.size())
+ {
+ return getCRL();
+ }
+ else
+ {
+ sCrlData = null;
+ sCrlDataObjectCount = 0;
+ return null;
+ }
+ }
+
+ InputStream pis;
+
+ if (in.markSupported())
+ {
+ pis = in;
+ }
+ else
+ {
+ pis = new ByteArrayInputStream(Streams.readAll(in));
+ }
+
+ pis.mark(1);
+ int tag = pis.read();
+
+ if (tag == -1)
+ {
+ return null;
+ }
+
+ pis.reset();
+ if (tag != 0x30) // assume ascii PEM encoded.
+ {
+ return readPEMCRL(pis);
+ }
+ else
+ { // lazy evaluate to help processing of large CRLs
+ return readDERCRL(new ASN1InputStream(pis, true));
+ }
+ }
+ catch (CRLException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new CRLException(e.toString());
+ }
+ }
+
+ /**
+ * Returns a (possibly empty) collection view of the CRLs read from
+ * the given input stream inStream.
+ *
+ * The inStream may contain a sequence of DER-encoded CRLs, or
+ * a PKCS#7 CRL set. This is a PKCS#7 SignedData object, with the
+ * only signficant field being crls. In particular the signature
+ * and the contents are ignored.
+ */
+ public Collection engineGenerateCRLs(
+ InputStream inStream)
+ throws CRLException
+ {
+ CRL crl;
+ List crls = new ArrayList();
+ BufferedInputStream in = new BufferedInputStream(inStream);
+
+ while ((crl = engineGenerateCRL(in)) != null)
+ {
+ crls.add(crl);
+ }
+
+ return crls;
+ }
+
+ public Iterator engineGetCertPathEncodings()
+ {
+ return PKIXCertPath.certPathEncodings.iterator();
+ }
+
+ public CertPath engineGenerateCertPath(
+ InputStream inStream)
+ throws CertificateException
+ {
+ return engineGenerateCertPath(inStream, "PkiPath");
+ }
+
+ public CertPath engineGenerateCertPath(
+ InputStream inStream,
+ String encoding)
+ throws CertificateException
+ {
+ return new PKIXCertPath(inStream, encoding);
+ }
+
+ public CertPath engineGenerateCertPath(
+ List certificates)
+ throws CertificateException
+ {
+ Iterator iter = certificates.iterator();
+ Object obj;
+ while (iter.hasNext())
+ {
+ obj = iter.next();
+ if (obj != null)
+ {
+ if (!(obj instanceof X509Certificate))
+ {
+ throw new CertificateException("list contains non X509Certificate object while creating CertPath\n" + obj.toString());
+ }
+ }
+ }
+ return new PKIXCertPath(certificates);
+ }
+
+ private class ExCertificateException
+ extends CertificateException
+ {
+ private Throwable cause;
+
+ public ExCertificateException(Throwable cause)
+ {
+ this.cause = cause;
+ }
+
+ public ExCertificateException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/ExtCRLException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/ExtCRLException.java
new file mode 100644
index 00000000..011494a0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/ExtCRLException.java
@@ -0,0 +1,21 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.security.cert.CRLException;
+
+class ExtCRLException
+ extends CRLException
+{
+ Throwable cause;
+
+ ExtCRLException(String message, Throwable cause)
+ {
+ super(message);
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/KeyFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/KeyFactory.java
new file mode 100644
index 00000000..7191d4ec
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/KeyFactory.java
@@ -0,0 +1,99 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactorySpi;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyFactory
+ extends KeyFactorySpi
+{
+
+ protected PrivateKey engineGeneratePrivate(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof PKCS8EncodedKeySpec)
+ {
+ try
+ {
+ PrivateKeyInfo info = PrivateKeyInfo.getInstance(((PKCS8EncodedKeySpec)keySpec).getEncoded());
+ PrivateKey key = BouncyCastleProvider.getPrivateKey(info);
+
+ if (key != null)
+ {
+ return key;
+ }
+
+ throw new InvalidKeySpecException("no factory found for OID: " + info.getPrivateKeyAlgorithm().getAlgorithm());
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeySpecException(e.toString());
+ }
+ }
+
+ throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
+ }
+
+ protected PublicKey engineGeneratePublic(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof X509EncodedKeySpec)
+ {
+ try
+ {
+ SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(((X509EncodedKeySpec)keySpec).getEncoded());
+ PublicKey key = BouncyCastleProvider.getPublicKey(info);
+
+ if (key != null)
+ {
+ return key;
+ }
+
+ throw new InvalidKeySpecException("no factory found for OID: " + info.getAlgorithm().getAlgorithm());
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeySpecException(e.toString());
+ }
+ }
+
+ throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
+ }
+
+ protected KeySpec engineGetKeySpec(Key key, Class keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class) && key.getFormat().equals("PKCS#8"))
+ {
+ return new PKCS8EncodedKeySpec(key.getEncoded());
+ }
+ else if (keySpec.isAssignableFrom(X509EncodedKeySpec.class) && key.getFormat().equals("X.509"))
+ {
+ return new X509EncodedKeySpec(key.getEncoded());
+ }
+
+ throw new InvalidKeySpecException("not implemented yet " + key + " " + keySpec);
+ }
+
+ protected Key engineTranslateKey(Key key)
+ throws InvalidKeyException
+ {
+ throw new InvalidKeyException("not implemented yet " + key);
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
new file mode 100644
index 00000000..25c42303
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
@@ -0,0 +1,175 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.util.encoders.Base64;
+
+class PEMUtil
+{
+ /**
+ * Boundary class. Keeps track of the required header/footer pair for the
+ * current PEM object.
+ *
+ */
+ private class Boundaries
+ {
+ private final String _header;
+ private final String _footer;
+
+ private Boundaries(String type)
+ {
+ this._header = "-----BEGIN " + type + "-----";
+ this._footer = "-----END " + type + "-----";
+ }
+
+ public boolean isTheExpectedHeader(String line)
+ {
+ return line.startsWith(_header);
+ }
+
+ public boolean isTheExpectedFooter(String line)
+ {
+ return line.startsWith(_footer);
+ }
+ }
+
+ private final Boundaries[] _supportedBoundaries;
+
+ PEMUtil(String type)
+ {
+ _supportedBoundaries = new Boundaries[]
+ { new Boundaries(type), new Boundaries("X509 " + type),
+ new Boundaries("PKCS7") };
+ }
+
+ private String readLine(InputStream in) throws IOException
+ {
+ int c;
+ StringBuffer l = new StringBuffer();
+
+ do
+ {
+ while (((c = in.read()) != '\r') && c != '\n' && (c >= 0))
+ {
+ l.append((char) c);
+ }
+ }
+ while (c >= 0 && l.length() == 0);
+
+ if (c < 0)
+ {
+ // make sure to return the read bytes if the end of file is encountered
+ if (l.length() == 0)
+ {
+ return null;
+ }
+ return l.toString();
+ }
+
+ // make sure we parse to end of line.
+ if (c == '\r')
+ {
+ // a '\n' may follow
+ in.mark(1);
+ if (((c = in.read()) == '\n'))
+ {
+ in.mark(1);
+ }
+
+ if (c > 0)
+ {
+ in.reset();
+ }
+ }
+
+ return l.toString();
+ }
+
+ /**
+ * Returns a {@link Boundaries} object representing the passed in boundary
+ * string.
+ *
+ * @param line the boundary string
+ * @return the {@link Boundaries} object corresponding to the given boundary
+ * string or <code>null</code> if the passed in string is not a valid
+ * boundary.
+ */
+ private Boundaries getBoundaries(String line)
+ {
+ for (int i = 0; i != _supportedBoundaries.length; i++)
+ {
+ Boundaries boundary = _supportedBoundaries[i];
+
+ if (boundary.isTheExpectedHeader(line) || boundary.isTheExpectedFooter(line))
+ {
+ return boundary;
+ }
+ }
+
+ return null;
+ }
+
+ ASN1Sequence readPEMObject(
+ InputStream in)
+ throws IOException
+ {
+ String line;
+ StringBuffer pemBuf = new StringBuffer();
+
+ Boundaries header = null;
+
+ while (header == null && (line = readLine(in)) != null)
+ {
+ header = getBoundaries(line);
+ if (header != null && !header.isTheExpectedHeader(line))
+ {
+ throw new IOException("malformed PEM data: found footer where header was expected");
+ }
+ }
+
+ if (header == null)
+ {
+ throw new IOException("malformed PEM data: no header found");
+ }
+
+ Boundaries footer = null;
+
+ while (footer == null && (line = readLine(in)) != null)
+ {
+ footer = getBoundaries(line);
+ if (footer != null)
+ {
+ if (!header.isTheExpectedFooter(line))
+ {
+ throw new IOException("malformed PEM data: header/footer mismatch");
+ }
+ }
+ else
+ {
+ pemBuf.append(line);
+ }
+ }
+
+ if (footer == null)
+ {
+ throw new IOException("malformed PEM data: no footer found");
+ }
+
+ if (pemBuf.length() != 0)
+ {
+ try
+ {
+ return ASN1Sequence.getInstance(Base64.decode(pemBuf.toString()));
+ }
+ catch (Exception e)
+ {
+ throw new IOException("malformed PEM data encountered");
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java
new file mode 100644
index 00000000..6200e0a5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java
@@ -0,0 +1,382 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.security.NoSuchProviderException;
+import java.security.cert.CertPath;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import javax.security.auth.x500.X500Principal;
+
+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.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERSet;
+import com.android.internal.org.bouncycastle.asn1.pkcs.ContentInfo;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.SignedData;
+import com.android.internal.org.bouncycastle.jcajce.util.BCJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.util.io.pem.PemObject;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.util.io.pem.PemWriter;
+
+/**
+ * CertPath implementation for X.509 certificates.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKIXCertPath
+ extends CertPath
+{
+ private final JcaJceHelper helper = new BCJcaJceHelper();
+
+ static final List certPathEncodings;
+
+ static
+ {
+ List encodings = new ArrayList();
+ encodings.add("PkiPath");
+ // Android-removed: Unsupported algorithms
+ // encodings.add("PEM");
+ encodings.add("PKCS7");
+ certPathEncodings = Collections.unmodifiableList(encodings);
+ }
+
+ private List certificates;
+
+ /**
+ * @param certs
+ */
+ private List sortCerts(
+ List certs)
+ {
+ if (certs.size() < 2)
+ {
+ return certs;
+ }
+
+ X500Principal issuer = ((X509Certificate)certs.get(0)).getIssuerX500Principal();
+ boolean okay = true;
+
+ for (int i = 1; i != certs.size(); i++)
+ {
+ X509Certificate cert = (X509Certificate)certs.get(i);
+
+ if (issuer.equals(cert.getSubjectX500Principal()))
+ {
+ issuer = ((X509Certificate)certs.get(i)).getIssuerX500Principal();
+ }
+ else
+ {
+ okay = false;
+ break;
+ }
+ }
+
+ if (okay)
+ {
+ return certs;
+ }
+
+ // find end-entity cert
+ List retList = new ArrayList(certs.size());
+ List orig = new ArrayList(certs);
+
+ for (int i = 0; i < certs.size(); i++)
+ {
+ X509Certificate cert = (X509Certificate)certs.get(i);
+ boolean found = false;
+
+ X500Principal subject = cert.getSubjectX500Principal();
+
+ for (int j = 0; j != certs.size(); j++)
+ {
+ X509Certificate c = (X509Certificate)certs.get(j);
+ if (c.getIssuerX500Principal().equals(subject))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ retList.add(cert);
+ certs.remove(i);
+ }
+ }
+
+ // can only have one end entity cert - something's wrong, give up.
+ if (retList.size() > 1)
+ {
+ return orig;
+ }
+
+ for (int i = 0; i != retList.size(); i++)
+ {
+ issuer = ((X509Certificate)retList.get(i)).getIssuerX500Principal();
+
+ for (int j = 0; j < certs.size(); j++)
+ {
+ X509Certificate c = (X509Certificate)certs.get(j);
+ if (issuer.equals(c.getSubjectX500Principal()))
+ {
+ retList.add(c);
+ certs.remove(j);
+ break;
+ }
+ }
+ }
+
+ // make sure all certificates are accounted for.
+ if (certs.size() > 0)
+ {
+ return orig;
+ }
+
+ return retList;
+ }
+
+ PKIXCertPath(List certificates)
+ {
+ super("X.509");
+ this.certificates = sortCerts(new ArrayList(certificates));
+ }
+
+ /**
+ * Creates a CertPath of the specified type.
+ * This constructor is protected because most users should use
+ * a CertificateFactory to create CertPaths.
+ **/
+ PKIXCertPath(
+ InputStream inStream,
+ String encoding)
+ throws CertificateException
+ {
+ super("X.509");
+ try
+ {
+ if (encoding.equalsIgnoreCase("PkiPath"))
+ {
+ ASN1InputStream derInStream = new ASN1InputStream(inStream);
+ ASN1Primitive derObject = derInStream.readObject();
+ if (!(derObject instanceof ASN1Sequence))
+ {
+ throw new CertificateException("input stream does not contain a ASN1 SEQUENCE while reading PkiPath encoded data to load CertPath");
+ }
+ Enumeration e = ((ASN1Sequence)derObject).getObjects();
+ certificates = new ArrayList();
+ CertificateFactory certFactory = helper.createCertificateFactory("X.509");
+ while (e.hasMoreElements())
+ {
+ ASN1Encodable element = (ASN1Encodable)e.nextElement();
+ byte[] encoded = element.toASN1Primitive().getEncoded(ASN1Encoding.DER);
+ certificates.add(0, certFactory.generateCertificate(
+ new ByteArrayInputStream(encoded)));
+ }
+ }
+ else if (encoding.equalsIgnoreCase("PKCS7") || encoding.equalsIgnoreCase("PEM"))
+ {
+ inStream = new BufferedInputStream(inStream);
+ certificates = new ArrayList();
+ CertificateFactory certFactory= helper.createCertificateFactory("X.509");
+ Certificate cert;
+ while ((cert = certFactory.generateCertificate(inStream)) != null)
+ {
+ certificates.add(cert);
+ }
+ }
+ else
+ {
+ throw new CertificateException("unsupported encoding: " + encoding);
+ }
+ }
+ catch (IOException ex)
+ {
+ throw new CertificateException("IOException throw while decoding CertPath:\n" + ex.toString());
+ }
+ catch (NoSuchProviderException ex)
+ {
+ throw new CertificateException("BouncyCastle provider not found while trying to get a CertificateFactory:\n" + ex.toString());
+ }
+
+ this.certificates = sortCerts(certificates);
+ }
+
+ /**
+ * Returns an iteration of the encodings supported by this
+ * certification path, with the default encoding
+ * first. Attempts to modify the returned Iterator via its
+ * remove method result in an UnsupportedOperationException.
+ *
+ * @return an Iterator over the names of the supported encodings (as Strings)
+ **/
+ public Iterator getEncodings()
+ {
+ return certPathEncodings.iterator();
+ }
+
+ /**
+ * Returns the encoded form of this certification path, using
+ * the default encoding.
+ *
+ * @return the encoded bytes
+ * @exception java.security.cert.CertificateEncodingException if an encoding error occurs
+ **/
+ public byte[] getEncoded()
+ throws CertificateEncodingException
+ {
+ Iterator iter = getEncodings();
+ if (iter.hasNext())
+ {
+ Object enc = iter.next();
+ if (enc instanceof String)
+ {
+ return getEncoded((String)enc);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the encoded form of this certification path, using
+ * the specified encoding.
+ *
+ * @param encoding the name of the encoding to use
+ * @return the encoded bytes
+ * @exception java.security.cert.CertificateEncodingException if an encoding error
+ * occurs or the encoding requested is not supported
+ *
+ **/
+ public byte[] getEncoded(String encoding)
+ throws CertificateEncodingException
+ {
+ if (encoding.equalsIgnoreCase("PkiPath"))
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ ListIterator iter = certificates.listIterator(certificates.size());
+ while (iter.hasPrevious())
+ {
+ v.add(toASN1Object((X509Certificate)iter.previous()));
+ }
+
+ return toDEREncoded(new DERSequence(v));
+ }
+ else if (encoding.equalsIgnoreCase("PKCS7"))
+ {
+ ContentInfo encInfo = new ContentInfo(PKCSObjectIdentifiers.data, null);
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ for (int i = 0; i != certificates.size(); i++)
+ {
+ v.add(toASN1Object((X509Certificate)certificates.get(i)));
+ }
+
+ SignedData sd = new SignedData(
+ new ASN1Integer(1),
+ new DERSet(),
+ encInfo,
+ new DERSet(v),
+ null,
+ new DERSet());
+
+ return toDEREncoded(new ContentInfo(
+ PKCSObjectIdentifiers.signedData, sd));
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (encoding.equalsIgnoreCase("PEM"))
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ PemWriter pWrt = new PemWriter(new OutputStreamWriter(bOut));
+
+ try
+ {
+ for (int i = 0; i != certificates.size(); i++)
+ {
+ pWrt.writeObject(new PemObject("CERTIFICATE", ((X509Certificate)certificates.get(i)).getEncoded()));
+ }
+
+ pWrt.close();
+ }
+ catch (Exception e)
+ {
+ throw new CertificateEncodingException("can't encode certificate for PEM encoded path");
+ }
+
+ return bOut.toByteArray();
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ else
+ {
+ throw new CertificateEncodingException("unsupported encoding: " + encoding);
+ }
+ }
+
+ /**
+ * Returns the list of certificates in this certification
+ * path. The List returned must be immutable and thread-safe.
+ *
+ * @return an immutable List of Certificates (may be empty, but not null)
+ **/
+ public List getCertificates()
+ {
+ return Collections.unmodifiableList(new ArrayList(certificates));
+ }
+
+ /**
+ * Return a DERObject containing the encoded certificate.
+ *
+ * @param cert the X509Certificate object to be encoded
+ *
+ * @return the DERObject
+ **/
+ private ASN1Primitive toASN1Object(
+ X509Certificate cert)
+ throws CertificateEncodingException
+ {
+ try
+ {
+ return new ASN1InputStream(cert.getEncoded()).readObject();
+ }
+ catch (Exception e)
+ {
+ throw new CertificateEncodingException("Exception while encoding certificate: " + e.toString());
+ }
+ }
+
+ private byte[] toDEREncoded(ASN1Encodable obj)
+ throws CertificateEncodingException
+ {
+ try
+ {
+ return obj.toASN1Primitive().getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException("Exception thrown: " + e);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureCreator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureCreator.java
new file mode 100644
index 00000000..0332450e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/SignatureCreator.java
@@ -0,0 +1,12 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Signature;
+
+interface SignatureCreator
+{
+ Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java
new file mode 100644
index 00000000..aac92316
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java
@@ -0,0 +1,328 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CRLException;
+import java.security.cert.X509CRLEntry;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.util.ASN1Dump;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.CRLReason;
+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.TBSCertList;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * The following extensions are listed in RFC 2459 as relevant to CRL Entries
+ *
+ * ReasonCode Hode Instruction Code Invalidity Date Certificate Issuer
+ * (critical)
+ */
+class X509CRLEntryObject extends X509CRLEntry
+{
+ private TBSCertList.CRLEntry c;
+
+ private X500Name certificateIssuer;
+
+ private volatile boolean hashValueSet;
+ private volatile int hashValue;
+
+ protected X509CRLEntryObject(TBSCertList.CRLEntry c)
+ {
+ this.c = c;
+ this.certificateIssuer = null;
+ }
+
+ /**
+ * Constructor for CRLEntries of indirect CRLs. If <code>isIndirect</code>
+ * is <code>false</code> {@link #getCertificateIssuer()} will always
+ * return <code>null</code>, <code>previousCertificateIssuer</code> is
+ * ignored. If this <code>isIndirect</code> is specified and this CRLEntry
+ * has no certificate issuer CRL entry extension
+ * <code>previousCertificateIssuer</code> is returned by
+ * {@link #getCertificateIssuer()}.
+ *
+ * @param c
+ * TBSCertList.CRLEntry object.
+ * @param isIndirect
+ * <code>true</code> if the corresponding CRL is a indirect
+ * CRL.
+ * @param previousCertificateIssuer
+ * Certificate issuer of the previous CRLEntry.
+ */
+ protected X509CRLEntryObject(
+ TBSCertList.CRLEntry c,
+ boolean isIndirect,
+ X500Name previousCertificateIssuer)
+ {
+ this.c = c;
+ this.certificateIssuer = loadCertificateIssuer(isIndirect, previousCertificateIssuer);
+ }
+
+ /**
+ * Will return true if any extensions are present and marked as critical as
+ * we currently don't handle any extensions!
+ */
+ public boolean hasUnsupportedCriticalExtension()
+ {
+ Set extns = getCriticalExtensionOIDs();
+
+ return extns != null && !extns.isEmpty();
+ }
+
+ private X500Name loadCertificateIssuer(boolean isIndirect, X500Name previousCertificateIssuer)
+ {
+ if (!isIndirect)
+ {
+ return null;
+ }
+
+ Extension ext = getExtension(Extension.certificateIssuer);
+ if (ext == null)
+ {
+ return previousCertificateIssuer;
+ }
+
+ try
+ {
+ GeneralName[] names = GeneralNames.getInstance(ext.getParsedValue()).getNames();
+ for (int i = 0; i < names.length; i++)
+ {
+ if (names[i].getTagNo() == GeneralName.directoryName)
+ {
+ return X500Name.getInstance(names[i].getName());
+ }
+ }
+ return null;
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+
+ public X500Principal getCertificateIssuer()
+ {
+ if (certificateIssuer == null)
+ {
+ return null;
+ }
+ try
+ {
+ return new X500Principal(certificateIssuer.getEncoded());
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ private Set getExtensionOIDs(boolean critical)
+ {
+ Extensions extensions = c.getExtensions();
+
+ if (extensions != null)
+ {
+ Set set = new HashSet();
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (critical == ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+
+ return null;
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(true);
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(false);
+ }
+
+ private Extension getExtension(ASN1ObjectIdentifier oid)
+ {
+ Extensions exts = c.getExtensions();
+
+ if (exts != null)
+ {
+ return exts.getExtension(oid);
+ }
+
+ return null;
+ }
+
+ public byte[] getExtensionValue(String oid)
+ {
+ Extension ext = getExtension(new ASN1ObjectIdentifier(oid));
+
+ if (ext != null)
+ {
+ try
+ {
+ return ext.getExtnValue().getEncoded();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException("Exception encoding: " + e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Cache the hashCode value - calculating it with the standard method.
+ * @return calculated hashCode.
+ */
+ public int hashCode()
+ {
+ if (!hashValueSet)
+ {
+ hashValue = super.hashCode();
+ hashValueSet = true;
+ }
+
+ return hashValue;
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (other instanceof X509CRLEntryObject)
+ {
+ X509CRLEntryObject otherBC = (X509CRLEntryObject)other;
+
+ if (this.hashValueSet && otherBC.hashValueSet)
+ {
+ if (this.hashValue != otherBC.hashValue)
+ {
+ return false;
+ }
+ }
+
+ return this.c.equals(otherBC.c);
+ }
+
+ return super.equals(this);
+ }
+
+ public byte[] getEncoded()
+ throws CRLException
+ {
+ try
+ {
+ return c.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CRLException(e.toString());
+ }
+ }
+
+ public BigInteger getSerialNumber()
+ {
+ return c.getUserCertificate().getValue();
+ }
+
+ public Date getRevocationDate()
+ {
+ return c.getRevocationDate().getDate();
+ }
+
+ public boolean hasExtensions()
+ {
+ return c.getExtensions() != null;
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append(" userCertificate: ").append(this.getSerialNumber()).append(nl);
+ buf.append(" revocationDate: ").append(this.getRevocationDate()).append(nl);
+ buf.append(" certificateIssuer: ").append(this.getCertificateIssuer()).append(nl);
+
+ Extensions extensions = c.getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+ if (e.hasMoreElements())
+ {
+ buf.append(" crlEntryExtensions:").append(nl);
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+ if (ext.getExtnValue() != null)
+ {
+ byte[] octs = ext.getExtnValue().getOctets();
+ ASN1InputStream dIn = new ASN1InputStream(octs);
+ buf.append(" critical(").append(ext.isCritical()).append(") ");
+ try
+ {
+ if (oid.equals(Extension.reasonCode))
+ {
+ buf.append(CRLReason.getInstance(ASN1Enumerated.getInstance(dIn.readObject()))).append(nl);
+ }
+ else if (oid.equals(Extension.certificateIssuer))
+ {
+ buf.append("Certificate issuer: ").append(GeneralNames.getInstance(dIn.readObject())).append(nl);
+ }
+ else
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl);
+ }
+ }
+ catch (Exception ex)
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append("*****").append(nl);
+ }
+ }
+ else
+ {
+ buf.append(nl);
+ }
+ }
+ }
+ }
+
+ return buf.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
new file mode 100644
index 00000000..755d8691
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLImpl.java
@@ -0,0 +1,737 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CRLException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.util.ASN1Dump;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.CRLDistPoint;
+import com.android.internal.org.bouncycastle.asn1.x509.CRLNumber;
+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.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.jcajce.CompositePublicKey;
+import com.android.internal.org.bouncycastle.jcajce.io.OutputStreamFactory;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.jce.X509Principal;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * The following extensions are listed in RFC 2459 as relevant to CRLs
+ * <p>
+ * Authority Key Identifier
+ * Issuer Alternative Name
+ * CRL Number
+ * Delta CRL Indicator (critical)
+ * Issuing Distribution Point (critical)
+ */
+abstract class X509CRLImpl
+ extends X509CRL
+{
+ protected JcaJceHelper bcHelper;
+ protected CertificateList c;
+ protected String sigAlgName;
+ protected byte[] sigAlgParams;
+ protected boolean isIndirect;
+
+ X509CRLImpl(JcaJceHelper bcHelper, CertificateList c, String sigAlgName, byte[] sigAlgParams, boolean isIndirect)
+ {
+ this.bcHelper = bcHelper;
+ this.c = c;
+ this.sigAlgName = sigAlgName;
+ this.sigAlgParams = sigAlgParams;
+ this.isIndirect = isIndirect;
+ }
+
+ /**
+ * Will return true if any extensions are present and marked
+ * as critical as we currently dont handle any extensions!
+ */
+ public boolean hasUnsupportedCriticalExtension()
+ {
+ Set extns = getCriticalExtensionOIDs();
+
+ if (extns == null)
+ {
+ return false;
+ }
+
+ extns.remove(Extension.issuingDistributionPoint.getId());
+ extns.remove(Extension.deltaCRLIndicator.getId());
+
+ return !extns.isEmpty();
+ }
+
+ private Set getExtensionOIDs(boolean critical)
+ {
+ if (this.getVersion() == 2)
+ {
+ Extensions extensions = c.getTBSCertList().getExtensions();
+
+ if (extensions != null)
+ {
+ Set set = new HashSet();
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (critical == ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+ }
+
+ return null;
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(true);
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(false);
+ }
+
+ public byte[] getExtensionValue(String oid)
+ {
+ ASN1OctetString extValue = getExtensionValue(c, oid);
+ if (null != extValue)
+ {
+ try
+ {
+ return extValue.getEncoded();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException("error parsing " + e.toString());
+ }
+ }
+ return null;
+ }
+
+ public byte[] getEncoded()
+ throws CRLException
+ {
+ try
+ {
+ return c.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CRLException(e.toString());
+ }
+ }
+
+ public void verify(PublicKey key)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ try
+ {
+ return bcHelper.createSignature(sigName);
+ }
+ catch (Exception e)
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+
+ public void verify(PublicKey key, final String sigProvider)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ if (sigProvider != null)
+ {
+ return Signature.getInstance(sigName, sigProvider);
+ }
+ else
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+
+ public void verify(PublicKey key, final Provider sigProvider)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
+ try
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ if (sigProvider != null)
+ {
+ return Signature.getInstance(getSigAlgName(), sigProvider);
+ }
+ else
+ {
+ return Signature.getInstance(getSigAlgName());
+ }
+ }
+ });
+ }
+ catch (NoSuchProviderException e)
+ {
+ // can't happen, but just in case
+ throw new NoSuchAlgorithmException("provider issue: " + e.getMessage());
+ }
+ }
+
+ private void doVerify(PublicKey key, SignatureCreator sigCreator)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException, NoSuchProviderException
+ {
+ if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature()))
+ {
+ throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList.");
+ }
+
+ if (key instanceof CompositePublicKey && X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
+ {
+ List<PublicKey> pubKeys = ((CompositePublicKey)key).getPublicKeys();
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+
+ boolean success = false;
+ for (int i = 0; i != pubKeys.size(); i++)
+ {
+ if (pubKeys.get(i) == null)
+ {
+ continue;
+ }
+
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ String sigName = X509SignatureUtil.getSignatureName(sigAlg);
+
+ Signature signature = sigCreator.createSignature(sigName);
+
+ SignatureException sigExc = null;
+
+ try
+ {
+ checkSignature(
+ (PublicKey)pubKeys.get(i), signature,
+ sigAlg.getParameters(),
+ DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ success = true;
+ }
+ catch (SignatureException e)
+ {
+ sigExc = e;
+ }
+
+ if (sigExc != null)
+ {
+ throw sigExc;
+ }
+ }
+
+ if (!success)
+ {
+ throw new InvalidKeyException("no matching key found");
+ }
+ }
+ else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
+ {
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+
+ boolean success = false;
+ for (int i = 0; i != sigSeq.size(); i++)
+ {
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ String sigName = X509SignatureUtil.getSignatureName(sigAlg);
+
+ SignatureException sigExc = null;
+
+ try
+ {
+ Signature signature = sigCreator.createSignature(sigName);
+
+ checkSignature(
+ key, signature,
+ sigAlg.getParameters(),
+ DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+
+ success = true;
+ }
+ catch (InvalidKeyException e)
+ {
+ // ignore
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // ignore
+ }
+ catch (SignatureException e)
+ {
+ sigExc = e;
+ }
+
+ if (sigExc != null)
+ {
+ throw sigExc;
+ }
+ }
+
+ if (!success)
+ {
+ throw new InvalidKeyException("no matching key found");
+ }
+ }
+ else
+ {
+ Signature sig = sigCreator.createSignature(getSigAlgName());
+
+ if (sigAlgParams == null)
+ {
+ checkSignature(key, sig, null, this.getSignature());
+ }
+ else
+ {
+ try
+ {
+ checkSignature(key, sig, ASN1Primitive.fromByteArray(sigAlgParams), this.getSignature());
+ }
+ catch (IOException e)
+ {
+ throw new SignatureException("cannot decode signature parameters: " + e.getMessage());
+ }
+ }
+ }
+ }
+
+ private void checkSignature(PublicKey key, Signature sig, ASN1Encodable sigAlgParams, byte[] encSig)
+ throws NoSuchAlgorithmException, SignatureException, InvalidKeyException, CRLException
+ {
+ if (sigAlgParams != null)
+ {
+ // needs to be called before initVerify().
+ X509SignatureUtil.setSignatureParameters(sig, sigAlgParams);
+ }
+
+ sig.initVerify(key);
+
+ try
+ {
+ OutputStream sigOut = new BufferedOutputStream(OutputStreamFactory.createStream(sig), 512);
+
+ c.getTBSCertList().encodeTo(sigOut, ASN1Encoding.DER);
+
+ sigOut.close();
+ }
+ catch (IOException e)
+ {
+ throw new CRLException(e.toString());
+ }
+
+ if (!sig.verify(encSig))
+ {
+ throw new SignatureException("CRL does not verify with supplied public key.");
+ }
+ }
+
+ public int getVersion()
+ {
+ return c.getVersionNumber();
+ }
+
+ public Principal getIssuerDN()
+ {
+ return new X509Principal(X500Name.getInstance(c.getIssuer().toASN1Primitive()));
+ }
+
+ public X500Principal getIssuerX500Principal()
+ {
+ try
+ {
+ return new X500Principal(c.getIssuer().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("can't encode issuer DN");
+ }
+ }
+
+ public Date getThisUpdate()
+ {
+ return c.getThisUpdate().getDate();
+ }
+
+ public Date getNextUpdate()
+ {
+ Time nextUpdate = c.getNextUpdate();
+
+ return null == nextUpdate ? null : nextUpdate.getDate();
+ }
+
+ private Set loadCRLEntries()
+ {
+ Set entrySet = new HashSet();
+ Enumeration certs = c.getRevokedCertificateEnumeration();
+
+ X500Name previousCertificateIssuer = null; // the issuer
+ while (certs.hasMoreElements())
+ {
+ TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement();
+ X509CRLEntryObject crlEntry = new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer);
+ entrySet.add(crlEntry);
+ if (isIndirect && entry.hasExtensions())
+ {
+ Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
+
+ if (currentCaName != null)
+ {
+ previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
+ }
+ }
+ }
+
+ return entrySet;
+ }
+
+ public X509CRLEntry getRevokedCertificate(BigInteger serialNumber)
+ {
+ Enumeration certs = c.getRevokedCertificateEnumeration();
+
+ X500Name previousCertificateIssuer = null; // the issuer
+ while (certs.hasMoreElements())
+ {
+ TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement();
+
+ if (entry.getUserCertificate().hasValue(serialNumber))
+ {
+ return new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer);
+ }
+
+ if (isIndirect && entry.hasExtensions())
+ {
+ Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
+
+ if (currentCaName != null)
+ {
+ previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public Set getRevokedCertificates()
+ {
+ Set entrySet = loadCRLEntries();
+
+ if (!entrySet.isEmpty())
+ {
+ return Collections.unmodifiableSet(entrySet);
+ }
+
+ return null;
+ }
+
+ public byte[] getTBSCertList()
+ throws CRLException
+ {
+ try
+ {
+ return c.getTBSCertList().getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CRLException(e.toString());
+ }
+ }
+
+ public byte[] getSignature()
+ {
+ return c.getSignature().getOctets();
+ }
+
+ public String getSigAlgName()
+ {
+ return sigAlgName;
+ }
+
+ public String getSigAlgOID()
+ {
+ return c.getSignatureAlgorithm().getAlgorithm().getId();
+ }
+
+ public byte[] getSigAlgParams()
+ {
+ return Arrays.clone(sigAlgParams);
+ }
+
+ /**
+ * Returns a string representation of this CRL.
+ *
+ * @return a string representation of this CRL.
+ */
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append(" Version: ").append(this.getVersion()).append(
+ nl);
+ buf.append(" IssuerDN: ").append(this.getIssuerDN())
+ .append(nl);
+ buf.append(" This update: ").append(this.getThisUpdate())
+ .append(nl);
+ buf.append(" Next update: ").append(this.getNextUpdate())
+ .append(nl);
+ buf.append(" Signature Algorithm: ").append(this.getSigAlgName())
+ .append(nl);
+
+ X509SignatureUtil.prettyPrintSignature(this.getSignature(), buf, nl);
+
+ Extensions extensions = c.getTBSCertList().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ if (e.hasMoreElements())
+ {
+ buf.append(" Extensions: ").append(nl);
+ }
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.getExtnValue() != null)
+ {
+ byte[] octs = ext.getExtnValue().getOctets();
+ ASN1InputStream dIn = new ASN1InputStream(octs);
+ buf.append(" critical(").append(
+ ext.isCritical()).append(") ");
+ try
+ {
+ if (oid.equals(Extension.cRLNumber))
+ {
+ buf.append(
+ new CRLNumber(ASN1Integer.getInstance(
+ dIn.readObject()).getPositiveValue()))
+ .append(nl);
+ }
+ else if (oid.equals(Extension.deltaCRLIndicator))
+ {
+ buf.append(
+ "Base CRL: "
+ + new CRLNumber(ASN1Integer.getInstance(
+ dIn.readObject()).getPositiveValue()))
+ .append(nl);
+ }
+ else if (oid
+ .equals(Extension.issuingDistributionPoint))
+ {
+ buf.append(
+ IssuingDistributionPoint.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid
+ .equals(Extension.cRLDistributionPoints))
+ {
+ buf.append(
+ CRLDistPoint.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid.equals(Extension.freshestCRL))
+ {
+ buf.append(
+ CRLDistPoint.getInstance(dIn.readObject())).append(nl);
+ }
+ else
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append(
+ ASN1Dump.dumpAsString(dIn.readObject()))
+ .append(nl);
+ }
+ }
+ catch (Exception ex)
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append("*****").append(nl);
+ }
+ }
+ else
+ {
+ buf.append(nl);
+ }
+ }
+ }
+ Set set = getRevokedCertificates();
+ if (set != null)
+ {
+ Iterator it = set.iterator();
+ while (it.hasNext())
+ {
+ buf.append(it.next());
+ buf.append(nl);
+ }
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Checks whether the given certificate is on this CRL.
+ *
+ * @param cert the certificate to check for.
+ * @return true if the given certificate is on this CRL,
+ * false otherwise.
+ */
+ public boolean isRevoked(Certificate cert)
+ {
+ if (!cert.getType().equals("X.509"))
+ {
+ throw new IllegalArgumentException("X.509 CRL used with non X.509 Cert");
+ }
+
+ Enumeration certs = c.getRevokedCertificateEnumeration();
+
+ X500Name caName = c.getIssuer();
+
+ if (certs.hasMoreElements())
+ {
+ BigInteger serial = ((X509Certificate)cert).getSerialNumber();
+
+ while (certs.hasMoreElements())
+ {
+ TBSCertList.CRLEntry entry = TBSCertList.CRLEntry.getInstance(certs.nextElement());
+
+ if (isIndirect && entry.hasExtensions())
+ {
+ Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
+
+ if (currentCaName != null)
+ {
+ caName = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
+ }
+ }
+
+ if (entry.getUserCertificate().hasValue(serial))
+ {
+ X500Name issuer;
+
+ if (cert instanceof X509Certificate)
+ {
+ issuer = X500Name.getInstance(((X509Certificate)cert).getIssuerX500Principal().getEncoded());
+ }
+ else
+ {
+ try
+ {
+ issuer = com.android.internal.org.bouncycastle.asn1.x509.Certificate.getInstance(cert.getEncoded()).getIssuer();
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IllegalArgumentException("Cannot process certificate: " + e.getMessage());
+ }
+ }
+
+ if (!caName.equals(issuer))
+ {
+ return false;
+ }
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ protected static byte[] getExtensionOctets(CertificateList c, String oid)
+ {
+ ASN1OctetString extValue = getExtensionValue(c, oid);
+ if (null != extValue)
+ {
+ return extValue.getOctets();
+ }
+ return null;
+ }
+
+ protected static ASN1OctetString getExtensionValue(CertificateList c, String oid)
+ {
+ Extensions exts = c.getTBSCertList().getExtensions();
+ if (null != exts)
+ {
+ Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
+ if (null != ext)
+ {
+ return ext.getExtnValue();
+ }
+ }
+ return null;
+ }
+}
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
new file mode 100644
index 00000000..a3a5fedf
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLInternal.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.security.cert.CRLException;
+
+import com.android.internal.org.bouncycastle.asn1.x509.CertificateList;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+
+class X509CRLInternal extends X509CRLImpl
+{
+ private final byte[] encoding;
+
+ X509CRLInternal(JcaJceHelper bcHelper, CertificateList c, String sigAlgName, byte[] sigAlgParams, boolean isIndirect,
+ byte[] encoding)
+ {
+ super(bcHelper, c, sigAlgName, sigAlgParams, isIndirect);
+
+ this.encoding = encoding;
+ }
+
+ public byte[] getEncoded() throws CRLException
+ {
+ if (null == encoding)
+ {
+ throw new CRLException();
+ }
+
+ return encoding;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
new file mode 100644
index 00000000..1eb9d66d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
@@ -0,0 +1,150 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.security.cert.CRLException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.x509.CertificateList;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.IssuingDistributionPoint;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+
+class X509CRLObject
+ extends X509CRLImpl
+{
+ private final Object cacheLock = new Object();
+ private X509CRLInternal internalCRLValue;
+
+ private volatile boolean hashValueSet;
+ private volatile int hashValue;
+
+ X509CRLObject(JcaJceHelper bcHelper, CertificateList c) throws CRLException
+ {
+ super(bcHelper, c, createSigAlgName(c), createSigAlgParams(c), isIndirectCRL(c));
+ }
+
+ public boolean equals(Object other)
+ {
+ if (this == other)
+ {
+ return true;
+ }
+
+ if (other instanceof X509CRLObject)
+ {
+ X509CRLObject otherBC = (X509CRLObject)other;
+
+ if (this.hashValueSet && otherBC.hashValueSet)
+ {
+ if (this.hashValue != otherBC.hashValue)
+ {
+ return false;
+ }
+ }
+ else if (null == internalCRLValue || null == otherBC.internalCRLValue)
+ {
+ ASN1BitString signature = c.getSignature();
+ if (null != signature && !signature.equals(otherBC.c.getSignature()))
+ {
+ return false;
+ }
+ }
+ }
+
+ return getInternalCRL().equals(other);
+ }
+
+ public int hashCode()
+ {
+ if (!hashValueSet)
+ {
+ hashValue = getInternalCRL().hashCode();
+ hashValueSet = true;
+ }
+
+ return hashValue;
+ }
+
+ private X509CRLInternal getInternalCRL()
+ {
+ synchronized (cacheLock)
+ {
+ if (null != internalCRLValue)
+ {
+ return internalCRLValue;
+ }
+ }
+
+ byte[] encoding;
+ try
+ {
+ encoding = getEncoded();
+ }
+ catch (CRLException e)
+ {
+ encoding = null;
+ }
+
+ X509CRLInternal temp = new X509CRLInternal(bcHelper, c, sigAlgName,sigAlgParams, isIndirect, encoding);
+
+ synchronized (cacheLock)
+ {
+ if (null == internalCRLValue)
+ {
+ internalCRLValue = temp;
+ }
+
+ return internalCRLValue;
+ }
+ }
+
+ private static String createSigAlgName(CertificateList c) throws CRLException
+ {
+ try
+ {
+ return X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
+ }
+ catch (Exception e)
+ {
+ throw new CRLException("CRL contents invalid: " + e);
+ }
+ }
+
+ private static byte[] createSigAlgParams(CertificateList c) throws CRLException
+ {
+ try
+ {
+ ASN1Encodable parameters = c.getSignatureAlgorithm().getParameters();
+ if (null == parameters)
+ {
+ return null;
+ }
+
+ return parameters.toASN1Primitive().getEncoded(ASN1Encoding.DER);
+ }
+ catch (Exception e)
+ {
+ throw new CRLException("CRL contents invalid: " + e);
+ }
+ }
+
+ private static boolean isIndirectCRL(CertificateList c) throws CRLException
+ {
+ try
+ {
+ byte[] extOctets = getExtensionOctets(c, Extension.issuingDistributionPoint.getId());
+ if (null == extOctets)
+ {
+ return false;
+ }
+
+ return IssuingDistributionPoint.getInstance(extOctets).isIndirectCRL();
+ }
+ catch (Exception e)
+ {
+ throw new ExtCRLException("Exception reading IssuingDistributionPoint", e);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
new file mode 100644
index 00000000..920186cf
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateImpl.java
@@ -0,0 +1,941 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1String;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERIA5String;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.misc.NetscapeCertType;
+import com.android.internal.org.bouncycastle.asn1.misc.NetscapeRevocationURL;
+import com.android.internal.org.bouncycastle.asn1.misc.VerisignCzagExtension;
+import com.android.internal.org.bouncycastle.asn1.util.ASN1Dump;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x500.style.RFC4519Style;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.BasicConstraints;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.internal.org.bouncycastle.asn1.x509.KeyUsage;
+import com.android.internal.org.bouncycastle.asn1.x509.TBSCertificate;
+import com.android.internal.org.bouncycastle.jcajce.CompositePublicKey;
+import com.android.internal.org.bouncycastle.jcajce.interfaces.BCX509Certificate;
+import com.android.internal.org.bouncycastle.jcajce.io.OutputStreamFactory;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.jce.X509Principal;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Integers;
+import com.android.internal.org.bouncycastle.util.Properties;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+abstract class X509CertificateImpl
+ extends X509Certificate
+ implements BCX509Certificate
+{
+ protected JcaJceHelper bcHelper;
+ protected com.android.internal.org.bouncycastle.asn1.x509.Certificate c;
+ protected BasicConstraints basicConstraints;
+ protected boolean[] keyUsage;
+ protected String sigAlgName;
+ protected byte[] sigAlgParams;
+
+ X509CertificateImpl(JcaJceHelper bcHelper, com.android.internal.org.bouncycastle.asn1.x509.Certificate c,
+ BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams)
+ {
+ this.bcHelper = bcHelper;
+ this.c = c;
+ this.basicConstraints = basicConstraints;
+ this.keyUsage = keyUsage;
+ this.sigAlgName = sigAlgName;
+ this.sigAlgParams = sigAlgParams;
+ }
+
+ public X500Name getIssuerX500Name()
+ {
+ return c.getIssuer();
+ }
+
+ public TBSCertificate getTBSCertificateNative()
+ {
+ return c.getTBSCertificate();
+ }
+
+ public X500Name getSubjectX500Name()
+ {
+ return c.getSubject();
+ }
+
+ public void checkValidity()
+ throws CertificateExpiredException, CertificateNotYetValidException
+ {
+ this.checkValidity(new Date());
+ }
+
+ public void checkValidity(
+ Date date)
+ throws CertificateExpiredException, CertificateNotYetValidException
+ {
+ if (date.getTime() > this.getNotAfter().getTime()) // for other VM compatibility
+ {
+ throw new CertificateExpiredException("certificate expired on " + c.getEndDate().getTime());
+ }
+
+ if (date.getTime() < this.getNotBefore().getTime())
+ {
+ throw new CertificateNotYetValidException("certificate not valid till " + c.getStartDate().getTime());
+ }
+ }
+
+ public int getVersion()
+ {
+ return c.getVersionNumber();
+ }
+
+ public BigInteger getSerialNumber()
+ {
+ return c.getSerialNumber().getValue();
+ }
+
+ public Principal getIssuerDN()
+ {
+ return new X509Principal(c.getIssuer());
+ }
+
+ public X500Principal getIssuerX500Principal()
+ {
+ try
+ {
+ byte[] encoding = c.getIssuer().getEncoded(ASN1Encoding.DER);
+
+ return new X500Principal(encoding);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("can't encode issuer DN");
+ }
+ }
+
+ public Principal getSubjectDN()
+ {
+ return new X509Principal(c.getSubject());
+ }
+
+ public X500Principal getSubjectX500Principal()
+ {
+ try
+ {
+ byte[] encoding = c.getSubject().getEncoded(ASN1Encoding.DER);
+
+ return new X500Principal(encoding);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("can't encode subject DN");
+ }
+ }
+
+ public Date getNotBefore()
+ {
+ return c.getStartDate().getDate();
+ }
+
+ public Date getNotAfter()
+ {
+ return c.getEndDate().getDate();
+ }
+
+ public byte[] getTBSCertificate()
+ throws CertificateEncodingException
+ {
+ try
+ {
+ return c.getTBSCertificate().getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException(e.toString());
+ }
+ }
+
+ public byte[] getSignature()
+ {
+ return c.getSignature().getOctets();
+ }
+
+ /**
+ * return a more "meaningful" representation for the signature algorithm used in
+ * the certificate.
+ */
+ public String getSigAlgName()
+ {
+ return sigAlgName;
+ }
+
+ /**
+ * return the object identifier for the signature.
+ */
+ public String getSigAlgOID()
+ {
+ return c.getSignatureAlgorithm().getAlgorithm().getId();
+ }
+
+ /**
+ * return the signature parameters, or null if there aren't any.
+ */
+ public byte[] getSigAlgParams()
+ {
+ return Arrays.clone(sigAlgParams);
+ }
+
+ public boolean[] getIssuerUniqueID()
+ {
+ DERBitString id = c.getTBSCertificate().getIssuerUniqueId();
+
+ if (id != null)
+ {
+ byte[] bytes = id.getBytes();
+ boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
+
+ for (int i = 0; i != boolId.length; i++)
+ {
+ boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ }
+
+ return boolId;
+ }
+
+ return null;
+ }
+
+ public boolean[] getSubjectUniqueID()
+ {
+ DERBitString id = c.getTBSCertificate().getSubjectUniqueId();
+
+ if (id != null)
+ {
+ byte[] bytes = id.getBytes();
+ boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
+
+ for (int i = 0; i != boolId.length; i++)
+ {
+ boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ }
+
+ return boolId;
+ }
+
+ return null;
+ }
+
+ public boolean[] getKeyUsage()
+ {
+ return Arrays.clone(keyUsage);
+ }
+
+ public List getExtendedKeyUsage()
+ throws CertificateParsingException
+ {
+ byte[] extOctets = getExtensionOctets(c, "2.5.29.37");
+ if (null == extOctets)
+ {
+ return null;
+ }
+
+ try
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(ASN1Primitive.fromByteArray(extOctets));
+
+ List list = new ArrayList();
+ for (int i = 0; i != seq.size(); i++)
+ {
+ list.add(((ASN1ObjectIdentifier)seq.getObjectAt(i)).getId());
+ }
+ return Collections.unmodifiableList(list);
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException("error processing extended key usage extension");
+ }
+ }
+
+ public int getBasicConstraints()
+ {
+ if (basicConstraints != null)
+ {
+ if (basicConstraints.isCA())
+ {
+ if (basicConstraints.getPathLenConstraint() == null)
+ {
+ return Integer.MAX_VALUE;
+ }
+ else
+ {
+ return basicConstraints.getPathLenConstraint().intValue();
+ }
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ return -1;
+ }
+
+ public Collection getSubjectAlternativeNames()
+ throws CertificateParsingException
+ {
+ return getAlternativeNames(c, Extension.subjectAlternativeName.getId());
+ }
+
+ public Collection getIssuerAlternativeNames()
+ throws CertificateParsingException
+ {
+ return getAlternativeNames(c, Extension.issuerAlternativeName.getId());
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ if (this.getVersion() == 3)
+ {
+ Set set = new HashSet();
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+ }
+
+ return null;
+ }
+
+ public byte[] getExtensionValue(String oid)
+ {
+ ASN1OctetString extValue = getExtensionValue(c, oid);
+ if (null != extValue)
+ {
+ try
+ {
+ return extValue.getEncoded();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException("error parsing " + e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ if (this.getVersion() == 3)
+ {
+ Set set = new HashSet();
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (!ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+ }
+
+ return null;
+ }
+
+ public boolean hasUnsupportedCriticalExtension()
+ {
+ if (this.getVersion() == 3)
+ {
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+
+ if (oid.equals(Extension.keyUsage)
+ || oid.equals(Extension.certificatePolicies)
+ || oid.equals(Extension.policyMappings)
+ || oid.equals(Extension.inhibitAnyPolicy)
+ || oid.equals(Extension.cRLDistributionPoints)
+ || oid.equals(Extension.issuingDistributionPoint)
+ || oid.equals(Extension.deltaCRLIndicator)
+ || oid.equals(Extension.policyConstraints)
+ || oid.equals(Extension.basicConstraints)
+ || oid.equals(Extension.subjectAlternativeName)
+ || oid.equals(Extension.nameConstraints))
+ {
+ continue;
+ }
+
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.isCritical())
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public PublicKey getPublicKey()
+ {
+ try
+ {
+ return BouncyCastleProvider.getPublicKey(c.getSubjectPublicKeyInfo());
+ }
+ catch (IOException e)
+ {
+ return null; // should never happen...
+ }
+ }
+
+ public byte[] getEncoded()
+ throws CertificateEncodingException
+ {
+ try
+ {
+ return c.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException(e.toString());
+ }
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append(" [0] Version: ").append(this.getVersion()).append(nl);
+ buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl);
+ buf.append(" IssuerDN: ").append(this.getIssuerDN()).append(nl);
+ buf.append(" Start Date: ").append(this.getNotBefore()).append(nl);
+ buf.append(" Final Date: ").append(this.getNotAfter()).append(nl);
+ buf.append(" SubjectDN: ").append(this.getSubjectDN()).append(nl);
+ buf.append(" Public Key: ").append(this.getPublicKey()).append(nl);
+ buf.append(" Signature Algorithm: ").append(this.getSigAlgName()).append(nl);
+
+ X509SignatureUtil.prettyPrintSignature(this.getSignature(), buf, nl);
+
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ if (e.hasMoreElements())
+ {
+ buf.append(" Extensions: \n");
+ }
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.getExtnValue() != null)
+ {
+ byte[] octs = ext.getExtnValue().getOctets();
+ ASN1InputStream dIn = new ASN1InputStream(octs);
+ buf.append(" critical(").append(ext.isCritical()).append(") ");
+ try
+ {
+ if (oid.equals(Extension.basicConstraints))
+ {
+ buf.append(BasicConstraints.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid.equals(Extension.keyUsage))
+ {
+ buf.append(KeyUsage.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid.equals(MiscObjectIdentifiers.netscapeCertType))
+ {
+ buf.append(new NetscapeCertType(DERBitString.getInstance(dIn.readObject()))).append(nl);
+ }
+ else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL))
+ {
+ buf.append(new NetscapeRevocationURL(DERIA5String.getInstance(dIn.readObject()))).append(nl);
+ }
+ else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension))
+ {
+ buf.append(new VerisignCzagExtension(DERIA5String.getInstance(dIn.readObject()))).append(nl);
+ }
+ else
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl);
+ //buf.append(" value = ").append("*****").append(nl);
+ }
+ }
+ catch (Exception ex)
+ {
+ buf.append(oid.getId());
+ // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl);
+ buf.append(" value = ").append("*****").append(nl);
+ }
+ }
+ else
+ {
+ buf.append(nl);
+ }
+ }
+ }
+
+ return buf.toString();
+ }
+
+ public final void verify(
+ PublicKey key)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException
+ {
+ try
+ {
+ return bcHelper.createSignature(sigName);
+ }
+ catch (Exception e)
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+
+ public final void verify(
+ PublicKey key,
+ final String sigProvider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ if (sigProvider != null)
+ {
+ return Signature.getInstance(sigName, sigProvider);
+ }
+ else
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+
+ public final void verify(
+ PublicKey key,
+ final Provider sigProvider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
+ try
+ {
+ doVerify(key, new SignatureCreator()
+ {
+ public Signature createSignature(String sigName)
+ throws NoSuchAlgorithmException
+ {
+ if (sigProvider != null)
+ {
+ return Signature.getInstance(sigName, sigProvider);
+ }
+ else
+ {
+ return Signature.getInstance(sigName);
+ }
+ }
+ });
+ }
+ catch (NoSuchProviderException e)
+ {
+ // can't happen, but just in case
+ throw new NoSuchAlgorithmException("provider issue: " + e.getMessage());
+ }
+ }
+
+ private void doVerify(
+ PublicKey key,
+ SignatureCreator signatureCreator)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException, NoSuchProviderException
+ {
+ if (key instanceof CompositePublicKey && X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
+ {
+ List<PublicKey> pubKeys = ((CompositePublicKey)key).getPublicKeys();
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+
+ boolean success = false;
+ for (int i = 0; i != pubKeys.size(); i++)
+ {
+ if (pubKeys.get(i) == null)
+ {
+ continue;
+ }
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ String sigName = X509SignatureUtil.getSignatureName(sigAlg);
+
+ Signature signature = signatureCreator.createSignature(sigName);
+
+ SignatureException sigExc = null;
+
+ try
+ {
+ checkSignature(
+ (PublicKey)pubKeys.get(i), signature,
+ sigAlg.getParameters(),
+ DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+ success = true;
+ }
+ catch (SignatureException e)
+ {
+ sigExc = e;
+ }
+
+ if (sigExc != null)
+ {
+ throw sigExc;
+ }
+ }
+
+ if (!success)
+ {
+ throw new InvalidKeyException("no matching key found");
+ }
+ }
+ else if (X509SignatureUtil.isCompositeAlgorithm(c.getSignatureAlgorithm()))
+ {
+ ASN1Sequence keySeq = ASN1Sequence.getInstance(c.getSignatureAlgorithm().getParameters());
+ ASN1Sequence sigSeq = ASN1Sequence.getInstance(DERBitString.getInstance(c.getSignature()).getBytes());
+
+ boolean success = false;
+ for (int i = 0; i != sigSeq.size(); i++)
+ {
+ AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
+ String sigName = X509SignatureUtil.getSignatureName(sigAlg);
+
+ SignatureException sigExc = null;
+
+ try
+ {
+ Signature signature = signatureCreator.createSignature(sigName);
+
+ checkSignature(
+ key, signature,
+ sigAlg.getParameters(),
+ DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes());
+
+ success = true;
+ }
+ catch (InvalidKeyException e)
+ {
+ // ignore
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // ignore
+ }
+ catch (SignatureException e)
+ {
+ sigExc = e;
+ }
+
+ if (sigExc != null)
+ {
+ throw sigExc;
+ }
+ }
+
+ if (!success)
+ {
+ throw new InvalidKeyException("no matching key found");
+ }
+ }
+ else
+ {
+ String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
+
+ Signature signature = signatureCreator.createSignature(sigName);
+
+ if (key instanceof CompositePublicKey)
+ {
+ List<PublicKey> keys = ((CompositePublicKey)key).getPublicKeys();
+
+ for (int i = 0; i != keys.size(); i++)
+ {
+ try
+ {
+ checkSignature((PublicKey)keys.get(i), signature,
+ c.getSignatureAlgorithm().getParameters(), this.getSignature());
+ return; // found the match!
+ }
+ catch (InvalidKeyException e)
+ {
+ // continue;
+ }
+ }
+
+ throw new InvalidKeyException("no matching signature found");
+ }
+ else
+ {
+ checkSignature(key, signature,
+ c.getSignatureAlgorithm().getParameters(), this.getSignature());
+ }
+ }
+ }
+
+ private void checkSignature(
+ PublicKey key,
+ Signature signature,
+ ASN1Encodable params,
+ byte[] sigBytes)
+ throws CertificateException, NoSuchAlgorithmException,
+ SignatureException, InvalidKeyException
+ {
+ if (!isAlgIdEqual(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature()))
+ {
+ throw new CertificateException("signature algorithm in TBS cert not same as outer cert");
+ }
+
+ // TODO This should go after the initVerify?
+ X509SignatureUtil.setSignatureParameters(signature, params);
+
+ signature.initVerify(key);
+
+ try
+ {
+ OutputStream sigOut = new BufferedOutputStream(OutputStreamFactory.createStream(signature), 512);
+
+ c.getTBSCertificate().encodeTo(sigOut, ASN1Encoding.DER);
+
+ sigOut.close();
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException(e.toString());
+ }
+
+ if (!signature.verify(sigBytes))
+ {
+ throw new SignatureException("certificate does not verify with supplied key");
+ }
+ }
+
+ private 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;
+ }
+
+ private static Collection getAlternativeNames(com.android.internal.org.bouncycastle.asn1.x509.Certificate c, String oid)
+ throws CertificateParsingException
+ {
+ byte[] extOctets = getExtensionOctets(c, oid);
+ if (extOctets == null)
+ {
+ return null;
+ }
+ try
+ {
+ Collection temp = new ArrayList();
+ Enumeration it = ASN1Sequence.getInstance(extOctets).getObjects();
+ while (it.hasMoreElements())
+ {
+ GeneralName genName = GeneralName.getInstance(it.nextElement());
+ List list = new ArrayList();
+ list.add(Integers.valueOf(genName.getTagNo()));
+ switch (genName.getTagNo())
+ {
+ case GeneralName.ediPartyName:
+ case GeneralName.x400Address:
+ case GeneralName.otherName:
+ list.add(genName.getEncoded());
+ break;
+ case GeneralName.directoryName:
+ list.add(X500Name.getInstance(RFC4519Style.INSTANCE, genName.getName()).toString());
+ break;
+ case GeneralName.dNSName:
+ case GeneralName.rfc822Name:
+ case GeneralName.uniformResourceIdentifier:
+ list.add(((ASN1String)genName.getName()).getString());
+ break;
+ case GeneralName.registeredID:
+ list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId());
+ break;
+ case GeneralName.iPAddress:
+ byte[] addrBytes = DEROctetString.getInstance(genName.getName()).getOctets();
+ final String addr;
+ try
+ {
+ addr = InetAddress.getByAddress(addrBytes).getHostAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ continue;
+ }
+ list.add(addr);
+ break;
+ default:
+ throw new IOException("Bad tag number: " + genName.getTagNo());
+ }
+
+ temp.add(Collections.unmodifiableList(list));
+ }
+ if (temp.size() == 0)
+ {
+ return null;
+ }
+ return Collections.unmodifiableCollection(temp);
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException(e.getMessage());
+ }
+ }
+
+ protected static byte[] getExtensionOctets(com.android.internal.org.bouncycastle.asn1.x509.Certificate c, String oid)
+ {
+ ASN1OctetString extValue = getExtensionValue(c, oid);
+ if (null != extValue)
+ {
+ return extValue.getOctets();
+ }
+ return null;
+ }
+
+ protected static ASN1OctetString getExtensionValue(com.android.internal.org.bouncycastle.asn1.x509.Certificate c, String oid)
+ {
+ Extensions exts = c.getTBSCertificate().getExtensions();
+ if (null != exts)
+ {
+ Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
+ if (null != ext)
+ {
+ return ext.getExtnValue();
+ }
+ }
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
new file mode 100644
index 00000000..6ff5ac1d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateInternal.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.security.cert.CertificateEncodingException;
+
+import com.android.internal.org.bouncycastle.asn1.x509.BasicConstraints;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+
+class X509CertificateInternal extends X509CertificateImpl
+{
+ private final byte[] encoding;
+
+ X509CertificateInternal(JcaJceHelper bcHelper, com.android.internal.org.bouncycastle.asn1.x509.Certificate c,
+ BasicConstraints basicConstraints, boolean[] keyUsage, String sigAlgName, byte[] sigAlgParams, byte[] encoding)
+ {
+ super(bcHelper, c, basicConstraints, keyUsage, sigAlgName, sigAlgParams);
+
+ this.encoding = encoding;
+ }
+
+ public byte[] getEncoded() throws CertificateEncodingException
+ {
+ if (null == encoding)
+ {
+ throw new CertificateEncodingException();
+ }
+
+ return encoding;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
new file mode 100644
index 00000000..39f0ff1d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
@@ -0,0 +1,423 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OutputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1String;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERIA5String;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.misc.NetscapeCertType;
+import com.android.internal.org.bouncycastle.asn1.misc.NetscapeRevocationURL;
+import com.android.internal.org.bouncycastle.asn1.misc.VerisignCzagExtension;
+import com.android.internal.org.bouncycastle.asn1.util.ASN1Dump;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x500.style.RFC4519Style;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.BasicConstraints;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.internal.org.bouncycastle.asn1.x509.KeyUsage;
+// BEGIN Android-added: Unknown reason
+import com.android.internal.org.bouncycastle.asn1.x509.X509Name;
+// END Android-added: Unknown reason
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.jce.X509Principal;
+import com.android.internal.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.util.Integers;
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+class X509CertificateObject
+ extends X509CertificateImpl
+ implements PKCS12BagAttributeCarrier
+{
+ private final Object cacheLock = new Object();
+ private X509CertificateInternal internalCertificateValue;
+ private X500Principal issuerValue;
+ private PublicKey publicKeyValue;
+ private X500Principal subjectValue;
+ private long[] validityValues;
+
+ private volatile boolean hashValueSet;
+ private volatile int hashValue;
+
+ private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
+ X509CertificateObject(JcaJceHelper bcHelper, com.android.internal.org.bouncycastle.asn1.x509.Certificate c)
+ throws CertificateParsingException
+ {
+ super(bcHelper, c, createBasicConstraints(c), createKeyUsage(c), createSigAlgName(c), createSigAlgParams(c));
+ }
+
+ public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException
+ {
+ long checkTime = date.getTime();
+ long[] validityValues = getValidityValues();
+
+ if (checkTime > validityValues[1]) // for other VM compatibility
+ {
+ throw new CertificateExpiredException("certificate expired on " + c.getEndDate().getTime());
+ }
+ if (checkTime < validityValues[0])
+ {
+ throw new CertificateNotYetValidException("certificate not valid till " + c.getStartDate().getTime());
+ }
+ }
+
+ public X500Principal getIssuerX500Principal()
+ {
+ synchronized (cacheLock)
+ {
+ if (null != issuerValue)
+ {
+ return issuerValue;
+ }
+ }
+
+ X500Principal temp = super.getIssuerX500Principal();
+
+ synchronized (cacheLock)
+ {
+ if (null == issuerValue)
+ {
+ issuerValue = temp;
+ }
+
+ return issuerValue;
+ }
+ }
+
+ public PublicKey getPublicKey()
+ {
+ // Cache the public key to support repeated-use optimizations
+ synchronized (cacheLock)
+ {
+ if (null != publicKeyValue)
+ {
+ return publicKeyValue;
+ }
+ }
+
+ PublicKey temp = super.getPublicKey();
+ if (null == temp)
+ {
+ return null;
+ }
+
+ synchronized (cacheLock)
+ {
+ if (null == publicKeyValue)
+ {
+ publicKeyValue = temp;
+ }
+
+ return publicKeyValue;
+ }
+ }
+
+ public X500Principal getSubjectX500Principal()
+ {
+ synchronized (cacheLock)
+ {
+ if (null != subjectValue)
+ {
+ return subjectValue;
+ }
+ }
+
+ X500Principal temp = super.getSubjectX500Principal();
+
+ synchronized (cacheLock)
+ {
+ if (null == subjectValue)
+ {
+ subjectValue = temp;
+ }
+
+ return subjectValue;
+ }
+ }
+
+ public long[] getValidityValues()
+ {
+ synchronized (cacheLock)
+ {
+ if (null != validityValues)
+ {
+ return validityValues;
+ }
+ }
+
+ long[] temp = new long[]
+ {
+ super.getNotBefore().getTime(),
+ super.getNotAfter().getTime()
+ };
+
+ synchronized (cacheLock)
+ {
+ if (null == validityValues)
+ {
+ validityValues = temp;
+ }
+
+ return validityValues;
+ }
+ }
+
+ // Android-added: Cache the encoded certificate
+ private byte[] encoded;
+ public byte[] getEncoded()
+ throws CertificateEncodingException
+ {
+ try
+ {
+ // BEGIN Android-changed: Cache the encoded certificate
+ if (encoded == null) {
+ encoded = c.getEncoded(ASN1Encoding.DER);
+ }
+ return encoded;
+ // END Android-changed: Cache the encoded certificate
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException(e.toString());
+ }
+ }
+
+ public boolean equals(
+ Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (other instanceof X509CertificateObject)
+ {
+ X509CertificateObject otherBC = (X509CertificateObject)other;
+
+ if (this.hashValueSet && otherBC.hashValueSet)
+ {
+ if (this.hashValue != otherBC.hashValue)
+ {
+ return false;
+ }
+ }
+ else if (null == internalCertificateValue || null == otherBC.internalCertificateValue)
+ {
+ ASN1BitString signature = c.getSignature();
+ if (null != signature && !signature.equals(otherBC.c.getSignature()))
+ {
+ return false;
+ }
+ }
+ }
+
+ return getInternalCertificate().equals(other);
+ }
+
+ public int hashCode()
+ {
+ if (!hashValueSet)
+ {
+ hashValue = getInternalCertificate().hashCode();
+ hashValueSet = true;
+ }
+
+ return hashValue;
+ }
+
+ /**
+ * Returns the original hash code for Certificates pre-JDK 1.8.
+ *
+ * @return the pre-JDK 1.8 hashcode calculation.
+ */
+ public int originalHashCode()
+ {
+ try
+ {
+ int hashCode = 0;
+ byte[] certData = getInternalCertificate().getEncoded();
+ for (int i = 1; i < certData.length; i++)
+ {
+ hashCode += certData[i] * i;
+ }
+ return hashCode;
+ }
+ catch (CertificateEncodingException e)
+ {
+ return 0;
+ }
+ }
+
+ public void setBagAttribute(ASN1ObjectIdentifier oid, ASN1Encodable attribute)
+ {
+ attrCarrier.setBagAttribute(oid, attribute);
+ }
+
+ public ASN1Encodable getBagAttribute(ASN1ObjectIdentifier oid)
+ {
+ return attrCarrier.getBagAttribute(oid);
+ }
+
+ public Enumeration getBagAttributeKeys()
+ {
+ return attrCarrier.getBagAttributeKeys();
+ }
+
+ private X509CertificateInternal getInternalCertificate()
+ {
+ synchronized (cacheLock)
+ {
+ if (null != internalCertificateValue)
+ {
+ return internalCertificateValue;
+ }
+ }
+
+ byte[] encoding;
+ try
+ {
+ encoding = getEncoded();
+ }
+ catch (CertificateEncodingException e)
+ {
+ encoding = null;
+ }
+
+ X509CertificateInternal temp = new X509CertificateInternal(bcHelper, c, basicConstraints, keyUsage, sigAlgName,
+ sigAlgParams, encoding);
+
+ synchronized (cacheLock)
+ {
+ if (null == internalCertificateValue)
+ {
+ internalCertificateValue = temp;
+ }
+
+ return internalCertificateValue;
+ }
+ }
+
+ private static BasicConstraints createBasicConstraints(com.android.internal.org.bouncycastle.asn1.x509.Certificate c)
+ throws CertificateParsingException
+ {
+ try
+ {
+ byte[] extOctets = getExtensionOctets(c, "2.5.29.19");
+ if (null == extOctets)
+ {
+ return null;
+ }
+
+ return BasicConstraints.getInstance(ASN1Primitive.fromByteArray(extOctets));
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException("cannot construct BasicConstraints: " + e);
+ }
+ }
+
+ private static boolean[] createKeyUsage(com.android.internal.org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException
+ {
+ try
+ {
+ byte[] extOctets = getExtensionOctets(c, "2.5.29.15");
+ if (null == extOctets)
+ {
+ return null;
+ }
+
+ ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(extOctets));
+
+ byte[] bytes = bits.getBytes();
+ int length = (bytes.length * 8) - bits.getPadBits();
+
+ boolean[] keyUsage = new boolean[(length < 9) ? 9 : length];
+
+ for (int i = 0; i != length; i++)
+ {
+ keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ }
+
+ return keyUsage;
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException("cannot construct KeyUsage: " + e);
+ }
+ }
+
+ private static String createSigAlgName(com.android.internal.org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException
+ {
+ try
+ {
+ return X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException("cannot construct SigAlgName: " + e);
+ }
+ }
+
+ private static byte[] createSigAlgParams(com.android.internal.org.bouncycastle.asn1.x509.Certificate c) throws CertificateParsingException
+ {
+ try
+ {
+ ASN1Encodable parameters = c.getSignatureAlgorithm().getParameters();
+ if (null == parameters)
+ {
+ return null;
+ }
+
+ return parameters.toASN1Primitive().getEncoded(ASN1Encoding.DER);
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException("cannot construct SigAlgParams: " + e);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
new file mode 100644
index 00000000..bcf9fb54
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
@@ -0,0 +1,205 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509;
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.PSSParameterSpec;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Null;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+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 com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.jcajce.util.MessageDigestUtils;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+class X509SignatureUtil
+{
+ private static final Map<ASN1ObjectIdentifier, String> algNames = new HashMap<ASN1ObjectIdentifier, String>();
+
+ static
+ {
+ // algNames.put(EdECObjectIdentifiers.id_Ed25519, "Ed25519");
+ // algNames.put(EdECObjectIdentifiers.id_Ed448, "Ed448");
+ algNames.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1withDSA");
+ algNames.put(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1withDSA");
+ }
+
+ private static final ASN1Null derNull = DERNull.INSTANCE;
+
+ static boolean isCompositeAlgorithm(AlgorithmIdentifier algorithmIdentifier)
+ {
+ return MiscObjectIdentifiers.id_alg_composite.equals(algorithmIdentifier.getAlgorithm());
+ }
+
+ static void setSignatureParameters(
+ Signature signature,
+ ASN1Encodable params)
+ throws NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ if (params != null && !derNull.equals(params))
+ {
+ AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider());
+
+ try
+ {
+ sigParams.init(params.toASN1Primitive().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new SignatureException("IOException decoding parameters: " + e.getMessage());
+ }
+
+ if (signature.getAlgorithm().endsWith("MGF1"))
+ {
+ try
+ {
+ signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class));
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new SignatureException("Exception extracting parameters: " + e.getMessage());
+ }
+ }
+ }
+ }
+
+ static String getSignatureName(
+ AlgorithmIdentifier sigAlgId)
+ {
+ ASN1Encodable params = sigAlgId.getParameters();
+
+ if (params != null && !derNull.equals(params))
+ {
+ if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params);
+
+ return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "withRSAandMGF1";
+ }
+ if (sigAlgId.getAlgorithm().equals(X9ObjectIdentifiers.ecdsa_with_SHA2))
+ {
+ ASN1Sequence ecDsaParams = ASN1Sequence.getInstance(params);
+
+ return getDigestAlgName((ASN1ObjectIdentifier)ecDsaParams.getObjectAt(0)) + "withECDSA";
+ }
+ }
+
+ // deal with the "weird" ones.
+ String algName = (String)algNames.get(sigAlgId.getAlgorithm());
+ if (algName != null)
+ {
+ return algName;
+ }
+
+ return findAlgName(sigAlgId.getAlgorithm());
+ }
+
+ /**
+ * Return the digest algorithm using one of the standard JCA string
+ * representations rather the the algorithm identifier (if possible).
+ */
+ private static String getDigestAlgName(
+ ASN1ObjectIdentifier digestAlgOID)
+ {
+ String name = MessageDigestUtils.getDigestName(digestAlgOID);
+
+ int dIndex = name.indexOf('-');
+ if (dIndex > 0 && !name.startsWith("SHA3"))
+ {
+ return name.substring(0, dIndex) + name.substring(dIndex + 1);
+ }
+
+ return name;
+ }
+
+ private static String findAlgName(ASN1ObjectIdentifier algOid)
+ {
+ Provider prov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);
+
+ if (prov != null)
+ {
+ String algName = lookupAlg(prov, algOid);
+ if (algName != null)
+ {
+ return algName;
+ }
+ }
+
+ Provider[] provs = Security.getProviders();
+
+ for (int i = 0; i != provs.length; i++)
+ {
+ if (prov != provs[i])
+ {
+ String algName = lookupAlg(provs[i], algOid);
+ if (algName != null)
+ {
+ return algName;
+ }
+ }
+ }
+
+ return algOid.getId();
+ }
+
+ private static String lookupAlg(Provider prov, ASN1ObjectIdentifier algOid)
+ {
+ String algName = prov.getProperty("Alg.Alias.Signature." + algOid);
+
+ if (algName != null)
+ {
+ return algName;
+ }
+
+ algName = prov.getProperty("Alg.Alias.Signature.OID." + algOid);
+
+ if (algName != null)
+ {
+ return algName;
+ }
+
+ return null;
+ }
+
+ static void prettyPrintSignature(byte[] sig, StringBuffer buf, String nl)
+ {
+ if (sig.length > 20)
+ {
+ buf.append(" Signature: ").append(Hex.toHexString(sig, 0, 20)).append(nl);
+ for (int i = 20; i < sig.length; i += 20)
+ {
+ if (i < sig.length - 20)
+ {
+ buf.append(" ").append(Hex.toHexString(sig, i, 20)).append(nl);
+ }
+ else
+ {
+ buf.append(" ").append(Hex.toHexString(sig, i, sig.length - i)).append(nl);
+ }
+ }
+ }
+ else
+ {
+ buf.append(" Signature: ").append(Hex.toHexString(sig)).append(nl);
+ }
+ }
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java
new file mode 100644
index 00000000..8f8787f7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java
@@ -0,0 +1,59 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.config;
+
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+
+/**
+ * Implemented by the BC provider. This allows setting of hidden parameters,
+ * such as the ImplicitCA parameters from X.962, if used.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ConfigurableProvider
+{
+ /**
+ * Elliptic Curve CA parameters - thread local version
+ */
+ static final String THREAD_LOCAL_EC_IMPLICITLY_CA = "threadLocalEcImplicitlyCa";
+
+ /**
+ * Elliptic Curve CA parameters - VM wide version
+ */
+ static final String EC_IMPLICITLY_CA = "ecImplicitlyCa";
+
+ /**
+ * Diffie-Hellman Default Parameters - thread local version
+ */
+ static final String THREAD_LOCAL_DH_DEFAULT_PARAMS = "threadLocalDhDefaultParams";
+
+ /**
+ * Diffie-Hellman Default Parameters - VM wide version
+ */
+ static final String DH_DEFAULT_PARAMS = "DhDefaultParams";
+
+ /**
+ * A set of OBJECT IDENTIFIERs representing acceptable named curves for imported keys.
+ */
+ static final String ACCEPTABLE_EC_CURVES = "acceptableEcCurves";
+
+ /**
+ * A set of OBJECT IDENTIFIERs to EC Curves providing local curve name mapping.
+ */
+ static final String ADDITIONAL_EC_PARAMETERS = "additionalEcParameters";
+
+ void setParameter(String parameterName, Object parameter);
+
+ void addAlgorithm(String key, String value);
+
+ void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className);
+
+ boolean hasAlgorithm(String type, String name);
+
+ void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter);
+
+ AsymmetricKeyInfoConverter getKeyInfoConverter(ASN1ObjectIdentifier oid);
+
+ void addAttributes(String key, Map<String, String> attributeMap);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/PKCS12StoreParameter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/PKCS12StoreParameter.java
new file mode 100644
index 00000000..67eaff26
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/PKCS12StoreParameter.java
@@ -0,0 +1,34 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.config;
+
+import java.io.OutputStream;
+import java.security.KeyStore;
+import java.security.KeyStore.ProtectionParameter;
+
+/**
+ * @deprecated use org.bouncycastle.jcajce.PKCS12StoreParameter
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS12StoreParameter
+ extends com.android.internal.org.bouncycastle.jcajce.PKCS12StoreParameter
+{
+ public PKCS12StoreParameter(OutputStream out, char[] password)
+ {
+ super(out, password, false);
+ }
+
+ public PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter)
+ {
+ super(out, protectionParameter, false);
+ }
+
+ public PKCS12StoreParameter(OutputStream out, char[] password, boolean forDEREncoding)
+ {
+ super(out, new KeyStore.PasswordProtection(password), forDEREncoding);
+ }
+
+ public PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter, boolean forDEREncoding)
+ {
+ super(out, protectionParameter, forDEREncoding);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java
new file mode 100644
index 00000000..ccca505c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.config;
+
+import java.security.spec.DSAParameterSpec;
+import java.util.Map;
+import java.util.Set;
+
+import javax.crypto.spec.DHParameterSpec;
+
+import com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ProviderConfiguration
+{
+ ECParameterSpec getEcImplicitlyCa();
+
+ DHParameterSpec getDHDefaultParameters(int keySize);
+
+ DSAParameterSpec getDSADefaultParameters(int keySize);
+
+ Set getAcceptableNamedCurves();
+
+ Map getAdditionalECParameters();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ProviderConfigurationPermission.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ProviderConfigurationPermission.java
new file mode 100644
index 00000000..ccb83275
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ProviderConfigurationPermission.java
@@ -0,0 +1,161 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.config;
+
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.util.StringTokenizer;
+
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * A permission class to define what can be done with the ConfigurableProvider interface.
+ * <p>
+ * Available permissions are "threadLocalEcImplicitlyCa" and "ecImplicitlyCa" which allow the setting
+ * of the thread local and global ecImplicitlyCa parameters respectively.
+ * </p>
+ * <p>
+ * Examples:
+ * <ul>
+ * <li>ProviderConfigurationPermission("BC"); // enable all permissions</li>
+ * <li>ProviderConfigurationPermission("BC", "threadLocalEcImplicitlyCa"); // enable thread local only</li>
+ * <li>ProviderConfigurationPermission("BC", "ecImplicitlyCa"); // enable global setting only</li>
+ * <li>ProviderConfigurationPermission("BC", "threadLocalEcImplicitlyCa, ecImplicitlyCa"); // enable both explicitly</li>
+ * </ul>
+ * <p>
+ * Note: permission checks are only enforced if a security manager is present.
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ProviderConfigurationPermission
+ extends BasicPermission
+{
+ private static final int THREAD_LOCAL_EC_IMPLICITLY_CA = 0x01;
+ private static final int EC_IMPLICITLY_CA = 0x02;
+ private static final int THREAD_LOCAL_DH_DEFAULT_PARAMS = 0x04;
+ private static final int DH_DEFAULT_PARAMS = 0x08;
+ private static final int ACCEPTABLE_EC_CURVES = 0x10;
+ private static final int ADDITIONAL_EC_PARAMETERS = 0x20;
+
+ private static final int ALL =
+ THREAD_LOCAL_EC_IMPLICITLY_CA | EC_IMPLICITLY_CA | THREAD_LOCAL_DH_DEFAULT_PARAMS | DH_DEFAULT_PARAMS |
+ ACCEPTABLE_EC_CURVES | ADDITIONAL_EC_PARAMETERS;
+
+ private static final String THREAD_LOCAL_EC_IMPLICITLY_CA_STR = "threadlocalecimplicitlyca";
+ private static final String EC_IMPLICITLY_CA_STR = "ecimplicitlyca";
+ private static final String THREAD_LOCAL_DH_DEFAULT_PARAMS_STR = "threadlocaldhdefaultparams";
+ private static final String DH_DEFAULT_PARAMS_STR = "dhdefaultparams";
+ private static final String ACCEPTABLE_EC_CURVES_STR = "acceptableeccurves";
+ private static final String ADDITIONAL_EC_PARAMETERS_STR = "additionalecparameters";
+ private static final String ALL_STR = "all";
+
+ private final String actions;
+ private final int permissionMask;
+
+ public ProviderConfigurationPermission(String name)
+ {
+ super(name);
+ this.actions = "all";
+ this.permissionMask = ALL;
+ }
+
+ public ProviderConfigurationPermission(String name, String actions)
+ {
+ super(name, actions);
+ this.actions = actions;
+ this.permissionMask = calculateMask(actions);
+ }
+
+ private int calculateMask(
+ String actions)
+ {
+ StringTokenizer tok = new StringTokenizer(Strings.toLowerCase(actions), " ,");
+ int mask = 0;
+
+ while (tok.hasMoreTokens())
+ {
+ String s = tok.nextToken();
+
+ if (s.equals(THREAD_LOCAL_EC_IMPLICITLY_CA_STR))
+ {
+ mask |= THREAD_LOCAL_EC_IMPLICITLY_CA;
+ }
+ else if (s.equals(EC_IMPLICITLY_CA_STR))
+ {
+ mask |= EC_IMPLICITLY_CA;
+ }
+ else if (s.equals(THREAD_LOCAL_DH_DEFAULT_PARAMS_STR))
+ {
+ mask |= THREAD_LOCAL_DH_DEFAULT_PARAMS;
+ }
+ else if (s.equals(DH_DEFAULT_PARAMS_STR))
+ {
+ mask |= DH_DEFAULT_PARAMS;
+ }
+ else if (s.equals(ACCEPTABLE_EC_CURVES_STR))
+ {
+ mask |= ACCEPTABLE_EC_CURVES;
+ }
+ else if (s.equals(ADDITIONAL_EC_PARAMETERS_STR))
+ {
+ mask |= ADDITIONAL_EC_PARAMETERS;
+ }
+ else if (s.equals(ALL_STR))
+ {
+ mask |= ALL;
+ }
+ }
+
+ if (mask == 0)
+ {
+ throw new IllegalArgumentException("unknown permissions passed to mask");
+ }
+
+ return mask;
+ }
+
+ public String getActions()
+ {
+ return actions;
+ }
+
+ public boolean implies(
+ Permission permission)
+ {
+ if (!(permission instanceof ProviderConfigurationPermission))
+ {
+ return false;
+ }
+
+ if (!this.getName().equals(permission.getName()))
+ {
+ return false;
+ }
+
+ ProviderConfigurationPermission other = (ProviderConfigurationPermission)permission;
+
+ return (this.permissionMask & other.permissionMask) == other.permissionMask;
+ }
+
+ public boolean equals(
+ Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (obj instanceof ProviderConfigurationPermission)
+ {
+ ProviderConfigurationPermission other = (ProviderConfigurationPermission)obj;
+
+ return this.permissionMask == other.permissionMask && this.getName().equals(other.getName());
+ }
+
+ return false;
+ }
+
+ public int hashCode()
+ {
+ return this.getName().hashCode() + this.permissionMask;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
new file mode 100644
index 00000000..da100c13
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
@@ -0,0 +1,72 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.digest;
+
+import java.security.MessageDigest;
+
+import com.android.internal.org.bouncycastle.crypto.Digest;
+// BEGIN Android-removed:
+// import org.bouncycastle.crypto.Xof;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCMessageDigest
+ extends MessageDigest
+{
+ protected Digest digest;
+ protected int digestSize;
+
+ protected BCMessageDigest(
+ Digest digest)
+ {
+ super(digest.getAlgorithmName());
+
+ this.digest = digest;
+ this.digestSize = digest.getDigestSize();
+ }
+
+ // BEGIN Android-removed:
+ /*
+ protected BCMessageDigest(
+ Xof digest, int outputSize)
+ {
+ super(digest.getAlgorithmName());
+
+ this.digest = digest;
+ this.digestSize = outputSize / 8;
+ }
+ */
+ // END Android-removed:
+ public void engineReset()
+ {
+ digest.reset();
+ }
+
+ public void engineUpdate(
+ byte input)
+ {
+ digest.update(input);
+ }
+
+ public void engineUpdate(
+ byte[] input,
+ int offset,
+ int len)
+ {
+ digest.update(input, offset, len);
+ }
+
+ public int engineGetDigestLength()
+ {
+ return digestSize;
+ }
+
+ public byte[] engineDigest()
+ {
+ byte[] digestBytes = new byte[digestSize];
+
+ digest.doFinal(digestBytes, 0);
+
+ return digestBytes;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java
new file mode 100644
index 00000000..b89a44e6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/DigestAlgorithmProvider.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.digest;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
+
+abstract class DigestAlgorithmProvider
+ extends AlgorithmProvider
+{
+ protected void addHMACAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String algorithmClassName,
+ String keyGeneratorClassName)
+ {
+ String mainName = "HMAC" + algorithm;
+
+ provider.addAlgorithm("Mac." + mainName, algorithmClassName);
+ provider.addAlgorithm("Alg.Alias.Mac.HMAC-" + algorithm, mainName);
+ provider.addAlgorithm("Alg.Alias.Mac.HMAC/" + algorithm, mainName);
+ provider.addAlgorithm("KeyGenerator." + mainName, keyGeneratorClassName);
+ provider.addAlgorithm("Alg.Alias.KeyGenerator.HMAC-" + algorithm, mainName);
+ provider.addAlgorithm("Alg.Alias.KeyGenerator.HMAC/" + algorithm, mainName);
+ }
+
+ protected void addHMACAlias(
+ ConfigurableProvider provider,
+ String algorithm,
+ ASN1ObjectIdentifier oid)
+ {
+ String mainName = "HMAC" + algorithm;
+
+ provider.addAlgorithm("Alg.Alias.Mac." + oid, mainName);
+ provider.addAlgorithm("Alg.Alias.KeyGenerator." + oid, mainName);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/MD5.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/MD5.java
new file mode 100644
index 00000000..86584a12
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/MD5.java
@@ -0,0 +1,95 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.digest;
+
+import com.android.internal.org.bouncycastle.asn1.iana.IANAObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.digests.MD5Digest;
+import com.android.internal.org.bouncycastle.crypto.macs.HMac;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class MD5
+{
+ private MD5()
+ {
+
+ }
+
+ /**
+ * MD5 HashMac
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class HashMac
+ extends BaseMac
+ {
+ public HashMac()
+ {
+ super(new HMac(new MD5Digest()));
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyGenerator
+ extends BaseKeyGenerator
+ {
+ public KeyGenerator()
+ {
+ super("HMACMD5", 128, new CipherKeyGenerator());
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class Digest
+ extends BCMessageDigest
+ implements Cloneable
+ {
+ public Digest()
+ {
+ super(new MD5Digest());
+ }
+
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ Digest d = (Digest)super.clone();
+ d.digest = new MD5Digest((MD5Digest)digest);
+
+ return d;
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends DigestAlgorithmProvider
+ {
+ private static final String PREFIX = MD5.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
+ provider.addAlgorithm("MessageDigest.MD5", PREFIX + "$Digest");
+ provider.addAlgorithm("Alg.Alias.MessageDigest." + PKCSObjectIdentifiers.md5, "MD5");
+
+ addHMACAlgorithm(provider, "MD5", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
+ addHMACAlias(provider, "MD5", IANAObjectIdentifiers.hmacMD5);
+ */
+ // END Android-removed: Unsupported algorithm
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA1.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA1.java
new file mode 100644
index 00000000..da2136d6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA1.java
@@ -0,0 +1,134 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.digest;
+
+import com.android.internal.org.bouncycastle.asn1.iana.IANAObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.digests.SHA1Digest;
+import com.android.internal.org.bouncycastle.crypto.macs.HMac;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SHA1
+{
+ private SHA1()
+ {
+
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class Digest
+ extends BCMessageDigest
+ implements Cloneable
+ {
+ public Digest()
+ {
+ super(new SHA1Digest());
+ }
+
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ Digest d = (Digest)super.clone();
+ d.digest = new SHA1Digest((SHA1Digest)digest);
+
+ return d;
+ }
+ }
+
+ /**
+ * SHA1 HMac
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class HashMac
+ extends BaseMac
+ {
+ public HashMac()
+ {
+ super(new HMac(new SHA1Digest()));
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyGenerator
+ extends BaseKeyGenerator
+ {
+ public KeyGenerator()
+ {
+ super("HMACSHA1", 160, new CipherKeyGenerator());
+ }
+ }
+
+ /**
+ * SHA1 HMac
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class SHA1Mac
+ extends BaseMac
+ {
+ public SHA1Mac()
+ {
+ super(new HMac(new SHA1Digest()));
+ }
+ }
+
+ /**
+ * PBEWithHmacSHA
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithMacKeyFactory
+ extends PBESecretKeyFactory
+ {
+ public PBEWithMacKeyFactory()
+ {
+ super("PBEwithHmacSHA", null, false, PKCS12, SHA1, 160, 0);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends DigestAlgorithmProvider
+ {
+ private static final String PREFIX = SHA1.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // BEGIN Android-removed: Unsupported algorithm
+ /*
+ provider.addAlgorithm("MessageDigest.SHA-1", PREFIX + "$Digest");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA1", "SHA-1");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA", "SHA-1");
+ provider.addAlgorithm("Alg.Alias.MessageDigest." + OIWObjectIdentifiers.idSHA1, "SHA-1");
+
+ addHMACAlgorithm(provider, "SHA1", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
+ addHMACAlias(provider, "SHA1", PKCSObjectIdentifiers.id_hmacWithSHA1);
+ addHMACAlias(provider, "SHA1", IANAObjectIdentifiers.hmacSHA1);
+ */
+ // END Android-removed: Unsupported algorithm
+
+ provider.addAlgorithm("Mac.PBEWITHHMACSHA", PREFIX + "$SHA1Mac");
+ provider.addAlgorithm("Mac.PBEWITHHMACSHA1", PREFIX + "$SHA1Mac");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHHMACSHA", "PBEWITHHMACSHA1");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + OIWObjectIdentifiers.idSHA1, "PBEWITHHMACSHA1");
+ provider.addAlgorithm("Alg.Alias.Mac." + OIWObjectIdentifiers.idSHA1, "PBEWITHHMACSHA");
+
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHHMACSHA1", PREFIX + "$PBEWithMacKeyFactory");
+ }
+ }
+}
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
new file mode 100644
index 00000000..5b5d9511
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA224.java
@@ -0,0 +1,97 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.digest;
+
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.digests.SHA224Digest;
+import com.android.internal.org.bouncycastle.crypto.macs.HMac;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SHA224
+{
+ private SHA224()
+ {
+
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class Digest
+ extends BCMessageDigest
+ implements Cloneable
+ {
+ public Digest()
+ {
+ super(new SHA224Digest());
+ }
+
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ Digest d = (Digest)super.clone();
+ d.digest = new SHA224Digest((SHA224Digest)digest);
+
+ return d;
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class HashMac
+ extends BaseMac
+ {
+ public HashMac()
+ {
+ super(new HMac(new SHA224Digest()));
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyGenerator
+ extends BaseKeyGenerator
+ {
+ public KeyGenerator()
+ {
+ super("HMACSHA224", 224, new CipherKeyGenerator());
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends DigestAlgorithmProvider
+ {
+ private static final String PREFIX = SHA224.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("MessageDigest.SHA-224", PREFIX + "$Digest");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA224", "SHA-224");
+ provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha224, "SHA-224");
+
+ provider.addAlgorithm("Mac.PBEWITHHMACSHA224", PREFIX + "$HashMac");
+
+ addHMACAlgorithm(provider, "SHA224", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
+ addHMACAlias(provider, "SHA224", PKCSObjectIdentifiers.id_hmacWithSHA224);
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+ }
+}
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
new file mode 100644
index 00000000..929364f5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA256.java
@@ -0,0 +1,120 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.digest;
+
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.digests.SHA256Digest;
+import com.android.internal.org.bouncycastle.crypto.macs.HMac;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SHA256
+{
+ private SHA256()
+ {
+
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class Digest
+ extends BCMessageDigest
+ implements Cloneable
+ {
+ public Digest()
+ {
+ super(new SHA256Digest());
+ }
+
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ Digest d = (Digest)super.clone();
+ d.digest = new SHA256Digest((SHA256Digest)digest);
+
+ return d;
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class HashMac
+ extends BaseMac
+ {
+ public HashMac()
+ {
+ super(new HMac(new SHA256Digest()));
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ /**
+ * PBEWithHmacSHA
+ *
+ public static class PBEWithMacKeyFactory
+ extends PBESecretKeyFactory
+ {
+ public PBEWithMacKeyFactory()
+ {
+ super("PBEwithHmacSHA256", null, false, PKCS12, SHA256, 256, 0);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * HMACSHA256
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyGenerator
+ extends BaseKeyGenerator
+ {
+ public KeyGenerator()
+ {
+ super("HMACSHA256", 256, new CipherKeyGenerator());
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends DigestAlgorithmProvider
+ {
+ private static final String PREFIX = SHA256.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("MessageDigest.SHA-256", PREFIX + "$Digest");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA256", "SHA-256");
+ provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha256, "SHA-256");
+
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHHMACSHA256", PREFIX + "$PBEWithMacKeyFactory");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHHMACSHA-256", "PBEWITHHMACSHA256");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + NISTObjectIdentifiers.id_sha256, "PBEWITHHMACSHA256");
+
+ provider.addAlgorithm("Mac.PBEWITHHMACSHA256", PREFIX + "$HashMac");
+
+ addHMACAlgorithm(provider, "SHA256", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
+ addHMACAlias(provider, "SHA256", PKCSObjectIdentifiers.id_hmacWithSHA256);
+ addHMACAlias(provider, "SHA256", NISTObjectIdentifiers.id_sha256);
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+ }
+}
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
new file mode 100644
index 00000000..89d14437
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA384.java
@@ -0,0 +1,114 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.digest;
+
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.digests.SHA384Digest;
+import com.android.internal.org.bouncycastle.crypto.macs.HMac;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.macs.OldHMac;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SHA384
+{
+ private SHA384()
+ {
+
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class Digest
+ extends BCMessageDigest
+ implements Cloneable
+ {
+ public Digest()
+ {
+ super(new SHA384Digest());
+ }
+
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ Digest d = (Digest)super.clone();
+ d.digest = new SHA384Digest((SHA384Digest)digest);
+
+ return d;
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class HashMac
+ extends BaseMac
+ {
+ public HashMac()
+ {
+ super(new HMac(new SHA384Digest()));
+ }
+ }
+
+ /**
+ * HMACSHA384
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyGenerator
+ extends BaseKeyGenerator
+ {
+ public KeyGenerator()
+ {
+ super("HMACSHA384", 384, new CipherKeyGenerator());
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class OldSHA384
+ extends BaseMac
+ {
+ public OldSHA384()
+ {
+ super(new OldHMac(new SHA384Digest()));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends DigestAlgorithmProvider
+ {
+ private static final String PREFIX = SHA384.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("MessageDigest.SHA-384", PREFIX + "$Digest");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA384", "SHA-384");
+ provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha384, "SHA-384");
+ provider.addAlgorithm("Mac.OLDHMACSHA384", PREFIX + "$OldSHA384");
+
+ provider.addAlgorithm("Mac.PBEWITHHMACSHA384", PREFIX + "$HashMac");
+
+ addHMACAlgorithm(provider, "SHA384", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
+ addHMACAlias(provider, "SHA384", PKCSObjectIdentifiers.id_hmacWithSHA384);
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+ }
+}
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
new file mode 100644
index 00000000..b726dbf8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/SHA512.java
@@ -0,0 +1,213 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.digest;
+
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.digests.SHA512Digest;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.digests.SHA512tDigest;
+import com.android.internal.org.bouncycastle.crypto.macs.HMac;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.macs.OldHMac;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SHA512
+{
+ private SHA512()
+ {
+
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class Digest
+ extends BCMessageDigest
+ implements Cloneable
+ {
+ public Digest()
+ {
+ super(new SHA512Digest());
+ }
+
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ Digest d = (Digest)super.clone();
+ d.digest = new SHA512Digest((SHA512Digest)digest);
+
+ return d;
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ static public class DigestT
+ extends BCMessageDigest
+ implements Cloneable
+ {
+ public DigestT(int bitLength)
+ {
+ super(new SHA512tDigest(bitLength));
+ }
+
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ DigestT d = (DigestT)super.clone();
+ d.digest = new SHA512tDigest((SHA512tDigest)digest);
+
+ return d;
+ }
+ }
+
+ static public class DigestT224
+ extends DigestT
+ {
+ public DigestT224()
+ {
+ super(224);
+ }
+ }
+
+ static public class DigestT256
+ extends DigestT
+ {
+ public DigestT256()
+ {
+ super(256);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class HashMac
+ extends BaseMac
+ {
+ public HashMac()
+ {
+ super(new HMac(new SHA512Digest()));
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class HashMacT224
+ extends BaseMac
+ {
+ public HashMacT224()
+ {
+ super(new HMac(new SHA512tDigest(224)));
+ }
+ }
+
+ public static class HashMacT256
+ extends BaseMac
+ {
+ public HashMacT256()
+ {
+ super(new HMac(new SHA512tDigest(256)));
+ }
+ }
+
+ /**
+ * SHA-512 HMac
+ *
+ public static class OldSHA512
+ extends BaseMac
+ {
+ public OldSHA512()
+ {
+ super(new OldHMac(new SHA512Digest()));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * HMACSHA512
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyGenerator
+ extends BaseKeyGenerator
+ {
+ public KeyGenerator()
+ {
+ super("HMACSHA512", 512, new CipherKeyGenerator());
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class KeyGeneratorT224
+ extends BaseKeyGenerator
+ {
+ public KeyGeneratorT224()
+ {
+ super("HMACSHA512/224", 224, new CipherKeyGenerator());
+ }
+ }
+
+ public static class KeyGeneratorT256
+ extends BaseKeyGenerator
+ {
+ public KeyGeneratorT256()
+ {
+ super("HMACSHA512/256", 256, new CipherKeyGenerator());
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends DigestAlgorithmProvider
+ {
+ private static final String PREFIX = SHA512.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("MessageDigest.SHA-512", PREFIX + "$Digest");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512", "SHA-512");
+ provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512, "SHA-512");
+
+ provider.addAlgorithm("MessageDigest.SHA-512/224", PREFIX + "$DigestT224");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512/224", "SHA-512/224");
+ provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512_224, "SHA-512/224");
+
+ provider.addAlgorithm("MessageDigest.SHA-512/256", PREFIX + "$DigestT256");
+ provider.addAlgorithm("Alg.Alias.MessageDigest.SHA512256", "SHA-512/256");
+ provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha512_256, "SHA-512/256");
+
+ provider.addAlgorithm("Mac.OLDHMACSHA512", PREFIX + "$OldSHA512");
+
+ provider.addAlgorithm("Mac.PBEWITHHMACSHA512", PREFIX + "$HashMac");
+
+ addHMACAlgorithm(provider, "SHA512", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
+ addHMACAlias(provider, "SHA512", PKCSObjectIdentifiers.id_hmacWithSHA512);
+
+ addHMACAlgorithm(provider, "SHA512/224", PREFIX + "$HashMacT224", PREFIX + "$KeyGeneratorT224");
+ addHMACAlgorithm(provider, "SHA512/256", PREFIX + "$HashMacT256", PREFIX + "$KeyGeneratorT256");
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+ }
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/BC.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/BC.java
new file mode 100644
index 00000000..1cfc6160
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/BC.java
@@ -0,0 +1,35 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.keystore;
+
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BC
+{
+ private static final String PREFIX = "com.android.internal.org.bouncycastle.jcajce.provider.keystore" + ".bc.";
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("KeyStore.BKS", PREFIX + "BcKeyStoreSpi$Std");
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("KeyStore.BKS-V1", PREFIX + "BcKeyStoreSpi$Version1");
+ provider.addAlgorithm("KeyStore.BouncyCastle", PREFIX + "BcKeyStoreSpi$BouncyCastleStore");
+ provider.addAlgorithm("Alg.Alias.KeyStore.UBER", "BouncyCastle");
+ provider.addAlgorithm("Alg.Alias.KeyStore.BOUNCYCASTLE", "BouncyCastle");
+ provider.addAlgorithm("Alg.Alias.KeyStore.bouncycastle", "BouncyCastle");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/PKCS12.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/PKCS12.java
new file mode 100644
index 00000000..e0f800d2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/PKCS12.java
@@ -0,0 +1,41 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.keystore;
+
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS12
+{
+ private static final String PREFIX = "com.android.internal.org.bouncycastle.jcajce.provider.keystore" + ".pkcs12.";
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AsymmetricAlgorithmProvider
+ {
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("KeyStore.PKCS12", PREFIX + "PKCS12KeyStoreSpi$BCPKCS12KeyStore");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("KeyStore.BCPKCS12", PREFIX + "PKCS12KeyStoreSpi$BCPKCS12KeyStore");
+ provider.addAlgorithm("KeyStore.PKCS12-DEF", PREFIX + "PKCS12KeyStoreSpi$DefPKCS12KeyStore");
+
+ provider.addAlgorithm("KeyStore.PKCS12-3DES-40RC2", PREFIX + "PKCS12KeyStoreSpi$BCPKCS12KeyStore");
+ provider.addAlgorithm("KeyStore.PKCS12-3DES-3DES", PREFIX + "PKCS12KeyStoreSpi$BCPKCS12KeyStore3DES");
+
+ provider.addAlgorithm("KeyStore.PKCS12-DEF-3DES-40RC2", PREFIX + "PKCS12KeyStoreSpi$DefPKCS12KeyStore");
+ provider.addAlgorithm("KeyStore.PKCS12-DEF-3DES-3DES", PREFIX + "PKCS12KeyStoreSpi$DefPKCS12KeyStore3DES");
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
new file mode 100644
index 00000000..44be654a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
@@ -0,0 +1,1100 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.keystore.bc;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.CipherOutputStream;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.PBEParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.digests.SHA1Digest;
+import com.android.internal.org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.io.DigestInputStream;
+import com.android.internal.org.bouncycastle.crypto.io.DigestOutputStream;
+import com.android.internal.org.bouncycastle.crypto.io.MacInputStream;
+import com.android.internal.org.bouncycastle.crypto.io.MacOutputStream;
+import com.android.internal.org.bouncycastle.crypto.macs.HMac;
+// Android-changed: Use default provider for JCA algorithms instead of BC
+// Was: import org.bouncycastle.jcajce.util.BCJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+// import org.bouncycastle.jcajce.io.CipherInputStream;
+// import org.bouncycastle.jcajce.io.CipherOutputStream;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.jce.interfaces.BCKeyStore;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.io.Streams;
+import com.android.internal.org.bouncycastle.util.io.TeeOutputStream;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BcKeyStoreSpi
+ extends KeyStoreSpi
+ implements BCKeyStore
+{
+ private static final int STORE_VERSION = 2;
+
+ private static final int STORE_SALT_SIZE = 20;
+ private static final String STORE_CIPHER = "PBEWithSHAAndTwofish-CBC";
+
+ private static final int KEY_SALT_SIZE = 20;
+ private static final int MIN_ITERATIONS = 1024;
+
+ private static final String KEY_CIPHER = "PBEWithSHAAnd3-KeyTripleDES-CBC";
+
+ //
+ // generic object types
+ //
+ static final int NULL = 0;
+ static final int CERTIFICATE = 1;
+ static final int KEY = 2;
+ static final int SECRET = 3;
+ static final int SEALED = 4;
+
+ //
+ // key types
+ //
+ static final int KEY_PRIVATE = 0;
+ static final int KEY_PUBLIC = 1;
+ static final int KEY_SECRET = 2;
+
+ protected Hashtable table = new Hashtable();
+
+ protected SecureRandom random = CryptoServicesRegistrar.getSecureRandom();
+
+ protected int version;
+
+ // Android-changed: Use default provider for JCA algorithms instead of BC
+ // Was: private final JcaJceHelper helper = new BCJcaJceHelper();
+ private final JcaJceHelper helper = new DefaultJcaJceHelper();
+
+ public BcKeyStoreSpi(int version)
+ {
+ this.version = version;
+ }
+
+ private class StoreEntry
+ {
+ int type;
+ String alias;
+ Object obj;
+ Certificate[] certChain;
+ Date date = new Date();
+
+ StoreEntry(
+ String alias,
+ Certificate obj)
+ {
+ this.type = CERTIFICATE;
+ this.alias = alias;
+ this.obj = obj;
+ this.certChain = null;
+ }
+
+ StoreEntry(
+ String alias,
+ byte[] obj,
+ Certificate[] certChain)
+ {
+ this.type = SECRET;
+ this.alias = alias;
+ this.obj = obj;
+ this.certChain = certChain;
+ }
+
+ StoreEntry(
+ String alias,
+ Key key,
+ char[] password,
+ Certificate[] certChain)
+ throws Exception
+ {
+ this.type = SEALED;
+ this.alias = alias;
+ this.certChain = certChain;
+
+ byte[] salt = new byte[KEY_SALT_SIZE];
+
+ random.nextBytes(salt);
+
+ int iterationCount = MIN_ITERATIONS + (random.nextInt() & 0x3ff);
+
+
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ DataOutputStream dOut = new DataOutputStream(bOut);
+
+ dOut.writeInt(salt.length);
+ dOut.write(salt);
+ dOut.writeInt(iterationCount);
+
+ Cipher cipher = makePBECipher(KEY_CIPHER, Cipher.ENCRYPT_MODE, password, salt, iterationCount);
+ CipherOutputStream cOut = new CipherOutputStream(dOut, cipher);
+
+ dOut = new DataOutputStream(cOut);
+
+ encodeKey(key, dOut);
+
+ dOut.close();
+
+ obj = bOut.toByteArray();
+ }
+
+ StoreEntry(
+ String alias,
+ Date date,
+ int type,
+ Object obj)
+ {
+ this.alias = alias;
+ this.date = date;
+ this.type = type;
+ this.obj = obj;
+ }
+
+ StoreEntry(
+ String alias,
+ Date date,
+ int type,
+ Object obj,
+ Certificate[] certChain)
+ {
+ this.alias = alias;
+ this.date = date;
+ this.type = type;
+ this.obj = obj;
+ this.certChain = certChain;
+ }
+
+ int getType()
+ {
+ return type;
+ }
+
+ String getAlias()
+ {
+ return alias;
+ }
+
+ Object getObject()
+ {
+ return obj;
+ }
+
+ Object getObject(
+ char[] password)
+ throws NoSuchAlgorithmException, UnrecoverableKeyException
+ {
+ if (password == null || password.length == 0)
+ {
+ if (obj instanceof Key)
+ {
+ return obj;
+ }
+ }
+
+ if (type == SEALED)
+ {
+ ByteArrayInputStream bIn = new ByteArrayInputStream((byte[])obj);
+ DataInputStream dIn = new DataInputStream(bIn);
+
+ try
+ {
+ byte[] salt = new byte[dIn.readInt()];
+
+ dIn.readFully(salt);
+
+ int iterationCount = dIn.readInt();
+
+ Cipher cipher = makePBECipher(KEY_CIPHER, Cipher.DECRYPT_MODE, password, salt, iterationCount);
+
+ CipherInputStream cIn = new CipherInputStream(dIn, cipher);
+
+ try
+ {
+ return decodeKey(new DataInputStream(cIn));
+ }
+ catch (Exception x)
+ {
+ bIn = new ByteArrayInputStream((byte[])obj);
+ dIn = new DataInputStream(bIn);
+
+ salt = new byte[dIn.readInt()];
+
+ dIn.readFully(salt);
+
+ iterationCount = dIn.readInt();
+
+ cipher = makePBECipher("Broken" + KEY_CIPHER, Cipher.DECRYPT_MODE, password, salt, iterationCount);
+
+ cIn = new CipherInputStream(dIn, cipher);
+
+ Key k = null;
+
+ try
+ {
+ k = decodeKey(new DataInputStream(cIn));
+ }
+ catch (Exception y)
+ {
+ bIn = new ByteArrayInputStream((byte[])obj);
+ dIn = new DataInputStream(bIn);
+
+ salt = new byte[dIn.readInt()];
+
+ dIn.readFully(salt);
+
+ iterationCount = dIn.readInt();
+
+ cipher = makePBECipher("Old" + KEY_CIPHER, Cipher.DECRYPT_MODE, password, salt, iterationCount);
+
+ cIn = new CipherInputStream(dIn, cipher);
+
+ k = decodeKey(new DataInputStream(cIn));
+ }
+
+ //
+ // reencrypt key with correct cipher.
+ //
+ if (k != null)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ DataOutputStream dOut = new DataOutputStream(bOut);
+
+ dOut.writeInt(salt.length);
+ dOut.write(salt);
+ dOut.writeInt(iterationCount);
+
+ Cipher out = makePBECipher(KEY_CIPHER, Cipher.ENCRYPT_MODE, password, salt, iterationCount);
+ CipherOutputStream cOut = new CipherOutputStream(dOut, out);
+
+ dOut = new DataOutputStream(cOut);
+
+ encodeKey(k, dOut);
+
+ dOut.close();
+
+ obj = bOut.toByteArray();
+
+ return k;
+ }
+ else
+ {
+ throw new UnrecoverableKeyException("no match");
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw new UnrecoverableKeyException("no match");
+ }
+ }
+ else
+ {
+ throw new RuntimeException("forget something!");
+ // TODO
+ // if we get to here key was saved as byte data, which
+ // according to the docs means it must be a private key
+ // in EncryptedPrivateKeyInfo (PKCS8 format), later...
+ //
+ }
+ }
+
+ Certificate[] getCertificateChain()
+ {
+ return certChain;
+ }
+
+ Date getDate()
+ {
+ return date;
+ }
+ }
+
+ private void encodeCertificate(
+ Certificate cert,
+ DataOutputStream dOut)
+ throws IOException
+ {
+ try
+ {
+ byte[] cEnc = cert.getEncoded();
+
+ dOut.writeUTF(cert.getType());
+ dOut.writeInt(cEnc.length);
+ dOut.write(cEnc);
+ }
+ catch (CertificateEncodingException ex)
+ {
+ throw new IOException(ex.toString());
+ }
+ }
+
+ private Certificate decodeCertificate(
+ DataInputStream dIn)
+ throws IOException
+ {
+ String type = dIn.readUTF();
+ byte[] cEnc = new byte[dIn.readInt()];
+
+ dIn.readFully(cEnc);
+
+ try
+ {
+ CertificateFactory cFact = helper.createCertificateFactory(type);
+ ByteArrayInputStream bIn = new ByteArrayInputStream(cEnc);
+
+ return cFact.generateCertificate(bIn);
+ }
+ catch (NoSuchProviderException ex)
+ {
+ throw new IOException(ex.toString());
+ }
+ catch (CertificateException ex)
+ {
+ throw new IOException(ex.toString());
+ }
+ }
+
+ private void encodeKey(
+ Key key,
+ DataOutputStream dOut)
+ throws IOException
+ {
+ byte[] enc = key.getEncoded();
+
+ if (key instanceof PrivateKey)
+ {
+ dOut.write(KEY_PRIVATE);
+ }
+ else if (key instanceof PublicKey)
+ {
+ dOut.write(KEY_PUBLIC);
+ }
+ else
+ {
+ dOut.write(KEY_SECRET);
+ }
+
+ dOut.writeUTF(key.getFormat());
+ dOut.writeUTF(key.getAlgorithm());
+ dOut.writeInt(enc.length);
+ dOut.write(enc);
+ }
+
+ private Key decodeKey(
+ DataInputStream dIn)
+ throws IOException
+ {
+ int keyType = dIn.read();
+ String format = dIn.readUTF();
+ String algorithm = dIn.readUTF();
+ byte[] enc = new byte[dIn.readInt()];
+ KeySpec spec;
+
+ dIn.readFully(enc);
+
+ if (format.equals("PKCS#8") || format.equals("PKCS8"))
+ {
+ spec = new PKCS8EncodedKeySpec(enc);
+ }
+ else if (format.equals("X.509") || format.equals("X509"))
+ {
+ spec = new X509EncodedKeySpec(enc);
+ }
+ else if (format.equals("RAW"))
+ {
+ return new SecretKeySpec(enc, algorithm);
+ }
+ else
+ {
+ throw new IOException("Key format " + format + " not recognised!");
+ }
+
+ try
+ {
+ switch (keyType)
+ {
+ case KEY_PRIVATE:
+ return BouncyCastleProvider.getPrivateKey(PrivateKeyInfo.getInstance(enc));
+ case KEY_PUBLIC:
+ return BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(enc));
+ case KEY_SECRET:
+ return helper.createSecretKeyFactory(algorithm).generateSecret(spec);
+ default:
+ throw new IOException("Key type " + keyType + " not recognised!");
+ }
+ }
+ catch (Exception e)
+ {
+ throw new IOException("Exception creating key: " + e.toString());
+ }
+ }
+
+ protected Cipher makePBECipher(
+ String algorithm,
+ int mode,
+ char[] password,
+ byte[] salt,
+ int iterationCount)
+ throws IOException
+ {
+ try
+ {
+ PBEKeySpec pbeSpec = new PBEKeySpec(password);
+ SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm);
+ PBEParameterSpec defParams = new PBEParameterSpec(salt, iterationCount);
+
+ Cipher cipher = helper.createCipher(algorithm);
+
+ cipher.init(mode, keyFact.generateSecret(pbeSpec), defParams);
+
+ return cipher;
+ }
+ catch (Exception e)
+ {
+ throw new IOException("Error initialising store of key store: " + e);
+ }
+ }
+
+ public void setRandom(
+ SecureRandom rand)
+ {
+ this.random = rand;
+ }
+
+ public Enumeration engineAliases()
+ {
+ return table.keys();
+ }
+
+ public boolean engineContainsAlias(
+ String alias)
+ {
+ return (table.get(alias) != null);
+ }
+
+ public void engineDeleteEntry(
+ String alias)
+ throws KeyStoreException
+ {
+ Object entry = table.get(alias);
+
+ if (entry == null)
+ {
+ return;
+ }
+
+ table.remove(alias);
+ }
+
+ public Certificate engineGetCertificate(
+ String alias)
+ {
+ StoreEntry entry = (StoreEntry)table.get(alias);
+
+ if (entry != null)
+ {
+ if (entry.getType() == CERTIFICATE)
+ {
+ return (Certificate)entry.getObject();
+ }
+ else
+ {
+ Certificate[] chain = entry.getCertificateChain();
+
+ if (chain != null)
+ {
+ return chain[0];
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public String engineGetCertificateAlias(
+ Certificate cert)
+ {
+ Enumeration e = table.elements();
+ while (e.hasMoreElements())
+ {
+ StoreEntry entry = (StoreEntry)e.nextElement();
+
+ if (entry.getObject() instanceof Certificate)
+ {
+ Certificate c = (Certificate)entry.getObject();
+
+ if (c.equals(cert))
+ {
+ return entry.getAlias();
+ }
+ }
+ else
+ {
+ Certificate[] chain = entry.getCertificateChain();
+
+ if (chain != null && chain[0].equals(cert))
+ {
+ return entry.getAlias();
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public Certificate[] engineGetCertificateChain(
+ String alias)
+ {
+ StoreEntry entry = (StoreEntry)table.get(alias);
+
+ if (entry != null)
+ {
+ return entry.getCertificateChain();
+ }
+
+ return null;
+ }
+
+ public Date engineGetCreationDate(String alias)
+ {
+ StoreEntry entry = (StoreEntry)table.get(alias);
+
+ if (entry != null)
+ {
+ return entry.getDate();
+ }
+
+ return null;
+ }
+
+ public Key engineGetKey(
+ String alias,
+ char[] password)
+ throws NoSuchAlgorithmException, UnrecoverableKeyException
+ {
+ StoreEntry entry = (StoreEntry)table.get(alias);
+
+ if (entry == null || entry.getType() == CERTIFICATE)
+ {
+ return null;
+ }
+
+ return (Key)entry.getObject(password);
+ }
+
+ public boolean engineIsCertificateEntry(
+ String alias)
+ {
+ StoreEntry entry = (StoreEntry)table.get(alias);
+
+ if (entry != null && entry.getType() == CERTIFICATE)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean engineIsKeyEntry(
+ String alias)
+ {
+ StoreEntry entry = (StoreEntry)table.get(alias);
+
+ if (entry != null && entry.getType() != CERTIFICATE)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public void engineSetCertificateEntry(
+ String alias,
+ Certificate cert)
+ throws KeyStoreException
+ {
+ StoreEntry entry = (StoreEntry)table.get(alias);
+
+ if (entry != null && entry.getType() != CERTIFICATE)
+ {
+ throw new KeyStoreException("key store already has a key entry with alias " + alias);
+ }
+
+ table.put(alias, new StoreEntry(alias, cert));
+ }
+
+ public void engineSetKeyEntry(
+ String alias,
+ byte[] key,
+ Certificate[] chain)
+ throws KeyStoreException
+ {
+ table.put(alias, new StoreEntry(alias, key, chain));
+ }
+
+ public void engineSetKeyEntry(
+ String alias,
+ Key key,
+ char[] password,
+ Certificate[] chain)
+ throws KeyStoreException
+ {
+ if ((key instanceof PrivateKey) && (chain == null))
+ {
+ throw new KeyStoreException("no certificate chain for private key");
+ }
+
+ try
+ {
+ table.put(alias, new StoreEntry(alias, key, password, chain));
+ }
+ catch (Exception e)
+ {
+ throw new BCKeyStoreException(e.toString(), e);
+ }
+ }
+
+ public int engineSize()
+ {
+ return table.size();
+ }
+
+ protected void loadStore(
+ InputStream in)
+ throws IOException
+ {
+ DataInputStream dIn = new DataInputStream(in);
+ int type = dIn.read();
+
+ while (type > NULL)
+ {
+ String alias = dIn.readUTF();
+ Date date = new Date(dIn.readLong());
+ int chainLength = dIn.readInt();
+ Certificate[] chain = null;
+
+ if (chainLength != 0)
+ {
+ chain = new Certificate[chainLength];
+
+ for (int i = 0; i != chainLength; i++)
+ {
+ chain[i] = decodeCertificate(dIn);
+ }
+ }
+
+ switch (type)
+ {
+ case CERTIFICATE:
+ Certificate cert = decodeCertificate(dIn);
+
+ table.put(alias, new StoreEntry(alias, date, CERTIFICATE, cert));
+ break;
+ case KEY:
+ Key key = decodeKey(dIn);
+ table.put(alias, new StoreEntry(alias, date, KEY, key, chain));
+ break;
+ case SECRET:
+ case SEALED:
+ byte[] b = new byte[dIn.readInt()];
+
+ dIn.readFully(b);
+ table.put(alias, new StoreEntry(alias, date, type, b, chain));
+ break;
+ default:
+ throw new IOException("Unknown object type in store.");
+ }
+
+ type = dIn.read();
+ }
+ }
+
+ protected void saveStore(
+ OutputStream out)
+ throws IOException
+ {
+ Enumeration e = table.elements();
+ DataOutputStream dOut = new DataOutputStream(out);
+
+ while (e.hasMoreElements())
+ {
+ StoreEntry entry = (StoreEntry)e.nextElement();
+
+ dOut.write(entry.getType());
+ dOut.writeUTF(entry.getAlias());
+ dOut.writeLong(entry.getDate().getTime());
+
+ Certificate[] chain = entry.getCertificateChain();
+ if (chain == null)
+ {
+ dOut.writeInt(0);
+ }
+ else
+ {
+ dOut.writeInt(chain.length);
+ for (int i = 0; i != chain.length; i++)
+ {
+ encodeCertificate(chain[i], dOut);
+ }
+ }
+
+ switch (entry.getType())
+ {
+ case CERTIFICATE:
+ encodeCertificate((Certificate)entry.getObject(), dOut);
+ break;
+ case KEY:
+ encodeKey((Key)entry.getObject(), dOut);
+ break;
+ case SEALED:
+ case SECRET:
+ byte[] b = (byte[])entry.getObject();
+
+ dOut.writeInt(b.length);
+ dOut.write(b);
+ break;
+ default:
+ throw new IOException("Unknown object type in store.");
+ }
+ }
+
+ dOut.write(NULL);
+ }
+
+ public void engineLoad(
+ InputStream stream,
+ char[] password)
+ throws IOException
+ {
+ table.clear();
+
+ if (stream == null) // just initialising
+ {
+ return;
+ }
+
+ DataInputStream dIn = new DataInputStream(stream);
+ int version = dIn.readInt();
+
+ if (version != STORE_VERSION)
+ {
+ if (version != 0 && version != 1)
+ {
+ throw new IOException("Wrong version of key store.");
+ }
+ }
+
+ int saltLength = dIn.readInt();
+ if (saltLength <= 0)
+ {
+ throw new IOException("Invalid salt detected");
+ }
+
+ byte[] salt = new byte[saltLength];
+
+ dIn.readFully(salt);
+
+ int iterationCount = dIn.readInt();
+
+ //
+ // we only do an integrity check if the password is provided.
+ //
+ HMac hMac = new HMac(new SHA1Digest());
+ if (password != null && password.length != 0)
+ {
+ byte[] passKey = PBEParametersGenerator.PKCS12PasswordToBytes(password);
+
+ PBEParametersGenerator pbeGen = new PKCS12ParametersGenerator(new SHA1Digest());
+ pbeGen.init(passKey, salt, iterationCount);
+
+ CipherParameters macParams;
+
+ if (version != 2)
+ {
+ macParams = pbeGen.generateDerivedMacParameters(hMac.getMacSize());
+ }
+ else
+ {
+ macParams = pbeGen.generateDerivedMacParameters(hMac.getMacSize() * 8);
+ }
+
+ Arrays.fill(passKey, (byte)0);
+
+ hMac.init(macParams);
+ MacInputStream mIn = new MacInputStream(dIn, hMac);
+
+ loadStore(mIn);
+
+ // Finalise our mac calculation
+ byte[] mac = new byte[hMac.getMacSize()];
+ hMac.doFinal(mac, 0);
+
+ // TODO Should this actually be reading the remainder of the stream?
+ // Read the original mac from the stream
+ byte[] oldMac = new byte[hMac.getMacSize()];
+ dIn.readFully(oldMac);
+
+ if (!Arrays.constantTimeAreEqual(mac, oldMac))
+ {
+ table.clear();
+ throw new IOException("KeyStore integrity check failed.");
+ }
+ }
+ else
+ {
+ loadStore(dIn);
+
+ // TODO Should this actually be reading the remainder of the stream?
+ // Parse the original mac from the stream too
+ byte[] oldMac = new byte[hMac.getMacSize()];
+ dIn.readFully(oldMac);
+ }
+ }
+
+
+ public void engineStore(OutputStream stream, char[] password)
+ throws IOException
+ {
+ DataOutputStream dOut = new DataOutputStream(stream);
+ byte[] salt = new byte[STORE_SALT_SIZE];
+ int iterationCount = MIN_ITERATIONS + (random.nextInt() & 0x3ff);
+
+ random.nextBytes(salt);
+
+ dOut.writeInt(version);
+ dOut.writeInt(salt.length);
+ dOut.write(salt);
+ dOut.writeInt(iterationCount);
+
+ HMac hMac = new HMac(new SHA1Digest());
+ MacOutputStream mOut = new MacOutputStream(hMac);
+ PBEParametersGenerator pbeGen = new PKCS12ParametersGenerator(new SHA1Digest());
+ byte[] passKey = PBEParametersGenerator.PKCS12PasswordToBytes(password);
+
+ pbeGen.init(passKey, salt, iterationCount);
+
+ if (version < 2)
+ {
+ hMac.init(pbeGen.generateDerivedMacParameters(hMac.getMacSize()));
+ }
+ else
+ {
+ hMac.init(pbeGen.generateDerivedMacParameters(hMac.getMacSize() * 8));
+ }
+
+ for (int i = 0; i != passKey.length; i++)
+ {
+ passKey[i] = 0;
+ }
+
+ saveStore(new TeeOutputStream(dOut, mOut));
+
+ byte[] mac = new byte[hMac.getMacSize()];
+
+ hMac.doFinal(mac, 0);
+
+ dOut.write(mac);
+
+ dOut.close();
+ }
+
+ /**
+ * the BouncyCastle store. This wont work with the key tool as the
+ * store is stored encrypted on disk, so the password is mandatory,
+ * however if you hard drive is in a bad part of town and you absolutely,
+ * positively, don't want nobody peeking at your things, this is the
+ * one to use, no problem! After all in a Bouncy Castle nothing can
+ * touch you.
+ *
+ * Also referred to by the alias UBER.
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class BouncyCastleStore
+ extends BcKeyStoreSpi
+ {
+ public BouncyCastleStore()
+ {
+ super(1);
+ }
+
+ public void engineLoad(
+ InputStream stream,
+ char[] password)
+ throws IOException
+ {
+ table.clear();
+
+ if (stream == null) // just initialising
+ {
+ return;
+ }
+
+ DataInputStream dIn = new DataInputStream(stream);
+ int version = dIn.readInt();
+
+ if (version != STORE_VERSION)
+ {
+ if (version != 0 && version != 1)
+ {
+ throw new IOException("Wrong version of key store.");
+ }
+ }
+
+ byte[] salt = new byte[dIn.readInt()];
+
+ if (salt.length != STORE_SALT_SIZE)
+ {
+ throw new IOException("Key store corrupted.");
+ }
+
+ dIn.readFully(salt);
+
+ int iterationCount = dIn.readInt();
+
+ if ((iterationCount < 0) || (iterationCount > (MIN_ITERATIONS << 6)))
+ {
+ throw new IOException("Key store corrupted.");
+ }
+
+ String cipherAlg;
+ if (version == 0)
+ {
+ cipherAlg = "Old" + STORE_CIPHER;
+ }
+ else
+ {
+ cipherAlg = STORE_CIPHER;
+ }
+
+ Cipher cipher = this.makePBECipher(cipherAlg, Cipher.DECRYPT_MODE, password, salt, iterationCount);
+ CipherInputStream cIn = new CipherInputStream(dIn, cipher);
+
+ Digest dig = new SHA1Digest();
+ DigestInputStream dgIn = new DigestInputStream(cIn, dig);
+
+ this.loadStore(dgIn);
+
+ // Finalise our digest calculation
+ byte[] hash = new byte[dig.getDigestSize()];
+ dig.doFinal(hash, 0);
+
+ // TODO Should this actually be reading the remainder of the stream?
+ // Read the original digest from the stream
+ byte[] oldHash = new byte[dig.getDigestSize()];
+ Streams.readFully(cIn, oldHash);
+
+ if (!Arrays.constantTimeAreEqual(hash, oldHash))
+ {
+ table.clear();
+ throw new IOException("KeyStore integrity check failed.");
+ }
+ }
+
+ public void engineStore(OutputStream stream, char[] password)
+ throws IOException
+ {
+ Cipher cipher;
+ DataOutputStream dOut = new DataOutputStream(stream);
+ byte[] salt = new byte[STORE_SALT_SIZE];
+ int iterationCount = MIN_ITERATIONS + (random.nextInt() & 0x3ff);
+
+ random.nextBytes(salt);
+
+ dOut.writeInt(version);
+ dOut.writeInt(salt.length);
+ dOut.write(salt);
+ dOut.writeInt(iterationCount);
+
+ cipher = this.makePBECipher(STORE_CIPHER, Cipher.ENCRYPT_MODE, password, salt, iterationCount);
+
+ CipherOutputStream cOut = new CipherOutputStream(dOut, cipher);
+ DigestOutputStream dgOut = new DigestOutputStream(new SHA1Digest());
+
+ this.saveStore(new TeeOutputStream(cOut, dgOut));
+
+ byte[] dig = dgOut.getDigest();
+
+ cOut.write(dig);
+
+ cOut.close();
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Std
+ extends BcKeyStoreSpi
+ {
+ public Std()
+ {
+ super(STORE_VERSION);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Version1
+ extends BcKeyStoreSpi
+ {
+ public Version1()
+ {
+ super(1);
+ }
+ }
+
+ private static class BCKeyStoreException
+ extends KeyStoreException
+ {
+ private final Exception cause;
+
+ public BCKeyStoreException(String msg, Exception cause)
+ {
+ super(msg);
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
+}
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
new file mode 100644
index 00000000..d5897959
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
@@ -0,0 +1,1938 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.keystore.pkcs12;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStore.LoadStoreParameter;
+import java.security.KeyStore.ProtectionParameter;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.crypto.Cipher;
+import javax.crypto.Mac;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+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.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.BEROctetString;
+import com.android.internal.org.bouncycastle.asn1.BERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERBMPString;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.DERSet;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.cryptopro.GOST28147Parameters;
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+// import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.AuthenticatedSafe;
+import com.android.internal.org.bouncycastle.asn1.pkcs.CertBag;
+import com.android.internal.org.bouncycastle.asn1.pkcs.ContentInfo;
+import com.android.internal.org.bouncycastle.asn1.pkcs.EncryptedData;
+import com.android.internal.org.bouncycastle.asn1.pkcs.MacData;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PBES2Parameters;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PBKDF2Params;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCS12PBEParams;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.Pfx;
+import com.android.internal.org.bouncycastle.asn1.pkcs.SafeBag;
+import com.android.internal.org.bouncycastle.asn1.util.ASN1Dump;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.DigestInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+// Android-changed: Use Android digests
+// import org.bouncycastle.crypto.util.DigestFactory;
+import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+import com.android.internal.org.bouncycastle.jcajce.PKCS12Key;
+import com.android.internal.org.bouncycastle.jcajce.PKCS12StoreParameter;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
+import com.android.internal.org.bouncycastle.jcajce.spec.PBKDF2KeySpec;
+import com.android.internal.org.bouncycastle.jcajce.util.BCJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.jce.interfaces.BCKeyStore;
+import com.android.internal.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.jce.provider.JDKPKCS12StoreParameter;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Integers;
+import com.android.internal.org.bouncycastle.util.Properties;
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS12KeyStoreSpi
+ extends KeyStoreSpi
+ implements PKCSObjectIdentifiers, X509ObjectIdentifiers, BCKeyStore
+{
+ 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
+ // Was: private final JcaJceHelper helper = new BCJcaJceHelper();
+ private final JcaJceHelper helper = new DefaultJcaJceHelper();
+
+ private static final int SALT_SIZE = 20;
+ private static final int MIN_ITERATIONS = 50 * 1024;
+
+ private static final DefaultSecretKeyProvider keySizeProvider = new DefaultSecretKeyProvider();
+
+ private IgnoresCaseHashtable keys = new IgnoresCaseHashtable();
+ private Hashtable localIds = new Hashtable();
+ private IgnoresCaseHashtable certs = new IgnoresCaseHashtable();
+ private Hashtable chainCerts = new Hashtable();
+ private Hashtable keyCerts = new Hashtable();
+
+ //
+ // generic object types
+ //
+ static final int NULL = 0;
+ static final int CERTIFICATE = 1;
+ static final int KEY = 2;
+ static final int SECRET = 3;
+ static final int SEALED = 4;
+
+ //
+ // key types
+ //
+ static final int KEY_PRIVATE = 0;
+ static final int KEY_PUBLIC = 1;
+ static final int KEY_SECRET = 2;
+
+ protected SecureRandom random = CryptoServicesRegistrar.getSecureRandom();
+
+ // use of final causes problems with JDK 1.2 compiler
+ private CertificateFactory certFact;
+ private ASN1ObjectIdentifier keyAlgorithm;
+ private ASN1ObjectIdentifier certAlgorithm;
+
+ private AlgorithmIdentifier macAlgorithm = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
+ private int itCount = 2 * MIN_ITERATIONS;
+ private int saltLength = 20;
+
+ private class CertId
+ {
+ byte[] id;
+
+ CertId(
+ PublicKey key)
+ {
+ this.id = createSubjectKeyId(key).getKeyIdentifier();
+ }
+
+ CertId(
+ byte[] id)
+ {
+ this.id = id;
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(id);
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (!(o instanceof CertId))
+ {
+ return false;
+ }
+
+ CertId cId = (CertId)o;
+
+ return Arrays.areEqual(id, cId.id);
+ }
+ }
+
+ public PKCS12KeyStoreSpi(
+ JcaJceHelper helper,
+ ASN1ObjectIdentifier keyAlgorithm,
+ ASN1ObjectIdentifier certAlgorithm)
+ {
+ this.keyAlgorithm = keyAlgorithm;
+ this.certAlgorithm = certAlgorithm;
+
+ try
+ {
+ certFact = helper.createCertificateFactory("X.509");
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("can't create cert factory - " + e.toString());
+ }
+ }
+
+ private SubjectKeyIdentifier createSubjectKeyId(
+ PublicKey pubKey)
+ {
+ try
+ {
+ SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded());
+
+ return new SubjectKeyIdentifier(getDigest(info));
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("error creating key");
+ }
+ }
+
+ private static byte[] getDigest(SubjectPublicKeyInfo spki)
+ {
+ // Android-changed: Use Android digests
+ // Digest digest = DigestFactory.createSHA1();
+ Digest digest = AndroidDigestFactory.getSHA1();
+ byte[] resBuf = new byte[digest.getDigestSize()];
+
+ byte[] bytes = spki.getPublicKeyData().getBytes();
+ digest.update(bytes, 0, bytes.length);
+ digest.doFinal(resBuf, 0);
+ return resBuf;
+ }
+
+ public void setRandom(
+ SecureRandom rand)
+ {
+ this.random = rand;
+ }
+
+ public Enumeration engineAliases()
+ {
+ Hashtable tab = new Hashtable();
+
+ Enumeration e = certs.keys();
+ while (e.hasMoreElements())
+ {
+ tab.put(e.nextElement(), "cert");
+ }
+
+ e = keys.keys();
+ while (e.hasMoreElements())
+ {
+ String a = (String)e.nextElement();
+ if (tab.get(a) == null)
+ {
+ tab.put(a, "key");
+ }
+ }
+
+ return tab.keys();
+ }
+
+ public boolean engineContainsAlias(
+ String alias)
+ {
+ return (certs.get(alias) != null || keys.get(alias) != null);
+ }
+
+ /**
+ * this is not quite complete - we should follow up on the chain, a bit
+ * tricky if a certificate appears in more than one chain... the store method
+ * now prunes out unused certificates from the chain map if they are present.
+ */
+ public void engineDeleteEntry(
+ String alias)
+ throws KeyStoreException
+ {
+ Key k = (Key)keys.remove(alias);
+
+ Certificate c = (Certificate)certs.remove(alias);
+
+ if (c != null)
+ {
+ chainCerts.remove(new CertId(c.getPublicKey()));
+ }
+
+ if (k != null)
+ {
+ String id = (String)localIds.remove(alias);
+ if (id != null)
+ {
+ c = (Certificate)keyCerts.remove(id);
+ }
+ if (c != null)
+ {
+ chainCerts.remove(new CertId(c.getPublicKey()));
+ }
+ }
+ }
+
+ /**
+ * simply return the cert for the private key
+ */
+ public Certificate engineGetCertificate(
+ String alias)
+ {
+ if (alias == null)
+ {
+ throw new IllegalArgumentException("null alias passed to getCertificate.");
+ }
+
+ Certificate c = (Certificate)certs.get(alias);
+
+ //
+ // look up the key table - and try the local key id
+ //
+ if (c == null)
+ {
+ String id = (String)localIds.get(alias);
+ if (id != null)
+ {
+ c = (Certificate)keyCerts.get(id);
+ }
+ else
+ {
+ c = (Certificate)keyCerts.get(alias);
+ }
+ }
+
+ return c;
+ }
+
+ public String engineGetCertificateAlias(
+ Certificate cert)
+ {
+ Enumeration c = certs.elements();
+ Enumeration k = certs.keys();
+
+ while (c.hasMoreElements())
+ {
+ Certificate tc = (Certificate)c.nextElement();
+ String ta = (String)k.nextElement();
+
+ if (tc.equals(cert))
+ {
+ return ta;
+ }
+ }
+
+ c = keyCerts.elements();
+ k = keyCerts.keys();
+
+ while (c.hasMoreElements())
+ {
+ Certificate tc = (Certificate)c.nextElement();
+ String ta = (String)k.nextElement();
+
+ if (tc.equals(cert))
+ {
+ return ta;
+ }
+ }
+
+ return null;
+ }
+
+ public Certificate[] engineGetCertificateChain(
+ String alias)
+ {
+ if (alias == null)
+ {
+ throw new IllegalArgumentException("null alias passed to getCertificateChain.");
+ }
+
+ if (!engineIsKeyEntry(alias))
+ {
+ return null;
+ }
+
+ Certificate c = engineGetCertificate(alias);
+
+ if (c != null)
+ {
+ Vector cs = new Vector();
+
+ while (c != null)
+ {
+ X509Certificate x509c = (X509Certificate)c;
+ Certificate nextC = null;
+
+ byte[] akiBytes = x509c.getExtensionValue(Extension.authorityKeyIdentifier.getId());
+ if (akiBytes != null)
+ {
+ ASN1OctetString akiValue = ASN1OctetString.getInstance(akiBytes);
+ AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance(akiValue.getOctets());
+
+ byte[] keyID = aki.getKeyIdentifier();
+ if (null != keyID)
+ {
+ nextC = (Certificate)chainCerts.get(new CertId(keyID));
+ }
+ }
+
+ if (nextC == null)
+ {
+ //
+ // no authority key id, try the Issuer DN
+ //
+ Principal i = x509c.getIssuerDN();
+ Principal s = x509c.getSubjectDN();
+
+ if (!i.equals(s))
+ {
+ Enumeration e = chainCerts.keys();
+
+ while (e.hasMoreElements())
+ {
+ X509Certificate crt = (X509Certificate)chainCerts.get(e.nextElement());
+ Principal sub = crt.getSubjectDN();
+ if (sub.equals(i))
+ {
+ try
+ {
+ x509c.verify(crt.getPublicKey());
+ nextC = crt;
+ break;
+ }
+ catch (Exception ex)
+ {
+ // continue
+ }
+ }
+ }
+ }
+ }
+
+ if (cs.contains(c))
+ {
+ c = null; // we've got a certificate chain loop time to stop
+ }
+ else
+ {
+ cs.addElement(c);
+ if (nextC != c) // self signed - end of the chain
+ {
+ c = nextC;
+ }
+ else
+ {
+ c = null;
+ }
+ }
+ }
+
+ Certificate[] certChain = new Certificate[cs.size()];
+
+ for (int i = 0; i != certChain.length; i++)
+ {
+ certChain[i] = (Certificate)cs.elementAt(i);
+ }
+
+ return certChain;
+ }
+
+ return null;
+ }
+
+ public Date engineGetCreationDate(String alias)
+ {
+ if (alias == null)
+ {
+ throw new NullPointerException("alias == null");
+ }
+ if (keys.get(alias) == null && certs.get(alias) == null)
+ {
+ return null;
+ }
+ return new Date();
+ }
+
+ public Key engineGetKey(
+ String alias,
+ char[] password)
+ throws NoSuchAlgorithmException, UnrecoverableKeyException
+ {
+ if (alias == null)
+ {
+ throw new IllegalArgumentException("null alias passed to getKey.");
+ }
+
+ return (Key)keys.get(alias);
+ }
+
+ public boolean engineIsCertificateEntry(
+ String alias)
+ {
+ return (certs.get(alias) != null && keys.get(alias) == null);
+ }
+
+ public boolean engineIsKeyEntry(
+ String alias)
+ {
+ return (keys.get(alias) != null);
+ }
+
+ public void engineSetCertificateEntry(
+ String alias,
+ Certificate cert)
+ throws KeyStoreException
+ {
+ if (keys.get(alias) != null)
+ {
+ throw new KeyStoreException("There is a key entry with the name " + alias + ".");
+ }
+
+ certs.put(alias, cert);
+ chainCerts.put(new CertId(cert.getPublicKey()), cert);
+ }
+
+ public void engineSetKeyEntry(
+ String alias,
+ byte[] key,
+ Certificate[] chain)
+ throws KeyStoreException
+ {
+ throw new RuntimeException("operation not supported");
+ }
+
+ public void engineSetKeyEntry(
+ String alias,
+ Key key,
+ char[] password,
+ Certificate[] chain)
+ throws KeyStoreException
+ {
+ if (!(key instanceof PrivateKey))
+ {
+ throw new KeyStoreException("PKCS12 does not support non-PrivateKeys");
+ }
+
+ if ((key instanceof PrivateKey) && (chain == null))
+ {
+ throw new KeyStoreException("no certificate chain for private key");
+ }
+
+ if (keys.get(alias) != null)
+ {
+ engineDeleteEntry(alias);
+ }
+
+ keys.put(alias, key);
+ if (chain != null)
+ {
+ certs.put(alias, chain[0]);
+
+ for (int i = 0; i != chain.length; i++)
+ {
+ chainCerts.put(new CertId(chain[i].getPublicKey()), chain[i]);
+ }
+ }
+ }
+
+ public int engineSize()
+ {
+ Hashtable tab = new Hashtable();
+
+ Enumeration e = certs.keys();
+ while (e.hasMoreElements())
+ {
+ tab.put(e.nextElement(), "cert");
+ }
+
+ e = keys.keys();
+ while (e.hasMoreElements())
+ {
+ String a = (String)e.nextElement();
+ if (tab.get(a) == null)
+ {
+ tab.put(a, "key");
+ }
+ }
+
+ return tab.size();
+ }
+
+ protected PrivateKey unwrapKey(
+ AlgorithmIdentifier algId,
+ byte[] data,
+ char[] password,
+ boolean wrongPKCS12Zero)
+ throws IOException
+ {
+ ASN1ObjectIdentifier algorithm = algId.getAlgorithm();
+ try
+ {
+ if (algorithm.on(PKCSObjectIdentifiers.pkcs_12PbeIds))
+ {
+ PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters());
+ PBEParameterSpec defParams = new PBEParameterSpec(
+ pbeParams.getIV(),
+ validateIterationCount(pbeParams.getIterations()));
+
+ Cipher cipher = helper.createCipher(algorithm.getId());
+
+ PKCS12Key key = new PKCS12Key(password, wrongPKCS12Zero);
+
+ cipher.init(Cipher.UNWRAP_MODE, key, defParams);
+
+ // we pass "" as the key algorithm type as it is unknown at this point
+ return (PrivateKey)cipher.unwrap(data, "", Cipher.PRIVATE_KEY);
+ }
+ else if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2))
+ {
+
+ Cipher cipher = createCipher(Cipher.UNWRAP_MODE, password, algId);
+
+ // we pass "" as the key algorithm type as it is unknown at this point
+ return (PrivateKey)cipher.unwrap(data, "", Cipher.PRIVATE_KEY);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new IOException("exception unwrapping private key - " + e.toString());
+ }
+
+ throw new IOException("exception unwrapping private key - cannot recognise: " + algorithm);
+ }
+
+ protected byte[] wrapKey(
+ String algorithm,
+ Key key,
+ PKCS12PBEParams pbeParams,
+ char[] password)
+ throws IOException
+ {
+ PBEKeySpec pbeSpec = new PBEKeySpec(password);
+ byte[] out;
+
+ try
+ {
+ SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm);
+ PBEParameterSpec defParams = new PBEParameterSpec(
+ pbeParams.getIV(),
+ pbeParams.getIterations().intValue());
+
+ Cipher cipher = helper.createCipher(algorithm);
+
+ cipher.init(Cipher.WRAP_MODE, keyFact.generateSecret(pbeSpec), defParams);
+
+ out = cipher.wrap(key);
+ }
+ catch (Exception e)
+ {
+ throw new IOException("exception encrypting data - " + e.toString());
+ }
+
+ return out;
+ }
+
+ protected byte[] cryptData(
+ boolean forEncryption,
+ AlgorithmIdentifier algId,
+ char[] password,
+ boolean wrongPKCS12Zero,
+ byte[] data)
+ throws IOException
+ {
+ ASN1ObjectIdentifier algorithm = algId.getAlgorithm();
+ int mode = forEncryption ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE;
+
+ if (algorithm.on(PKCSObjectIdentifiers.pkcs_12PbeIds))
+ {
+ PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters());
+ try
+ {
+ PBEParameterSpec defParams = new PBEParameterSpec(
+ pbeParams.getIV(),
+ pbeParams.getIterations().intValue());
+ PKCS12Key key = new PKCS12Key(password, wrongPKCS12Zero);
+
+ Cipher cipher = helper.createCipher(algorithm.getId());
+
+ cipher.init(mode, key, defParams);
+ return cipher.doFinal(data);
+ }
+ catch (Exception e)
+ {
+ throw new IOException("exception decrypting data - " + e.toString());
+ }
+ }
+ else if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2))
+ {
+ try
+ {
+ Cipher cipher = createCipher(mode, password, algId);
+
+ return cipher.doFinal(data);
+ }
+ catch (Exception e)
+ {
+ throw new IOException("exception decrypting data - " + e.toString());
+ }
+ }
+ else
+ {
+ throw new IOException("unknown PBE algorithm: " + algorithm);
+ }
+ }
+
+ private Cipher createCipher(int mode, char[] password, AlgorithmIdentifier algId)
+ throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, NoSuchProviderException
+ {
+ PBES2Parameters alg = PBES2Parameters.getInstance(algId.getParameters());
+ PBKDF2Params func = PBKDF2Params.getInstance(alg.getKeyDerivationFunc().getParameters());
+ AlgorithmIdentifier encScheme = AlgorithmIdentifier.getInstance(alg.getEncryptionScheme());
+
+ SecretKeyFactory keyFact = helper.createSecretKeyFactory(alg.getKeyDerivationFunc().getAlgorithm().getId());
+ SecretKey key;
+
+ if (func.isDefaultPrf())
+ {
+ key = keyFact.generateSecret(new PBEKeySpec(password, func.getSalt(), validateIterationCount(func.getIterationCount()), keySizeProvider.getKeySize(encScheme)));
+ }
+ else
+ {
+ key = keyFact.generateSecret(new PBKDF2KeySpec(password, func.getSalt(), validateIterationCount(func.getIterationCount()), keySizeProvider.getKeySize(encScheme), func.getPrf()));
+ }
+
+ Cipher cipher = Cipher.getInstance(alg.getEncryptionScheme().getAlgorithm().getId());
+
+ ASN1Encodable encParams = alg.getEncryptionScheme().getParameters();
+ if (encParams instanceof ASN1OctetString)
+ {
+ cipher.init(mode, key, new IvParameterSpec(ASN1OctetString.getInstance(encParams).getOctets()));
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else
+ {
+ // TODO: at the moment it's just GOST, but...
+ GOST28147Parameters gParams = GOST28147Parameters.getInstance(encParams);
+
+ cipher.init(mode, key, new GOST28147ParameterSpec(gParams.getEncryptionParamSet(), gParams.getIV()));
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ return cipher;
+ }
+
+ public void engineLoad(
+ InputStream stream,
+ char[] password)
+ throws IOException
+ {
+ if (stream == null) // just initialising
+ {
+ return;
+ }
+
+ BufferedInputStream bufIn = new BufferedInputStream(stream);
+
+ bufIn.mark(10);
+
+ int head = bufIn.read();
+
+ if (head != 0x30)
+ {
+ throw new IOException("stream does not represent a PKCS12 key store");
+ }
+
+ bufIn.reset();
+
+ ASN1InputStream bIn = new ASN1InputStream(bufIn);
+
+ Pfx bag;
+ try
+ {
+ bag = Pfx.getInstance(bIn.readObject());
+ }
+ catch (Exception e)
+ {
+ throw new IOException(e.getMessage());
+ }
+
+ ContentInfo info = bag.getAuthSafe();
+ Vector chain = new Vector();
+ boolean unmarkedKey = false;
+ boolean wrongPKCS12Zero = false;
+
+ if (bag.getMacData() != null) // check the mac code
+ {
+ if (password == null)
+ {
+ throw new NullPointerException("no password supplied when one expected");
+ }
+
+ MacData mData = bag.getMacData();
+ DigestInfo dInfo = mData.getMac();
+ macAlgorithm = dInfo.getAlgorithmId();
+ byte[] salt = mData.getSalt();
+ itCount = validateIterationCount(mData.getIterationCount());
+ saltLength = salt.length;
+
+ byte[] data = ((ASN1OctetString)info.getContent()).getOctets();
+
+ try
+ {
+ byte[] res = calculatePbeMac(macAlgorithm.getAlgorithm(), salt, itCount, password, false, data);
+ byte[] dig = dInfo.getDigest();
+
+ if (!Arrays.constantTimeAreEqual(res, dig))
+ {
+ if (password.length > 0)
+ {
+ throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file.");
+ }
+
+ // Try with incorrect zero length password
+ res = calculatePbeMac(macAlgorithm.getAlgorithm(), salt, itCount, password, true, data);
+
+ if (!Arrays.constantTimeAreEqual(res, dig))
+ {
+ throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file.");
+ }
+
+ wrongPKCS12Zero = true;
+ }
+ }
+ catch (IOException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new IOException("error constructing MAC: " + e.toString());
+ }
+ }
+ // BEGIN Android-removed: keep v1.61 behaviour to keep backwards-compatibility
+ /*
+ else if (password != null)
+ {
+ if (!Properties.isOverrideSet("org.bouncycastle.pkcs12.ignore_useless_passwd"))
+ {
+ throw new IOException("password supplied for keystore that does not require one");
+ }
+ }
+ */
+ // END Android-removed: keep v1.61 behaviour to keep backwards-compatibility
+
+ keys = new IgnoresCaseHashtable();
+ localIds = new Hashtable();
+
+ if (info.getContentType().equals(data))
+ {
+ ASN1OctetString content = ASN1OctetString.getInstance(info.getContent());
+ AuthenticatedSafe authSafe = AuthenticatedSafe.getInstance(content.getOctets());
+ ContentInfo[] c = authSafe.getContentInfo();
+
+ for (int i = 0; i != c.length; i++)
+ {
+ if (c[i].getContentType().equals(data))
+ {
+ ASN1OctetString authSafeContent = ASN1OctetString.getInstance(c[i].getContent());
+ ASN1Sequence seq = ASN1Sequence.getInstance(authSafeContent.getOctets());
+
+ for (int j = 0; j != seq.size(); j++)
+ {
+ SafeBag b = SafeBag.getInstance(seq.getObjectAt(j));
+ if (b.getBagId().equals(pkcs8ShroudedKeyBag))
+ {
+ com.android.internal.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = com.android.internal.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
+ PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
+
+ //
+ // set the attributes on the key
+ //
+ String alias = null;
+ ASN1OctetString localId = null;
+
+ if (b.getBagAttributes() != null)
+ {
+ Enumeration e = b.getBagAttributes().getObjects();
+ while (e.hasMoreElements())
+ {
+ ASN1Sequence sq = (ASN1Sequence)e.nextElement();
+ ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0);
+ ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1);
+ ASN1Primitive attr = null;
+
+ if (attrSet.size() > 0)
+ {
+ attr = (ASN1Primitive)attrSet.getObjectAt(0);
+
+ if (privKey instanceof PKCS12BagAttributeCarrier)
+ {
+ PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
+ ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
+ if (existing != null)
+ {
+ // OK, but the value has to be the same
+ if (!existing.toASN1Primitive().equals(attr))
+ {
+ throw new IOException(
+ "attempt to add existing attribute with different value");
+ }
+ }
+ else
+ {
+ bagAttr.setBagAttribute(aOid, attr);
+ }
+ }
+ }
+
+ if (aOid.equals(pkcs_9_at_friendlyName))
+ {
+ alias = ((DERBMPString)attr).getString();
+ keys.put(alias, privKey);
+ }
+ else if (aOid.equals(pkcs_9_at_localKeyId))
+ {
+ localId = (ASN1OctetString)attr;
+ }
+ }
+ }
+
+ if (localId != null)
+ {
+ String name = new String(Hex.encode(localId.getOctets()));
+
+ if (alias == null)
+ {
+ keys.put(name, privKey);
+ }
+ else
+ {
+ localIds.put(alias, name);
+ }
+ }
+ else
+ {
+ unmarkedKey = true;
+ keys.put("unmarked", privKey);
+ }
+ }
+ else if (b.getBagId().equals(certBag))
+ {
+ chain.addElement(b);
+ }
+ else
+ {
+ System.out.println("extra in data " + b.getBagId());
+ System.out.println(ASN1Dump.dumpAsString(b));
+ }
+ }
+ }
+ else if (c[i].getContentType().equals(encryptedData))
+ {
+ EncryptedData d = EncryptedData.getInstance(c[i].getContent());
+ byte[] octets = cryptData(false, d.getEncryptionAlgorithm(),
+ password, wrongPKCS12Zero, d.getContent().getOctets());
+ ASN1Sequence seq = ASN1Sequence.getInstance(octets);
+
+ for (int j = 0; j != seq.size(); j++)
+ {
+ SafeBag b = SafeBag.getInstance(seq.getObjectAt(j));
+
+ if (b.getBagId().equals(certBag))
+ {
+ chain.addElement(b);
+ }
+ else if (b.getBagId().equals(pkcs8ShroudedKeyBag))
+ {
+ com.android.internal.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = com.android.internal.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
+ PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
+
+ //
+ // set the attributes on the key
+ //
+ PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
+ String alias = null;
+ ASN1OctetString localId = null;
+
+ Enumeration e = b.getBagAttributes().getObjects();
+ while (e.hasMoreElements())
+ {
+ ASN1Sequence sq = (ASN1Sequence)e.nextElement();
+ ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0);
+ ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1);
+ ASN1Primitive attr = null;
+
+ if (attrSet.size() > 0)
+ {
+ attr = (ASN1Primitive)attrSet.getObjectAt(0);
+
+ ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
+ if (existing != null)
+ {
+ // OK, but the value has to be the same
+ if (!existing.toASN1Primitive().equals(attr))
+ {
+ throw new IOException(
+ "attempt to add existing attribute with different value");
+ }
+ }
+ else
+ {
+ bagAttr.setBagAttribute(aOid, attr);
+ }
+ }
+
+ if (aOid.equals(pkcs_9_at_friendlyName))
+ {
+ alias = ((DERBMPString)attr).getString();
+ keys.put(alias, privKey);
+ }
+ else if (aOid.equals(pkcs_9_at_localKeyId))
+ {
+ localId = (ASN1OctetString)attr;
+ }
+ }
+
+ String name = new String(Hex.encode(localId.getOctets()));
+
+ if (alias == null)
+ {
+ keys.put(name, privKey);
+ }
+ else
+ {
+ localIds.put(alias, name);
+ }
+ }
+ else if (b.getBagId().equals(keyBag))
+ {
+ com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(b.getBagValue());
+ PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo);
+
+ //
+ // set the attributes on the key
+ //
+ PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
+ String alias = null;
+ ASN1OctetString localId = null;
+
+ Enumeration e = b.getBagAttributes().getObjects();
+ while (e.hasMoreElements())
+ {
+ ASN1Sequence sq = ASN1Sequence.getInstance(e.nextElement());
+ ASN1ObjectIdentifier aOid = ASN1ObjectIdentifier.getInstance(sq.getObjectAt(0));
+ ASN1Set attrSet = ASN1Set.getInstance(sq.getObjectAt(1));
+ ASN1Primitive attr = null;
+
+ if (attrSet.size() > 0)
+ {
+ attr = (ASN1Primitive)attrSet.getObjectAt(0);
+
+ ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
+ if (existing != null)
+ {
+ // OK, but the value has to be the same
+ if (!existing.toASN1Primitive().equals(attr))
+ {
+ throw new IOException(
+ "attempt to add existing attribute with different value");
+ }
+ }
+ else
+ {
+ bagAttr.setBagAttribute(aOid, attr);
+ }
+
+ if (aOid.equals(pkcs_9_at_friendlyName))
+ {
+ alias = ((DERBMPString)attr).getString();
+ keys.put(alias, privKey);
+ }
+ else if (aOid.equals(pkcs_9_at_localKeyId))
+ {
+ localId = (ASN1OctetString)attr;
+ }
+ }
+ }
+
+ String name = new String(Hex.encode(localId.getOctets()));
+
+ if (alias == null)
+ {
+ keys.put(name, privKey);
+ }
+ else
+ {
+ localIds.put(alias, name);
+ }
+ }
+ else
+ {
+ System.out.println("extra in encryptedData " + b.getBagId());
+ System.out.println(ASN1Dump.dumpAsString(b));
+ }
+ }
+ }
+ else
+ {
+ System.out.println("extra " + c[i].getContentType().getId());
+ System.out.println("extra " + ASN1Dump.dumpAsString(c[i].getContent()));
+ }
+ }
+ }
+
+ certs = new IgnoresCaseHashtable();
+ chainCerts = new Hashtable();
+ keyCerts = new Hashtable();
+
+ for (int i = 0; i != chain.size(); i++)
+ {
+ SafeBag b = (SafeBag)chain.elementAt(i);
+ CertBag cb = CertBag.getInstance(b.getBagValue());
+
+ if (!cb.getCertId().equals(x509Certificate))
+ {
+ throw new RuntimeException("Unsupported certificate type: " + cb.getCertId());
+ }
+
+ Certificate cert;
+
+ try
+ {
+ ByteArrayInputStream cIn = new ByteArrayInputStream(
+ ((ASN1OctetString)cb.getCertValue()).getOctets());
+ cert = certFact.generateCertificate(cIn);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.toString());
+ }
+
+ //
+ // set the attributes
+ //
+ ASN1OctetString localId = null;
+ String alias = null;
+
+ if (b.getBagAttributes() != null)
+ {
+ Enumeration e = b.getBagAttributes().getObjects();
+ while (e.hasMoreElements())
+ {
+ ASN1Sequence sq = ASN1Sequence.getInstance(e.nextElement());
+ ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(sq.getObjectAt(0));
+ ASN1Set attrSet = ASN1Set.getInstance(sq.getObjectAt(1));
+
+ if (attrSet.size() > 0) // sometimes this is empty!
+ {
+ ASN1Primitive attr = (ASN1Primitive)attrSet.getObjectAt(0);
+ PKCS12BagAttributeCarrier bagAttr = null;
+
+ if (cert instanceof PKCS12BagAttributeCarrier)
+ {
+ bagAttr = (PKCS12BagAttributeCarrier)cert;
+
+ ASN1Encodable existing = bagAttr.getBagAttribute(oid);
+ if (existing != null)
+ {
+ // OK, but the value has to be the same
+ if (!existing.toASN1Primitive().equals(attr))
+ {
+ throw new IOException(
+ "attempt to add existing attribute with different value");
+ }
+ }
+ else
+ {
+ bagAttr.setBagAttribute(oid, attr);
+ }
+ }
+
+ if (oid.equals(pkcs_9_at_friendlyName))
+ {
+ alias = ((DERBMPString)attr).getString();
+ }
+ else if (oid.equals(pkcs_9_at_localKeyId))
+ {
+ localId = (ASN1OctetString)attr;
+ }
+ }
+ }
+ }
+
+ chainCerts.put(new CertId(cert.getPublicKey()), cert);
+
+ if (unmarkedKey)
+ {
+ if (keyCerts.isEmpty())
+ {
+ String name = new String(Hex.encode(createSubjectKeyId(cert.getPublicKey()).getKeyIdentifier()));
+
+ keyCerts.put(name, cert);
+ keys.put(name, keys.remove("unmarked"));
+ }
+ }
+ else
+ {
+ //
+ // the local key id needs to override the friendly name
+ //
+ if (localId != null)
+ {
+ String name = new String(Hex.encode(localId.getOctets()));
+
+ keyCerts.put(name, cert);
+ }
+ if (alias != null)
+ {
+ certs.put(alias, cert);
+ }
+ }
+ }
+ }
+
+ private int validateIterationCount(BigInteger i)
+ {
+ int count = i.intValue();
+
+ if (count < 0)
+ {
+ throw new IllegalStateException("negative iteration count found");
+ }
+
+ BigInteger maxValue = Properties.asBigInteger(PKCS12_MAX_IT_COUNT_PROPERTY);
+ if (maxValue != null)
+ {
+ if (maxValue.intValue() < count)
+ {
+ throw new IllegalStateException("iteration count " + count + " greater than " + maxValue.intValue());
+ }
+ }
+
+ return count;
+ }
+
+ public void engineStore(LoadStoreParameter param)
+ throws IOException,
+ NoSuchAlgorithmException, CertificateException
+ {
+ if (param == null)
+ {
+ throw new IllegalArgumentException("'param' arg cannot be null");
+ }
+
+ if (!(param instanceof PKCS12StoreParameter || param instanceof JDKPKCS12StoreParameter))
+ {
+ throw new IllegalArgumentException(
+ "No support for 'param' of type " + param.getClass().getName());
+ }
+
+ PKCS12StoreParameter bcParam;
+
+ if (param instanceof PKCS12StoreParameter)
+ {
+ bcParam = (PKCS12StoreParameter)param;
+ }
+ else
+ {
+ bcParam = new PKCS12StoreParameter(((JDKPKCS12StoreParameter)param).getOutputStream(),
+ param.getProtectionParameter(), ((JDKPKCS12StoreParameter)param).isUseDEREncoding());
+ }
+
+ char[] password;
+ ProtectionParameter protParam = param.getProtectionParameter();
+ if (protParam == null)
+ {
+ password = null;
+ }
+ else if (protParam instanceof KeyStore.PasswordProtection)
+ {
+ password = ((KeyStore.PasswordProtection)protParam).getPassword();
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "No support for protection parameter of type " + protParam.getClass().getName());
+ }
+
+ doStore(bcParam.getOutputStream(), password, bcParam.isForDEREncoding());
+ }
+
+ public void engineStore(OutputStream stream, char[] password)
+ throws IOException
+ {
+ doStore(stream, password, false);
+ }
+
+ private void doStore(OutputStream stream, char[] password, boolean useDEREncoding)
+ throws IOException
+ {
+ // BEGIN Android-changed: Upstream allows null passwords, but we maintain historical Android
+ // behaviour.
+ // See CtsKeystoreTestCases:android.keystore.cts.KeyStoreTest
+ if (password == null)
+ {
+ throw new NullPointerException("No password supplied for PKCS#12 KeyStore.");
+ }
+ /*
+ if (keys.size() == 0)
+ {
+ if (password == null)
+ {
+ Enumeration cs = certs.keys();
+
+ ASN1EncodableVector certSeq = new ASN1EncodableVector();
+
+ while (cs.hasMoreElements())
+ {
+ try
+ {
+ String certId = (String)cs.nextElement();
+ Certificate cert = (Certificate)certs.get(certId);
+
+ SafeBag sBag = createSafeBag(certId, cert);
+
+ certSeq.add(sBag);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IOException("Error encoding certificate: " + e.toString());
+ }
+ }
+
+ if (useDEREncoding)
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.DER);
+ }
+ else
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.BER);
+ }
+
+ return;
+ }
+ }
+ else
+ {
+ if (password == null)
+ {
+ throw new NullPointerException("no password supplied for PKCS#12 KeyStore");
+ }
+ }
+ */
+ // END Android-changed: Upstream allows null passwords, but we maintain historical Android
+ // behaviour.
+
+ //
+ // handle the key
+ //
+ ASN1EncodableVector keyS = new ASN1EncodableVector();
+
+ Enumeration ks = keys.keys();
+
+ while (ks.hasMoreElements())
+ {
+ byte[] kSalt = new byte[SALT_SIZE];
+
+ random.nextBytes(kSalt);
+
+ String name = (String)ks.nextElement();
+ PrivateKey privKey = (PrivateKey)keys.get(name);
+ PKCS12PBEParams kParams = new PKCS12PBEParams(kSalt, MIN_ITERATIONS);
+ byte[] kBytes = wrapKey(keyAlgorithm.getId(), privKey, kParams, password);
+ AlgorithmIdentifier kAlgId = new AlgorithmIdentifier(keyAlgorithm, kParams.toASN1Primitive());
+ com.android.internal.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo kInfo = new com.android.internal.org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(kAlgId, kBytes);
+ boolean attrSet = false;
+ ASN1EncodableVector kName = new ASN1EncodableVector();
+
+ if (privKey instanceof PKCS12BagAttributeCarrier)
+ {
+ PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)privKey;
+ //
+ // make sure we are using the local alias on store
+ //
+ DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
+ if (nm == null || !nm.getString().equals(name))
+ {
+ bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name));
+ }
+
+ //
+ // make sure we have a local key-id
+ //
+ if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null)
+ {
+ Certificate ct = engineGetCertificate(name);
+
+ bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(ct.getPublicKey()));
+ }
+
+ Enumeration e = bagAttrs.getBagAttributeKeys();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ ASN1EncodableVector kSeq = new ASN1EncodableVector();
+
+ kSeq.add(oid);
+ kSeq.add(new DERSet(bagAttrs.getBagAttribute(oid)));
+
+ attrSet = true;
+
+ kName.add(new DERSequence(kSeq));
+ }
+ }
+
+ if (!attrSet)
+ {
+ //
+ // set a default friendly name (from the key id) and local id
+ //
+ ASN1EncodableVector kSeq = new ASN1EncodableVector();
+ Certificate ct = engineGetCertificate(name);
+
+ kSeq.add(pkcs_9_at_localKeyId);
+ kSeq.add(new DERSet(createSubjectKeyId(ct.getPublicKey())));
+
+ kName.add(new DERSequence(kSeq));
+
+ kSeq = new ASN1EncodableVector();
+
+ kSeq.add(pkcs_9_at_friendlyName);
+ kSeq.add(new DERSet(new DERBMPString(name)));
+
+ kName.add(new DERSequence(kSeq));
+ }
+
+ SafeBag kBag = new SafeBag(pkcs8ShroudedKeyBag, kInfo.toASN1Primitive(), new DERSet(kName));
+ keyS.add(kBag);
+ }
+
+ byte[] keySEncoded = new DERSequence(keyS).getEncoded(ASN1Encoding.DER);
+ BEROctetString keyString = new BEROctetString(keySEncoded);
+
+ //
+ // certificate processing
+ //
+ byte[] cSalt = new byte[SALT_SIZE];
+
+ random.nextBytes(cSalt);
+
+ ASN1EncodableVector certSeq = new ASN1EncodableVector();
+ PKCS12PBEParams cParams = new PKCS12PBEParams(cSalt, MIN_ITERATIONS);
+ AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(certAlgorithm, cParams.toASN1Primitive());
+ Hashtable doneCerts = new Hashtable();
+
+ Enumeration cs = keys.keys();
+ while (cs.hasMoreElements())
+ {
+ try
+ {
+ String name = (String)cs.nextElement();
+ Certificate cert = engineGetCertificate(name);
+ boolean cAttrSet = false;
+ CertBag cBag = new CertBag(
+ x509Certificate,
+ new DEROctetString(cert.getEncoded()));
+ ASN1EncodableVector fName = new ASN1EncodableVector();
+
+ if (cert instanceof PKCS12BagAttributeCarrier)
+ {
+ PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert;
+ //
+ // make sure we are using the local alias on store
+ //
+ DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
+ if (nm == null || !nm.getString().equals(name))
+ {
+ bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name));
+ }
+
+ //
+ // make sure we have a local key-id
+ //
+ if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null)
+ {
+ bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(cert.getPublicKey()));
+ }
+
+ Enumeration e = bagAttrs.getBagAttributeKeys();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ fSeq.add(oid);
+ fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid)));
+ fName.add(new DERSequence(fSeq));
+
+ cAttrSet = true;
+ }
+ }
+
+ if (!cAttrSet)
+ {
+ ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ fSeq.add(pkcs_9_at_localKeyId);
+ fSeq.add(new DERSet(createSubjectKeyId(cert.getPublicKey())));
+ fName.add(new DERSequence(fSeq));
+
+ fSeq = new ASN1EncodableVector();
+
+ fSeq.add(pkcs_9_at_friendlyName);
+ fSeq.add(new DERSet(new DERBMPString(name)));
+
+ fName.add(new DERSequence(fSeq));
+ }
+
+ SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName));
+
+ certSeq.add(sBag);
+
+ doneCerts.put(cert, cert);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IOException("Error encoding certificate: " + e.toString());
+ }
+ }
+
+ cs = certs.keys();
+ while (cs.hasMoreElements())
+ {
+ try
+ {
+ String certId = (String)cs.nextElement();
+ Certificate cert = (Certificate)certs.get(certId);
+
+ if (keys.get(certId) != null)
+ {
+ continue;
+ }
+
+ SafeBag sBag = createSafeBag(certId, cert);
+
+ certSeq.add(sBag);
+
+ doneCerts.put(cert, cert);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IOException("Error encoding certificate: " + e.toString());
+ }
+ }
+
+ Set usedSet = getUsedCertificateSet();
+
+ cs = chainCerts.keys();
+ while (cs.hasMoreElements())
+ {
+ try
+ {
+ CertId certId = (CertId)cs.nextElement();
+ Certificate cert = (Certificate)chainCerts.get(certId);
+
+ if (!usedSet.contains(cert))
+ {
+ continue;
+ }
+
+ if (doneCerts.get(cert) != null)
+ {
+ continue;
+ }
+
+ CertBag cBag = new CertBag(
+ x509Certificate,
+ new DEROctetString(cert.getEncoded()));
+ ASN1EncodableVector fName = new ASN1EncodableVector();
+
+ if (cert instanceof PKCS12BagAttributeCarrier)
+ {
+ PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert;
+ Enumeration e = bagAttrs.getBagAttributeKeys();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+
+ // a certificate not immediately linked to a key doesn't require
+ // a localKeyID and will confuse some PKCS12 implementations.
+ //
+ // If we find one, we'll prune it out.
+ if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId))
+ {
+ continue;
+ }
+
+ ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ fSeq.add(oid);
+ fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid)));
+ fName.add(new DERSequence(fSeq));
+ }
+ }
+
+ SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName));
+
+ certSeq.add(sBag);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IOException("Error encoding certificate: " + e.toString());
+ }
+ }
+
+ byte[] certSeqEncoded = new DERSequence(certSeq).getEncoded(ASN1Encoding.DER);
+ byte[] certBytes = cryptData(true, cAlgId, password, false, certSeqEncoded);
+ EncryptedData cInfo = new EncryptedData(data, cAlgId, new BEROctetString(certBytes));
+
+ ContentInfo[] info = new ContentInfo[]
+ {
+ new ContentInfo(data, keyString),
+ new ContentInfo(encryptedData, cInfo.toASN1Primitive())
+ };
+
+ AuthenticatedSafe auth = new AuthenticatedSafe(info);
+
+ byte[] pkg = auth.getEncoded(useDEREncoding ? ASN1Encoding.DER : ASN1Encoding.BER);
+
+ ContentInfo mainInfo = new ContentInfo(data, new BEROctetString(pkg));
+
+ //
+ // create the mac
+ //
+ byte[] mSalt = new byte[saltLength];
+
+ random.nextBytes(mSalt);
+
+ byte[] data = ((ASN1OctetString)mainInfo.getContent()).getOctets();
+
+ MacData mData;
+
+ try
+ {
+ byte[] res = calculatePbeMac(macAlgorithm.getAlgorithm(), mSalt, itCount, password, false, data);
+
+ DigestInfo dInfo = new DigestInfo(macAlgorithm, res);
+
+ mData = new MacData(dInfo, mSalt, itCount);
+ }
+ catch (Exception e)
+ {
+ throw new IOException("error constructing MAC: " + e.toString());
+ }
+
+ //
+ // output the Pfx
+ //
+ Pfx pfx = new Pfx(mainInfo, mData);
+
+ pfx.encodeTo(stream, useDEREncoding ? ASN1Encoding.DER : ASN1Encoding.BER);
+ }
+
+ private SafeBag createSafeBag(String certId, Certificate cert)
+ throws CertificateEncodingException
+ {
+ CertBag cBag = new CertBag(
+ x509Certificate,
+ new DEROctetString(cert.getEncoded()));
+ ASN1EncodableVector fName = new ASN1EncodableVector();
+
+ boolean cAttrSet = false;
+ if (cert instanceof PKCS12BagAttributeCarrier)
+ {
+ PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert;
+ //
+ // make sure we are using the local alias on store
+ //
+ DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
+ if (nm == null || !nm.getString().equals(certId))
+ {
+ if (certId != null)
+ {
+ bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(certId));
+ }
+ }
+
+ Enumeration e = bagAttrs.getBagAttributeKeys();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+
+ // a certificate not immediately linked to a key doesn't require
+ // a localKeyID and will confuse some PKCS12 implementations.
+ //
+ // If we find one, we'll prune it out.
+ if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId))
+ {
+ continue;
+ }
+
+ ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ fSeq.add(oid);
+ fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid)));
+ fName.add(new DERSequence(fSeq));
+
+ cAttrSet = true;
+ }
+ }
+
+ if (!cAttrSet)
+ {
+ ASN1EncodableVector fSeq = new ASN1EncodableVector();
+
+ fSeq.add(pkcs_9_at_friendlyName);
+ fSeq.add(new DERSet(new DERBMPString(certId)));
+
+ fName.add(new DERSequence(fSeq));
+ }
+
+ return new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName));
+ }
+
+ private Set getUsedCertificateSet()
+ {
+ Set usedSet = new HashSet();
+
+ for (Enumeration en = keys.keys(); en.hasMoreElements();)
+ {
+ String alias = (String)en.nextElement();
+
+ Certificate[] certs = engineGetCertificateChain(alias);
+
+ for (int i = 0; i != certs.length; i++)
+ {
+ usedSet.add(certs[i]);
+ }
+ }
+
+ for (Enumeration en = certs.keys(); en.hasMoreElements();)
+ {
+ String alias = (String)en.nextElement();
+
+ Certificate cert = engineGetCertificate(alias);
+
+ usedSet.add(cert);
+ }
+
+ return usedSet;
+ }
+
+ private byte[] calculatePbeMac(
+ ASN1ObjectIdentifier oid,
+ byte[] salt,
+ int itCount,
+ char[] password,
+ boolean wrongPkcs12Zero,
+ byte[] data)
+ throws Exception
+ {
+ PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount);
+
+ Mac mac = helper.createMac(oid.getId());
+ mac.init(new PKCS12Key(password, wrongPkcs12Zero), defParams);
+ mac.update(data);
+
+ return mac.doFinal();
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class BCPKCS12KeyStore
+ extends PKCS12KeyStoreSpi
+ {
+ public BCPKCS12KeyStore()
+ {
+ // Android-changed: Use default provider for JCA algorithms instead of BC
+ // Was: super(new BCJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC);
+ super(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class BCPKCS12KeyStore3DES
+ extends PKCS12KeyStoreSpi
+ {
+ public BCPKCS12KeyStore3DES()
+ {
+ super(new BCJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC);
+ }
+ }
+
+ public static class DefPKCS12KeyStore
+ extends PKCS12KeyStoreSpi
+ {
+ public DefPKCS12KeyStore()
+ {
+ super(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC);
+ }
+ }
+
+ public static class DefPKCS12KeyStore3DES
+ extends PKCS12KeyStoreSpi
+ {
+ public DefPKCS12KeyStore3DES()
+ {
+ super(new DefaultJcaJceHelper(), pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC);
+ }
+ }
+ */
+ // END android-removed
+
+ private static class IgnoresCaseHashtable
+ {
+ private Hashtable orig = new Hashtable();
+ private Hashtable keys = new Hashtable();
+
+ public void put(String key, Object value)
+ {
+ String lower = (key == null) ? null : Strings.toLowerCase(key);
+ String k = (String)keys.get(lower);
+ if (k != null)
+ {
+ orig.remove(k);
+ }
+
+ keys.put(lower, key);
+ orig.put(key, value);
+ }
+
+ public Enumeration keys()
+ {
+ return orig.keys();
+ }
+
+ public Object remove(String alias)
+ {
+ String k = (String)keys.remove(alias == null ? null : Strings.toLowerCase(alias));
+ if (k == null)
+ {
+ return null;
+ }
+
+ return orig.remove(k);
+ }
+
+ public Object get(String alias)
+ {
+ String k = (String)keys.get(alias == null ? null : Strings.toLowerCase(alias));
+ if (k == null)
+ {
+ return null;
+ }
+
+ return orig.get(k);
+ }
+
+ public Enumeration elements()
+ {
+ return orig.elements();
+ }
+
+ public int size()
+ {
+ return orig.size();
+ }
+ }
+
+ private static class DefaultSecretKeyProvider
+ {
+ private final Map KEY_SIZES;
+
+ DefaultSecretKeyProvider()
+ {
+ Map keySizes = new HashMap();
+
+ keySizes.put(new ASN1ObjectIdentifier("1.2.840.113533.7.66.10"), Integers.valueOf(128));
+
+ keySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC, Integers.valueOf(192));
+
+ keySizes.put(NISTObjectIdentifiers.id_aes128_CBC, Integers.valueOf(128));
+ keySizes.put(NISTObjectIdentifiers.id_aes192_CBC, Integers.valueOf(192));
+ keySizes.put(NISTObjectIdentifiers.id_aes256_CBC, Integers.valueOf(256));
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ keySizes.put(NTTObjectIdentifiers.id_camellia128_cbc, Integers.valueOf(128));
+ keySizes.put(NTTObjectIdentifiers.id_camellia192_cbc, Integers.valueOf(192));
+ keySizes.put(NTTObjectIdentifiers.id_camellia256_cbc, Integers.valueOf(256));
+
+ keySizes.put(CryptoProObjectIdentifiers.gostR28147_gcfb, Integers.valueOf(256));
+ */
+ // END Android-removed: Unsupported algorithms
+
+ KEY_SIZES = Collections.unmodifiableMap(keySizes);
+ }
+
+ public int getKeySize(AlgorithmIdentifier algorithmIdentifier)
+ {
+ // TODO: not all ciphers/oid relationships are this simple.
+ Integer keySize = (Integer)KEY_SIZES.get(algorithmIdentifier.getAlgorithm());
+
+ if (keySize != null)
+ {
+ return keySize.intValue();
+ }
+
+ return -1;
+ }
+ }
+}
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
new file mode 100644
index 00000000..55510fd2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java
@@ -0,0 +1,1151 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric;
+
+import java.io.IOException;
+// BEGIN Android-added: Needed for setting mode with GCM
+import java.security.NoSuchAlgorithmException;
+// END Android-added: Needed for setting mode with GCM
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.spec.IvParameterSpec;
+
+// BEGIN Android-added: Needed for setting padding with GCM
+import javax.crypto.NoSuchPaddingException;
+// END Android-added: Needed for setting padding with GCM
+import com.android.internal.org.bouncycastle.asn1.bc.BCObjectIdentifiers;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.cms.CCMParameters;
+import com.android.internal.org.bouncycastle.asn1.cms.GCMParameters;
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.BufferedBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.Mac;
+import com.android.internal.org.bouncycastle.crypto.engines.AESEngine;
+import com.android.internal.org.bouncycastle.crypto.engines.AESWrapEngine;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.engines.AESWrapPadEngine;
+// import org.bouncycastle.crypto.engines.RFC3211WrapEngine;
+// import org.bouncycastle.crypto.engines.RFC5649WrapEngine;
+// import org.bouncycastle.crypto.generators.Poly1305KeyGenerator;
+// import org.bouncycastle.crypto.macs.CMac;
+// import org.bouncycastle.crypto.macs.GMac;
+import com.android.internal.org.bouncycastle.crypto.modes.CBCBlockCipher;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.modes.CCMBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.modes.CFBBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.modes.GCMBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.modes.OFBBlockCipher;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
+// import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.GcmSpecUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory;
+import com.android.internal.org.bouncycastle.jcajce.spec.AEADParameterSpec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class AES
+{
+ private static final Map<String, String> generalAesAttributes = new HashMap<String, String>();
+
+ static
+ {
+ generalAesAttributes.put("SupportedKeyClasses", "javax.crypto.SecretKey");
+ generalAesAttributes.put("SupportedKeyFormats", "RAW");
+ }
+
+ private AES()
+ {
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class ECB
+ extends BaseBlockCipher
+ {
+ public ECB()
+ {
+ super(new BlockCipherProvider()
+ {
+ public BlockCipher get()
+ {
+ return new AESEngine();
+ }
+ });
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class CBC
+ extends BaseBlockCipher
+ {
+ public CBC()
+ {
+ super(new CBCBlockCipher(new AESEngine()), 128);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class CFB
+ extends BaseBlockCipher
+ {
+ public CFB()
+ {
+ super(new BufferedBlockCipher(new CFBBlockCipher(new AESEngine(), 128)), 128);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class OFB
+ extends BaseBlockCipher
+ {
+ public OFB()
+ {
+ super(new BufferedBlockCipher(new OFBBlockCipher(new AESEngine(), 128)), 128);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class GCM
+ extends BaseBlockCipher
+ {
+ public GCM()
+ {
+ super(new GCMBlockCipher(new AESEngine()));
+ // BEGIN Android-added: Set mode and padding due to name change (see note in Mappings)
+ try {
+ engineSetMode("GCM");
+ engineSetPadding("NoPadding");
+ } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
+ // this should not be possible
+ throw new RuntimeException("Could not set mode or padding for GCM mode", e);
+ }
+ // END Android-added: Set mode and padding due to name change (see note in Mappings)
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ static public class CCM
+ extends BaseBlockCipher
+ {
+ public CCM()
+ {
+ super(new CCMBlockCipher(new AESEngine()), false, 12);
+ }
+ }
+
+ public static class AESCMAC
+ extends BaseMac
+ {
+ public AESCMAC()
+ {
+ super(new CMac(new AESEngine()));
+ }
+ }
+
+ public static class AESGMAC
+ extends BaseMac
+ {
+ public AESGMAC()
+ {
+ super(new GMac(new GCMBlockCipher(new AESEngine())));
+ }
+ }
+
+ public static class AESCCMMAC
+ extends BaseMac
+ {
+ public AESCCMMAC()
+ {
+ super(new CCMMac());
+ }
+
+ private static class CCMMac
+ implements Mac
+ {
+ private final CCMBlockCipher ccm = new CCMBlockCipher(new AESEngine());
+
+ private int macLength = 8;
+
+ public void init(CipherParameters params)
+ throws IllegalArgumentException
+ {
+ ccm.init(true, params);
+
+ this.macLength = ccm.getMac().length;
+ }
+
+ public String getAlgorithmName()
+ {
+ return ccm.getAlgorithmName() + "Mac";
+ }
+
+ public int getMacSize()
+ {
+ return macLength;
+ }
+
+ public void update(byte in)
+ throws IllegalStateException
+ {
+ ccm.processAADByte(in);
+ }
+
+ public void update(byte[] in, int inOff, int len)
+ throws DataLengthException, IllegalStateException
+ {
+ ccm.processAADBytes(in, inOff, len);
+ }
+
+ public int doFinal(byte[] out, int outOff)
+ throws DataLengthException, IllegalStateException
+ {
+ try
+ {
+ return ccm.doFinal(out, 0);
+ }
+ catch (InvalidCipherTextException e)
+ {
+ throw new IllegalStateException("exception on doFinal(): " + e.toString());
+ }
+ }
+
+ public void reset()
+ {
+ ccm.reset();
+ }
+ }
+ }
+
+ static public class KeyFactory
+ extends BaseSecretKeyFactory
+ {
+ public KeyFactory()
+ {
+ super("AES", null);
+ }
+ }
+
+ public static class Poly1305
+ extends BaseMac
+ {
+ public Poly1305()
+ {
+ super(new org.bouncycastle.crypto.macs.Poly1305(new AESEngine()));
+ }
+ }
+
+ public static class Poly1305KeyGen
+ extends BaseKeyGenerator
+ {
+ public Poly1305KeyGen()
+ {
+ super("Poly1305-AES", 256, new Poly1305KeyGenerator());
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class Wrap
+ extends BaseWrapCipher
+ {
+ public Wrap()
+ {
+ super(new AESWrapEngine());
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class WrapPad
+ extends BaseWrapCipher
+ {
+ public WrapPad()
+ {
+ super(new AESWrapPadEngine());
+ }
+ }
+
+ public static class RFC3211Wrap
+ extends BaseWrapCipher
+ {
+ public RFC3211Wrap()
+ {
+ super(new RFC3211WrapEngine(new AESEngine()), 16);
+ }
+ }
+
+ public static class RFC5649Wrap
+ extends BaseWrapCipher
+ {
+ public RFC5649Wrap()
+ {
+ super(new RFC5649WrapEngine(new AESEngine()));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * PBEWithAES-CBC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithAESCBC
+ extends BaseBlockCipher
+ {
+ public PBEWithAESCBC()
+ {
+ super(new CBCBlockCipher(new AESEngine()));
+ }
+ }
+
+ /**
+ * PBEWithSHA1AES-CBC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHA1AESCBC128
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA1AESCBC128()
+ {
+ super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 128, 16);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHA1AESCBC192
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA1AESCBC192()
+ {
+ super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 192, 16);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHA1AESCBC256
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA1AESCBC256()
+ {
+ super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 256, 16);
+ }
+ }
+
+ /**
+ * PBEWithSHA256AES-CBC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHA256AESCBC128
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA256AESCBC128()
+ {
+ super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 128, 16);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHA256AESCBC192
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA256AESCBC192()
+ {
+ super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 192, 16);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHA256AESCBC256
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA256AESCBC256()
+ {
+ super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 256, 16);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyGen
+ extends BaseKeyGenerator
+ {
+ public KeyGen()
+ {
+ // Android-changed: Use 128-bit keys by default.
+ // Bouncy Castle defaults to 192-bit keys, which is the worst choice: worse security
+ // than 256-bit keys, slower than 128-bit keys, narrower support than either.
+ // Use 128-bit keys by default since they're faster and should still be plenty secure.
+ // this(192);
+ this(128);
+ }
+
+ public KeyGen(int keySize)
+ {
+ super("AES", keySize, new CipherKeyGenerator());
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class KeyGen128
+ extends KeyGen
+ {
+ public KeyGen128()
+ {
+ super(128);
+ }
+ }
+
+ public static class KeyGen192
+ extends KeyGen
+ {
+ public KeyGen192()
+ {
+ super(192);
+ }
+ }
+
+ public static class KeyGen256
+ extends KeyGen
+ {
+ public KeyGen256()
+ {
+ super(256);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * PBEWithSHA1And128BitAES-BC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAnd128BitAESBC
+ extends PBESecretKeyFactory
+ {
+ public PBEWithSHAAnd128BitAESBC()
+ {
+ super("PBEWithSHA1And128BitAES-CBC-BC", null, true, PKCS12, SHA1, 128, 128);
+ }
+ }
+
+ /**
+ * PBEWithSHA1And192BitAES-BC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAnd192BitAESBC
+ extends PBESecretKeyFactory
+ {
+ public PBEWithSHAAnd192BitAESBC()
+ {
+ super("PBEWithSHA1And192BitAES-CBC-BC", null, true, PKCS12, SHA1, 192, 128);
+ }
+ }
+
+ /**
+ * PBEWithSHA1And256BitAES-BC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAnd256BitAESBC
+ extends PBESecretKeyFactory
+ {
+ public PBEWithSHAAnd256BitAESBC()
+ {
+ super("PBEWithSHA1And256BitAES-CBC-BC", null, true, PKCS12, SHA1, 256, 128);
+ }
+ }
+
+ /**
+ * PBEWithSHA256And128BitAES-BC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHA256And128BitAESBC
+ extends PBESecretKeyFactory
+ {
+ public PBEWithSHA256And128BitAESBC()
+ {
+ super("PBEWithSHA256And128BitAES-CBC-BC", null, true, PKCS12, SHA256, 128, 128);
+ }
+ }
+
+ /**
+ * PBEWithSHA256And192BitAES-BC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHA256And192BitAESBC
+ extends PBESecretKeyFactory
+ {
+ public PBEWithSHA256And192BitAESBC()
+ {
+ super("PBEWithSHA256And192BitAES-CBC-BC", null, true, PKCS12, SHA256, 192, 128);
+ }
+ }
+
+ /**
+ * PBEWithSHA256And256BitAES-BC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHA256And256BitAESBC
+ extends PBESecretKeyFactory
+ {
+ public PBEWithSHA256And256BitAESBC()
+ {
+ super("PBEWithSHA256And256BitAES-CBC-BC", null, true, PKCS12, SHA256, 256, 128);
+ }
+ }
+
+ /**
+ * PBEWithMD5And128BitAES-OpenSSL
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithMD5And128BitAESCBCOpenSSL
+ extends PBESecretKeyFactory
+ {
+ public PBEWithMD5And128BitAESCBCOpenSSL()
+ {
+ super("PBEWithMD5And128BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 128, 128);
+ }
+ }
+
+ /**
+ * PBEWithMD5And192BitAES-OpenSSL
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithMD5And192BitAESCBCOpenSSL
+ extends PBESecretKeyFactory
+ {
+ public PBEWithMD5And192BitAESCBCOpenSSL()
+ {
+ super("PBEWithMD5And192BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 192, 128);
+ }
+ }
+
+ /**
+ * PBEWithMD5And256BitAES-OpenSSL
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithMD5And256BitAESCBCOpenSSL
+ extends PBESecretKeyFactory
+ {
+ public PBEWithMD5And256BitAESCBCOpenSSL()
+ {
+ super("PBEWithMD5And256BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 256, 128);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class AlgParamGen
+ extends BaseAlgorithmParameterGenerator
+ {
+ protected void engineInit(
+ AlgorithmParameterSpec genParamSpec,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for AES parameter generation.");
+ }
+
+ protected AlgorithmParameters engineGenerateParameters()
+ {
+ byte[] iv = new byte[16];
+
+ if (random == null)
+ {
+ random = CryptoServicesRegistrar.getSecureRandom();
+ }
+
+ random.nextBytes(iv);
+
+ AlgorithmParameters params;
+
+ try
+ {
+ params = createParametersInstance("AES");
+ params.init(new IvParameterSpec(iv));
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.getMessage());
+ }
+
+ return params;
+ }
+ }
+
+ public static class AlgParamGenCCM
+ extends BaseAlgorithmParameterGenerator
+ {
+ protected void engineInit(
+ AlgorithmParameterSpec genParamSpec,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ // TODO: add support for GCMParameterSpec as a template.
+ throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for AES parameter generation.");
+ }
+
+ protected AlgorithmParameters engineGenerateParameters()
+ {
+ byte[] iv = new byte[12];
+
+ if (random == null)
+ {
+ random = new SecureRandom();
+ }
+
+ random.nextBytes(iv);
+
+ AlgorithmParameters params;
+
+ try
+ {
+ params = createParametersInstance("CCM");
+ params.init(new CCMParameters(iv, 12).getEncoded());
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.getMessage());
+ }
+
+ return params;
+ }
+ }
+
+ public static class AlgParamGenGCM
+ extends BaseAlgorithmParameterGenerator
+ {
+ protected void engineInit(
+ AlgorithmParameterSpec genParamSpec,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ // TODO: add support for GCMParameterSpec as a template.
+ throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for AES parameter generation.");
+ }
+
+ protected AlgorithmParameters engineGenerateParameters()
+ {
+ byte[] nonce = new byte[12];
+
+ if (random == null)
+ {
+ random = new SecureRandom();
+ }
+
+ random.nextBytes(nonce);
+
+ AlgorithmParameters params;
+
+ try
+ {
+ params = createParametersInstance("GCM");
+ params.init(new GCMParameters(nonce, 16).getEncoded());
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.getMessage());
+ }
+
+ return params;
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class AlgParams
+ extends IvAlgorithmParameters
+ {
+ protected String engineToString()
+ {
+ return "AES IV";
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class AlgParamsGCM
+ extends BaseAlgorithmParameters
+ {
+ private GCMParameters gcmParams;
+
+ protected void engineInit(AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (GcmSpecUtil.isGcmSpec(paramSpec))
+ {
+ gcmParams = GcmSpecUtil.extractGcmParameters(paramSpec);
+ }
+ else if (paramSpec instanceof AEADParameterSpec)
+ {
+ gcmParams = new GCMParameters(((AEADParameterSpec)paramSpec).getNonce(), ((AEADParameterSpec)paramSpec).getMacSizeInBits() / 8);
+ }
+ else
+ {
+ throw new InvalidParameterSpecException("AlgorithmParameterSpec class not recognized: " + paramSpec.getClass().getName());
+ }
+ }
+
+ protected void engineInit(byte[] params)
+ throws IOException
+ {
+ gcmParams = GCMParameters.getInstance(params);
+ }
+
+ protected void engineInit(byte[] params, String format)
+ throws IOException
+ {
+ if (!isASN1FormatString(format))
+ {
+ throw new IOException("unknown format specified");
+ }
+
+ gcmParams = GCMParameters.getInstance(params);
+ }
+
+ protected byte[] engineGetEncoded()
+ throws IOException
+ {
+ return gcmParams.getEncoded();
+ }
+
+ protected byte[] engineGetEncoded(String format)
+ throws IOException
+ {
+ if (!isASN1FormatString(format))
+ {
+ throw new IOException("unknown format specified");
+ }
+
+ return gcmParams.getEncoded();
+ }
+
+ protected String engineToString()
+ {
+ return "GCM";
+ }
+
+ protected AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec == AlgorithmParameterSpec.class || GcmSpecUtil.isGcmSpec(paramSpec))
+ {
+ if (GcmSpecUtil.gcmSpecExists())
+ {
+ return GcmSpecUtil.extractGcmSpec(gcmParams.toASN1Primitive());
+ }
+ return new AEADParameterSpec(gcmParams.getNonce(), gcmParams.getIcvLen() * 8);
+ }
+ if (paramSpec == AEADParameterSpec.class)
+ {
+ return new AEADParameterSpec(gcmParams.getNonce(), gcmParams.getIcvLen() * 8);
+ }
+ if (paramSpec == IvParameterSpec.class)
+ {
+ return new IvParameterSpec(gcmParams.getNonce());
+ }
+
+ throw new InvalidParameterSpecException("AlgorithmParameterSpec not recognized: " + paramSpec.getName());
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class AlgParamsCCM
+ extends BaseAlgorithmParameters
+ {
+ private CCMParameters ccmParams;
+
+ protected void engineInit(AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (GcmSpecUtil.isGcmSpec(paramSpec))
+ {
+ ccmParams = CCMParameters.getInstance(GcmSpecUtil.extractGcmParameters(paramSpec));
+ }
+ else if (paramSpec instanceof AEADParameterSpec)
+ {
+ ccmParams = new CCMParameters(((AEADParameterSpec)paramSpec).getNonce(), ((AEADParameterSpec)paramSpec).getMacSizeInBits() / 8);
+ }
+ else
+ {
+ throw new InvalidParameterSpecException("AlgorithmParameterSpec class not recognized: " + paramSpec.getClass().getName());
+ }
+ }
+
+ protected void engineInit(byte[] params)
+ throws IOException
+ {
+ ccmParams = CCMParameters.getInstance(params);
+ }
+
+ protected void engineInit(byte[] params, String format)
+ throws IOException
+ {
+ if (!isASN1FormatString(format))
+ {
+ throw new IOException("unknown format specified");
+ }
+
+ ccmParams = CCMParameters.getInstance(params);
+ }
+
+ protected byte[] engineGetEncoded()
+ throws IOException
+ {
+ return ccmParams.getEncoded();
+ }
+
+ protected byte[] engineGetEncoded(String format)
+ throws IOException
+ {
+ if (!isASN1FormatString(format))
+ {
+ throw new IOException("unknown format specified");
+ }
+
+ return ccmParams.getEncoded();
+ }
+
+ protected String engineToString()
+ {
+ return "CCM";
+ }
+
+ protected AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec == AlgorithmParameterSpec.class || GcmSpecUtil.isGcmSpec(paramSpec))
+ {
+ if (GcmSpecUtil.gcmSpecExists())
+ {
+ return GcmSpecUtil.extractGcmSpec(ccmParams.toASN1Primitive());
+ }
+ return new AEADParameterSpec(ccmParams.getNonce(), ccmParams.getIcvLen() * 8);
+ }
+ if (paramSpec == AEADParameterSpec.class)
+ {
+ return new AEADParameterSpec(ccmParams.getNonce(), ccmParams.getIcvLen() * 8);
+ }
+ if (paramSpec == IvParameterSpec.class)
+ {
+ return new IvParameterSpec(ccmParams.getNonce());
+ }
+
+ throw new InvalidParameterSpecException("AlgorithmParameterSpec not recognized: " + paramSpec.getName());
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends SymmetricAlgorithmProvider
+ {
+ private static final String PREFIX = AES.class.getName();
+
+ /**
+ * These three got introduced in some messages as a result of a typo in an
+ * early document. We don't produce anything using these OID values, but we'll
+ * read them.
+ */
+ private static final String wrongAES128 = "2.16.840.1.101.3.4.2";
+ private static final String wrongAES192 = "2.16.840.1.101.3.4.22";
+ private static final String wrongAES256 = "2.16.840.1.101.3.4.42";
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("AlgorithmParameters.AES", PREFIX + "$AlgParams");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + wrongAES128, "AES");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + wrongAES192, "AES");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + wrongAES256, "AES");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes128_CBC, "AES");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes192_CBC, "AES");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes256_CBC, "AES");
+
+ provider.addAlgorithm("AlgorithmParameters.GCM", PREFIX + "$AlgParamsGCM");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes128_GCM, "GCM");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes192_GCM, "GCM");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes256_GCM, "GCM");
+
+ provider.addAlgorithm("AlgorithmParameters.CCM", PREFIX + "$AlgParamsCCM");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes128_CCM, "CCM");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes192_CCM, "CCM");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + NISTObjectIdentifiers.id_aes256_CCM, "CCM");
+
+ provider.addAlgorithm("AlgorithmParameterGenerator.AES", PREFIX + "$AlgParamGen");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + wrongAES128, "AES");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + wrongAES192, "AES");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + wrongAES256, "AES");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes128_CBC, "AES");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes192_CBC, "AES");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes256_CBC, "AES");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ provider.addAttributes("Cipher.AES", generalAesAttributes);
+ provider.addAlgorithm("Cipher.AES", PREFIX + "$ECB");
+ provider.addAlgorithm("Alg.Alias.Cipher." + wrongAES128, "AES");
+ provider.addAlgorithm("Alg.Alias.Cipher." + wrongAES192, "AES");
+ provider.addAlgorithm("Alg.Alias.Cipher." + wrongAES256, "AES");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes128_ECB, PREFIX + "$ECB");
+ provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes192_ECB, PREFIX + "$ECB");
+ provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes256_ECB, PREFIX + "$ECB");
+ provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes128_CBC, PREFIX + "$CBC");
+ provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes192_CBC, PREFIX + "$CBC");
+ provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes256_CBC, PREFIX + "$CBC");
+ provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes128_OFB, PREFIX + "$OFB");
+ provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes192_OFB, PREFIX + "$OFB");
+ provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes256_OFB, PREFIX + "$OFB");
+ provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes128_CFB, PREFIX + "$CFB");
+ provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes192_CFB, PREFIX + "$CFB");
+ provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes256_CFB, PREFIX + "$CFB");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ provider.addAttributes("Cipher.AESWRAP", generalAesAttributes);
+ provider.addAlgorithm("Cipher.AESWRAP", PREFIX + "$Wrap");
+ provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes128_wrap, "AESWRAP");
+ provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes192_wrap, "AESWRAP");
+ provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes256_wrap, "AESWRAP");
+ provider.addAlgorithm("Alg.Alias.Cipher.AESKW", "AESWRAP");
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAttributes("Cipher.AESWRAPPAD", generalAesAttributes);
+ provider.addAlgorithm("Cipher.AESWRAPPAD", PREFIX + "$WrapPad");
+ provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes128_wrap_pad, "AESWRAPPAD");
+ provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes192_wrap_pad, "AESWRAPPAD");
+ provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes256_wrap_pad, "AESWRAPPAD");
+ provider.addAlgorithm("Alg.Alias.Cipher.AESKWP", "AESWRAPPAD");
+
+ provider.addAlgorithm("Cipher.AESRFC3211WRAP", PREFIX + "$RFC3211Wrap");
+ provider.addAlgorithm("Cipher.AESRFC5649WRAP", PREFIX + "$RFC5649Wrap");
+
+ provider.addAlgorithm("AlgorithmParameterGenerator.CCM", PREFIX + "$AlgParamGenCCM");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes128_CCM, "CCM");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes192_CCM, "CCM");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes256_CCM, "CCM");
+
+ provider.addAttributes("Cipher.CCM", generalAesAttributes);
+ provider.addAlgorithm("Cipher.CCM", PREFIX + "$CCM");
+ provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes128_CCM, "CCM");
+ provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes192_CCM, "CCM");
+ provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes256_CCM, "CCM");
+
+ provider.addAlgorithm("AlgorithmParameterGenerator.GCM", PREFIX + "$AlgParamGenGCM");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes128_GCM, "GCM");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes192_GCM, "GCM");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes256_GCM, "GCM");
+
+ provider.addAttributes("Cipher.AES/GCM/NOPADDING", generalAesAttributes);
+ provider.addAlgorithm("Cipher.AES/GCM/NOPADDING", PREFIX + "$GCM");
+ provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes128_GCM, "AES/GCM/NOPADDING");
+ provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes192_GCM, "AES/GCM/NOPADDING");
+ provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes256_GCM, "AES/GCM/NOPADDING");
+
+ provider.addAlgorithm("KeyGenerator.AES", PREFIX + "$KeyGen");
+ provider.addAlgorithm("KeyGenerator." + wrongAES128, PREFIX + "$KeyGen128");
+ provider.addAlgorithm("KeyGenerator." + wrongAES192, PREFIX + "$KeyGen192");
+ provider.addAlgorithm("KeyGenerator." + wrongAES256, PREFIX + "$KeyGen256");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_ECB, PREFIX + "$KeyGen128");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_CBC, PREFIX + "$KeyGen128");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_OFB, PREFIX + "$KeyGen128");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_CFB, PREFIX + "$KeyGen128");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_ECB, PREFIX + "$KeyGen192");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_CBC, PREFIX + "$KeyGen192");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_OFB, PREFIX + "$KeyGen192");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_CFB, PREFIX + "$KeyGen192");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_ECB, PREFIX + "$KeyGen256");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_CBC, PREFIX + "$KeyGen256");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_OFB, PREFIX + "$KeyGen256");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_CFB, PREFIX + "$KeyGen256");
+ provider.addAlgorithm("KeyGenerator.AESWRAP", PREFIX + "$KeyGen");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_wrap, PREFIX + "$KeyGen128");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_wrap, PREFIX + "$KeyGen192");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_wrap, PREFIX + "$KeyGen256");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_GCM, PREFIX + "$KeyGen128");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_GCM, PREFIX + "$KeyGen192");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_GCM, PREFIX + "$KeyGen256");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_CCM, PREFIX + "$KeyGen128");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_CCM, PREFIX + "$KeyGen192");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_CCM, PREFIX + "$KeyGen256");
+ provider.addAlgorithm("KeyGenerator.AESWRAPPAD", PREFIX + "$KeyGen");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_wrap_pad, PREFIX + "$KeyGen128");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_wrap_pad, PREFIX + "$KeyGen192");
+ provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_wrap_pad, PREFIX + "$KeyGen256");
+
+ provider.addAlgorithm("Mac.AESCMAC", PREFIX + "$AESCMAC");
+
+ provider.addAlgorithm("Mac.AESCCMMAC", PREFIX + "$AESCCMMAC");
+ provider.addAlgorithm("Alg.Alias.Mac." + NISTObjectIdentifiers.id_aes128_CCM.getId(), "AESCCMMAC");
+ provider.addAlgorithm("Alg.Alias.Mac." + NISTObjectIdentifiers.id_aes192_CCM.getId(), "AESCCMMAC");
+ provider.addAlgorithm("Alg.Alias.Mac." + NISTObjectIdentifiers.id_aes256_CCM.getId(), "AESCCMMAC");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ provider.addAlgorithm("Alg.Alias.Cipher", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc, "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc, "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc, "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc, "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc, "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc, "PBEWITHSHA256AND256BITAES-CBC-BC");
+
+ provider.addAlgorithm("Cipher.PBEWITHSHAAND128BITAES-CBC-BC", PREFIX + "$PBEWithSHA1AESCBC128");
+ provider.addAlgorithm("Cipher.PBEWITHSHAAND192BITAES-CBC-BC", PREFIX + "$PBEWithSHA1AESCBC192");
+ provider.addAlgorithm("Cipher.PBEWITHSHAAND256BITAES-CBC-BC", PREFIX + "$PBEWithSHA1AESCBC256");
+ provider.addAlgorithm("Cipher.PBEWITHSHA256AND128BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC128");
+ provider.addAlgorithm("Cipher.PBEWITHSHA256AND192BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC192");
+ provider.addAlgorithm("Cipher.PBEWITHSHA256AND256BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC256");
+
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND192BITAES-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND256BITAES-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-BC","PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-BC","PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-BC","PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-BC","PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-CBC-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-CBC-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-CBC-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
+
+ provider.addAlgorithm("Cipher.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
+ provider.addAlgorithm("Cipher.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
+ provider.addAlgorithm("Cipher.PBEWITHMD5AND256BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
+
+ // BEGIN Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("SecretKeyFactory.AES", PREFIX + "$KeyFactory");
+ // provider.addAlgorithm("SecretKeyFactory", NISTObjectIdentifiers.aes, PREFIX + "$KeyFactory");
+ // END Android-removed: Unsupported algorithms
+
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And128BitAESCBCOpenSSL");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And192BitAESCBCOpenSSL");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND256BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And256BitAESCBCOpenSSL");
+
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND128BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd128BitAESBC");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND192BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd192BitAESBC");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND256BITAES-CBC-BC", PREFIX + "$PBEWithSHAAnd256BitAESBC");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND128BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And128BitAESBC");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND192BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And192BitAESBC");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA256AND256BITAES-CBC-BC", PREFIX + "$PBEWithSHA256And256BitAESBC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-CBC-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-CBC-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-CBC-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc, "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc, "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc, "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc, "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc, "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc, "PBEWITHSHA256AND256BITAES-CBC-BC");
+
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND128BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND192BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND256BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND128BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND192BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND256BITAES-CBC-BC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND128BITAES-CBC-BC","PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND192BITAES-CBC-BC","PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND256BITAES-CBC-BC","PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND128BITAES-CBC-BC","PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND192BITAES-CBC-BC","PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND256BITAES-CBC-BC","PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND128BITAES-CBC-BC","PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND192BITAES-CBC-BC","PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND256BITAES-CBC-BC","PKCS12PBE");
+
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.getId(), "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.getId(), "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.getId(), "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc.getId(), "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc.getId(), "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc.getId(), "PKCS12PBE");
+
+ // BEGIN Android-removed: Unsupported algorithms
+ // addGMacAlgorithm(provider, "AES", PREFIX + "$AESGMAC", PREFIX + "$KeyGen128");
+ // addPoly1305Algorithm(provider, "AES", PREFIX + "$Poly1305", PREFIX + "$Poly1305KeyGen");
+ // END Android-removed: Unsupported algorithms
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/ARC4.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/ARC4.java
new file mode 100644
index 00000000..852248c9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/ARC4.java
@@ -0,0 +1,147 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric;
+
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.engines.RC4Engine;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseStreamCipher;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class ARC4
+{
+ private ARC4()
+ {
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Base
+ extends BaseStreamCipher
+ {
+ public Base()
+ {
+ super(new RC4Engine(), 0);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyGen
+ extends BaseKeyGenerator
+ {
+ public KeyGen()
+ {
+ // Android-changed: Use ARC4 for algorithm name to match name used in provider
+ // super("RC4", 128, new CipherKeyGenerator());
+ super("ARC4", 128, new CipherKeyGenerator());
+ }
+ }
+
+ /**
+ * PBEWithSHAAnd128BitRC4
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAnd128BitKeyFactory
+ extends PBESecretKeyFactory
+ {
+ public PBEWithSHAAnd128BitKeyFactory()
+ {
+ super("PBEWithSHAAnd128BitRC4", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, true, PKCS12, SHA1, 128, 0);
+ }
+ }
+
+ /**
+ * PBEWithSHAAnd40BitRC4
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAnd40BitKeyFactory
+ extends PBESecretKeyFactory
+ {
+ public PBEWithSHAAnd40BitKeyFactory()
+ {
+ super("PBEWithSHAAnd128BitRC4", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, true, PKCS12, SHA1, 40, 0);
+ }
+ }
+
+
+ /**
+ * PBEWithSHAAnd128BitRC4
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAnd128Bit
+ extends BaseStreamCipher
+ {
+ public PBEWithSHAAnd128Bit()
+ {
+ super(new RC4Engine(), 0, 128, SHA1);
+ }
+ }
+
+ /**
+ * PBEWithSHAAnd40BitRC4
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAnd40Bit
+ extends BaseStreamCipher
+ {
+ public PBEWithSHAAnd40Bit()
+ {
+ super(new RC4Engine(), 0, 40, SHA1);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AlgorithmProvider
+ {
+ private static final String PREFIX = ARC4.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("Cipher.ARC4", PREFIX + "$Base");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.rc4, "ARC4");
+ provider.addAlgorithm("Alg.Alias.Cipher.ARCFOUR", "ARC4");
+ provider.addAlgorithm("Alg.Alias.Cipher.RC4", "ARC4");
+ */
+ // END Android-removed: Unsupported algorithms
+ provider.addAlgorithm("KeyGenerator.ARC4", PREFIX + "$KeyGen");
+ provider.addAlgorithm("Alg.Alias.KeyGenerator.RC4", "ARC4");
+ provider.addAlgorithm("Alg.Alias.KeyGenerator.1.2.840.113549.3.4", "ARC4");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND128BITRC4", PREFIX + "$PBEWithSHAAnd128BitKeyFactory");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND40BITRC4", PREFIX + "$PBEWithSHAAnd40BitKeyFactory");
+
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4, "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND40BITRC4", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND128BITRC4", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDRC4", "PKCS12PBE");
+ provider.addAlgorithm("Cipher.PBEWITHSHAAND128BITRC4", PREFIX + "$PBEWithSHAAnd128Bit");
+ provider.addAlgorithm("Cipher.PBEWITHSHAAND40BITRC4", PREFIX + "$PBEWithSHAAnd40Bit");
+
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, "PBEWITHSHAAND128BITRC4");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4, "PBEWITHSHAAND40BITRC4");
+
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITRC4", "PBEWITHSHAAND128BITRC4");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND40BITRC4", "PBEWITHSHAAND40BITRC4");
+
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, "PBEWITHSHAAND128BITRC4");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4, "PBEWITHSHAAND40BITRC4");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java
new file mode 100644
index 00000000..9918d36f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java
@@ -0,0 +1,114 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric;
+
+import com.android.internal.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.engines.BlowfishEngine;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.macs.CMac;
+import com.android.internal.org.bouncycastle.crypto.modes.CBCBlockCipher;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Blowfish
+{
+ private Blowfish()
+ {
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class ECB
+ extends BaseBlockCipher
+ {
+ public ECB()
+ {
+ super(new BlowfishEngine());
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class CBC
+ extends BaseBlockCipher
+ {
+ public CBC()
+ {
+ super(new CBCBlockCipher(new BlowfishEngine()), 64);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class CMAC
+ extends BaseMac
+ {
+ public CMAC()
+ {
+ super(new CMac(new BlowfishEngine()));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyGen
+ extends BaseKeyGenerator
+ {
+ public KeyGen()
+ {
+ super("Blowfish", 128, new CipherKeyGenerator());
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class AlgParams
+ extends IvAlgorithmParameters
+ {
+ protected String engineToString()
+ {
+ return "Blowfish IV";
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AlgorithmProvider
+ {
+ private static final String PREFIX = Blowfish.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("Mac.BLOWFISHCMAC", PREFIX + "$CMAC");
+ provider.addAlgorithm("Cipher.BLOWFISH", PREFIX + "$ECB");
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("Cipher", MiscObjectIdentifiers.cryptlib_algorithm_blowfish_CBC, PREFIX + "$CBC");
+ provider.addAlgorithm("KeyGenerator.BLOWFISH", PREFIX + "$KeyGen");
+ provider.addAlgorithm("Alg.Alias.KeyGenerator", MiscObjectIdentifiers.cryptlib_algorithm_blowfish_CBC, "BLOWFISH");
+ provider.addAlgorithm("AlgorithmParameters.BLOWFISH", PREFIX + "$AlgParams");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters", MiscObjectIdentifiers.cryptlib_algorithm_blowfish_CBC, "BLOWFISH");
+
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/DES.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/DES.java
new file mode 100644
index 00000000..169497b4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/DES.java
@@ -0,0 +1,589 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.DESKeySpec;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.PasswordConverter;
+import com.android.internal.org.bouncycastle.crypto.engines.DESEngine;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.engines.RFC3211WrapEngine;
+import com.android.internal.org.bouncycastle.crypto.generators.DESKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.macs.CBCBlockCipherMac;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.macs.CFBBlockCipherMac;
+// import org.bouncycastle.crypto.macs.CMac;
+// import org.bouncycastle.crypto.macs.ISO9797Alg3Mac;
+import com.android.internal.org.bouncycastle.crypto.modes.CBCBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.paddings.ISO7816d4Padding;
+import com.android.internal.org.bouncycastle.crypto.params.DESParameters;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jcajce.PBKDF1Key;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.PBE;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class DES
+{
+ private DES()
+ {
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class ECB
+ extends BaseBlockCipher
+ {
+ public ECB()
+ {
+ super(new DESEngine());
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class CBC
+ extends BaseBlockCipher
+ {
+ public CBC()
+ {
+ super(new CBCBlockCipher(new DESEngine()), 64);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ /**
+ * DES CFB8
+ *
+ public static class DESCFB8
+ extends BaseMac
+ {
+ public DESCFB8()
+ {
+ super(new CFBBlockCipherMac(new DESEngine()));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * DES64
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class DES64
+ extends BaseMac
+ {
+ public DES64()
+ {
+ super(new CBCBlockCipherMac(new DESEngine(), 64));
+ }
+ }
+
+ /**
+ * DES64with7816-4Padding
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class DES64with7816d4
+ extends BaseMac
+ {
+ public DES64with7816d4()
+ {
+ super(new CBCBlockCipherMac(new DESEngine(), 64, new ISO7816d4Padding()));
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class CBCMAC
+ extends BaseMac
+ {
+ public CBCMAC()
+ {
+ super(new CBCBlockCipherMac(new DESEngine()));
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ static public class CMAC
+ extends BaseMac
+ {
+ public CMAC()
+ {
+ super(new CMac(new DESEngine()));
+ }
+ }
+
+ /**
+ * DES9797Alg3with7816-4Padding
+ *
+ public static class DES9797Alg3with7816d4
+ extends BaseMac
+ {
+ public DES9797Alg3with7816d4()
+ {
+ super(new ISO9797Alg3Mac(new DESEngine(), new ISO7816d4Padding()));
+ }
+ }
+
+ /**
+ * DES9797Alg3
+ *
+ public static class DES9797Alg3
+ extends BaseMac
+ {
+ public DES9797Alg3()
+ {
+ super(new ISO9797Alg3Mac(new DESEngine()));
+ }
+ }
+
+ public static class RFC3211
+ extends BaseWrapCipher
+ {
+ public RFC3211()
+ {
+ super(new RFC3211WrapEngine(new DESEngine()), 8);
+ }
+ }
+
+ public static class AlgParamGen
+ extends BaseAlgorithmParameterGenerator
+ {
+ protected void engineInit(
+ AlgorithmParameterSpec genParamSpec,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for DES parameter generation.");
+ }
+
+ protected AlgorithmParameters engineGenerateParameters()
+ {
+ byte[] iv = new byte[8];
+
+ if (random == null)
+ {
+ random = CryptoServicesRegistrar.getSecureRandom();
+ }
+
+ random.nextBytes(iv);
+
+ AlgorithmParameters params;
+
+ try
+ {
+ params = createParametersInstance("DES");
+ params.init(new IvParameterSpec(iv));
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.getMessage());
+ }
+
+ return params;
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * DES - the default for this is to generate a key in
+ * a-b-a format that's 24 bytes long but has 16 bytes of
+ * key material (the first 8 bytes is repeated as the last
+ * 8 bytes). If you give it a size, you'll get just what you
+ * asked for.
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyGenerator
+ extends BaseKeyGenerator
+ {
+ public KeyGenerator()
+ {
+ super("DES", 64, new DESKeyGenerator());
+ }
+
+ protected void engineInit(
+ int keySize,
+ SecureRandom random)
+ {
+ super.engineInit(keySize, random);
+ }
+
+ protected SecretKey engineGenerateKey()
+ {
+ if (uninitialised)
+ {
+ engine.init(new KeyGenerationParameters(CryptoServicesRegistrar.getSecureRandom(), defaultKeySize));
+ uninitialised = false;
+ }
+
+ return new SecretKeySpec(engine.generateKey(), algName);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class KeyFactory
+ extends BaseSecretKeyFactory
+ {
+ public KeyFactory()
+ {
+ super("DES", null);
+ }
+
+ protected KeySpec engineGetKeySpec(
+ SecretKey key,
+ Class keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec == null)
+ {
+ throw new InvalidKeySpecException("keySpec parameter is null");
+ }
+ if (key == null)
+ {
+ throw new InvalidKeySpecException("key parameter is null");
+ }
+
+ if (SecretKeySpec.class.isAssignableFrom(keySpec))
+ {
+ return new SecretKeySpec(key.getEncoded(), algName);
+ }
+ else if (DESKeySpec.class.isAssignableFrom(keySpec))
+ {
+ byte[] bytes = key.getEncoded();
+
+ try
+ {
+ return new DESKeySpec(bytes);
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeySpecException(e.toString());
+ }
+ }
+
+ throw new InvalidKeySpecException("Invalid KeySpec");
+ }
+
+ protected SecretKey engineGenerateSecret(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof DESKeySpec)
+ {
+ DESKeySpec desKeySpec = (DESKeySpec)keySpec;
+ return new SecretKeySpec(desKeySpec.getKey(), "DES");
+ }
+
+ return super.engineGenerateSecret(keySpec);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class DESPBEKeyFactory
+ extends BaseSecretKeyFactory
+ {
+ private boolean forCipher;
+ private int scheme;
+ private int digest;
+ private int keySize;
+ private int ivSize;
+
+ public DESPBEKeyFactory(
+ String algorithm,
+ ASN1ObjectIdentifier oid,
+ boolean forCipher,
+ int scheme,
+ int digest,
+ int keySize,
+ int ivSize)
+ {
+ super(algorithm, oid);
+
+ this.forCipher = forCipher;
+ this.scheme = scheme;
+ this.digest = digest;
+ this.keySize = keySize;
+ this.ivSize = ivSize;
+ }
+
+ protected SecretKey engineGenerateSecret(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof PBEKeySpec)
+ {
+ PBEKeySpec pbeSpec = (PBEKeySpec)keySpec;
+ CipherParameters param;
+
+ if (pbeSpec.getSalt() == null)
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ if (scheme == PKCS5S1 || scheme == PKCS5S1_UTF8)
+ {
+ return new PBKDF1Key(pbeSpec.getPassword(),
+ scheme == PKCS5S1 ? PasswordConverter.ASCII : PasswordConverter.UTF8);
+ }
+ else
+ {
+ */
+ // END Android-removed: Unsupported algorithms
+ return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, null);
+ /*
+ }
+ */
+ }
+
+ if (forCipher)
+ {
+ param = PBE.Util.makePBEParameters(pbeSpec, scheme, digest, keySize, ivSize);
+ }
+ else
+ {
+ param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize);
+ }
+
+ KeyParameter kParam;
+ if (param instanceof ParametersWithIV)
+ {
+ kParam = (KeyParameter)((ParametersWithIV)param).getParameters();
+ }
+ else
+ {
+ kParam = (KeyParameter)param;
+ }
+
+ DESParameters.setOddParity(kParam.getKey());
+
+ return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param);
+ }
+
+ throw new InvalidKeySpecException("Invalid KeySpec");
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ /**
+ * PBEWithMD2AndDES
+ *
+ static public class PBEWithMD2KeyFactory
+ extends DESPBEKeyFactory
+ {
+ public PBEWithMD2KeyFactory()
+ {
+ super("PBEwithMD2andDES", PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, true, PKCS5S1, MD2, 64, 64);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * PBEWithMD5AndDES
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithMD5KeyFactory
+ extends DESPBEKeyFactory
+ {
+ public PBEWithMD5KeyFactory()
+ {
+ super("PBEwithMD5andDES", PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, true, PKCS5S1, MD5, 64, 64);
+ }
+ }
+
+ /**
+ * PBEWithSHA1AndDES
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHA1KeyFactory
+ extends DESPBEKeyFactory
+ {
+ public PBEWithSHA1KeyFactory()
+ {
+ super("PBEwithSHA1andDES", PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, true, PKCS5S1, SHA1, 64, 64);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ /**
+ * PBEWithMD2AndDES
+ *
+ static public class PBEWithMD2
+ extends BaseBlockCipher
+ {
+ public PBEWithMD2()
+ {
+ super(new CBCBlockCipher(new DESEngine()), PKCS5S1, MD2, 64, 8);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * PBEWithMD5AndDES
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithMD5
+ extends BaseBlockCipher
+ {
+ public PBEWithMD5()
+ {
+ super(new CBCBlockCipher(new DESEngine()), PKCS5S1, MD5, 64, 8);
+ }
+ }
+
+ /**
+ * PBEWithSHA1AndDES
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHA1
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA1()
+ {
+ super(new CBCBlockCipher(new DESEngine()), PKCS5S1, SHA1, 64, 8);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AlgorithmProvider
+ {
+ private static final String PREFIX = DES.class.getName();
+ private static final String PACKAGE = "com.android.internal.org.bouncycastle.jcajce.provider.symmetric"; // JDK 1.2
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+
+ provider.addAlgorithm("Cipher.DES", PREFIX + "$ECB");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("Cipher", OIWObjectIdentifiers.desCBC, PREFIX + "$CBC");
+
+ addAlias(provider, OIWObjectIdentifiers.desCBC, "DES");
+
+ provider.addAlgorithm("Cipher.DESRFC3211WRAP", PREFIX + "$RFC3211");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ provider.addAlgorithm("KeyGenerator.DES", PREFIX + "$KeyGenerator");
+
+ provider.addAlgorithm("SecretKeyFactory.DES", PREFIX + "$KeyFactory");
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("Mac.DESCMAC", PREFIX + "$CMAC");
+ provider.addAlgorithm("Mac.DESMAC", PREFIX + "$CBCMAC");
+ provider.addAlgorithm("Alg.Alias.Mac.DES", "DESMAC");
+
+ provider.addAlgorithm("Mac.DESMAC/CFB8", PREFIX + "$DESCFB8");
+ provider.addAlgorithm("Alg.Alias.Mac.DES/CFB8", "DESMAC/CFB8");
+
+ provider.addAlgorithm("Mac.DESMAC64", PREFIX + "$DES64");
+ provider.addAlgorithm("Alg.Alias.Mac.DES64", "DESMAC64");
+
+ provider.addAlgorithm("Mac.DESMAC64WITHISO7816-4PADDING", PREFIX + "$DES64with7816d4");
+ provider.addAlgorithm("Alg.Alias.Mac.DES64WITHISO7816-4PADDING", "DESMAC64WITHISO7816-4PADDING");
+ provider.addAlgorithm("Alg.Alias.Mac.DESISO9797ALG1MACWITHISO7816-4PADDING", "DESMAC64WITHISO7816-4PADDING");
+ provider.addAlgorithm("Alg.Alias.Mac.DESISO9797ALG1WITHISO7816-4PADDING", "DESMAC64WITHISO7816-4PADDING");
+
+ provider.addAlgorithm("Mac.DESWITHISO9797", PREFIX + "$DES9797Alg3");
+ provider.addAlgorithm("Alg.Alias.Mac.DESISO9797MAC", "DESWITHISO9797");
+
+ provider.addAlgorithm("Mac.ISO9797ALG3MAC", PREFIX + "$DES9797Alg3");
+ provider.addAlgorithm("Alg.Alias.Mac.ISO9797ALG3", "ISO9797ALG3MAC");
+ provider.addAlgorithm("Mac.ISO9797ALG3WITHISO7816-4PADDING", PREFIX + "$DES9797Alg3with7816d4");
+ provider.addAlgorithm("Alg.Alias.Mac.ISO9797ALG3MACWITHISO7816-4PADDING", "ISO9797ALG3WITHISO7816-4PADDING");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ provider.addAlgorithm("AlgorithmParameters.DES", PACKAGE + ".util.IvAlgorithmParameters");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters", OIWObjectIdentifiers.desCBC, "DES");
+
+ // BEGIN Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("AlgorithmParameterGenerator.DES", PREFIX + "$AlgParamGen");
+ // provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + OIWObjectIdentifiers.desCBC, "DES");
+ //
+ // provider.addAlgorithm("Cipher.PBEWITHMD2ANDDES", PREFIX + "$PBEWithMD2");
+ // END Android-removed: Unsupported algorithms
+ provider.addAlgorithm("Cipher.PBEWITHMD5ANDDES", PREFIX + "$PBEWithMD5");
+ provider.addAlgorithm("Cipher.PBEWITHSHA1ANDDES", PREFIX + "$PBEWithSHA1");
+
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, "PBEWITHMD2ANDDES");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES");
+
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHMD2ANDDES-CBC", "PBEWITHMD2ANDDES");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHMD5ANDDES-CBC", "PBEWITHMD5ANDDES");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDDES-CBC", "PBEWITHSHA1ANDDES");
+
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("SecretKeyFactory.PBEWITHMD2ANDDES", PREFIX + "$PBEWithMD2KeyFactory");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5ANDDES", PREFIX + "$PBEWithMD5KeyFactory");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA1ANDDES", PREFIX + "$PBEWithSHA1KeyFactory");
+
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHMD2ANDDES-CBC", "PBEWITHMD2ANDDES");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHMD5ANDDES-CBC", "PBEWITHMD5ANDDES");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1ANDDES-CBC", "PBEWITHSHA1ANDDES");
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, "PBEWITHMD2ANDDES");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES");
+ }
+
+ private void addAlias(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name)
+ {
+ provider.addAlgorithm("Alg.Alias.KeyGenerator." + oid.getId(), name);
+ provider.addAlgorithm("Alg.Alias.KeyFactory." + oid.getId(), name);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/DESede.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/DESede.java
new file mode 100644
index 00000000..ea07f691
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/DESede.java
@@ -0,0 +1,512 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric;
+
+// Android-removed: Unsupported algorithms
+// import java.security.AlgorithmParameters;
+// import java.security.InvalidAlgorithmParameterException;
+import java.security.SecureRandom;
+// Android-removed: Unsupported algorithms
+// import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.DESedeKeySpec;
+// Android-removed: Unsupported algorithms
+// import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+import com.android.internal.org.bouncycastle.crypto.engines.DESedeEngine;
+import com.android.internal.org.bouncycastle.crypto.engines.DESedeWrapEngine;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.engines.RFC3211WrapEngine;
+import com.android.internal.org.bouncycastle.crypto.generators.DESedeKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.macs.CBCBlockCipherMac;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.macs.CFBBlockCipherMac;
+// import org.bouncycastle.crypto.macs.CMac;
+import com.android.internal.org.bouncycastle.crypto.modes.CBCBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.paddings.ISO7816d4Padding;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class DESede
+{
+ private DESede()
+ {
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class ECB
+ extends BaseBlockCipher
+ {
+ public ECB()
+ {
+ super(new DESedeEngine());
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class CBC
+ extends BaseBlockCipher
+ {
+ public CBC()
+ {
+ super(new CBCBlockCipher(new DESedeEngine()), 64);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ /**
+ * DESede CFB8
+ *
+ public static class DESedeCFB8
+ extends BaseMac
+ {
+ public DESedeCFB8()
+ {
+ super(new CFBBlockCipherMac(new DESedeEngine()));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * DESede64
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class DESede64
+ extends BaseMac
+ {
+ public DESede64()
+ {
+ super(new CBCBlockCipherMac(new DESedeEngine(), 64));
+ }
+ }
+
+ /**
+ * DESede64with7816-4Padding
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class DESede64with7816d4
+ extends BaseMac
+ {
+ public DESede64with7816d4()
+ {
+ super(new CBCBlockCipherMac(new DESedeEngine(), 64, new ISO7816d4Padding()));
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class CBCMAC
+ extends BaseMac
+ {
+ public CBCMAC()
+ {
+ super(new CBCBlockCipherMac(new DESedeEngine()));
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ static public class CMAC
+ extends BaseMac
+ {
+ public CMAC()
+ {
+ super(new CMac(new DESedeEngine()));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Wrap
+ extends BaseWrapCipher
+ {
+ public Wrap()
+ {
+ super(new DESedeWrapEngine());
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class RFC3211
+ extends BaseWrapCipher
+ {
+ public RFC3211()
+ {
+ super(new RFC3211WrapEngine(new DESedeEngine()), 8);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * DESede - the default for this is to generate a key in
+ * a-b-a format that's 24 bytes long but has 16 bytes of
+ * key material (the first 8 bytes is repeated as the last
+ * 8 bytes). If you give it a size, you'll get just what you
+ * asked for.
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyGenerator
+ extends BaseKeyGenerator
+ {
+ private boolean keySizeSet = false;
+
+ public KeyGenerator()
+ {
+ super("DESede", 192, new DESedeKeyGenerator());
+ }
+
+ protected void engineInit(
+ int keySize,
+ SecureRandom random)
+ {
+ super.engineInit(keySize, random);
+ keySizeSet = true;
+ }
+
+ protected SecretKey engineGenerateKey()
+ {
+ if (uninitialised)
+ {
+ engine.init(new KeyGenerationParameters(CryptoServicesRegistrar.getSecureRandom(), defaultKeySize));
+ uninitialised = false;
+ }
+
+ //
+ // if no key size has been defined generate a 24 byte key in
+ // the a-b-a format
+ //
+ if (!keySizeSet)
+ {
+ byte[] k = engine.generateKey();
+
+ System.arraycopy(k, 0, k, 16, 8);
+
+ return new SecretKeySpec(k, algName);
+ }
+ else
+ {
+ return new SecretKeySpec(engine.generateKey(), algName);
+ }
+ }
+ }
+
+ /**
+ * generate a desEDE key in the a-b-c format.
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class KeyGenerator3
+ extends BaseKeyGenerator
+ {
+ public KeyGenerator3()
+ {
+ super("DESede3", 192, new DESedeKeyGenerator());
+ }
+ }
+
+ /**
+ * PBEWithSHAAnd3-KeyTripleDES-CBC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAndDES3Key
+ extends BaseBlockCipher
+ {
+ public PBEWithSHAAndDES3Key()
+ {
+ super(new CBCBlockCipher(new DESedeEngine()), PKCS12, SHA1, 192, 8);
+ }
+ }
+
+ /**
+ * PBEWithSHAAnd2-KeyTripleDES-CBC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAndDES2Key
+ extends BaseBlockCipher
+ {
+ public PBEWithSHAAndDES2Key()
+ {
+ super(new CBCBlockCipher(new DESedeEngine()), PKCS12, SHA1, 128, 8);
+ }
+ }
+
+ /**
+ * PBEWithSHAAnd3-KeyTripleDES-CBC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAndDES3KeyFactory
+ extends DES.DESPBEKeyFactory
+ {
+ public PBEWithSHAAndDES3KeyFactory()
+ {
+ super("PBEwithSHAandDES3Key-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, true, PKCS12, SHA1, 192, 64);
+ }
+ }
+
+ /**
+ * PBEWithSHAAnd2-KeyTripleDES-CBC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAndDES2KeyFactory
+ extends DES.DESPBEKeyFactory
+ {
+ public PBEWithSHAAndDES2KeyFactory()
+ {
+ super("PBEwithSHAandDES2Key-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, true, PKCS12, SHA1, 128, 64);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class AlgParamGen
+ extends BaseAlgorithmParameterGenerator
+ {
+ protected void engineInit(
+ AlgorithmParameterSpec genParamSpec,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for DES parameter generation.");
+ }
+
+ protected AlgorithmParameters engineGenerateParameters()
+ {
+ byte[] iv = new byte[8];
+
+ if (random == null)
+ {
+ random = CryptoServicesRegistrar.getSecureRandom();
+ }
+
+ random.nextBytes(iv);
+
+ AlgorithmParameters params;
+
+ try
+ {
+ params = createParametersInstance("DES");
+ params.init(new IvParameterSpec(iv));
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.getMessage());
+ }
+
+ return params;
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class KeyFactory
+ extends BaseSecretKeyFactory
+ {
+ public KeyFactory()
+ {
+ super("DESede", null);
+ }
+
+ protected KeySpec engineGetKeySpec(
+ SecretKey key,
+ Class keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec == null)
+ {
+ throw new InvalidKeySpecException("keySpec parameter is null");
+ }
+ if (key == null)
+ {
+ throw new InvalidKeySpecException("key parameter is null");
+ }
+
+ if (SecretKeySpec.class.isAssignableFrom(keySpec))
+ {
+ return new SecretKeySpec(key.getEncoded(), algName);
+ }
+ else if (DESedeKeySpec.class.isAssignableFrom(keySpec))
+ {
+ byte[] bytes = key.getEncoded();
+
+ try
+ {
+ if (bytes.length == 16)
+ {
+ byte[] longKey = new byte[24];
+
+ System.arraycopy(bytes, 0, longKey, 0, 16);
+ System.arraycopy(bytes, 0, longKey, 16, 8);
+
+ return new DESedeKeySpec(longKey);
+ }
+ else
+ {
+ return new DESedeKeySpec(bytes);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeySpecException(e.toString());
+ }
+ }
+
+ throw new InvalidKeySpecException("Invalid KeySpec");
+ }
+
+ protected SecretKey engineGenerateSecret(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof DESedeKeySpec)
+ {
+ DESedeKeySpec desKeySpec = (DESedeKeySpec)keySpec;
+ return new SecretKeySpec(desKeySpec.getKey(), "DESede");
+ }
+
+ return super.engineGenerateSecret(keySpec);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AlgorithmProvider
+ {
+ private static final String PREFIX = DESede.class.getName();
+ private static final String PACKAGE = "com.android.internal.org.bouncycastle.jcajce.provider.symmetric"; // JDK 1.2
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("Cipher.DESEDE", PREFIX + "$ECB");
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("Cipher", PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$CBC");
+ provider.addAlgorithm("Cipher.DESEDEWRAP", PREFIX + "$Wrap");
+ // BEGIN Android-changed: Make alias of DESEDEWRAP rather than separate algorithm
+ provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.id_alg_CMS3DESwrap, "DESEDEWRAP");
+ // END Android-changed: Make alias of DESEDEWRAP rather than separate algorithm
+ // BEGIN Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("Cipher.DESEDERFC3211WRAP", PREFIX + "$RFC3211");
+ // provider.addAlgorithm("Alg.Alias.Cipher.DESEDERFC3217WRAP", "DESEDEWRAP");
+ // END Android-removed: Unsupported algorithms
+
+ provider.addAlgorithm("Alg.Alias.Cipher.TDEA", "DESEDE");
+ provider.addAlgorithm("Alg.Alias.Cipher.TDEAWRAP", "DESEDEWRAP");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("Alg.Alias.KeyGenerator.TDEA", "DESEDE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.TDEA", "DESEDE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator.TDEA", "DESEDE");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.TDEA", "DESEDE");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ // Android-removed Bouncy Castle's SHA-1 implementation is removed but we still need PBEWithSHAAnd3-KeyTripleDES-CBC
+ // if (provider.hasAlgorithm("MessageDigest", "SHA-1"))
+ {
+ provider.addAlgorithm("Cipher.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES3Key");
+ provider.addAlgorithm("Cipher.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES2Key");
+
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDDESEDE", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND3-KEYTRIPLEDES-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND2-KEYTRIPLEDES-CBC", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND3-KEYDESEDE-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND2-KEYDESEDE-CBC", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND3-KEYDESEDE-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND2-KEYDESEDE-CBC", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDDESEDE-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("KeyGenerator.DESEDE", PREFIX + "$KeyGenerator");
+ provider.addAlgorithm("KeyGenerator." + PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$KeyGenerator3");
+ provider.addAlgorithm("KeyGenerator.DESEDEWRAP", PREFIX + "$KeyGenerator");
+
+ provider.addAlgorithm("SecretKeyFactory.DESEDE", PREFIX + "$KeyFactory");
+
+ provider.addAlgorithm("SecretKeyFactory", OIWObjectIdentifiers.desEDE, PREFIX + "$KeyFactory");
+
+ provider.addAlgorithm("Mac.DESEDECMAC", PREFIX + "$CMAC");
+ provider.addAlgorithm("Mac.DESEDEMAC", PREFIX + "$CBCMAC");
+ provider.addAlgorithm("Alg.Alias.Mac.DESEDE", "DESEDEMAC");
+
+ provider.addAlgorithm("Mac.DESEDEMAC/CFB8", PREFIX + "$DESedeCFB8");
+ provider.addAlgorithm("Alg.Alias.Mac.DESEDE/CFB8", "DESEDEMAC/CFB8");
+
+ provider.addAlgorithm("Mac.DESEDEMAC64", PREFIX + "$DESede64");
+ provider.addAlgorithm("Alg.Alias.Mac.DESEDE64", "DESEDEMAC64");
+
+ provider.addAlgorithm("Mac.DESEDEMAC64WITHISO7816-4PADDING", PREFIX + "$DESede64with7816d4");
+ provider.addAlgorithm("Alg.Alias.Mac.DESEDE64WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
+ provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1MACWITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
+ provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
+
+ provider.addAlgorithm("AlgorithmParameters.DESEDE", PACKAGE + ".util.IvAlgorithmParameters");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ // BEGIN Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("AlgorithmParameterGenerator.DESEDE", PREFIX + "$AlgParamGen");
+ // provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE");
+ // END Android-removed: Unsupported algorithms
+
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES3KeyFactory");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES2KeyFactory");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1ANDDESEDE", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
+
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND3-KEYTRIPLEDES", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND2-KEYTRIPLEDES", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDDES3KEY-CBC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDDES2KEY-CBC", "PKCS12PBE");
+
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBE", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.3", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.4", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWithSHAAnd3KeyTripleDES", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.3", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.4", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWithSHAAnd3KeyTripleDES", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java
new file mode 100644
index 00000000..55feea6b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java
@@ -0,0 +1,68 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.cms.GCMParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.ClassUtil;
+import com.android.internal.org.bouncycastle.util.Integers;
+
+class GcmSpecUtil
+{
+ static final Class gcmSpecClass = ClassUtil.loadClass(GcmSpecUtil.class, "javax.crypto.spec.GCMParameterSpec");
+
+ static boolean gcmSpecExists()
+ {
+ return gcmSpecClass != null;
+ }
+
+ static boolean isGcmSpec(AlgorithmParameterSpec paramSpec)
+ {
+ return gcmSpecClass != null && gcmSpecClass.isInstance(paramSpec);
+ }
+
+ static boolean isGcmSpec(Class paramSpecClass)
+ {
+ return gcmSpecClass == paramSpecClass;
+ }
+
+ static AlgorithmParameterSpec extractGcmSpec(ASN1Primitive spec)
+ throws InvalidParameterSpecException
+ {
+ try
+ {
+ GCMParameters gcmParams = GCMParameters.getInstance(spec);
+ Constructor constructor = gcmSpecClass.getConstructor(new Class[]{Integer.TYPE, byte[].class});
+
+ return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(gcmParams.getIcvLen() * 8), gcmParams.getNonce() });
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new InvalidParameterSpecException("No constructor found!"); // should never happen
+ }
+ catch (Exception e)
+ {
+ throw new InvalidParameterSpecException("Construction failed: " + e.getMessage()); // should never happen
+ }
+ }
+
+ static GCMParameters extractGcmParameters(AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ try
+ {
+ Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]);
+ Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]);
+
+ return new GCMParameters((byte[])iv.invoke(paramSpec, new Object[0]), ((Integer)tLen.invoke(paramSpec, new Object[0])).intValue() / 8);
+ }
+ catch (Exception e)
+ {
+ throw new InvalidParameterSpecException("Cannot process GCMParameterSpec");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
new file mode 100644
index 00000000..ab218e1f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
@@ -0,0 +1,692 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric;
+
+import java.io.IOException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.KeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
+// import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PBKDF2Params;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+// Android-removed: Unneeded imports of files we don't include
+// import org.bouncycastle.crypto.PasswordConverter;
+// import org.bouncycastle.jcajce.PBKDF2Key;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.PBE;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
+import com.android.internal.org.bouncycastle.jcajce.spec.PBKDF2KeySpec;
+import com.android.internal.org.bouncycastle.util.Integers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PBEPBKDF2
+{
+ private static final Map prfCodes = new HashMap();
+
+ 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));
+ 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));
+ prfCodes.put(NISTObjectIdentifiers.id_hmacWithSHA3_512, Integers.valueOf(PBE.SHA3_512));
+ prfCodes.put(GMObjectIdentifiers.hmac_sm3, Integers.valueOf(PBE.SM3));
+ */
+ // END Android-removed: Unsupported algorithm
+ }
+
+ private PBEPBKDF2()
+ {
+
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class AlgParams
+ extends BaseAlgorithmParameters
+ {
+ PBKDF2Params params;
+
+ protected byte[] engineGetEncoded()
+ {
+ try
+ {
+ return params.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Oooops! " + e.toString());
+ }
+ }
+
+ protected byte[] engineGetEncoded(
+ String format)
+ {
+ if (this.isASN1FormatString(format))
+ {
+ return engineGetEncoded();
+ }
+
+ return null;
+ }
+
+ protected AlgorithmParameterSpec localEngineGetParameterSpec(
+ Class paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec == PBEParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
+ {
+ return new PBEParameterSpec(params.getSalt(),
+ params.getIterationCount().intValue());
+ }
+
+ throw new InvalidParameterSpecException("unknown parameter spec passed to PBKDF2 PBE parameters object.");
+ }
+
+ protected void engineInit(
+ AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (!(paramSpec instanceof PBEParameterSpec))
+ {
+ throw new InvalidParameterSpecException("PBEParameterSpec required to initialise a PBKDF2 PBE parameters algorithm parameters object");
+ }
+
+ PBEParameterSpec pbeSpec = (PBEParameterSpec)paramSpec;
+
+ this.params = new PBKDF2Params(pbeSpec.getSalt(),
+ pbeSpec.getIterationCount());
+ }
+
+ protected void engineInit(
+ byte[] params)
+ throws IOException
+ {
+ this.params = PBKDF2Params.getInstance(ASN1Primitive.fromByteArray(params));
+ }
+
+ protected void engineInit(
+ byte[] params,
+ String format)
+ throws IOException
+ {
+ if (this.isASN1FormatString(format))
+ {
+ engineInit(params);
+ return;
+ }
+
+ throw new IOException("Unknown parameters format in PBKDF2 parameters object");
+ }
+
+ protected String engineToString()
+ {
+ return "PBKDF2 Parameters";
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class BasePBKDF2
+ extends BaseSecretKeyFactory
+ {
+ private int scheme;
+ // BEGIN Android-added: Allow to specify a key using only the password.
+ private int keySizeInBits;
+ private int ivSizeInBits;
+ // END Android-added: Allow to specify a key using only the password.
+ private int defaultDigest;
+
+ public BasePBKDF2(String name, int scheme)
+ {
+ this(name, scheme, SHA1);
+ }
+
+ // BEGIN Android-changed: Allow to specify a key using only the password.
+ // public BasePBKDF2(String name, int scheme, int defaultDigest)
+ private BasePBKDF2(
+ String name, int scheme, int digest, int keySizeInBits, int ivSizeInBits)
+ // END Android-changed: Allow to specify a key using only the password.
+ {
+ super(name, PKCSObjectIdentifiers.id_PBKDF2);
+
+ this.scheme = scheme;
+ // BEGIN Android-added: Support key-restricted versions.
+ this.keySizeInBits = keySizeInBits;
+ this.ivSizeInBits = ivSizeInBits;
+ // END Android-added: Support key-restricted versions.
+ this.defaultDigest = digest;
+ }
+
+ // BEGIN Android-added: Allow to specify a key using only the password.
+ private BasePBKDF2(String name, int scheme, int digest) {
+ this(name, scheme, digest, 0, 0);
+ }
+ // END Android-added: Allow to specify a key using only the password.
+
+ protected SecretKey engineGenerateSecret(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof PBEKeySpec)
+ {
+ PBEKeySpec pbeSpec = (PBEKeySpec)keySpec;
+
+ // BEGIN Android-added: Allow to specify a key using only the password.
+ // The key will be generated later when other parameters are known.
+ if (pbeSpec.getSalt() == null
+ && pbeSpec.getIterationCount() == 0
+ && pbeSpec.getKeyLength() == 0
+ && pbeSpec.getPassword().length > 0
+ && keySizeInBits != 0) {
+ return new BCPBEKey(
+ this.algName, this.algOid, scheme, defaultDigest, keySizeInBits,
+ ivSizeInBits, pbeSpec,
+ // cipherParameters, to be generated when the PBE parameters are known.
+ null);
+ }
+ // END Android-added: Allow to specify a key using only the password.
+
+ if (pbeSpec.getSalt() == null)
+ {
+ // Android-changed: Throw an exception if the salt is missing
+ // return new PBKDF2Key(((PBEKeySpec)keySpec).getPassword(),
+ // scheme == PKCS5S2 ? PasswordConverter.ASCII : PasswordConverter.UTF8);
+ throw new InvalidKeySpecException("missing required salt");
+ }
+
+ if (pbeSpec.getIterationCount() <= 0)
+ {
+ throw new InvalidKeySpecException("positive iteration count required: "
+ + pbeSpec.getIterationCount());
+ }
+
+ if (pbeSpec.getKeyLength() <= 0)
+ {
+ throw new InvalidKeySpecException("positive key length required: "
+ + pbeSpec.getKeyLength());
+ }
+
+ if (pbeSpec.getPassword().length == 0)
+ {
+ throw new IllegalArgumentException("password empty");
+ }
+
+ if (pbeSpec instanceof PBKDF2KeySpec)
+ {
+ PBKDF2KeySpec spec = (PBKDF2KeySpec)pbeSpec;
+
+ int digest = getDigestCode(spec.getPrf().getAlgorithm());
+ int keySize = pbeSpec.getKeyLength();
+ int ivSize = -1; // JDK 1,2 and earlier does not understand simplified version.
+ CipherParameters param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize);
+
+ return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param);
+ }
+ else
+ {
+ int digest = defaultDigest;
+ int keySize = pbeSpec.getKeyLength();
+ int ivSize = -1; // JDK 1,2 and earlier does not understand simplified version.
+ CipherParameters param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize);
+
+ return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param);
+ }
+ }
+
+ throw new InvalidKeySpecException("Invalid KeySpec");
+ }
+
+
+ private int getDigestCode(ASN1ObjectIdentifier algorithm)
+ throws InvalidKeySpecException
+ {
+ Integer code = (Integer)prfCodes.get(algorithm);
+ if (code != null)
+ {
+ return code.intValue();
+ }
+
+ throw new InvalidKeySpecException("Invalid KeySpec: unknown PRF algorithm " + algorithm);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class PBKDF2withUTF8
+ extends BasePBKDF2
+ {
+ public PBKDF2withUTF8()
+ {
+ super("PBKDF2", PKCS5S2_UTF8);
+ }
+ }
+
+ public static class PBKDF2withSHA224
+ extends BasePBKDF2
+ {
+ public PBKDF2withSHA224()
+ {
+ super("PBKDF2", PKCS5S2_UTF8, SHA224);
+ }
+ }
+
+ public static class PBKDF2withSHA256
+ extends BasePBKDF2
+ {
+ public PBKDF2withSHA256()
+ {
+ super("PBKDF2", PKCS5S2_UTF8, SHA256);
+ }
+ }
+
+ public static class PBKDF2withSHA384
+ extends BasePBKDF2
+ {
+ public PBKDF2withSHA384()
+ {
+ super("PBKDF2", PKCS5S2_UTF8, SHA384);
+ }
+ }
+
+ public static class PBKDF2withSHA512
+ extends BasePBKDF2
+ {
+ public PBKDF2withSHA512()
+ {
+ super("PBKDF2", PKCS5S2_UTF8, SHA512);
+ }
+ }
+
+ public static class PBKDF2withGOST3411
+ extends BasePBKDF2
+ {
+ public PBKDF2withGOST3411()
+ {
+ super("PBKDF2", PKCS5S2_UTF8, GOST3411);
+ }
+ }
+
+ public static class PBKDF2withSHA3_224
+ extends BasePBKDF2
+ {
+ public PBKDF2withSHA3_224()
+ {
+ super("PBKDF2", PKCS5S2_UTF8, SHA3_224);
+ }
+ }
+
+ public static class PBKDF2withSHA3_256
+ extends BasePBKDF2
+ {
+ public PBKDF2withSHA3_256()
+ {
+ super("PBKDF2", PKCS5S2_UTF8, SHA3_256);
+ }
+ }
+
+ public static class PBKDF2withSHA3_384
+ extends BasePBKDF2
+ {
+ public PBKDF2withSHA3_384()
+ {
+ super("PBKDF2", PKCS5S2_UTF8, SHA3_384);
+ }
+ }
+
+ public static class PBKDF2withSHA3_512
+ extends BasePBKDF2
+ {
+ public PBKDF2withSHA3_512()
+ {
+ super("PBKDF2", PKCS5S2_UTF8, SHA3_512);
+ }
+ }
+
+ public static class PBKDF2with8BIT
+ extends BasePBKDF2
+ {
+ public PBKDF2with8BIT()
+ {
+ super("PBKDF2", PKCS5S2);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ // BEGIN Android-added: Android implementations of PBKDF2 algorithms.
+ // See note in Mappings below.
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class BasePBKDF2WithHmacSHA1 extends BasePBKDF2 {
+ public BasePBKDF2WithHmacSHA1(String name, int scheme)
+ {
+ super(name, scheme, SHA1);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBKDF2WithHmacSHA1UTF8
+ extends BasePBKDF2WithHmacSHA1
+ {
+ public PBKDF2WithHmacSHA1UTF8()
+ {
+ super("PBKDF2WithHmacSHA1", PKCS5S2_UTF8);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBKDF2WithHmacSHA18BIT
+ extends BasePBKDF2WithHmacSHA1
+ {
+ public PBKDF2WithHmacSHA18BIT()
+ {
+ super("PBKDF2WithHmacSHA1And8bit", PKCS5S2);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class BasePBKDF2WithHmacSHA224 extends BasePBKDF2 {
+ public BasePBKDF2WithHmacSHA224(String name, int scheme)
+ {
+ super(name, scheme, SHA224);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBKDF2WithHmacSHA224UTF8
+ extends BasePBKDF2WithHmacSHA224
+ {
+ public PBKDF2WithHmacSHA224UTF8()
+ {
+ super("PBKDF2WithHmacSHA224", PKCS5S2_UTF8);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class BasePBKDF2WithHmacSHA256 extends BasePBKDF2 {
+ public BasePBKDF2WithHmacSHA256(String name, int scheme)
+ {
+ super(name, scheme, SHA256);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBKDF2WithHmacSHA256UTF8
+ extends BasePBKDF2WithHmacSHA256
+ {
+ public PBKDF2WithHmacSHA256UTF8()
+ {
+ super("PBKDF2WithHmacSHA256", PKCS5S2_UTF8);
+ }
+ }
+
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class BasePBKDF2WithHmacSHA384 extends BasePBKDF2 {
+ public BasePBKDF2WithHmacSHA384(String name, int scheme)
+ {
+ super(name, scheme, SHA384);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBKDF2WithHmacSHA384UTF8
+ extends BasePBKDF2WithHmacSHA384
+ {
+ public PBKDF2WithHmacSHA384UTF8()
+ {
+ super("PBKDF2WithHmacSHA384", PKCS5S2_UTF8);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class BasePBKDF2WithHmacSHA512 extends BasePBKDF2 {
+ public BasePBKDF2WithHmacSHA512(String name, int scheme)
+ {
+ super(name, scheme, SHA512);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBKDF2WithHmacSHA512UTF8
+ extends BasePBKDF2WithHmacSHA512
+ {
+ public PBKDF2WithHmacSHA512UTF8()
+ {
+ super("PBKDF2WithHmacSHA512", PKCS5S2_UTF8);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA1AndAES_128
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA1AndAES_128() {
+ super("PBEWithHmacSHA1AndAES_128", PKCS5S2_UTF8, SHA1, 128, 128);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA224AndAES_128
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA224AndAES_128() {
+ super("PBEWithHmacSHA224AndAES_128", PKCS5S2_UTF8, SHA224, 128, 128);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA256AndAES_128
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA256AndAES_128() {
+ super("PBEWithHmacSHA256AndAES_128", PKCS5S2_UTF8, SHA256, 128, 128);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA384AndAES_128
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA384AndAES_128() {
+ super("PBEWithHmacSHA384AndAES_128", PKCS5S2_UTF8, SHA384, 128, 128);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA512AndAES_128
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA512AndAES_128() {
+ super("PBEWithHmacSHA512AndAES_128", PKCS5S2_UTF8, SHA512, 128, 128);
+ }
+ }
+
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA1AndAES_256
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA1AndAES_256() {
+ super("PBEWithHmacSHA1AndAES_256", PKCS5S2_UTF8, SHA1, 256, 128);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA224AndAES_256
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA224AndAES_256() {
+ super("PBEWithHmacSHA224AndAES_256", PKCS5S2_UTF8, SHA224, 256, 128);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA256AndAES_256
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA256AndAES_256() {
+ super("PBEWithHmacSHA256AndAES_256", PKCS5S2_UTF8, SHA256, 256, 128);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA384AndAES_256
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA384AndAES_256() {
+ super("PBEWithHmacSHA384AndAES_256", PKCS5S2_UTF8, SHA384, 256, 128);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA512AndAES_256
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA512AndAES_256() {
+ super("PBEWithHmacSHA512AndAES_256", PKCS5S2_UTF8, SHA512, 256, 128);
+ }
+ }
+ // END Android-added: Android implementations of PBKDF2 algorithms.
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class PBKDF2withSM3
+ extends BasePBKDF2
+ {
+ public PBKDF2withSM3() {
+ super("PBKDF2", PKCS5S2_UTF8, SM3);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AlgorithmProvider
+ {
+ private static final String PREFIX = PBEPBKDF2.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // Android-note: Provided classes differ significantly from upstream.
+ // Before BC 1.56, this class was omitted in Android and the algorithms we desired
+ // were provided in org.bouncycastle.jcajce.provider.digest.SHA1. During that
+ // time, Android added some additional versions of these algorithms for fixed key sizes.
+ // BC eventually consolidated the algorithms into this class. As a result, when
+ // upgrading to BC 1.56, we added this class but replaced its contents with
+ // our versions.
+ // BEGIN Android-removed: Bouncy Castle versions of algorithms.
+ /*
+ provider.addAlgorithm("AlgorithmParameters.PBKDF2", PREFIX + "$AlgParams");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.id_PBKDF2, "PBKDF2");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2", PREFIX + "$PBKDF2withUTF8");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WITHHMACSHA1", "PBKDF2");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WITHHMACSHA1ANDUTF8", "PBKDF2");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.id_PBKDF2, "PBKDF2");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHASCII", PREFIX + "$PBKDF2with8BIT");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WITH8BIT", "PBKDF2WITHASCII");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WITHHMACSHA1AND8BIT", "PBKDF2WITHASCII");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA224", PREFIX + "$PBKDF2withSHA224");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA256", PREFIX + "$PBKDF2withSHA256");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA384", PREFIX + "$PBKDF2withSHA384");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA512", PREFIX + "$PBKDF2withSHA512");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA3-224", PREFIX + "$PBKDF2withSHA3_224");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA3-256", PREFIX + "$PBKDF2withSHA3_256");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA3-384", PREFIX + "$PBKDF2withSHA3_384");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA3-512", PREFIX + "$PBKDF2withSHA3_512");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACGOST3411", PREFIX + "$PBKDF2withGOST3411");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSM3", PREFIX + "$PBKDF2withSM3");
+ */
+ // END Android-removed: Bouncy Castle versions of algorithms.
+ // BEGIN Android-added: Android versions of algorithms.
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WithHmacSHA1AndUTF8", "PBKDF2WithHmacSHA1");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2with8BIT", "PBKDF2WithHmacSHA1And8BIT");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2withASCII", "PBKDF2WithHmacSHA1And8BIT");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA1", PREFIX + "$PBKDF2WithHmacSHA1UTF8");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA224", PREFIX + "$PBKDF2WithHmacSHA224UTF8");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA256", PREFIX + "$PBKDF2WithHmacSHA256UTF8");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA384", PREFIX + "$PBKDF2WithHmacSHA384UTF8");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA512", PREFIX + "$PBKDF2WithHmacSHA512UTF8");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA1AndAES_128", PREFIX + "$PBEWithHmacSHA1AndAES_128");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA224AndAES_128", PREFIX + "$PBEWithHmacSHA224AndAES_128");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA256AndAES_128", PREFIX + "$PBEWithHmacSHA256AndAES_128");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA384AndAES_128", PREFIX + "$PBEWithHmacSHA384AndAES_128");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA512AndAES_128", PREFIX + "$PBEWithHmacSHA512AndAES_128");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA1AndAES_256", PREFIX + "$PBEWithHmacSHA1AndAES_256");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA224AndAES_256", PREFIX + "$PBEWithHmacSHA224AndAES_256");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA256AndAES_256", PREFIX + "$PBEWithHmacSHA256AndAES_256");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA384AndAES_256", PREFIX + "$PBEWithHmacSHA384AndAES_256");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA512AndAES_256", PREFIX + "$PBEWithHmacSHA512AndAES_256");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA1And8BIT", PREFIX + "$PBKDF2WithHmacSHA18BIT");
+ // END Android-added: Android versions of algorithms.
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java
new file mode 100644
index 00000000..66ad0d50
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java
@@ -0,0 +1,130 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric;
+
+import java.io.IOException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import javax.crypto.spec.PBEParameterSpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCS12PBEParams;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PBEPKCS12
+{
+ private PBEPKCS12()
+ {
+
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class AlgParams
+ extends BaseAlgorithmParameters
+ {
+ PKCS12PBEParams params;
+
+ protected byte[] engineGetEncoded()
+ {
+ try
+ {
+ return params.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Oooops! " + e.toString());
+ }
+ }
+
+ protected byte[] engineGetEncoded(
+ String format)
+ {
+ if (this.isASN1FormatString(format))
+ {
+ return engineGetEncoded();
+ }
+
+ return null;
+ }
+
+ protected AlgorithmParameterSpec localEngineGetParameterSpec(
+ Class paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec == PBEParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
+ {
+ return new PBEParameterSpec(params.getIV(),
+ params.getIterations().intValue());
+ }
+
+ throw new InvalidParameterSpecException("unknown parameter spec passed to PKCS12 PBE parameters object.");
+ }
+
+ protected void engineInit(
+ AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (!(paramSpec instanceof PBEParameterSpec))
+ {
+ throw new InvalidParameterSpecException("PBEParameterSpec required to initialise a PKCS12 PBE parameters algorithm parameters object");
+ }
+
+ PBEParameterSpec pbeSpec = (PBEParameterSpec)paramSpec;
+
+ this.params = new PKCS12PBEParams(pbeSpec.getSalt(),
+ pbeSpec.getIterationCount());
+ }
+
+ protected void engineInit(
+ byte[] params)
+ throws IOException
+ {
+ this.params = PKCS12PBEParams.getInstance(ASN1Primitive.fromByteArray(params));
+ }
+
+ protected void engineInit(
+ byte[] params,
+ String format)
+ throws IOException
+ {
+ if (this.isASN1FormatString(format))
+ {
+ engineInit(params);
+ return;
+ }
+
+ throw new IOException("Unknown parameters format in PKCS12 PBE parameters object");
+ }
+
+ protected String engineToString()
+ {
+ return "PKCS12 PBE Parameters";
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AlgorithmProvider
+ {
+ private static final String PREFIX = PBEPKCS12.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ provider.addAlgorithm("AlgorithmParameters.PKCS12PBE", PREFIX + "$AlgParams");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBES2AlgorithmParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBES2AlgorithmParameters.java
new file mode 100644
index 00000000..2898aa9d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBES2AlgorithmParameters.java
@@ -0,0 +1,367 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+// BEGIN android-added
+// Based on org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12
+
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric;
+
+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.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.EncryptionScheme;
+import com.android.internal.org.bouncycastle.asn1.pkcs.KeyDerivationFunc;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PBES2Parameters;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PBKDF2Params;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.PBE;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.util.Enumeration;
+
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PBES2AlgorithmParameters
+{
+ private PBES2AlgorithmParameters()
+ {
+
+ }
+
+ private static abstract class BasePBEWithHmacAlgorithmParameters
+ extends BaseAlgorithmParameters
+ {
+ private final AlgorithmIdentifier kdf;
+ private final String kdfShortName;
+ private final int keySize;
+ private final ASN1ObjectIdentifier cipherAlgorithm;
+ private final String cipherAlgorithmShortName;
+
+ private PBES2Parameters params;
+
+ private BasePBEWithHmacAlgorithmParameters(
+ ASN1ObjectIdentifier kdf,
+ String kdfShortName,
+ int keySize,
+ ASN1ObjectIdentifier cipherAlgorithm,
+ String cipherAlgorithmShortName) {
+ this.kdf = new AlgorithmIdentifier(kdf, DERNull.INSTANCE);
+ this.kdfShortName = kdfShortName;
+ this.keySize = keySize;
+ this.cipherAlgorithm = cipherAlgorithm;
+ this.cipherAlgorithmShortName = cipherAlgorithmShortName;
+ }
+
+ protected byte[] engineGetEncoded()
+ {
+ try
+ {
+ return new DERSequence(new ASN1Encodable[] {
+ PKCSObjectIdentifiers.id_PBES2,
+ params
+ }).getEncoded();
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Unable to read PBES2 parameters: " + e.toString());
+ }
+ }
+
+ protected byte[] engineGetEncoded(
+ String format)
+ {
+ if (this.isASN1FormatString(format))
+ {
+ return engineGetEncoded();
+ }
+
+ return null;
+ }
+
+ protected AlgorithmParameterSpec localEngineGetParameterSpec(
+ Class parameterSpec)
+ throws InvalidParameterSpecException
+ {
+ if (parameterSpec == PBEParameterSpec.class)
+ {
+ PBKDF2Params pbeParamSpec =
+ (PBKDF2Params) params.getKeyDerivationFunc().getParameters();
+ byte[] iv = ((ASN1OctetString) params.getEncryptionScheme().getParameters())
+ .getOctets();
+ return createPBEParameterSpec(pbeParamSpec.getSalt(),
+ pbeParamSpec.getIterationCount().intValue(),
+ iv);
+ }
+
+ throw new InvalidParameterSpecException(
+ "unknown parameter spec passed to PBES2 parameters object.");
+ }
+
+ protected void engineInit(
+ AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (!(paramSpec instanceof PBEParameterSpec))
+ {
+ throw new InvalidParameterSpecException(
+ "PBEParameterSpec required to initialise PBES2 algorithm parameters");
+ }
+
+ PBEParameterSpec pbeSpec = (PBEParameterSpec)paramSpec;
+
+ byte[] iv;
+
+ AlgorithmParameterSpec algorithmParameterSpec =
+ PBE.Util.getParameterSpecFromPBEParameterSpec(pbeSpec);
+ if (algorithmParameterSpec instanceof IvParameterSpec) {
+ iv = ((IvParameterSpec) algorithmParameterSpec).getIV();
+ } else {
+ throw new IllegalArgumentException("Expecting an IV as a parameter");
+ }
+
+ this.params = new PBES2Parameters(
+ new KeyDerivationFunc(
+ PKCSObjectIdentifiers.id_PBKDF2,
+ new PBKDF2Params(
+ pbeSpec.getSalt(), pbeSpec.getIterationCount(), keySize, kdf)),
+ new EncryptionScheme(cipherAlgorithm, new DEROctetString(iv)));
+ }
+
+ protected void engineInit(
+ byte[] params)
+ throws IOException
+ {
+ // Dual of engineGetEncoded()
+ ASN1Sequence seq = ASN1Sequence.getInstance(ASN1Primitive.fromByteArray(params));
+ Enumeration seqObjects = seq.getObjects();
+ ASN1ObjectIdentifier id = (ASN1ObjectIdentifier) seqObjects.nextElement();
+ if (!id.getId().equals(PKCSObjectIdentifiers.id_PBES2.getId())) {
+ throw new IllegalArgumentException("Invalid PBES2 parameters");
+ }
+ this.params = PBES2Parameters.getInstance(seqObjects.nextElement());
+ }
+
+ protected void engineInit(
+ byte[] params,
+ String format)
+ throws IOException
+ {
+ if (this.isASN1FormatString(format))
+ {
+ engineInit(params);
+ return;
+ }
+
+ throw new IOException("Unknown parameters format in PBES2 parameters object");
+ }
+
+ protected String engineToString()
+ {
+ return "PBES2 " + kdfShortName + " " + cipherAlgorithmShortName + " Parameters";
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA1AES128AlgorithmParameters
+ extends BasePBEWithHmacAlgorithmParameters {
+ public PBEWithHmacSHA1AES128AlgorithmParameters() {
+ super(PKCSObjectIdentifiers.id_hmacWithSHA1,
+ "HmacSHA1",
+ 16, /* keySize */
+ NISTObjectIdentifiers.id_aes128_CBC,
+ "AES128");
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA224AES128AlgorithmParameters
+ extends BasePBEWithHmacAlgorithmParameters {
+ public PBEWithHmacSHA224AES128AlgorithmParameters() {
+ super(PKCSObjectIdentifiers.id_hmacWithSHA224,
+ "HmacSHA224",
+ 16, /* keySize */
+ NISTObjectIdentifiers.id_aes128_CBC,
+ "AES128");
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA256AES128AlgorithmParameters
+ extends BasePBEWithHmacAlgorithmParameters {
+ public PBEWithHmacSHA256AES128AlgorithmParameters() {
+ super(PKCSObjectIdentifiers.id_hmacWithSHA256,
+ "HmacSHA256",
+ 16, /* keySize */
+ NISTObjectIdentifiers.id_aes128_CBC,
+ "AES128");
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA384AES128AlgorithmParameters
+ extends BasePBEWithHmacAlgorithmParameters {
+ public PBEWithHmacSHA384AES128AlgorithmParameters() {
+ super(PKCSObjectIdentifiers.id_hmacWithSHA384,
+ "HmacSHA384",
+ 16, /* keySize */
+ NISTObjectIdentifiers.id_aes128_CBC,
+ "AES128");
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA512AES128AlgorithmParameters
+ extends BasePBEWithHmacAlgorithmParameters {
+ public PBEWithHmacSHA512AES128AlgorithmParameters() {
+ super(PKCSObjectIdentifiers.id_hmacWithSHA512,
+ "HmacSHA512",
+ 16, /* keySize */
+ NISTObjectIdentifiers.id_aes128_CBC,
+ "AES128");
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA1AES256AlgorithmParameters
+ extends BasePBEWithHmacAlgorithmParameters {
+ public PBEWithHmacSHA1AES256AlgorithmParameters() {
+ super(PKCSObjectIdentifiers.id_hmacWithSHA1,
+ "HmacSHA1",
+ 32, /* keySize */
+ NISTObjectIdentifiers.id_aes256_CBC,
+ "AES256");
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA224AES256AlgorithmParameters
+ extends BasePBEWithHmacAlgorithmParameters {
+ public PBEWithHmacSHA224AES256AlgorithmParameters() {
+ super(PKCSObjectIdentifiers.id_hmacWithSHA224,
+ "HmacSHA224",
+ 32, /* keySize */
+ NISTObjectIdentifiers.id_aes256_CBC,
+ "AES256");
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA256AES256AlgorithmParameters
+ extends BasePBEWithHmacAlgorithmParameters {
+ public PBEWithHmacSHA256AES256AlgorithmParameters() {
+ super(PKCSObjectIdentifiers.id_hmacWithSHA256,
+ "HmacSHA256",
+ 32, /* keySize */
+ NISTObjectIdentifiers.id_aes256_CBC,
+ "AES256");
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA384AES256AlgorithmParameters
+ extends BasePBEWithHmacAlgorithmParameters {
+ public PBEWithHmacSHA384AES256AlgorithmParameters() {
+ super(PKCSObjectIdentifiers.id_hmacWithSHA384,
+ "HmacSHA384",
+ 32, /* keySize */
+ NISTObjectIdentifiers.id_aes256_CBC,
+ "AES256");
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class PBEWithHmacSHA512AES256AlgorithmParameters
+ extends BasePBEWithHmacAlgorithmParameters {
+ public PBEWithHmacSHA512AES256AlgorithmParameters() {
+ super(PKCSObjectIdentifiers.id_hmacWithSHA512,
+ "HmacSHA512",
+ 32, /* keySize */
+ NISTObjectIdentifiers.id_aes256_CBC,
+ "AES256");
+ }
+ }
+
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AlgorithmProvider
+ {
+ private static final String PREFIX = PBES2AlgorithmParameters.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ int[] keySizes = { 128, 256 };
+ int[] shaVariants = { 1, 224, 256, 384, 512 };
+ for (int keySize : keySizes) {
+ for (int shaVariant : shaVariants) {
+ provider.addAlgorithm(
+ "AlgorithmParameters.PBEWithHmacSHA" + shaVariant + "AndAES_" + keySize,
+ PREFIX + "$PBEWithHmacSHA" + shaVariant + "AES" + keySize
+ + "AlgorithmParameters");
+ }
+ }
+ }
+ }
+
+ /**
+ * Helper method to create a PBEParameterSpec with a parameter specification via reflection, as
+ * the constructor became available in Java 1.8 and Bouncycastle is at level 1.5.
+ */
+ private static PBEParameterSpec createPBEParameterSpec(
+ byte[] salt, int iterationCount, byte[] iv) {
+ try {
+ Class<PBEParameterSpec> pbeParameterSpecClass =
+ (Class<PBEParameterSpec>) PBES2AlgorithmParameters.class.getClassLoader()
+ .loadClass("javax.crypto.spec.PBEParameterSpec");
+ Constructor<PBEParameterSpec> constructor =
+ pbeParameterSpecClass.getConstructor(new Class[]{
+ byte[].class, int.class, AlgorithmParameterSpec.class });
+ return constructor.newInstance(salt, iterationCount, new IvParameterSpec(iv));
+ } catch (Exception e) {
+ throw new IllegalStateException(
+ "Requested creation PBES2 parameters in an SDK that doesn't support them", e);
+ }
+ }
+}
+// END android-added \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/RC2.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/RC2.java
new file mode 100644
index 00000000..0160099a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/RC2.java
@@ -0,0 +1,566 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric;
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.RC2ParameterSpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.pkcs.RC2CBCParameter;
+// import org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.engines.RC2Engine;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.engines.RC2WrapEngine;
+// import org.bouncycastle.crypto.macs.CBCBlockCipherMac;
+// import org.bouncycastle.crypto.macs.CFBBlockCipherMac;
+import com.android.internal.org.bouncycastle.crypto.modes.CBCBlockCipher;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator;
+// import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
+// import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
+// import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class RC2
+{
+ private RC2()
+ {
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ /**
+ * RC2
+ *
+ static public class ECB
+ extends BaseBlockCipher
+ {
+ public ECB()
+ {
+ super(new RC2Engine());
+ }
+ }
+
+ /**
+ * RC2CBC
+ *
+ static public class CBC
+ extends BaseBlockCipher
+ {
+ public CBC()
+ {
+ super(new CBCBlockCipher(new RC2Engine()), 64);
+ }
+ }
+
+ public static class Wrap
+ extends BaseWrapCipher
+ {
+ public Wrap()
+ {
+ super(new RC2WrapEngine());
+ }
+ }
+
+ /**
+ * RC2
+ *
+ public static class CBCMAC
+ extends BaseMac
+ {
+ public CBCMAC()
+ {
+ super(new CBCBlockCipherMac(new RC2Engine()));
+ }
+ }
+
+ public static class CFB8MAC
+ extends BaseMac
+ {
+ public CFB8MAC()
+ {
+ super(new CFBBlockCipherMac(new RC2Engine()));
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * PBEWithSHA1AndRC2
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHA1KeyFactory
+ extends PBESecretKeyFactory
+ {
+ public PBEWithSHA1KeyFactory()
+ {
+ super("PBEwithSHA1andRC2", PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC, true, PKCS5S1, SHA1, 64, 64);
+ }
+ }
+
+ /**
+ * PBEWithSHAAnd128BitRC2-CBC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAnd128BitKeyFactory
+ extends PBESecretKeyFactory
+ {
+ public PBEWithSHAAnd128BitKeyFactory()
+ {
+ super("PBEwithSHAand128BitRC2-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC, true, PKCS12, SHA1, 128, 64);
+ }
+ }
+
+ /**
+ * PBEWithSHAAnd40BitRC2-CBC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAnd40BitKeyFactory
+ extends PBESecretKeyFactory
+ {
+ public PBEWithSHAAnd40BitKeyFactory()
+ {
+ super("PBEwithSHAand40BitRC2-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC, true, PKCS12, SHA1, 40, 64);
+ }
+ }
+
+ /**
+ * PBEWithMD5AndRC2
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithMD5AndRC2
+ extends BaseBlockCipher
+ {
+ public PBEWithMD5AndRC2()
+ {
+ super(new CBCBlockCipher(new RC2Engine()), PKCS5S1, MD5, 64, 8);
+ }
+ }
+
+ /**
+ * PBEWithSHA1AndRC2
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHA1AndRC2
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA1AndRC2()
+ {
+ super(new CBCBlockCipher(new RC2Engine()), PKCS5S1, SHA1, 64, 8);
+ }
+ }
+
+ /**
+ * PBEWithSHAAnd128BitRC2-CBC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAnd128BitRC2
+ extends BaseBlockCipher
+ {
+ public PBEWithSHAAnd128BitRC2()
+ {
+ super(new CBCBlockCipher(new RC2Engine()), PKCS12, SHA1, 128, 8);
+ }
+ }
+
+ /**
+ * PBEWithSHAAnd40BitRC2-CBC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAAnd40BitRC2
+ extends BaseBlockCipher
+ {
+ public PBEWithSHAAnd40BitRC2()
+ {
+ super(new CBCBlockCipher(new RC2Engine()), PKCS12, SHA1, 40, 8);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ /**
+ * PBEWithMD2AndRC2
+ *
+ static public class PBEWithMD2KeyFactory
+ extends PBESecretKeyFactory
+ {
+ public PBEWithMD2KeyFactory()
+ {
+ super("PBEwithMD2andRC2", PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC, true, PKCS5S1, MD2, 64, 64);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * PBEWithMD5AndRC2
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithMD5KeyFactory
+ extends PBESecretKeyFactory
+ {
+ public PBEWithMD5KeyFactory()
+ {
+ super("PBEwithMD5andRC2", PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, true, PKCS5S1, MD5, 64, 64);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class AlgParamGen
+ extends BaseAlgorithmParameterGenerator
+ {
+ RC2ParameterSpec spec = null;
+
+ protected void engineInit(
+ AlgorithmParameterSpec genParamSpec,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ if (genParamSpec instanceof RC2ParameterSpec)
+ {
+ spec = (RC2ParameterSpec)genParamSpec;
+ return;
+ }
+
+ throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for RC2 parameter generation.");
+ }
+
+ protected AlgorithmParameters engineGenerateParameters()
+ {
+ AlgorithmParameters params;
+
+ if (spec == null)
+ {
+ byte[] iv = new byte[8];
+
+ if (random == null)
+ {
+ random = CryptoServicesRegistrar.getSecureRandom();
+ }
+
+ random.nextBytes(iv);
+
+ try
+ {
+ params = createParametersInstance("RC2");
+ params.init(new IvParameterSpec(iv));
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ else
+ {
+ try
+ {
+ params = createParametersInstance("RC2");
+ params.init(spec);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+
+ return params;
+ }
+ }
+
+ public static class KeyGenerator
+ extends BaseKeyGenerator
+ {
+ public KeyGenerator()
+ {
+ super("RC2", 128, new CipherKeyGenerator());
+ }
+ }
+
+ public static class AlgParams
+ extends BaseAlgorithmParameters
+ {
+ private static final short[] table = {
+ 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0,
+ 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a,
+ 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36,
+ 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c,
+ 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60,
+ 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa,
+ 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e,
+ 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf,
+ 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6,
+ 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3,
+ 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c,
+ 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2,
+ 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5,
+ 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5,
+ 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f,
+ 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab
+ };
+
+ private static final short[] ekb = {
+ 0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d, 0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5,
+ 0xe4, 0x73, 0x6b, 0x3a, 0x68, 0x5a, 0xc0, 0x47, 0xa0, 0x64, 0x34, 0x0c, 0xf1, 0xd0, 0x52, 0xa5,
+ 0xb9, 0x1e, 0x96, 0x43, 0x41, 0xd8, 0xd4, 0x2c, 0xdb, 0xf8, 0x07, 0x77, 0x2a, 0xca, 0xeb, 0xef,
+ 0x10, 0x1c, 0x16, 0x0d, 0x38, 0x72, 0x2f, 0x89, 0xc1, 0xf9, 0x80, 0xc4, 0x6d, 0xae, 0x30, 0x3d,
+ 0xce, 0x20, 0x63, 0xfe, 0xe6, 0x1a, 0xc7, 0xb8, 0x50, 0xe8, 0x24, 0x17, 0xfc, 0x25, 0x6f, 0xbb,
+ 0x6a, 0xa3, 0x44, 0x53, 0xd9, 0xa2, 0x01, 0xab, 0xbc, 0xb6, 0x1f, 0x98, 0xee, 0x9a, 0xa7, 0x2d,
+ 0x4f, 0x9e, 0x8e, 0xac, 0xe0, 0xc6, 0x49, 0x46, 0x29, 0xf4, 0x94, 0x8a, 0xaf, 0xe1, 0x5b, 0xc3,
+ 0xb3, 0x7b, 0x57, 0xd1, 0x7c, 0x9c, 0xed, 0x87, 0x40, 0x8c, 0xe2, 0xcb, 0x93, 0x14, 0xc9, 0x61,
+ 0x2e, 0xe5, 0xcc, 0xf6, 0x5e, 0xa8, 0x5c, 0xd6, 0x75, 0x8d, 0x62, 0x95, 0x58, 0x69, 0x76, 0xa1,
+ 0x4a, 0xb5, 0x55, 0x09, 0x78, 0x33, 0x82, 0xd7, 0xdd, 0x79, 0xf5, 0x1b, 0x0b, 0xde, 0x26, 0x21,
+ 0x28, 0x74, 0x04, 0x97, 0x56, 0xdf, 0x3c, 0xf0, 0x37, 0x39, 0xdc, 0xff, 0x06, 0xa4, 0xea, 0x42,
+ 0x08, 0xda, 0xb4, 0x71, 0xb0, 0xcf, 0x12, 0x7a, 0x4e, 0xfa, 0x6c, 0x1d, 0x84, 0x00, 0xc8, 0x7f,
+ 0x91, 0x45, 0xaa, 0x2b, 0xc2, 0xb1, 0x8f, 0xd5, 0xba, 0xf2, 0xad, 0x19, 0xb2, 0x67, 0x36, 0xf7,
+ 0x0f, 0x0a, 0x92, 0x7d, 0xe3, 0x9d, 0xe9, 0x90, 0x3e, 0x23, 0x27, 0x66, 0x13, 0xec, 0x81, 0x15,
+ 0xbd, 0x22, 0xbf, 0x9f, 0x7e, 0xa9, 0x51, 0x4b, 0x4c, 0xfb, 0x02, 0xd3, 0x70, 0x86, 0x31, 0xe7,
+ 0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd
+ };
+
+ private byte[] iv;
+ private int parameterVersion = 58;
+
+ protected byte[] engineGetEncoded()
+ {
+ return Arrays.clone(iv);
+ }
+
+ protected byte[] engineGetEncoded(
+ String format)
+ throws IOException
+ {
+ if (this.isASN1FormatString(format))
+ {
+ if (parameterVersion == -1)
+ {
+ return new RC2CBCParameter(engineGetEncoded()).getEncoded();
+ }
+ else
+ {
+ return new RC2CBCParameter(parameterVersion, engineGetEncoded()).getEncoded();
+ }
+ }
+
+ if (format.equals("RAW"))
+ {
+ return engineGetEncoded();
+ }
+
+ return null;
+ }
+
+ protected AlgorithmParameterSpec localEngineGetParameterSpec(
+ Class paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec == RC2ParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
+ {
+ if (parameterVersion != -1)
+ {
+ if (parameterVersion < 256)
+ {
+ return new RC2ParameterSpec(ekb[parameterVersion], iv);
+ }
+ else
+ {
+ return new RC2ParameterSpec(parameterVersion, iv);
+ }
+ }
+ }
+
+ if (paramSpec == IvParameterSpec.class)
+ {
+ return new IvParameterSpec(iv);
+ }
+
+ throw new InvalidParameterSpecException("unknown parameter spec passed to RC2 parameters object.");
+ }
+
+ protected void engineInit(
+ AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec instanceof IvParameterSpec)
+ {
+ this.iv = ((IvParameterSpec)paramSpec).getIV();
+ }
+ else if (paramSpec instanceof RC2ParameterSpec)
+ {
+ int effKeyBits = ((RC2ParameterSpec)paramSpec).getEffectiveKeyBits();
+ if (effKeyBits != -1)
+ {
+ if (effKeyBits < 256)
+ {
+ parameterVersion = table[effKeyBits];
+ }
+ else
+ {
+ parameterVersion = effKeyBits;
+ }
+ }
+
+ this.iv = ((RC2ParameterSpec)paramSpec).getIV();
+ }
+ else
+ {
+ throw new InvalidParameterSpecException("IvParameterSpec or RC2ParameterSpec required to initialise a RC2 parameters algorithm parameters object");
+ }
+ }
+
+ protected void engineInit(
+ byte[] params)
+ throws IOException
+ {
+ this.iv = Arrays.clone(params);
+ }
+
+ protected void engineInit(
+ byte[] params,
+ String format)
+ throws IOException
+ {
+ if (this.isASN1FormatString(format))
+ {
+ RC2CBCParameter p = RC2CBCParameter.getInstance(ASN1Primitive.fromByteArray(params));
+
+ if (p.getRC2ParameterVersion() != null)
+ {
+ parameterVersion = p.getRC2ParameterVersion().intValue();
+ }
+
+ iv = p.getIV();
+
+ return;
+ }
+
+ if (format.equals("RAW"))
+ {
+ engineInit(params);
+ return;
+ }
+
+ throw new IOException("Unknown parameters format in IV parameters object");
+ }
+
+ protected String engineToString()
+ {
+ return "RC2 Parameters";
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends AlgorithmProvider
+ {
+ private static final String PREFIX = RC2.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ provider.addAlgorithm("AlgorithmParameterGenerator.RC2", PREFIX + "$AlgParamGen");
+ provider.addAlgorithm("AlgorithmParameterGenerator.1.2.840.113549.3.2", PREFIX + "$AlgParamGen");
+
+ provider.addAlgorithm("KeyGenerator.RC2", PREFIX + "$KeyGenerator");
+ provider.addAlgorithm("KeyGenerator.1.2.840.113549.3.2", PREFIX + "$KeyGenerator");
+
+ provider.addAlgorithm("AlgorithmParameters.RC2", PREFIX + "$AlgParams");
+ provider.addAlgorithm("AlgorithmParameters.1.2.840.113549.3.2", PREFIX + "$AlgParams");
+
+ provider.addAlgorithm("Cipher.RC2", PREFIX + "$ECB");
+ provider.addAlgorithm("Cipher.RC2WRAP", PREFIX + "$Wrap");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.id_alg_CMSRC2wrap, "RC2WRAP");
+ provider.addAlgorithm("Cipher", PKCSObjectIdentifiers.RC2_CBC, PREFIX + "$CBC");
+
+ provider.addAlgorithm("Mac.RC2MAC", PREFIX + "$CBCMAC");
+ provider.addAlgorithm("Alg.Alias.Mac.RC2", "RC2MAC");
+ provider.addAlgorithm("Mac.RC2MAC/CFB8", PREFIX + "$CFB8MAC");
+ provider.addAlgorithm("Alg.Alias.Mac.RC2/CFB8", "RC2MAC/CFB8");
+
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHMD2ANDRC2-CBC", "PBEWITHMD2ANDRC2");
+ */
+ // END Android-removed: Unsupported algorithms
+
+ // Android-note: All of the non-disabled algorithms in this class are necessary
+ // for KeyStore.PKCS12
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHMD5ANDRC2-CBC", "PBEWITHMD5ANDRC2");
+
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1ANDRC2-CBC", "PBEWITHSHA1ANDRC2");
+
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("Alg.Alias.SecretKeyFactory", PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC, "PBEWITHMD2ANDRC2");
+
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, "PBEWITHMD5ANDRC2");
+
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC, "PBEWITHSHA1ANDRC2");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.5", "PBEWITHSHAAND128BITRC2-CBC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.6", "PBEWITHSHAAND40BITRC2-CBC");
+
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("SecretKeyFactory.PBEWITHMD2ANDRC2", PREFIX + "$PBEWithMD2KeyFactory");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5ANDRC2", PREFIX + "$PBEWithMD5KeyFactory");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA1ANDRC2", PREFIX + "$PBEWithSHA1KeyFactory");
+
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND128BITRC2-CBC", PREFIX + "$PBEWithSHAAnd128BitKeyFactory");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND40BITRC2-CBC", PREFIX + "$PBEWithSHAAnd40BitKeyFactory");
+
+ // Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC, "PBEWITHMD2ANDRC2");
+
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, "PBEWITHMD5ANDRC2");
+
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC, "PBEWITHSHA1ANDRC2");
+
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.5", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.6", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWithSHAAnd3KeyTripleDES", "PKCS12PBE");
+
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC, "PBEWITHSHAAND128BITRC2-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC, "PBEWITHSHAAND40BITRC2-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITRC2-CBC", "PBEWITHSHAAND128BITRC2-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND40BITRC2-CBC", "PBEWITHSHAAND40BITRC2-CBC");
+ provider.addAlgorithm("Cipher.PBEWITHSHA1ANDRC2", PREFIX + "$PBEWithSHA1AndRC2");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAANDRC2-CBC", "PBEWITHSHA1ANDRC2");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDRC2-CBC", "PBEWITHSHA1ANDRC2");
+
+ provider.addAlgorithm("Cipher.PBEWITHSHAAND128BITRC2-CBC", PREFIX + "$PBEWithSHAAnd128BitRC2");
+ provider.addAlgorithm("Cipher.PBEWITHSHAAND40BITRC2-CBC", PREFIX + "$PBEWithSHAAnd40BitRC2");
+ provider.addAlgorithm("Cipher.PBEWITHMD5ANDRC2", PREFIX + "$PBEWithMD5AndRC2");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHMD5ANDRC2-CBC", "PBEWITHMD5ANDRC2");
+
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1ANDRC2", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDRC2", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1ANDRC2-CBC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND40BITRC2-CBC", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND128BITRC2-CBC", "PKCS12PBE");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/SymmetricAlgorithmProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/SymmetricAlgorithmProvider.java
new file mode 100644
index 00000000..02c2d160
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/SymmetricAlgorithmProvider.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric;
+
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
+
+abstract class SymmetricAlgorithmProvider
+ extends AlgorithmProvider
+{
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ protected void addCMacAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String algorithmClassName,
+ String keyGeneratorClassName)
+ {
+ provider.addAlgorithm("Mac." + algorithm + "-CMAC", algorithmClassName);
+ provider.addAlgorithm("Alg.Alias.Mac." + algorithm + "CMAC", algorithm + "-CMAC");
+
+ provider.addAlgorithm("KeyGenerator." + algorithm + "-CMAC", keyGeneratorClassName);
+ provider.addAlgorithm("Alg.Alias.KeyGenerator." + algorithm + "CMAC", algorithm + "-CMAC");
+ }
+
+ protected void addGMacAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String algorithmClassName,
+ String keyGeneratorClassName)
+ {
+ provider.addAlgorithm("Mac." + algorithm + "-GMAC", algorithmClassName);
+ provider.addAlgorithm("Alg.Alias.Mac." + algorithm + "GMAC", algorithm + "-GMAC");
+
+ provider.addAlgorithm("KeyGenerator." + algorithm + "-GMAC", keyGeneratorClassName);
+ provider.addAlgorithm("Alg.Alias.KeyGenerator." + algorithm + "GMAC", algorithm + "-GMAC");
+ }
+
+ protected void addPoly1305Algorithm(ConfigurableProvider provider,
+ String algorithm,
+ String algorithmClassName,
+ String keyGeneratorClassName)
+ {
+ provider.addAlgorithm("Mac.POLY1305-" + algorithm, algorithmClassName);
+ provider.addAlgorithm("Alg.Alias.Mac.POLY1305" + algorithm, "POLY1305-" + algorithm);
+
+ provider.addAlgorithm("KeyGenerator.POLY1305-" + algorithm, keyGeneratorClassName);
+ provider.addAlgorithm("Alg.Alias.KeyGenerator.POLY1305" + algorithm, "POLY1305-" + algorithm);
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/Twofish.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/Twofish.java
new file mode 100644
index 00000000..8681eebd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/Twofish.java
@@ -0,0 +1,158 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric;
+
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.BlockCipher;
+// import org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.engines.TwofishEngine;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.generators.Poly1305KeyGenerator;
+// import org.bouncycastle.crypto.macs.GMac;
+import com.android.internal.org.bouncycastle.crypto.modes.CBCBlockCipher;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.modes.GCMBlockCipher;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
+// import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
+// import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider;
+// import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Twofish
+{
+ private Twofish()
+ {
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class ECB
+ extends BaseBlockCipher
+ {
+ public ECB()
+ {
+ super(new BlockCipherProvider()
+ {
+ public BlockCipher get()
+ {
+ return new TwofishEngine();
+ }
+ });
+ }
+ }
+
+ public static class KeyGen
+ extends BaseKeyGenerator
+ {
+ public KeyGen()
+ {
+ super("Twofish", 256, new CipherKeyGenerator());
+ }
+ }
+
+ public static class GMAC
+ extends BaseMac
+ {
+ public GMAC()
+ {
+ super(new GMac(new GCMBlockCipher(new TwofishEngine())));
+ }
+ }
+
+ public static class Poly1305
+ extends BaseMac
+ {
+ public Poly1305()
+ {
+ super(new org.bouncycastle.crypto.macs.Poly1305(new TwofishEngine()));
+ }
+ }
+
+ public static class Poly1305KeyGen
+ extends BaseKeyGenerator
+ {
+ public Poly1305KeyGen()
+ {
+ super("Poly1305-Twofish", 256, new Poly1305KeyGenerator());
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * PBEWithSHAAndTwofish-CBC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHAKeyFactory
+ extends PBESecretKeyFactory
+ {
+ public PBEWithSHAKeyFactory()
+ {
+ super("PBEwithSHAandTwofish-CBC", null, true, PKCS12, SHA1, 256, 128);
+ }
+ }
+
+ /**
+ * PBEWithSHAAndTwofish-CBC
+ * @hide This class is not part of the Android public SDK API
+ */
+ static public class PBEWithSHA
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA()
+ {
+ super(new CBCBlockCipher(new TwofishEngine()), PKCS12, SHA1, 256, 16);
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ public static class AlgParams
+ extends IvAlgorithmParameters
+ {
+ protected String engineToString()
+ {
+ return "Twofish IV";
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Mappings
+ extends SymmetricAlgorithmProvider
+ {
+ private static final String PREFIX = Twofish.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ // provider.addAlgorithm("Cipher.Twofish", PREFIX + "$ECB");
+ // provider.addAlgorithm("KeyGenerator.Twofish", PREFIX + "$KeyGen");
+ // provider.addAlgorithm("AlgorithmParameters.Twofish", PREFIX + "$AlgParams");
+ // END Android-removed: Unsupported algorithms
+
+ // Android-note: These algorithms are necessary for KeyStore.BouncyCastle
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDTWOFISH", "PKCS12PBE");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDTWOFISH-CBC", "PKCS12PBE");
+ provider.addAlgorithm("Cipher.PBEWITHSHAANDTWOFISH-CBC", PREFIX + "$PBEWithSHA");
+ provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAANDTWOFISH-CBC", PREFIX + "$PBEWithSHAKeyFactory");
+
+ // BEGIN Android-removed: Unsupported algorithms
+ // addGMacAlgorithm(provider, "Twofish", PREFIX + "$GMAC", PREFIX + "$KeyGen");
+ // addPoly1305Algorithm(provider, "Twofish", PREFIX + "$Poly1305", PREFIX + "$Poly1305KeyGen");
+ // END Android-removed: Unsupported algorithms
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
new file mode 100644
index 00000000..de352165
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
@@ -0,0 +1,236 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.crypto.interfaces.PBEKey;
+import javax.crypto.spec.PBEKeySpec;
+import javax.security.auth.Destroyable;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.PBEParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCPBEKey
+ implements PBEKey, Destroyable
+{
+ private final AtomicBoolean hasBeenDestroyed = new AtomicBoolean(false);
+
+ String algorithm;
+ ASN1ObjectIdentifier oid;
+ int type;
+ int digest;
+ int keySize;
+ int ivSize;
+
+ private final char[] password;
+ private final byte[] salt;
+ private final int iterationCount;
+
+ private final CipherParameters param;
+
+ boolean tryWrong = false;
+
+ /**
+ * @param param
+ */
+ public BCPBEKey(
+ String algorithm,
+ ASN1ObjectIdentifier oid,
+ int type,
+ int digest,
+ int keySize,
+ int ivSize,
+ PBEKeySpec pbeKeySpec,
+ CipherParameters param)
+ {
+ this.algorithm = algorithm;
+ this.oid = oid;
+ this.type = type;
+ this.digest = digest;
+ this.keySize = keySize;
+ this.ivSize = ivSize;
+ this.password = pbeKeySpec.getPassword();
+ this.iterationCount = pbeKeySpec.getIterationCount();
+ this.salt = pbeKeySpec.getSalt();
+ this.param = param;
+ }
+
+ public BCPBEKey(String algName, CipherParameters param)
+ {
+ this.algorithm = algName;
+ this.param = param;
+ this.password = null;
+ this.iterationCount = -1;
+ this.salt = null;
+ }
+
+ public String getAlgorithm()
+ {
+ checkDestroyed(this);
+
+ return algorithm;
+ }
+
+ public String getFormat()
+ {
+ return "RAW";
+ }
+
+ public byte[] getEncoded()
+ {
+ checkDestroyed(this);
+
+ if (param != null)
+ {
+ KeyParameter kParam;
+
+ if (param instanceof ParametersWithIV)
+ {
+ kParam = (KeyParameter)((ParametersWithIV)param).getParameters();
+ }
+ else
+ {
+ kParam = (KeyParameter)param;
+ }
+
+ return kParam.getKey();
+ }
+ else
+ {
+ if (type == PBE.PKCS12)
+ {
+ return PBEParametersGenerator.PKCS12PasswordToBytes(password);
+ }
+ else if (type == PBE.PKCS5S2_UTF8)
+ {
+ return PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password);
+ }
+ else
+ {
+ return PBEParametersGenerator.PKCS5PasswordToBytes(password);
+ }
+ }
+ }
+
+ int getType()
+ {
+ checkDestroyed(this);
+
+ return type;
+ }
+
+ int getDigest()
+ {
+ checkDestroyed(this);
+
+ return digest;
+ }
+
+ int getKeySize()
+ {
+ checkDestroyed(this);
+
+ return keySize;
+ }
+
+ public int getIvSize()
+ {
+ checkDestroyed(this);
+
+ return ivSize;
+ }
+
+ public CipherParameters getParam()
+ {
+ checkDestroyed(this);
+
+ return param;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.crypto.interfaces.PBEKey#getPassword()
+ */
+ public char[] getPassword()
+ {
+ checkDestroyed(this);
+
+ if (password == null)
+ {
+ throw new IllegalStateException("no password available");
+ }
+
+ return Arrays.clone(password);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.crypto.interfaces.PBEKey#getSalt()
+ */
+ public byte[] getSalt()
+ {
+ checkDestroyed(this);
+
+ return Arrays.clone(salt);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.crypto.interfaces.PBEKey#getIterationCount()
+ */
+ public int getIterationCount()
+ {
+ checkDestroyed(this);
+
+ return iterationCount;
+ }
+
+ public ASN1ObjectIdentifier getOID()
+ {
+ checkDestroyed(this);
+
+ return oid;
+ }
+
+ public void setTryWrongPKCS12Zero(boolean tryWrong)
+ {
+ this.tryWrong = tryWrong;
+ }
+
+ boolean shouldTryWrongPKCS12()
+ {
+ return tryWrong;
+ }
+
+ public void destroy()
+ {
+ if (!hasBeenDestroyed.getAndSet(true))
+ {
+ if (password != null)
+ {
+ Arrays.fill(password, (char)0);
+ }
+ if (salt != null)
+ {
+ Arrays.fill(salt, (byte)0);
+ }
+ }
+ }
+
+ public boolean isDestroyed()
+ {
+ return hasBeenDestroyed.get();
+ }
+
+ static void checkDestroyed(Destroyable destroyable)
+ {
+ if (destroyable.isDestroyed())
+ {
+ throw new IllegalStateException("key has been destroyed");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameterGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameterGenerator.java
new file mode 100644
index 00000000..aecf672a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameterGenerator.java
@@ -0,0 +1,45 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.security.AlgorithmParameterGeneratorSpi;
+import java.security.AlgorithmParameters;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
+
+// Android-changed: Use default provider for JCA algorithms instead of BC
+// Was: import org.bouncycastle.jcajce.util.BCJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class BaseAlgorithmParameterGenerator
+ extends AlgorithmParameterGeneratorSpi
+{
+ // Android-changed: Use default provider for JCA algorithms instead of BC
+ // Was: private final JcaJceHelper helper = new BCJcaJceHelper();
+ private final JcaJceHelper helper = new DefaultJcaJceHelper();
+
+ protected SecureRandom random;
+ protected int strength = 1024;
+
+ public BaseAlgorithmParameterGenerator()
+ {
+ }
+
+ protected final AlgorithmParameters createParametersInstance(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return helper.createAlgorithmParameters(algorithm);
+ }
+
+ protected void engineInit(
+ int strength,
+ SecureRandom random)
+ {
+ this.strength = strength;
+ this.random = random;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameters.java
new file mode 100644
index 00000000..aac66318
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseAlgorithmParameters.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.security.AlgorithmParametersSpi;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class BaseAlgorithmParameters
+ extends AlgorithmParametersSpi
+{
+ protected boolean isASN1FormatString(String format)
+ {
+ return format == null || format.equals("ASN.1");
+ }
+
+ protected AlgorithmParameterSpec engineGetParameterSpec(
+ Class paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec == null)
+ {
+ throw new NullPointerException("argument to getParameterSpec must not be null");
+ }
+
+ return localEngineGetParameterSpec(paramSpec);
+ }
+
+ protected abstract AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec)
+ throws InvalidParameterSpecException;
+}
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
new file mode 100644
index 00000000..7eaf8ac8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java
@@ -0,0 +1,1579 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.lang.reflect.Constructor;
+import java.nio.ByteBuffer;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import javax.crypto.interfaces.PBEKey;
+import javax.crypto.spec.IvParameterSpec;
+// BEGIN Android-added: Various key-handling modifications
+import javax.crypto.spec.PBEKeySpec;
+// END Android-added: Various key-handling modifications
+import javax.crypto.spec.PBEParameterSpec;
+// Android-removed: Unsupported algorithms
+// import javax.crypto.spec.RC2ParameterSpec;
+// import javax.crypto.spec.RC5ParameterSpec;
+
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.cms.GCMParameters;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+import com.android.internal.org.bouncycastle.crypto.BufferedBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.OutputLengthException;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.engines.DSTU7624Engine;
+import com.android.internal.org.bouncycastle.crypto.modes.AEADBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.modes.AEADCipher;
+import com.android.internal.org.bouncycastle.crypto.modes.CBCBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.modes.CCMBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.modes.CFBBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.modes.CTSBlockCipher;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.modes.EAXBlockCipher;
+// import org.bouncycastle.crypto.modes.GCFBBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.modes.GCMBlockCipher;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.modes.GOFBBlockCipher;
+// import org.bouncycastle.crypto.modes.KCCMBlockCipher;
+// import org.bouncycastle.crypto.modes.KCTRBlockCipher;
+// import org.bouncycastle.crypto.modes.KGCMBlockCipher;
+// import org.bouncycastle.crypto.modes.OCBBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.modes.OFBBlockCipher;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.modes.OpenPGPCFBBlockCipher;
+// import org.bouncycastle.crypto.modes.PGPCFBBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.modes.SICBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.paddings.BlockCipherPadding;
+import com.android.internal.org.bouncycastle.crypto.paddings.ISO10126d2Padding;
+import com.android.internal.org.bouncycastle.crypto.paddings.ISO7816d4Padding;
+import com.android.internal.org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
+import com.android.internal.org.bouncycastle.crypto.paddings.TBCPadding;
+import com.android.internal.org.bouncycastle.crypto.paddings.X923Padding;
+import com.android.internal.org.bouncycastle.crypto.paddings.ZeroBytePadding;
+import com.android.internal.org.bouncycastle.crypto.params.AEADParameters;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.params.ParametersWithSBox;
+import com.android.internal.org.bouncycastle.crypto.params.RC2Parameters;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.params.RC5Parameters;
+// import org.bouncycastle.jcajce.PBKDF1Key;
+// import org.bouncycastle.jcajce.PBKDF1KeyWithParameters;
+import com.android.internal.org.bouncycastle.jcajce.PKCS12Key;
+import com.android.internal.org.bouncycastle.jcajce.PKCS12KeyWithParameters;
+import com.android.internal.org.bouncycastle.jcajce.spec.AEADParameterSpec;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
+// import org.bouncycastle.jcajce.spec.RepeatedSecretKeySpec;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BaseBlockCipher
+ extends BaseWrapCipher
+ implements PBE
+{
+ private static final int BUF_SIZE = 512;
+ private static final Class gcmSpecClass = ClassUtil.loadClass(BaseBlockCipher.class, "javax.crypto.spec.GCMParameterSpec");
+
+ //
+ // specs we can handle.
+ //
+ private Class[] availableSpecs =
+ {
+ // Android-removed: Unsupported alhorithms
+ // RC2ParameterSpec.class,
+ // RC5ParameterSpec.class,
+ gcmSpecClass,
+ // Android-removed: unsupported algorithms
+ // GOST28147ParameterSpec.class,
+ IvParameterSpec.class,
+ PBEParameterSpec.class
+ };
+
+ private BlockCipher baseEngine;
+ private BlockCipherProvider engineProvider;
+ private GenericBlockCipher cipher;
+ private ParametersWithIV ivParam;
+ private AEADParameters aeadParams;
+
+ private int keySizeInBits;
+ private int scheme = -1;
+ private int digest;
+
+ private int ivLength = 0;
+
+ private boolean padded;
+ private boolean fixedIv = true;
+ private PBEParameterSpec pbeSpec = null;
+ private String pbeAlgorithm = null;
+
+ private String modeName = null;
+
+ protected BaseBlockCipher(
+ BlockCipher engine)
+ {
+ baseEngine = engine;
+
+ cipher = new BufferedGenericBlockCipher(engine);
+ }
+
+ protected BaseBlockCipher(
+ BlockCipher engine,
+ int scheme,
+ int digest,
+ int keySizeInBits,
+ int ivLength)
+ {
+ baseEngine = engine;
+
+ this.scheme = scheme;
+ this.digest = digest;
+ this.keySizeInBits = keySizeInBits;
+ this.ivLength = ivLength;
+
+ cipher = new BufferedGenericBlockCipher(engine);
+ }
+
+ protected BaseBlockCipher(
+ BlockCipherProvider provider)
+ {
+ baseEngine = provider.get();
+ engineProvider = provider;
+
+ cipher = new BufferedGenericBlockCipher(provider.get());
+ }
+
+ protected BaseBlockCipher(
+ AEADBlockCipher engine)
+ {
+ this.baseEngine = engine.getUnderlyingCipher();
+ this.ivLength = baseEngine.getBlockSize();
+ this.cipher = new AEADGenericBlockCipher(engine);
+ }
+
+ protected BaseBlockCipher(
+ AEADCipher engine,
+ boolean fixedIv,
+ int ivLength)
+ {
+ this.baseEngine = null;
+ this.fixedIv = fixedIv;
+ this.ivLength = ivLength;
+ this.cipher = new AEADGenericBlockCipher(engine);
+ }
+
+ protected BaseBlockCipher(
+ AEADBlockCipher engine,
+ boolean fixedIv,
+ int ivLength)
+ {
+ this.baseEngine = engine.getUnderlyingCipher();
+ this.fixedIv = fixedIv;
+ this.ivLength = ivLength;
+ this.cipher = new AEADGenericBlockCipher(engine);
+ }
+
+ protected BaseBlockCipher(
+ com.android.internal.org.bouncycastle.crypto.BlockCipher engine,
+ int ivLength)
+ {
+ this(engine, true, ivLength);
+ }
+
+ protected BaseBlockCipher(
+ com.android.internal.org.bouncycastle.crypto.BlockCipher engine,
+ boolean fixedIv,
+ int ivLength)
+ {
+ baseEngine = engine;
+
+ this.fixedIv = fixedIv;
+ this.cipher = new BufferedGenericBlockCipher(engine);
+ this.ivLength = ivLength / 8;
+ }
+
+ protected BaseBlockCipher(
+ BufferedBlockCipher engine,
+ int ivLength)
+ {
+ this(engine, true, ivLength);
+ }
+
+ protected BaseBlockCipher(
+ BufferedBlockCipher engine,
+ boolean fixedIv,
+ int ivLength)
+ {
+ baseEngine = engine.getUnderlyingCipher();
+
+ this.cipher = new BufferedGenericBlockCipher(engine);
+ this.fixedIv = fixedIv;
+ this.ivLength = ivLength / 8;
+ }
+
+ protected int engineGetBlockSize()
+ {
+ if (baseEngine == null)
+ {
+ return -1;
+ }
+ return baseEngine.getBlockSize();
+ }
+
+ protected byte[] engineGetIV()
+ {
+ if (aeadParams != null)
+ {
+ return aeadParams.getNonce();
+ }
+
+ return (ivParam != null) ? ivParam.getIV() : null;
+ }
+
+ protected int engineGetKeySize(
+ Key key)
+ {
+ return key.getEncoded().length * 8;
+ }
+
+ protected int engineGetOutputSize(
+ int inputLen)
+ {
+ return cipher.getOutputSize(inputLen);
+ }
+
+ protected AlgorithmParameters engineGetParameters()
+ {
+ if (engineParams == null)
+ {
+ if (pbeSpec != null)
+ {
+ try
+ {
+ engineParams = createParametersInstance(pbeAlgorithm);
+ engineParams.init(pbeSpec);
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+ else if (aeadParams != null)
+ {
+ // CHACHA20-Poly1305
+ if (baseEngine == null)
+ {
+ try
+ {
+ engineParams = createParametersInstance(PKCSObjectIdentifiers.id_alg_AEADChaCha20Poly1305.getId());
+ engineParams.init(new DEROctetString(aeadParams.getNonce()).getEncoded());
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.toString());
+ }
+ }
+ else
+ {
+ try
+ {
+ engineParams = createParametersInstance("GCM");
+ engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize() / 8).getEncoded());
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.toString());
+ }
+ }
+ }
+ else if (ivParam != null)
+ {
+ String name = cipher.getUnderlyingCipher().getAlgorithmName();
+
+ if (name.indexOf('/') >= 0)
+ {
+ name = name.substring(0, name.indexOf('/'));
+ }
+
+ try
+ {
+ engineParams = createParametersInstance(name);
+ engineParams.init(new IvParameterSpec(ivParam.getIV()));
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.toString());
+ }
+ }
+ }
+
+ return engineParams;
+ }
+
+ protected void engineSetMode(
+ String mode)
+ throws NoSuchAlgorithmException
+ {
+ if (baseEngine == null)
+ {
+ throw new NoSuchAlgorithmException("no mode supported for this algorithm");
+ }
+ modeName = Strings.toUpperCase(mode);
+
+ if (modeName.equals("ECB"))
+ {
+ ivLength = 0;
+ cipher = new BufferedGenericBlockCipher(baseEngine);
+ }
+ else if (modeName.equals("CBC"))
+ {
+ ivLength = baseEngine.getBlockSize();
+ cipher = new BufferedGenericBlockCipher(
+ new CBCBlockCipher(baseEngine));
+ }
+ else if (modeName.startsWith("OFB"))
+ {
+ ivLength = baseEngine.getBlockSize();
+ if (modeName.length() != 3)
+ {
+ int wordSize = Integer.parseInt(modeName.substring(3));
+
+ cipher = new BufferedGenericBlockCipher(
+ new OFBBlockCipher(baseEngine, wordSize));
+ }
+ else
+ {
+ cipher = new BufferedGenericBlockCipher(
+ new OFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
+ }
+ }
+ else if (modeName.startsWith("CFB"))
+ {
+ ivLength = baseEngine.getBlockSize();
+ if (modeName.length() != 3)
+ {
+ int wordSize = Integer.parseInt(modeName.substring(3));
+
+ cipher = new BufferedGenericBlockCipher(
+ new CFBBlockCipher(baseEngine, wordSize));
+ }
+ else
+ {
+ cipher = new BufferedGenericBlockCipher(
+ new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
+ }
+ }
+ // BEGIN Android-removed: Unsupported modes
+ /*
+ else if (modeName.startsWith("PGPCFB"))
+ {
+ boolean inlineIV = modeName.equals("PGPCFBWITHIV");
+
+ if (!inlineIV && modeName.length() != 6)
+ {
+ throw new NoSuchAlgorithmException("no mode support for " + modeName);
+ }
+
+ ivLength = baseEngine.getBlockSize();
+ cipher = new BufferedGenericBlockCipher(
+ new PGPCFBBlockCipher(baseEngine, inlineIV));
+ }
+ else if (modeName.equals("OPENPGPCFB"))
+ {
+ ivLength = 0;
+ cipher = new BufferedGenericBlockCipher(
+ new OpenPGPCFBBlockCipher(baseEngine));
+ }
+ else if (modeName.equals("SIC"))
+ {
+ ivLength = baseEngine.getBlockSize();
+ if (ivLength < 16)
+ {
+ throw new IllegalArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
+ }
+ fixedIv = false;
+ cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
+ new SICBlockCipher(baseEngine)));
+ }
+ */
+ // END Android-removed: Unsupported modes
+ else if (modeName.equals("CTR"))
+ {
+ ivLength = baseEngine.getBlockSize();
+ fixedIv = false;
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ if (baseEngine instanceof DSTU7624Engine)
+ {
+ cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
+ new KCTRBlockCipher(baseEngine)));
+ }
+ else
+ {
+ */
+ cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
+ new SICBlockCipher(baseEngine)));
+ /*
+ }
+ */
+ }
+ // BEGIN Android-removed: Unsupported modes
+ /*
+ else if (modeName.equals("GOFB"))
+ {
+ ivLength = baseEngine.getBlockSize();
+ cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
+ new GOFBBlockCipher(baseEngine)));
+ }
+ else if (modeName.equals("GCFB"))
+ {
+ ivLength = baseEngine.getBlockSize();
+ cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
+ new GCFBBlockCipher(baseEngine)));
+ }
+ */
+ // END Android-removed: Unsupported modes
+ else if (modeName.equals("CTS"))
+ {
+ ivLength = baseEngine.getBlockSize();
+ cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(new CBCBlockCipher(baseEngine)));
+ }
+ else if (modeName.equals("CCM"))
+ {
+ ivLength = 12; // CCM nonce 7..13 bytes
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ if (baseEngine instanceof DSTU7624Engine)
+ {
+ cipher = new AEADGenericBlockCipher(new KCCMBlockCipher(baseEngine));
+ }
+ else
+ {
+ */
+ cipher = new AEADGenericBlockCipher(new CCMBlockCipher(baseEngine));
+ /*
+ }
+ */
+ }
+ // BEGIN Android-removed: Unsupported modes
+ /*
+ else if (modeName.equals("OCB"))
+ {
+ if (engineProvider != null)
+ {
+ /*
+ * RFC 7253 4.2. Nonce is a string of no more than 120 bits
+ *
+ ivLength = 15;
+ cipher = new AEADGenericBlockCipher(new OCBBlockCipher(baseEngine, engineProvider.get()));
+ }
+ else
+ {
+ throw new NoSuchAlgorithmException("can't support mode " + mode);
+ }
+ }
+ else if (modeName.equals("EAX"))
+ {
+ ivLength = baseEngine.getBlockSize();
+ cipher = new AEADGenericBlockCipher(new EAXBlockCipher(baseEngine));
+ }
+ */
+ // END Android-removed: Unsupported modes
+ else if (modeName.equals("GCM"))
+ {
+ ivLength = baseEngine.getBlockSize();
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ if (baseEngine instanceof DSTU7624Engine)
+ {
+ cipher = new AEADGenericBlockCipher(new KGCMBlockCipher(baseEngine));
+ }
+ else
+ {
+ */
+ cipher = new AEADGenericBlockCipher(new GCMBlockCipher(baseEngine));
+ /*
+ }
+ */
+ }
+ else
+ {
+ throw new NoSuchAlgorithmException("can't support mode " + mode);
+ }
+ }
+
+ protected void engineSetPadding(
+ String padding)
+ throws NoSuchPaddingException
+ {
+ if (baseEngine == null)
+ {
+ throw new NoSuchPaddingException("no padding supported for this algorithm");
+ }
+
+ String paddingName = Strings.toUpperCase(padding);
+
+ if (paddingName.equals("NOPADDING"))
+ {
+ if (cipher.wrapOnNoPadding())
+ {
+ cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(cipher.getUnderlyingCipher()));
+ }
+ }
+ else if (paddingName.equals("WITHCTS") || paddingName.equals("CTSPADDING") || paddingName.equals("CS3PADDING"))
+ {
+ cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(cipher.getUnderlyingCipher()));
+ }
+ else
+ {
+ padded = true;
+
+ if (isAEADModeName(modeName))
+ {
+ throw new NoSuchPaddingException("Only NoPadding can be used with AEAD modes.");
+ }
+ else if (paddingName.equals("PKCS5PADDING") || paddingName.equals("PKCS7PADDING"))
+ {
+ cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher());
+ }
+ else if (paddingName.equals("ZEROBYTEPADDING"))
+ {
+ cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new ZeroBytePadding());
+ }
+ else if (paddingName.equals("ISO10126PADDING") || paddingName.equals("ISO10126-2PADDING"))
+ {
+ cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new ISO10126d2Padding());
+ }
+ else if (paddingName.equals("X9.23PADDING") || paddingName.equals("X923PADDING"))
+ {
+ cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new X923Padding());
+ }
+ else if (paddingName.equals("ISO7816-4PADDING") || paddingName.equals("ISO9797-1PADDING"))
+ {
+ cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new ISO7816d4Padding());
+ }
+ else if (paddingName.equals("TBCPADDING"))
+ {
+ cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new TBCPadding());
+ }
+ else
+ {
+ throw new NoSuchPaddingException("Padding " + padding + " unknown.");
+ }
+ }
+ }
+
+ // BEGIN Android-added: Handling missing IVs
+ private boolean isBCPBEKeyWithoutIV(Key key) {
+ return (key instanceof BCPBEKey) && !(((BCPBEKey)key).getParam() instanceof ParametersWithIV);
+ }
+ // END Android-added: Handling missing IVs
+
+ protected void engineInit(
+ int opmode,
+ Key key,
+ final AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ CipherParameters param;
+
+ this.pbeSpec = null;
+ this.pbeAlgorithm = null;
+ this.engineParams = null;
+ this.aeadParams = null;
+
+ //
+ // basic key check
+ //
+ if (!(key instanceof SecretKey))
+ {
+ throw new InvalidKeyException("Key for algorithm " + ((key != null) ? key.getAlgorithm() : null) + " not suitable for symmetric enryption.");
+ }
+
+ //
+ // for RC5-64 we must have some default parameters
+ //
+ if (params == null && (baseEngine != null && baseEngine.getAlgorithmName().startsWith("RC5-64")))
+ {
+ throw new InvalidAlgorithmParameterException("RC5 requires an RC5ParametersSpec to be passed in.");
+ }
+
+ //
+ // a note on iv's - if ivLength is zero the IV gets ignored (we don't use it).
+ //
+ // BEGIN Android-changed: Don't use PKCS12 with missing IV.
+ // If the key is a BCPBE one without an IV, ignore the fact that the scheme is PKCS12.
+ // if (scheme == PKCS12 || key instanceof PKCS12Key)
+ if ((scheme == PKCS12 || key instanceof PKCS12Key) && !isBCPBEKeyWithoutIV(key))
+ // END Android-changed: Don't use PKCS12 with missing IV.
+ {
+ SecretKey k;
+ try
+ {
+ k = (SecretKey)key;
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeyException("PKCS12 requires a SecretKey/PBEKey");
+ }
+
+ if (params instanceof PBEParameterSpec)
+ {
+ pbeSpec = (PBEParameterSpec)params;
+ }
+
+ if (k instanceof PBEKey && pbeSpec == null)
+ {
+ PBEKey pbeKey = (PBEKey)k;
+ if (pbeKey.getSalt() == null)
+ {
+ throw new InvalidAlgorithmParameterException("PBEKey requires parameters to specify salt");
+ }
+ pbeSpec = new PBEParameterSpec(pbeKey.getSalt(), pbeKey.getIterationCount());
+ }
+
+ if (pbeSpec == null && !(k instanceof PBEKey))
+ {
+ throw new InvalidKeyException("Algorithm requires a PBE key");
+ }
+
+ if (key instanceof BCPBEKey)
+ {
+ // PKCS#12 sets an IV, if we get a key that doesn't have ParametersWithIV we need to reject it. If the
+ // key has no parameters it means it's an old-school JCE PBE Key - we use getEncoded() on it.
+ CipherParameters pbeKeyParam = ((BCPBEKey)key).getParam();
+ if (pbeKeyParam instanceof ParametersWithIV)
+ {
+ param = pbeKeyParam;
+ }
+ else if (pbeKeyParam == null)
+ {
+ // BEGIN Android-changed: Unreachable code
+ // See above for the Android change that makes this code unreachable.
+ // param = PBE.Util.makePBEParameters(k.getEncoded(), PKCS12, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName());
+ throw new AssertionError("Unreachable code");
+ // END Android-changed: Unreachable code
+ }
+ else
+ {
+ throw new InvalidKeyException("Algorithm requires a PBE key suitable for PKCS12");
+ }
+ }
+ else
+ {
+ param = PBE.Util.makePBEParameters(k.getEncoded(), PKCS12, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName());
+ }
+ if (param instanceof ParametersWithIV)
+ {
+ ivParam = (ParametersWithIV)param;
+ }
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (key instanceof PBKDF1Key)
+ {
+ PBKDF1Key k = (PBKDF1Key)key;
+
+ if (params instanceof PBEParameterSpec)
+ {
+ pbeSpec = (PBEParameterSpec)params;
+ }
+ if (k instanceof PBKDF1KeyWithParameters && pbeSpec == null)
+ {
+ pbeSpec = new PBEParameterSpec(((PBKDF1KeyWithParameters)k).getSalt(), ((PBKDF1KeyWithParameters)k).getIterationCount());
+ }
+
+ param = PBE.Util.makePBEParameters(k.getEncoded(), PKCS5S1, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName());
+ if (param instanceof ParametersWithIV)
+ {
+ ivParam = (ParametersWithIV)param;
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ else if (key instanceof BCPBEKey)
+ {
+ BCPBEKey k = (BCPBEKey)key;
+
+ if (k.getOID() != null)
+ {
+ pbeAlgorithm = k.getOID().getId();
+ }
+ else
+ {
+ pbeAlgorithm = k.getAlgorithm();
+ }
+
+ if (k.getParam() != null)
+ {
+ param = adjustParameters(params, k.getParam());
+ }
+ else if (params instanceof PBEParameterSpec)
+ {
+ pbeSpec = (PBEParameterSpec)params;
+ // BEGIN Android-added: Allow PBE keys with only passwords.
+ // At this point, k.getParam() == null, so the key hasn't been generated. If
+ // the parameters have non-default values, recreate the BCPBEKey from algorithm
+ // parameters as to generate the key.
+ if ((pbeSpec.getSalt().length != 0) && (pbeSpec.getIterationCount() > 0)) {
+ k = new BCPBEKey(k.getAlgorithm(), k.getOID(), k.getType(), k.getDigest(),
+ k.getKeySize(), k.getIvSize(),
+ new PBEKeySpec(
+ k.getPassword(), pbeSpec.getSalt(), pbeSpec.getIterationCount(),
+ k.getKeySize()),
+ null /* CipherParameters */);
+ }
+ // END Android-added: Allow PBE keys with only passwords.
+ param = PBE.Util.makePBEParameters(k, params, cipher.getUnderlyingCipher().getAlgorithmName());
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set.");
+ }
+
+ if (param instanceof ParametersWithIV)
+ {
+ ivParam = (ParametersWithIV)param;
+ }
+ }
+ else if (key instanceof PBEKey)
+ {
+ PBEKey k = (PBEKey)key;
+ pbeSpec = (PBEParameterSpec)params;
+ if (k instanceof PKCS12KeyWithParameters && pbeSpec == null)
+ {
+ pbeSpec = new PBEParameterSpec(k.getSalt(), k.getIterationCount());
+ }
+
+ param = PBE.Util.makePBEParameters(k.getEncoded(), scheme, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName());
+ if (param instanceof ParametersWithIV)
+ {
+ ivParam = (ParametersWithIV)param;
+ }
+ }
+ // BEGIN Android-changed: Unsupported algorithm
+ // else if (!(key instanceof RepeatedSecretKeySpec))
+ else
+ // END Android-changed: Unsupported algorithms
+ {
+ if (scheme == PKCS5S1 || scheme == PKCS5S1_UTF8 || scheme == PKCS5S2 || scheme == PKCS5S2_UTF8)
+ {
+ throw new InvalidKeyException("Algorithm requires a PBE key");
+ }
+ param = new KeyParameter(key.getEncoded());
+ }
+ // BEGIN Android-removed: Unreachable
+ // else
+ // {
+ // param = null;
+ // }
+ // END Android-removed: Unreachable
+
+ if (params instanceof AEADParameterSpec)
+ {
+ if (!isAEADModeName(modeName) && !(cipher instanceof AEADGenericBlockCipher))
+ {
+ throw new InvalidAlgorithmParameterException("AEADParameterSpec can only be used with AEAD modes.");
+ }
+
+ AEADParameterSpec aeadSpec = (AEADParameterSpec)params;
+
+ KeyParameter keyParam;
+ if (param instanceof ParametersWithIV)
+ {
+ keyParam = (KeyParameter)((ParametersWithIV)param).getParameters();
+ }
+ else
+ {
+ keyParam = (KeyParameter)param;
+ }
+ param = aeadParams = new AEADParameters(keyParam, aeadSpec.getMacSizeInBits(), aeadSpec.getNonce(), aeadSpec.getAssociatedData());
+ }
+ else if (params instanceof IvParameterSpec)
+ {
+ if (ivLength != 0)
+ {
+ IvParameterSpec p = (IvParameterSpec)params;
+
+ if (p.getIV().length != ivLength && !(cipher instanceof AEADGenericBlockCipher) && fixedIv)
+ {
+ throw new InvalidAlgorithmParameterException("IV must be " + ivLength + " bytes long.");
+ }
+
+ if (param instanceof ParametersWithIV)
+ {
+ param = new ParametersWithIV(((ParametersWithIV)param).getParameters(), p.getIV());
+ }
+ else
+ {
+ param = new ParametersWithIV(param, p.getIV());
+ }
+ ivParam = (ParametersWithIV)param;
+ }
+ else
+ {
+ if (modeName != null && modeName.equals("ECB"))
+ {
+ throw new InvalidAlgorithmParameterException("ECB mode does not use an IV");
+ }
+ }
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (params instanceof GOST28147ParameterSpec)
+ {
+ GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
+
+ param = new ParametersWithSBox(
+ new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSbox());
+
+ if (gost28147Param.getIV() != null && ivLength != 0)
+ {
+ if (param instanceof ParametersWithIV)
+ {
+ param = new ParametersWithIV(((ParametersWithIV)param).getParameters(), gost28147Param.getIV());
+ }
+ else
+ {
+ param = new ParametersWithIV(param, gost28147Param.getIV());
+ }
+ ivParam = (ParametersWithIV)param;
+ }
+ }
+ else if (params instanceof RC2ParameterSpec)
+ {
+ RC2ParameterSpec rc2Param = (RC2ParameterSpec)params;
+
+ param = new RC2Parameters(key.getEncoded(), ((RC2ParameterSpec)params).getEffectiveKeyBits());
+
+ if (rc2Param.getIV() != null && ivLength != 0)
+ {
+ if (param instanceof ParametersWithIV)
+ {
+ param = new ParametersWithIV(((ParametersWithIV)param).getParameters(), rc2Param.getIV());
+ }
+ else
+ {
+ param = new ParametersWithIV(param, rc2Param.getIV());
+ }
+ ivParam = (ParametersWithIV)param;
+ }
+ }
+ else if (params instanceof RC5ParameterSpec)
+ {
+ RC5ParameterSpec rc5Param = (RC5ParameterSpec)params;
+
+ param = new RC5Parameters(key.getEncoded(), ((RC5ParameterSpec)params).getRounds());
+ if (baseEngine.getAlgorithmName().startsWith("RC5"))
+ {
+ if (baseEngine.getAlgorithmName().equals("RC5-32"))
+ {
+ if (rc5Param.getWordSize() != 32)
+ {
+ throw new InvalidAlgorithmParameterException("RC5 already set up for a word size of 32 not " + rc5Param.getWordSize() + ".");
+ }
+ }
+ else if (baseEngine.getAlgorithmName().equals("RC5-64"))
+ {
+ if (rc5Param.getWordSize() != 64)
+ {
+ throw new InvalidAlgorithmParameterException("RC5 already set up for a word size of 64 not " + rc5Param.getWordSize() + ".");
+ }
+ }
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("RC5 parameters passed to a cipher that is not RC5.");
+ }
+ if ((rc5Param.getIV() != null) && (ivLength != 0))
+ {
+ if (param instanceof ParametersWithIV)
+ {
+ param = new ParametersWithIV(((ParametersWithIV)param).getParameters(), rc5Param.getIV());
+ }
+ else
+ {
+ param = new ParametersWithIV(param, rc5Param.getIV());
+ }
+ ivParam = (ParametersWithIV)param;
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ else if (gcmSpecClass != null && gcmSpecClass.isInstance(params))
+ {
+ if (!isAEADModeName(modeName) && !(cipher instanceof AEADGenericBlockCipher))
+ {
+ throw new InvalidAlgorithmParameterException("GCMParameterSpec can only be used with AEAD modes.");
+ }
+
+ final KeyParameter keyParam;
+ if (param instanceof ParametersWithIV)
+ {
+ keyParam = (KeyParameter)((ParametersWithIV)param).getParameters();
+ }
+ else
+ {
+ keyParam = (KeyParameter)param;
+ }
+
+ param = aeadParams = GcmSpecUtil.extractAeadParameters(keyParam, params);
+ }
+ else if (params != null && !(params instanceof PBEParameterSpec))
+ {
+ throw new InvalidAlgorithmParameterException("unknown parameter type.");
+ }
+
+ if ((ivLength != 0) && !(param instanceof ParametersWithIV) && !(param instanceof AEADParameters))
+ {
+ SecureRandom ivRandom = random;
+
+ if (ivRandom == null)
+ {
+ ivRandom = CryptoServicesRegistrar.getSecureRandom();
+ }
+
+ if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE))
+ {
+ byte[] iv = new byte[ivLength];
+
+ // BEGIN Android-changed: For PBE keys with no IV, log and use IV of 0
+ // 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);
+ 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);
+ }
+ // END Android-changed: For PBE keys with no IV, log and use IV of 0
+ 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
+ // 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
+ }
+ }
+
+
+ if (random != null && padded)
+ {
+ param = new ParametersWithRandom(param, random);
+ }
+
+ try
+ {
+ switch (opmode)
+ {
+ case Cipher.ENCRYPT_MODE:
+ case Cipher.WRAP_MODE:
+ cipher.init(true, param);
+ break;
+ case Cipher.DECRYPT_MODE:
+ case Cipher.UNWRAP_MODE:
+ cipher.init(false, param);
+ break;
+ default:
+ throw new InvalidParameterException("unknown opmode " + opmode + " passed");
+ }
+
+ if (cipher instanceof AEADGenericBlockCipher && aeadParams == null)
+ {
+ AEADCipher aeadCipher = ((AEADGenericBlockCipher)cipher).cipher;
+
+ aeadParams = new AEADParameters((KeyParameter)ivParam.getParameters(), aeadCipher.getMac().length * 8, ivParam.getIV());
+ }
+ }
+ // BEGIN Android-removed: keeping pre 1.68 behaviour
+ /*
+ catch (IllegalArgumentException e)
+ {
+ throw new InvalidAlgorithmParameterException(e.getMessage(), e);
+ }
+ */
+ // END Android-removed: keeping pre 1.68 behaviour
+ catch (Exception e)
+ {
+ throw new InvalidKeyOrParametersException(e.getMessage(), e);
+ }
+ }
+
+ private CipherParameters adjustParameters(AlgorithmParameterSpec params, CipherParameters param)
+ {
+ CipherParameters key;
+
+ if (param instanceof ParametersWithIV)
+ {
+ key = ((ParametersWithIV)param).getParameters();
+ if (params instanceof IvParameterSpec)
+ {
+ IvParameterSpec iv = (IvParameterSpec)params;
+
+ ivParam = new ParametersWithIV(key, iv.getIV());
+ param = ivParam;
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (params instanceof GOST28147ParameterSpec)
+ {
+ // need to pick up IV and SBox.
+ GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
+
+ param = new ParametersWithSBox(param, gost28147Param.getSbox());
+
+ if (gost28147Param.getIV() != null && ivLength != 0)
+ {
+ ivParam = new ParametersWithIV(key, gost28147Param.getIV());
+ param = ivParam;
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+ else
+ {
+ if (params instanceof IvParameterSpec)
+ {
+ IvParameterSpec iv = (IvParameterSpec)params;
+
+ ivParam = new ParametersWithIV(param, iv.getIV());
+ param = ivParam;
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (params instanceof GOST28147ParameterSpec)
+ {
+ // need to pick up IV and SBox.
+ GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
+
+ param = new ParametersWithSBox(param, gost28147Param.getSbox());
+
+ if (gost28147Param.getIV() != null && ivLength != 0)
+ {
+ param = new ParametersWithIV(param, gost28147Param.getIV());
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+ return param;
+ }
+
+ protected void engineInit(
+ int opmode,
+ Key key,
+ AlgorithmParameters params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ AlgorithmParameterSpec paramSpec = null;
+
+ if (params != null)
+ {
+ paramSpec = SpecUtil.extractSpec(params, availableSpecs);
+
+ if (paramSpec == null)
+ {
+ throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString());
+ }
+ }
+
+ engineInit(opmode, key, paramSpec, random);
+
+ engineParams = params;
+ }
+
+ protected void engineInit(
+ int opmode,
+ Key key,
+ SecureRandom random)
+ throws InvalidKeyException
+ {
+ try
+ {
+ engineInit(opmode, key, (AlgorithmParameterSpec)null, random);
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ throw new InvalidKeyException(e.getMessage());
+ }
+ }
+
+ protected void engineUpdateAAD(byte[] input, int offset, int length)
+ {
+ cipher.updateAAD(input, offset, length);
+ }
+
+ protected void engineUpdateAAD(ByteBuffer src)
+ {
+ int remaining = src.remaining();
+ if (remaining < 1)
+ {
+ // No data to update
+ }
+ else if (src.hasArray())
+ {
+ engineUpdateAAD(src.array(), src.arrayOffset() + src.position(), remaining);
+ src.position(src.limit());
+ }
+ else if (remaining <= BUF_SIZE)
+ {
+ byte[] data = new byte[remaining];
+ src.get(data);
+ engineUpdateAAD(data, 0, data.length);
+ Arrays.fill(data, (byte)0);
+ }
+ else
+ {
+ byte[] data = new byte[BUF_SIZE];
+ do
+ {
+ int length = Math.min(data.length, remaining);
+ src.get(data, 0, length);
+ engineUpdateAAD(data, 0, length);
+ remaining -= length;
+ }
+ while (remaining > 0);
+ Arrays.fill(data, (byte)0);
+ }
+ }
+
+ protected byte[] engineUpdate(
+ byte[] input,
+ int inputOffset,
+ int inputLen)
+ {
+ int length = cipher.getUpdateOutputSize(inputLen);
+
+ if (length > 0)
+ {
+ byte[] out = new byte[length];
+
+ int len = cipher.processBytes(input, inputOffset, inputLen, out, 0);
+
+ if (len == 0)
+ {
+ return null;
+ }
+ else if (len != out.length)
+ {
+ byte[] tmp = new byte[len];
+
+ System.arraycopy(out, 0, tmp, 0, len);
+
+ return tmp;
+ }
+
+ return out;
+ }
+
+ cipher.processBytes(input, inputOffset, inputLen, null, 0);
+
+ return null;
+ }
+
+ protected int engineUpdate(
+ byte[] input,
+ int inputOffset,
+ int inputLen,
+ byte[] output,
+ int outputOffset)
+ throws ShortBufferException
+ {
+ if (outputOffset + cipher.getUpdateOutputSize(inputLen) > output.length)
+ {
+ throw new ShortBufferException("output buffer too short for input.");
+ }
+
+ try
+ {
+ return cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
+ }
+ catch (DataLengthException e)
+ {
+ // should never occur
+ throw new IllegalStateException(e.toString());
+ }
+ }
+
+ protected byte[] engineDoFinal(
+ byte[] input,
+ int inputOffset,
+ int inputLen)
+ throws IllegalBlockSizeException, BadPaddingException
+ {
+ int len = 0;
+ byte[] tmp = new byte[engineGetOutputSize(inputLen)];
+
+ if (inputLen != 0)
+ {
+ len = cipher.processBytes(input, inputOffset, inputLen, tmp, 0);
+ }
+
+ try
+ {
+ len += cipher.doFinal(tmp, len);
+ }
+ catch (DataLengthException e)
+ {
+ throw new IllegalBlockSizeException(e.getMessage());
+ }
+
+ if (len == tmp.length)
+ {
+ return tmp;
+ }
+
+ if (len > tmp.length)
+ {
+ throw new IllegalBlockSizeException("internal buffer overflow");
+ }
+
+ byte[] out = new byte[len];
+
+ System.arraycopy(tmp, 0, out, 0, len);
+
+ return out;
+ }
+
+ protected int engineDoFinal(
+ byte[] input,
+ int inputOffset,
+ int inputLen,
+ byte[] output,
+ int outputOffset)
+ throws IllegalBlockSizeException, BadPaddingException, ShortBufferException
+ {
+ int len = 0;
+
+ if (outputOffset + engineGetOutputSize(inputLen) > output.length)
+ {
+ throw new ShortBufferException("output buffer too short for input.");
+ }
+
+ try
+ {
+ if (inputLen != 0)
+ {
+ len = cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
+ }
+
+ return (len + cipher.doFinal(output, outputOffset + len));
+ }
+ catch (OutputLengthException e)
+ {
+ throw new IllegalBlockSizeException(e.getMessage());
+ }
+ catch (DataLengthException e)
+ {
+ throw new IllegalBlockSizeException(e.getMessage());
+ }
+ }
+
+ private boolean isAEADModeName(
+ String modeName)
+ {
+ // Android-changed: Unsupported modes
+ // return "CCM".equals(modeName) || "EAX".equals(modeName) || "GCM".equals(modeName) || "OCB".equals(modeName);
+ return "CCM".equals(modeName) || "GCM".equals(modeName);
+ }
+
+ /*
+ * The ciphers that inherit from us.
+ */
+
+ static private interface GenericBlockCipher
+ {
+ public void init(boolean forEncryption, CipherParameters params)
+ throws IllegalArgumentException;
+
+ public boolean wrapOnNoPadding();
+
+ public String getAlgorithmName();
+
+ public com.android.internal.org.bouncycastle.crypto.BlockCipher getUnderlyingCipher();
+
+ public int getOutputSize(int len);
+
+ public int getUpdateOutputSize(int len);
+
+ public void updateAAD(byte[] input, int offset, int length);
+
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException;
+
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException;
+
+ public int doFinal(byte[] out, int outOff)
+ throws IllegalStateException,
+ BadPaddingException;
+ }
+
+ private static class BufferedGenericBlockCipher
+ implements GenericBlockCipher
+ {
+ private BufferedBlockCipher cipher;
+
+ BufferedGenericBlockCipher(BufferedBlockCipher cipher)
+ {
+ this.cipher = cipher;
+ }
+
+ BufferedGenericBlockCipher(com.android.internal.org.bouncycastle.crypto.BlockCipher cipher)
+ {
+ this.cipher = new PaddedBufferedBlockCipher(cipher);
+ }
+
+ BufferedGenericBlockCipher(com.android.internal.org.bouncycastle.crypto.BlockCipher cipher, BlockCipherPadding padding)
+ {
+ this.cipher = new PaddedBufferedBlockCipher(cipher, padding);
+ }
+
+ public void init(boolean forEncryption, CipherParameters params)
+ throws IllegalArgumentException
+ {
+ cipher.init(forEncryption, params);
+ }
+
+ public boolean wrapOnNoPadding()
+ {
+ return !(cipher instanceof CTSBlockCipher);
+ }
+
+ public String getAlgorithmName()
+ {
+ return cipher.getUnderlyingCipher().getAlgorithmName();
+ }
+
+ public com.android.internal.org.bouncycastle.crypto.BlockCipher getUnderlyingCipher()
+ {
+ return cipher.getUnderlyingCipher();
+ }
+
+ public int getOutputSize(int len)
+ {
+ return cipher.getOutputSize(len);
+ }
+
+ public int getUpdateOutputSize(int len)
+ {
+ return cipher.getUpdateOutputSize(len);
+ }
+
+ public void updateAAD(byte[] input, int offset, int length)
+ {
+ throw new UnsupportedOperationException("AAD is not supported in the current mode.");
+ }
+
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException
+ {
+ return cipher.processByte(in, out, outOff);
+ }
+
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException
+ {
+ return cipher.processBytes(in, inOff, len, out, outOff);
+ }
+
+ public int doFinal(byte[] out, int outOff)
+ throws IllegalStateException, BadPaddingException
+ {
+ try
+ {
+ return cipher.doFinal(out, outOff);
+ }
+ catch (InvalidCipherTextException e)
+ {
+ throw new BadPaddingException(e.getMessage());
+ }
+ }
+ }
+
+ private static class AEADGenericBlockCipher
+ implements GenericBlockCipher
+ {
+ private static final Constructor aeadBadTagConstructor;
+
+ static
+ {
+ Class aeadBadTagClass = ClassUtil.loadClass(BaseBlockCipher.class, "javax.crypto.AEADBadTagException");
+ if (aeadBadTagClass != null)
+ {
+ aeadBadTagConstructor = findExceptionConstructor(aeadBadTagClass);
+ }
+ else
+ {
+ aeadBadTagConstructor = null;
+ }
+ }
+
+ private static Constructor findExceptionConstructor(Class clazz)
+ {
+ try
+ {
+ return clazz.getConstructor(new Class[]{String.class});
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+
+ private AEADCipher cipher;
+
+ AEADGenericBlockCipher(AEADCipher cipher)
+ {
+ this.cipher = cipher;
+ }
+
+ public void init(boolean forEncryption, CipherParameters params)
+ throws IllegalArgumentException
+ {
+ cipher.init(forEncryption, params);
+ }
+
+ public String getAlgorithmName()
+ {
+ if (cipher instanceof AEADBlockCipher)
+ {
+ return ((AEADBlockCipher)cipher).getUnderlyingCipher().getAlgorithmName();
+ }
+
+ return cipher.getAlgorithmName();
+ }
+
+ public boolean wrapOnNoPadding()
+ {
+ return false;
+ }
+
+ public com.android.internal.org.bouncycastle.crypto.BlockCipher getUnderlyingCipher()
+ {
+ if (cipher instanceof AEADBlockCipher)
+ {
+ return ((AEADBlockCipher)cipher).getUnderlyingCipher();
+ }
+
+ return null;
+ }
+
+ public int getOutputSize(int len)
+ {
+ return cipher.getOutputSize(len);
+ }
+
+ public int getUpdateOutputSize(int len)
+ {
+ return cipher.getUpdateOutputSize(len);
+ }
+
+ public void updateAAD(byte[] input, int offset, int length)
+ {
+ cipher.processAADBytes(input, offset, length);
+ }
+
+ public int processByte(byte in, byte[] out, int outOff)
+ throws DataLengthException
+ {
+ return cipher.processByte(in, out, outOff);
+ }
+
+ public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
+ throws DataLengthException
+ {
+ return cipher.processBytes(in, inOff, len, out, outOff);
+ }
+
+ public int doFinal(byte[] out, int outOff)
+ throws IllegalStateException, BadPaddingException
+ {
+ try
+ {
+ return cipher.doFinal(out, outOff);
+ }
+ catch (InvalidCipherTextException e)
+ {
+ if (aeadBadTagConstructor != null)
+ {
+ BadPaddingException aeadBadTag = null;
+ try
+ {
+ aeadBadTag = (BadPaddingException)aeadBadTagConstructor
+ .newInstance(new Object[]{e.getMessage()});
+ }
+ catch (Exception i)
+ {
+ // Shouldn't happen, but fall through to BadPaddingException
+ }
+ if (aeadBadTag != null)
+ {
+ throw aeadBadTag;
+ }
+ }
+ throw new BadPaddingException(e.getMessage());
+ }
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseKeyGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseKeyGenerator.java
new file mode 100644
index 00000000..64e09b95
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseKeyGenerator.java
@@ -0,0 +1,87 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.KeyGeneratorSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import com.android.internal.org.bouncycastle.crypto.CipherKeyGenerator;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.KeyGenerationParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BaseKeyGenerator
+ extends KeyGeneratorSpi
+{
+ protected String algName;
+ protected int keySize;
+ protected int defaultKeySize;
+ protected CipherKeyGenerator engine;
+
+ protected boolean uninitialised = true;
+
+ protected BaseKeyGenerator(
+ String algName,
+ int defaultKeySize,
+ CipherKeyGenerator engine)
+ {
+ this.algName = algName;
+ this.keySize = this.defaultKeySize = defaultKeySize;
+ this.engine = engine;
+ }
+
+ protected void engineInit(
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ throw new InvalidAlgorithmParameterException("Not Implemented");
+ }
+
+ protected void engineInit(
+ SecureRandom random)
+ {
+ if (random != null)
+ {
+ engine.init(new KeyGenerationParameters(random, defaultKeySize));
+ uninitialised = false;
+ }
+ }
+
+ protected void engineInit(
+ int keySize,
+ SecureRandom random)
+ {
+ try
+ {
+ if (random == null)
+ {
+ random = CryptoServicesRegistrar.getSecureRandom();
+ }
+ engine.init(new KeyGenerationParameters(random, keySize));
+ uninitialised = false;
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new InvalidParameterException(e.getMessage());
+ }
+ }
+
+ protected SecretKey engineGenerateKey()
+ {
+ if (uninitialised)
+ {
+ engine.init(new KeyGenerationParameters(CryptoServicesRegistrar.getSecureRandom(), defaultKeySize));
+ uninitialised = false;
+ }
+
+ return new SecretKeySpec(engine.generateKey(), algName);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
new file mode 100644
index 00000000..c142c388
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
@@ -0,0 +1,283 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.crypto.MacSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.interfaces.PBEKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEParameterSpec;
+import javax.crypto.spec.RC2ParameterSpec;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.Mac;
+import com.android.internal.org.bouncycastle.crypto.macs.HMac;
+import com.android.internal.org.bouncycastle.crypto.params.AEADParameters;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.params.RC2Parameters;
+// import org.bouncycastle.crypto.params.SkeinParameters;
+import com.android.internal.org.bouncycastle.jcajce.PKCS12Key;
+import com.android.internal.org.bouncycastle.jcajce.spec.AEADParameterSpec;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jcajce.spec.SkeinParameterSpec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BaseMac
+ extends MacSpi implements PBE
+{
+ private static final Class gcmSpecClass = ClassUtil.loadClass(BaseMac.class, "javax.crypto.spec.GCMParameterSpec");
+
+ private Mac macEngine;
+
+ private int scheme = PKCS12;
+ private int pbeHash = SHA1;
+ private int keySize = 160;
+
+ protected BaseMac(
+ Mac macEngine)
+ {
+ this.macEngine = macEngine;
+ }
+
+ protected BaseMac(
+ Mac macEngine,
+ int scheme,
+ int pbeHash,
+ int keySize)
+ {
+ this.macEngine = macEngine;
+ this.scheme = scheme;
+ this.pbeHash = pbeHash;
+ this.keySize = keySize;
+ }
+
+ protected void engineInit(
+ Key key,
+ final AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ CipherParameters param;
+
+ if (key == null)
+ {
+ throw new InvalidKeyException("key is null");
+ }
+
+ if (key instanceof PKCS12Key)
+ {
+ SecretKey k;
+ PBEParameterSpec pbeSpec;
+
+ try
+ {
+ k = (SecretKey)key;
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeyException("PKCS12 requires a SecretKey/PBEKey");
+ }
+
+ try
+ {
+ pbeSpec = (PBEParameterSpec)params;
+ }
+ catch (Exception e)
+ {
+ throw new InvalidAlgorithmParameterException("PKCS12 requires a PBEParameterSpec");
+ }
+
+ if (k instanceof PBEKey && pbeSpec == null)
+ {
+ pbeSpec = new PBEParameterSpec(((PBEKey)k).getSalt(), ((PBEKey)k).getIterationCount());
+ }
+
+ int digest = SHA1;
+ int keySize = 160;
+ // BEGIN Android-removed: Unsupported algorithms
+ // if (macEngine.getAlgorithmName().startsWith("GOST"))
+ // {
+ // digest = GOST3411;
+ // keySize = 256;
+ // }
+ // END Android-removed: Unsupported algorithms
+ // Android-changed: Adjust for missing if
+ // else if (macEngine instanceof HMac)
+ if (macEngine instanceof HMac)
+ {
+ if (!macEngine.getAlgorithmName().startsWith("SHA-1"))
+ {
+ if (macEngine.getAlgorithmName().startsWith("SHA-224"))
+ {
+ digest = SHA224;
+ keySize = 224;
+ }
+ else if (macEngine.getAlgorithmName().startsWith("SHA-256"))
+ {
+ digest = SHA256;
+ keySize = 256;
+ }
+ else if (macEngine.getAlgorithmName().startsWith("SHA-384"))
+ {
+ digest = SHA384;
+ keySize = 384;
+ }
+ else if (macEngine.getAlgorithmName().startsWith("SHA-512"))
+ {
+ digest = SHA512;
+ keySize = 512;
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ // else if (macEngine.getAlgorithmName().startsWith("RIPEMD160"))
+ // {
+ // digest = RIPEMD160;
+ // keySize = 160;
+ // }
+ // END Android-removed: Unsupported algorithms
+ else
+ {
+ throw new InvalidAlgorithmParameterException("no PKCS12 mapping for HMAC: " + macEngine.getAlgorithmName());
+ }
+ }
+ }
+ // TODO: add correct handling for other digests
+ param = PBE.Util.makePBEMacParameters(k, PKCS12, digest, keySize, pbeSpec);
+ }
+ else if (key instanceof BCPBEKey)
+ {
+ BCPBEKey k = (BCPBEKey)key;
+
+ if (k.getParam() != null)
+ {
+ param = k.getParam();
+ }
+ else if (params instanceof PBEParameterSpec)
+ {
+ param = PBE.Util.makePBEMacParameters(k, params);
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set.");
+ }
+ }
+ else
+ {
+ if (params instanceof PBEParameterSpec)
+ {
+ throw new InvalidAlgorithmParameterException("inappropriate parameter type: " + params.getClass().getName());
+ }
+ param = new KeyParameter(key.getEncoded());
+ }
+
+ final KeyParameter keyParam;
+ if (param instanceof ParametersWithIV)
+ {
+ keyParam = (KeyParameter)((ParametersWithIV)param).getParameters();
+ }
+ else
+ {
+ keyParam = (KeyParameter)param;
+ }
+
+ if (params instanceof AEADParameterSpec)
+ {
+ AEADParameterSpec aeadSpec = (AEADParameterSpec)params;
+
+ param = new AEADParameters(keyParam, aeadSpec.getMacSizeInBits(), aeadSpec.getNonce(), aeadSpec.getAssociatedData());
+ }
+ else if (params instanceof IvParameterSpec)
+ {
+ param = new ParametersWithIV(keyParam, ((IvParameterSpec)params).getIV());
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (params instanceof RC2ParameterSpec)
+ {
+ param = new ParametersWithIV(new RC2Parameters(keyParam.getKey(), ((RC2ParameterSpec)params).getEffectiveKeyBits()), ((RC2ParameterSpec)params).getIV());
+ }
+ else if (params instanceof SkeinParameterSpec)
+ {
+ param = new SkeinParameters.Builder(copyMap(((SkeinParameterSpec)params).getParameters())).setKey(keyParam.getKey()).build();
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ else if (params == null)
+ {
+ param = new KeyParameter(key.getEncoded());
+ }
+ else if (gcmSpecClass != null && gcmSpecClass.isAssignableFrom(params.getClass()))
+ {
+ param = GcmSpecUtil.extractAeadParameters(keyParam, params);
+ }
+ else if (!(params instanceof PBEParameterSpec))
+ {
+ throw new InvalidAlgorithmParameterException("unknown parameter type: " + params.getClass().getName());
+ }
+
+ try
+ {
+ macEngine.init(param);
+ }
+ catch (Exception e)
+ {
+ throw new InvalidAlgorithmParameterException("cannot initialize MAC: " + e.getMessage());
+ }
+ }
+
+ protected int engineGetMacLength()
+ {
+ return macEngine.getMacSize();
+ }
+
+ protected void engineReset()
+ {
+ macEngine.reset();
+ }
+
+ protected void engineUpdate(
+ byte input)
+ {
+ macEngine.update(input);
+ }
+
+ protected void engineUpdate(
+ byte[] input,
+ int offset,
+ int len)
+ {
+ macEngine.update(input, offset, len);
+ }
+
+ protected byte[] engineDoFinal()
+ {
+ byte[] out = new byte[engineGetMacLength()];
+
+ macEngine.doFinal(out, 0);
+
+ return out;
+ }
+
+ private static Hashtable copyMap(Map paramsMap)
+ {
+ Hashtable newTable = new Hashtable();
+
+ Iterator keys = paramsMap.keySet().iterator();
+ while (keys.hasNext())
+ {
+ Object key = keys.next();
+ newTable.put(key, paramsMap.get(key));
+ }
+
+ return newTable;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java
new file mode 100644
index 00000000..0265e6ae
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java
@@ -0,0 +1,97 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.lang.reflect.Constructor;
+import java.security.InvalidKeyException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactorySpi;
+import javax.crypto.spec.SecretKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BaseSecretKeyFactory
+ extends SecretKeyFactorySpi
+ implements PBE
+{
+ protected String algName;
+ protected ASN1ObjectIdentifier algOid;
+
+ protected BaseSecretKeyFactory(
+ String algName,
+ ASN1ObjectIdentifier algOid)
+ {
+ this.algName = algName;
+ this.algOid = algOid;
+ }
+
+ protected SecretKey engineGenerateSecret(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof SecretKeySpec)
+ {
+ return new SecretKeySpec(((SecretKeySpec)keySpec).getEncoded(), algName);
+ }
+
+ throw new InvalidKeySpecException("Invalid KeySpec");
+ }
+
+ protected KeySpec engineGetKeySpec(
+ SecretKey key,
+ Class keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec == null)
+ {
+ throw new InvalidKeySpecException("keySpec parameter is null");
+ }
+ if (key == null)
+ {
+ throw new InvalidKeySpecException("key parameter is null");
+ }
+
+ if (SecretKeySpec.class.isAssignableFrom(keySpec))
+ {
+ return new SecretKeySpec(key.getEncoded(), algName);
+ }
+
+ try
+ {
+ Class[] parameters = { byte[].class };
+
+ Constructor c = keySpec.getConstructor(parameters);
+ Object[] p = new Object[1];
+
+ p[0] = key.getEncoded();
+
+ return (KeySpec)c.newInstance(p);
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeySpecException(e.toString());
+ }
+ }
+
+ protected SecretKey engineTranslateKey(
+ SecretKey key)
+ throws InvalidKeyException
+ {
+ if (key == null)
+ {
+ throw new InvalidKeyException("key parameter is null");
+ }
+
+ if (!key.getAlgorithm().equalsIgnoreCase(algName))
+ {
+ throw new InvalidKeyException("Key not of type " + algName + ".");
+ }
+
+ return new SecretKeySpec(key.getEncoded(), algName);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java
new file mode 100644
index 00000000..a1f9a8d8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java
@@ -0,0 +1,438 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEParameterSpec;
+// Android-removed: Unsupported algorithms
+// import javax.crypto.spec.RC2ParameterSpec;
+// import javax.crypto.spec.RC5ParameterSpec;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.DataLengthException;
+import com.android.internal.org.bouncycastle.crypto.StreamCipher;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.internal.org.bouncycastle.jcajce.PKCS12Key;
+import com.android.internal.org.bouncycastle.jcajce.PKCS12KeyWithParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BaseStreamCipher
+ extends BaseWrapCipher
+ implements PBE
+{
+ //
+ // specs we can handle.
+ //
+ private Class[] availableSpecs =
+ {
+ // Android-removed: Unsupported algorithms
+ // RC2ParameterSpec.class,
+ // RC5ParameterSpec.class,
+ IvParameterSpec.class,
+ PBEParameterSpec.class
+ };
+
+ private StreamCipher cipher;
+ private int keySizeInBits;
+ private int digest;
+ private ParametersWithIV ivParam;
+
+ private int ivLength = 0;
+
+ private PBEParameterSpec pbeSpec = null;
+ private String pbeAlgorithm = null;
+
+ protected BaseStreamCipher(
+ StreamCipher engine,
+ int ivLength)
+ {
+ this(engine, ivLength, -1, -1);
+ }
+
+ protected BaseStreamCipher(
+ StreamCipher engine,
+ int ivLength,
+ int keySizeInBits)
+ {
+ this(engine, ivLength, keySizeInBits, -1);
+ }
+
+ protected BaseStreamCipher(
+ StreamCipher engine,
+ int ivLength,
+ int keySizeInBits,
+ int digest)
+ {
+ cipher = engine;
+ this.ivLength = ivLength;
+ this.keySizeInBits = keySizeInBits;
+ this.digest = digest;
+ }
+
+ protected int engineGetBlockSize()
+ {
+ return 0;
+ }
+
+ protected byte[] engineGetIV()
+ {
+ return (ivParam != null) ? ivParam.getIV() : null;
+ }
+
+ protected int engineGetKeySize(
+ Key key)
+ {
+ return key.getEncoded().length * 8;
+ }
+
+ protected int engineGetOutputSize(
+ int inputLen)
+ {
+ return inputLen;
+ }
+
+ protected AlgorithmParameters engineGetParameters()
+ {
+ if (engineParams == null)
+ {
+ if (pbeSpec != null)
+ {
+ try
+ {
+ AlgorithmParameters engineParams = createParametersInstance(pbeAlgorithm);
+ engineParams.init(pbeSpec);
+
+ return engineParams;
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+ else if (ivParam != null)
+ {
+ String name = cipher.getAlgorithmName();
+
+ if (name.indexOf('/') >= 0)
+ {
+ name = name.substring(0, name.indexOf('/'));
+ }
+ if (name.startsWith("ChaCha7539"))
+ {
+ name = "ChaCha7539";
+ }
+ else if (name.startsWith("Grain"))
+ {
+ name = "Grainv1";
+ }
+ else if (name.startsWith("HC"))
+ {
+ int endIndex = name.indexOf('-');
+ name = name.substring(0, endIndex) + name.substring(endIndex + 1);
+ }
+
+ try
+ {
+ engineParams = createParametersInstance(name);
+ engineParams.init(new IvParameterSpec(ivParam.getIV()));
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.toString());
+ }
+ }
+ }
+
+ return engineParams;
+ }
+
+ /**
+ * should never be called.
+ */
+ protected void engineSetMode(
+ String mode)
+ throws NoSuchAlgorithmException
+ {
+ if (!(mode.equalsIgnoreCase("ECB") || mode.equals("NONE")))
+ {
+ throw new NoSuchAlgorithmException("can't support mode " + mode);
+ }
+ }
+
+ /**
+ * should never be called.
+ */
+ protected void engineSetPadding(
+ String padding)
+ throws NoSuchPaddingException
+ {
+ if (!padding.equalsIgnoreCase("NoPadding"))
+ {
+ throw new NoSuchPaddingException("Padding " + padding + " unknown.");
+ }
+ }
+
+ protected void engineInit(
+ int opmode,
+ Key key,
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ CipherParameters param;
+
+ this.pbeSpec = null;
+ this.pbeAlgorithm = null;
+
+ this.engineParams = null;
+
+ //
+ // basic key check
+ //
+ if (!(key instanceof SecretKey))
+ {
+ throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption.");
+ }
+
+ if (key instanceof PKCS12Key)
+ {
+ PKCS12Key k = (PKCS12Key)key;
+ pbeSpec = (PBEParameterSpec)params;
+ if (k instanceof PKCS12KeyWithParameters && pbeSpec == null)
+ {
+ pbeSpec = new PBEParameterSpec(((PKCS12KeyWithParameters)k).getSalt(), ((PKCS12KeyWithParameters)k).getIterationCount());
+ }
+
+ param = PBE.Util.makePBEParameters(k.getEncoded(), PKCS12, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName());
+ }
+ else if (key instanceof BCPBEKey)
+ {
+ BCPBEKey k = (BCPBEKey)key;
+
+ if (k.getOID() != null)
+ {
+ pbeAlgorithm = k.getOID().getId();
+ }
+ else
+ {
+ pbeAlgorithm = k.getAlgorithm();
+ }
+
+ if (k.getParam() != null)
+ {
+ param = k.getParam();
+ pbeSpec = new PBEParameterSpec(k.getSalt(), k.getIterationCount());
+ }
+ else if (params instanceof PBEParameterSpec)
+ {
+ param = PBE.Util.makePBEParameters(k, params, cipher.getAlgorithmName());
+ pbeSpec = (PBEParameterSpec)params;
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set.");
+ }
+
+ if (k.getIvSize() != 0)
+ {
+ ivParam = (ParametersWithIV)param;
+ }
+ }
+ else if (params == null)
+ {
+ if (digest > 0)
+ {
+ throw new InvalidKeyException("Algorithm requires a PBE key");
+ }
+ param = new KeyParameter(key.getEncoded());
+ }
+ else if (params instanceof IvParameterSpec)
+ {
+ param = new ParametersWithIV(new KeyParameter(key.getEncoded()), ((IvParameterSpec)params).getIV());
+ ivParam = (ParametersWithIV)param;
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("unknown parameter type.");
+ }
+
+ if ((ivLength != 0) && !(param instanceof ParametersWithIV))
+ {
+ SecureRandom ivRandom = random;
+
+ if (ivRandom == null)
+ {
+ ivRandom = CryptoServicesRegistrar.getSecureRandom();
+ }
+
+ if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE))
+ {
+ byte[] iv = new byte[ivLength];
+
+ ivRandom.nextBytes(iv);
+ param = new ParametersWithIV(param, iv);
+ ivParam = (ParametersWithIV)param;
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("no IV set when one expected");
+ }
+ }
+
+ try
+ {
+ switch (opmode)
+ {
+ case Cipher.ENCRYPT_MODE:
+ case Cipher.WRAP_MODE:
+ cipher.init(true, param);
+ break;
+ case Cipher.DECRYPT_MODE:
+ case Cipher.UNWRAP_MODE:
+ cipher.init(false, param);
+ break;
+ default:
+ throw new InvalidParameterException("unknown opmode " + opmode + " passed");
+ }
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeyException(e.getMessage());
+ }
+ }
+
+ protected void engineInit(
+ int opmode,
+ Key key,
+ AlgorithmParameters params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ AlgorithmParameterSpec paramSpec = null;
+
+ if (params != null)
+ {
+ paramSpec = SpecUtil.extractSpec(params, availableSpecs);
+
+ if (paramSpec == null)
+ {
+ throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString());
+ }
+ }
+
+ engineInit(opmode, key, paramSpec, random);
+ engineParams = params;
+ }
+
+ protected void engineInit(
+ int opmode,
+ Key key,
+ SecureRandom random)
+ throws InvalidKeyException
+ {
+ try
+ {
+ engineInit(opmode, key, (AlgorithmParameterSpec)null, random);
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ throw new InvalidKeyException(e.getMessage());
+ }
+ }
+
+ protected byte[] engineUpdate(
+ byte[] input,
+ int inputOffset,
+ int inputLen)
+ {
+ byte[] out = new byte[inputLen];
+
+ cipher.processBytes(input, inputOffset, inputLen, out, 0);
+
+ return out;
+ }
+
+ protected int engineUpdate(
+ byte[] input,
+ int inputOffset,
+ int inputLen,
+ byte[] output,
+ int outputOffset)
+ throws ShortBufferException
+ {
+ if (outputOffset + inputLen > output.length)
+ {
+ throw new ShortBufferException("output buffer too short for input.");
+ }
+
+ try
+ {
+ cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
+
+ return inputLen;
+ }
+ catch (DataLengthException e)
+ {
+ // should never happen
+ throw new IllegalStateException(e.getMessage());
+ }
+ }
+
+ protected byte[] engineDoFinal(
+ byte[] input,
+ int inputOffset,
+ int inputLen)
+ {
+ if (inputLen != 0)
+ {
+ byte[] out = engineUpdate(input, inputOffset, inputLen);
+
+ cipher.reset();
+
+ return out;
+ }
+
+ cipher.reset();
+
+ return new byte[0];
+ }
+
+ protected int engineDoFinal(
+ byte[] input,
+ int inputOffset,
+ int inputLen,
+ byte[] output,
+ int outputOffset)
+ throws ShortBufferException
+ {
+ if (outputOffset + inputLen > output.length)
+ {
+ throw new ShortBufferException("output buffer too short for input.");
+ }
+
+ if (inputLen != 0)
+ {
+ cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
+ }
+
+ cipher.reset();
+
+ return inputLen;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java
new file mode 100644
index 00000000..e70fe76f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java
@@ -0,0 +1,609 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.io.ByteArrayOutputStream;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherSpi;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEParameterSpec;
+// Android-removed: Unsupported algorithms
+// import javax.crypto.spec.RC2ParameterSpec;
+// import javax.crypto.spec.RC5ParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.InvalidCipherTextException;
+import com.android.internal.org.bouncycastle.crypto.Wrapper;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithRandom;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.params.ParametersWithSBox;
+// import org.bouncycastle.crypto.params.ParametersWithUKM;
+// import org.bouncycastle.jcajce.spec.GOST28147WrapParameterSpec;
+// Android-changed: Use default provider for JCA algorithms instead of BC
+// Was: import org.bouncycastle.jcajce.util.BCJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class BaseWrapCipher
+ extends CipherSpi
+ implements PBE
+{
+ //
+ // specs we can handle.
+ //
+ private Class[] availableSpecs =
+ {
+ // Android-removed: Unsupported algorithms
+ // GOST28147WrapParameterSpec.class,
+ PBEParameterSpec.class,
+ // Android-removed: Unsupported algorithms
+ // RC2ParameterSpec.class,
+ // RC5ParameterSpec.class
+ IvParameterSpec.class
+ };
+
+ protected int pbeType = PKCS12;
+ protected int pbeHash = SHA1;
+ protected int pbeKeySize;
+ protected int pbeIvSize;
+
+ protected AlgorithmParameters engineParams = null;
+
+ protected Wrapper wrapEngine = null;
+
+ private int ivSize;
+ private byte[] iv;
+
+ private ErasableOutputStream wrapStream = null;
+ private boolean forWrapping;
+
+ // Android-changed: Use default provider for JCA algorithms instead of BC
+ // Was: private final JcaJceHelper helper = new BCJcaJceHelper();
+ private final JcaJceHelper helper = new DefaultJcaJceHelper();
+
+ protected BaseWrapCipher()
+ {
+ }
+
+ protected BaseWrapCipher(
+ Wrapper wrapEngine)
+ {
+ this(wrapEngine, 0);
+ }
+
+ protected BaseWrapCipher(
+ Wrapper wrapEngine,
+ int ivSize)
+ {
+ this.wrapEngine = wrapEngine;
+ this.ivSize = ivSize;
+ }
+
+ protected int engineGetBlockSize()
+ {
+ return 0;
+ }
+
+ protected byte[] engineGetIV()
+ {
+ return Arrays.clone(iv);
+ }
+
+ protected int engineGetKeySize(
+ Key key)
+ {
+ return key.getEncoded().length * 8;
+ }
+
+ protected int engineGetOutputSize(
+ int inputLen)
+ {
+ return -1;
+ }
+
+ protected AlgorithmParameters engineGetParameters()
+ {
+ if (engineParams == null)
+ {
+ if (iv != null)
+ {
+ String name = wrapEngine.getAlgorithmName();
+
+ if (name.indexOf('/') >= 0)
+ {
+ name = name.substring(0, name.indexOf('/'));
+ }
+
+ try
+ {
+ engineParams = createParametersInstance(name);
+ engineParams.init(new IvParameterSpec(iv));
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.toString());
+ }
+ }
+ }
+
+ return engineParams;
+ }
+
+ protected final AlgorithmParameters createParametersInstance(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return helper.createAlgorithmParameters(algorithm);
+ }
+
+ protected void engineSetMode(
+ String mode)
+ throws NoSuchAlgorithmException
+ {
+ throw new NoSuchAlgorithmException("can't support mode " + mode);
+ }
+
+ protected void engineSetPadding(
+ String padding)
+ throws NoSuchPaddingException
+ {
+ throw new NoSuchPaddingException("Padding " + padding + " unknown.");
+ }
+
+ protected void engineInit(
+ int opmode,
+ Key key,
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ CipherParameters param;
+
+ if (key instanceof BCPBEKey)
+ {
+ BCPBEKey k = (BCPBEKey)key;
+
+ if (params instanceof PBEParameterSpec)
+ {
+ param = PBE.Util.makePBEParameters(k, params, wrapEngine.getAlgorithmName());
+ }
+ else if (k.getParam() != null)
+ {
+ param = k.getParam();
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set.");
+ }
+ }
+ else
+ {
+ param = new KeyParameter(key.getEncoded());
+ }
+
+ if (params instanceof IvParameterSpec)
+ {
+ IvParameterSpec ivSpec = (IvParameterSpec)params;
+ this.iv = ivSpec.getIV();
+ param = new ParametersWithIV(param, iv);
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ if (params instanceof GOST28147WrapParameterSpec)
+ {
+ GOST28147WrapParameterSpec spec = (GOST28147WrapParameterSpec) params;
+
+ byte[] sBox = spec.getSBox();
+ if (sBox != null)
+ {
+ param = new ParametersWithSBox(param, sBox);
+ }
+ param = new ParametersWithUKM(param, spec.getUKM());
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ if (param instanceof KeyParameter && ivSize != 0)
+ {
+ if (opmode == Cipher.WRAP_MODE || opmode == Cipher.ENCRYPT_MODE)
+ {
+ iv = new byte[ivSize];
+ random.nextBytes(iv);
+ param = new ParametersWithIV(param, iv);
+ }
+ }
+
+ if (random != null)
+ {
+ param = new ParametersWithRandom(param, random);
+ }
+
+ try
+ {
+ switch (opmode)
+ {
+ case Cipher.WRAP_MODE:
+ wrapEngine.init(true, param);
+ this.wrapStream = null;
+ this.forWrapping = true;
+ break;
+ case Cipher.UNWRAP_MODE:
+ wrapEngine.init(false, param);
+ this.wrapStream = null;
+ this.forWrapping = false;
+ break;
+ case Cipher.ENCRYPT_MODE:
+ wrapEngine.init(true, param);
+ this.wrapStream = new ErasableOutputStream();
+ this.forWrapping = true;
+ break;
+ case Cipher.DECRYPT_MODE:
+ wrapEngine.init(false, param);
+ this.wrapStream = new ErasableOutputStream();
+ this.forWrapping = false;
+ break;
+ default:
+ throw new InvalidParameterException("Unknown mode parameter passed to init.");
+ }
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeyOrParametersException(e.getMessage(), e);
+ }
+ }
+
+ protected void engineInit(
+ int opmode,
+ Key key,
+ AlgorithmParameters params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException
+ {
+ AlgorithmParameterSpec paramSpec = null;
+
+ if (params != null)
+ {
+ paramSpec = SpecUtil.extractSpec(params, availableSpecs);
+
+ if (paramSpec == null)
+ {
+ throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString());
+ }
+ }
+
+ engineParams = params;
+ engineInit(opmode, key, paramSpec, random);
+ }
+
+ protected void engineInit(
+ int opmode,
+ Key key,
+ SecureRandom random)
+ throws InvalidKeyException
+ {
+ try
+ {
+ engineInit(opmode, key, (AlgorithmParameterSpec)null, random);
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ throw new InvalidKeyOrParametersException(e.getMessage(), e);
+ }
+ }
+
+ protected byte[] engineUpdate(
+ byte[] input,
+ int inputOffset,
+ int inputLen)
+ {
+ if (wrapStream == null)
+ {
+ throw new IllegalStateException("not supported in a wrapping mode");
+ }
+
+ wrapStream.write(input, inputOffset, inputLen);
+
+ return null;
+ }
+
+ protected int engineUpdate(
+ byte[] input,
+ int inputOffset,
+ int inputLen,
+ byte[] output,
+ int outputOffset)
+ throws ShortBufferException
+ {
+ if (wrapStream == null)
+ {
+ throw new IllegalStateException("not supported in a wrapping mode");
+ }
+
+ wrapStream.write(input, inputOffset, inputLen);
+
+ return 0;
+ }
+
+ protected byte[] engineDoFinal(
+ byte[] input,
+ int inputOffset,
+ int inputLen)
+ throws IllegalBlockSizeException, BadPaddingException
+ {
+ if (wrapStream == null)
+ {
+ throw new IllegalStateException("not supported in a wrapping mode");
+ }
+
+ if (input != null)
+ {
+ wrapStream.write(input, inputOffset, inputLen);
+ }
+
+ try
+ {
+ if (forWrapping)
+ {
+ try
+ {
+ return wrapEngine.wrap(wrapStream.getBuf(), 0, wrapStream.size());
+ }
+ catch (Exception e)
+ {
+ throw new IllegalBlockSizeException(e.getMessage());
+ }
+ }
+ else
+ {
+ try
+ {
+ return wrapEngine.unwrap(wrapStream.getBuf(), 0, wrapStream.size());
+ }
+ catch (InvalidCipherTextException e)
+ {
+ throw new BadPaddingException(e.getMessage());
+ }
+ }
+ }
+ finally
+ {
+ wrapStream.erase();
+ }
+ }
+
+ protected int engineDoFinal(
+ byte[] input,
+ int inputOffset,
+ int inputLen,
+ byte[] output,
+ int outputOffset)
+ throws IllegalBlockSizeException, BadPaddingException, ShortBufferException
+ {
+ if (wrapStream == null)
+ {
+ throw new IllegalStateException("not supported in a wrapping mode");
+ }
+
+ wrapStream.write(input, inputOffset, inputLen);
+
+ try
+ {
+ byte[] enc;
+
+ if (forWrapping)
+ {
+ try
+ {
+ enc = wrapEngine.wrap(wrapStream.getBuf(), 0, wrapStream.size());
+ }
+ catch (Exception e)
+ {
+ throw new IllegalBlockSizeException(e.getMessage());
+ }
+ }
+ else
+ {
+ try
+ {
+ enc = wrapEngine.unwrap(wrapStream.getBuf(), 0, wrapStream.size());
+ }
+ catch (InvalidCipherTextException e)
+ {
+ throw new BadPaddingException(e.getMessage());
+ }
+ }
+
+ if (outputOffset + enc.length > output.length)
+ {
+ throw new ShortBufferException("output buffer too short for input.");
+ }
+
+ System.arraycopy(enc, 0, output, outputOffset, enc.length);
+
+ return enc.length;
+ }
+ finally
+ {
+ wrapStream.erase();
+ }
+ }
+
+ protected byte[] engineWrap(
+ Key key)
+ throws IllegalBlockSizeException, InvalidKeyException
+ {
+ byte[] encoded = key.getEncoded();
+ if (encoded == null)
+ {
+ throw new InvalidKeyException("Cannot wrap key, null encoding.");
+ }
+
+ try
+ {
+ if (wrapEngine == null)
+ {
+ return engineDoFinal(encoded, 0, encoded.length);
+ }
+ else
+ {
+ return wrapEngine.wrap(encoded, 0, encoded.length);
+ }
+ }
+ catch (BadPaddingException e)
+ {
+ throw new IllegalBlockSizeException(e.getMessage());
+ }
+ }
+
+ protected Key engineUnwrap(
+ byte[] wrappedKey,
+ String wrappedKeyAlgorithm,
+ int wrappedKeyType)
+ throws InvalidKeyException, NoSuchAlgorithmException
+ {
+ byte[] encoded;
+ try
+ {
+ if (wrapEngine == null)
+ {
+ encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length);
+ }
+ else
+ {
+ encoded = wrapEngine.unwrap(wrappedKey, 0, wrappedKey.length);
+ }
+ }
+ catch (InvalidCipherTextException e)
+ {
+ throw new InvalidKeyException(e.getMessage());
+ }
+ catch (BadPaddingException e)
+ {
+ throw new InvalidKeyException(e.getMessage());
+ }
+ catch (IllegalBlockSizeException e2)
+ {
+ throw new InvalidKeyException(e2.getMessage());
+ }
+
+ if (wrappedKeyType == Cipher.SECRET_KEY)
+ {
+ return new SecretKeySpec(encoded, wrappedKeyAlgorithm);
+ }
+ else if (wrappedKeyAlgorithm.equals("") && wrappedKeyType == Cipher.PRIVATE_KEY)
+ {
+ /*
+ * The caller doesn't know the algorithm as it is part of
+ * the encrypted data.
+ */
+ try
+ {
+ PrivateKeyInfo in = PrivateKeyInfo.getInstance(encoded);
+
+ PrivateKey privKey = BouncyCastleProvider.getPrivateKey(in);
+
+ if (privKey != null)
+ {
+ return privKey;
+ }
+ else
+ {
+ throw new InvalidKeyException("algorithm " + in.getPrivateKeyAlgorithm().getAlgorithm() + " not supported");
+ }
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeyException("Invalid key encoding.");
+ }
+ }
+ else
+ {
+ try
+ {
+ KeyFactory kf = helper.createKeyFactory(wrappedKeyAlgorithm);
+
+ if (wrappedKeyType == Cipher.PUBLIC_KEY)
+ {
+ return kf.generatePublic(new X509EncodedKeySpec(encoded));
+ }
+ else if (wrappedKeyType == Cipher.PRIVATE_KEY)
+ {
+ return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded));
+ }
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new InvalidKeyException("Unknown key type " + e.getMessage());
+ }
+ catch (InvalidKeySpecException e2)
+ {
+ throw new InvalidKeyException("Unknown key type " + e2.getMessage());
+ }
+
+ throw new InvalidKeyException("Unknown key type " + wrappedKeyType);
+ }
+ }
+
+ protected static final class ErasableOutputStream
+ extends ByteArrayOutputStream
+ {
+ public ErasableOutputStream()
+ {
+ }
+
+ public byte[] getBuf()
+ {
+ return buf;
+ }
+
+ public void erase()
+ {
+ Arrays.fill(this.buf, (byte)0);
+ reset();
+ }
+ }
+
+ protected static class InvalidKeyOrParametersException
+ extends InvalidKeyException
+ {
+ private final Throwable cause;
+
+ InvalidKeyOrParametersException(String msg, Throwable cause)
+ {
+ super(msg);
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BlockCipherProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BlockCipherProvider.java
new file mode 100644
index 00000000..330d51bd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BlockCipherProvider.java
@@ -0,0 +1,12 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import com.android.internal.org.bouncycastle.crypto.BlockCipher;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface BlockCipherProvider
+{
+ BlockCipher get();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java
new file mode 100644
index 00000000..5582be73
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/ClassUtil.java
@@ -0,0 +1,49 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ClassUtil
+{
+ public static Class loadClass(Class sourceClass, final String className)
+ {
+ try
+ {
+ ClassLoader loader = sourceClass.getClassLoader();
+
+ if (loader != null)
+ {
+ return loader.loadClass(className);
+ }
+ else
+ {
+ return (Class)AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ try
+ {
+ return Class.forName(className);
+ }
+ catch (Exception e)
+ {
+ // ignore - maybe log?
+ }
+
+ return null;
+ }
+ });
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ // ignore - maybe log?
+ }
+
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
new file mode 100644
index 00000000..242306bf
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/GcmSpecUtil.java
@@ -0,0 +1,136 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.cms.GCMParameters;
+import com.android.internal.org.bouncycastle.crypto.params.AEADParameters;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.util.Integers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GcmSpecUtil
+{
+ static final Class gcmSpecClass = ClassUtil.loadClass(GcmSpecUtil.class, "javax.crypto.spec.GCMParameterSpec");
+
+ static final Method tLen;
+ static final Method iv;
+
+ static
+ {
+ if (gcmSpecClass != null)
+ {
+ tLen = extractMethod("getTLen");
+ iv = extractMethod("getIV");
+ }
+ else
+ {
+ tLen = null;
+ iv = null;
+ }
+ }
+
+ private static Method extractMethod(final String name)
+ {
+ try
+ {
+ return (Method)AccessController.doPrivileged(new PrivilegedExceptionAction()
+ {
+ public Object run()
+ throws Exception
+ {
+ return gcmSpecClass.getDeclaredMethod(name, new Class[0]);
+ }
+ });
+ }
+ catch (PrivilegedActionException e)
+ {
+ return null;
+ }
+ }
+
+ public static boolean gcmSpecExists()
+ {
+ return gcmSpecClass != null;
+ }
+
+ public static boolean isGcmSpec(AlgorithmParameterSpec paramSpec)
+ {
+ return gcmSpecClass != null && gcmSpecClass.isInstance(paramSpec);
+ }
+
+ public static boolean isGcmSpec(Class paramSpecClass)
+ {
+ return gcmSpecClass == paramSpecClass;
+ }
+
+ public static AlgorithmParameterSpec extractGcmSpec(ASN1Primitive spec)
+ throws InvalidParameterSpecException
+ {
+ try
+ {
+ GCMParameters gcmParams = GCMParameters.getInstance(spec);
+ Constructor constructor = gcmSpecClass.getConstructor(new Class[]{Integer.TYPE, byte[].class});
+
+ return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(gcmParams.getIcvLen() * 8), gcmParams.getNonce() });
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new InvalidParameterSpecException("No constructor found!"); // should never happen
+ }
+ catch (Exception e)
+ {
+ throw new InvalidParameterSpecException("Construction failed: " + e.getMessage()); // should never happen
+ }
+ }
+
+ static AEADParameters extractAeadParameters(final KeyParameter keyParam, final AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException
+ {
+ try
+ {
+ return (AEADParameters)AccessController.doPrivileged(new PrivilegedExceptionAction()
+ {
+ public Object run()
+ throws Exception
+ {
+ return new AEADParameters(keyParam, ((Integer)tLen.invoke(params, new Object[0])).intValue(), (byte[])iv.invoke(params, new Object[0]));
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ throw new InvalidAlgorithmParameterException("Cannot process GCMParameterSpec.");
+ }
+ }
+
+ public static GCMParameters extractGcmParameters(final AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ try
+ {
+ return (GCMParameters)AccessController.doPrivileged(new PrivilegedExceptionAction()
+ {
+ public Object run()
+ throws Exception
+ {
+ return new GCMParameters((byte[])iv.invoke(paramSpec, new Object[0]), ((Integer)tLen.invoke(paramSpec, new Object[0])).intValue() / 8);
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ throw new InvalidParameterSpecException("Cannot process GCMParameterSpec");
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.java
new file mode 100644
index 00000000..c9990aef
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.java
@@ -0,0 +1,122 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.io.IOException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import javax.crypto.spec.IvParameterSpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class IvAlgorithmParameters
+ extends BaseAlgorithmParameters
+{
+ private byte[] iv;
+
+ protected byte[] engineGetEncoded()
+ throws IOException
+ {
+ return engineGetEncoded("ASN.1");
+ }
+
+ protected byte[] engineGetEncoded(
+ String format)
+ throws IOException
+ {
+ if (isASN1FormatString(format))
+ {
+ return new DEROctetString(engineGetEncoded("RAW")).getEncoded();
+ }
+
+ if (format.equals("RAW"))
+ {
+ return Arrays.clone(iv);
+ }
+
+ return null;
+ }
+
+ protected AlgorithmParameterSpec localEngineGetParameterSpec(
+ Class paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (paramSpec == IvParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
+ {
+ return new IvParameterSpec(iv);
+ }
+
+ throw new InvalidParameterSpecException("unknown parameter spec passed to IV parameters object.");
+ }
+
+ protected void engineInit(
+ AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (!(paramSpec instanceof IvParameterSpec))
+ {
+ throw new InvalidParameterSpecException("IvParameterSpec required to initialise a IV parameters algorithm parameters object");
+ }
+
+ this.iv = ((IvParameterSpec)paramSpec).getIV();
+ }
+
+ protected void engineInit(
+ byte[] params)
+ throws IOException
+ {
+ //
+ // check that we don't have a DER encoded octet string
+ //
+ if ((params.length % 8) != 0
+ && params[0] == 0x04 && params[1] == params.length - 2)
+ {
+ ASN1OctetString oct = (ASN1OctetString)ASN1Primitive.fromByteArray(params);
+
+ params = oct.getOctets();
+ }
+
+ this.iv = Arrays.clone(params);
+ }
+
+ protected void engineInit(
+ byte[] params,
+ String format)
+ throws IOException
+ {
+ if (isASN1FormatString(format))
+ {
+ try
+ {
+ ASN1OctetString oct = (ASN1OctetString)ASN1Primitive.fromByteArray(params);
+
+ engineInit(oct.getOctets());
+ }
+ catch (Exception e)
+ {
+ throw new IOException("Exception decoding: " + e);
+ }
+
+ return;
+ }
+
+ if (format.equals("RAW"))
+ {
+ engineInit(params);
+ return;
+ }
+
+ throw new IOException("Unknown parameters format in IV parameters object");
+ }
+
+ protected String engineToString()
+ {
+ return "IV Parameters";
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
new file mode 100644
index 00000000..52557652
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
@@ -0,0 +1,547 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+// BEGIN Android-added: Needed for compatibility helper
+import java.lang.reflect.Method;
+// END Android-added: Needed for compatibility helper
+import java.security.InvalidAlgorithmParameterException;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.SecretKey;
+// BEGIN Android-added: Allow IVs specified in parameters.
+import javax.crypto.spec.IvParameterSpec;
+// END Android-added: Allow IVs specified in parameters.
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+import com.android.internal.org.bouncycastle.crypto.PBEParametersGenerator;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.crypto.digests.GOST3411Digest;
+// import org.bouncycastle.crypto.digests.MD2Digest;
+// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
+// import org.bouncycastle.crypto.digests.TigerDigest;
+// import org.bouncycastle.crypto.digests.SM3Digest;
+import com.android.internal.org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
+import com.android.internal.org.bouncycastle.crypto.params.DESParameters;
+import com.android.internal.org.bouncycastle.crypto.params.KeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.ParametersWithIV;
+// BEGIN Android-changed: Use Android digests
+// import org.bouncycastle.crypto.util.DigestFactory;
+import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+// END Android-changed: Use Android digests
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PBE
+{
+ //
+ // PBE Based encryption constants - by default we do PKCS12 with SHA-1
+ //
+ static final int MD5 = 0;
+ static final int SHA1 = 1;
+ // Android-removed: Unsupported algorithms
+ // static final int RIPEMD160 = 2;
+ // static final int TIGER = 3;
+ static final int SHA256 = 4;
+ // Android-removed: Unsupported algorithms
+ // static final int MD2 = 5;
+ // static final int GOST3411 = 6;
+ static final int SHA224 = 7;
+ static final int SHA384 = 8;
+ static final int SHA512 = 9;
+ // Android-removed: Unsupported algorithms
+ // static final int SHA3_224 = 10;
+ // static final int SHA3_256 = 11;
+ // static final int SHA3_384 = 12;
+ // static final int SHA3_512 = 13;
+ // static final int SM3 = 14;
+
+ static final int PKCS5S1 = 0;
+ static final int PKCS5S2 = 1;
+ static final int PKCS12 = 2;
+ static final int OPENSSL = 3;
+ static final int PKCS5S1_UTF8 = 4;
+ static final int PKCS5S2_UTF8 = 5;
+
+ /**
+ * uses the appropriate mixer to generate the key and IV if necessary.
+ */
+ static class Util
+ {
+ static private PBEParametersGenerator makePBEGenerator(
+ int type,
+ int hash)
+ {
+ PBEParametersGenerator generator;
+
+ if (type == PKCS5S1 || type == PKCS5S1_UTF8)
+ {
+ switch (hash)
+ {
+ // Android-removed: Unsupported algorithms
+ // case MD2:
+ // generator = new PKCS5S1ParametersGenerator(new MD2Digest());
+ // break;
+ case MD5:
+ // Android-changed: Use Android digests
+ // generator = new PKCS5S1ParametersGenerator(DigestFactory.createMD5());
+ generator = new PKCS5S1ParametersGenerator(AndroidDigestFactory.getMD5());
+ break;
+ case SHA1:
+ // Android-changed: Use Android digests
+ // generator = new PKCS5S1ParametersGenerator(DigestFactory.createSHA1());
+ generator = new PKCS5S1ParametersGenerator(AndroidDigestFactory.getSHA1());
+ break;
+ default:
+ throw new IllegalStateException("PKCS5 scheme 1 only supports MD2, MD5 and SHA1.");
+ }
+ }
+ else if (type == PKCS5S2 || type == PKCS5S2_UTF8)
+ {
+ switch (hash)
+ {
+ // Android-removed: Unsupported algorithms
+ // case MD2:
+ // generator = new PKCS5S2ParametersGenerator(new MD2Digest());
+ // break;
+ case MD5:
+ // Android-changed: Use Android digests
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createMD5());
+ generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getMD5());
+ break;
+ case SHA1:
+ // Android-changed: Use Android digests
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA1());
+ generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA1());
+ break;
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ case RIPEMD160:
+ generator = new PKCS5S2ParametersGenerator(new RIPEMD160Digest());
+ break;
+ case TIGER:
+ generator = new PKCS5S2ParametersGenerator(new TigerDigest());
+ break;
+ */
+ // END Android-removed: Unsupported algorithms
+ case SHA256:
+ // Android-changed: Use Android digests
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA256());
+ generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA256());
+ break;
+ // Android-removed: Unsupported algorithms
+ // case GOST3411:
+ // generator = new PKCS5S2ParametersGenerator(new GOST3411Digest());
+ // break;
+ case SHA224:
+ // Android-changed: Use Android digests
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA224());
+ generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA224());
+ break;
+ case SHA384:
+ // Android-changed: Use Android digests
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA384());
+ generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA384());
+ break;
+ case SHA512:
+ // Android-changed: Use Android digests
+ // generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA512());
+ generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA512());
+ break;
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ case SHA3_224:
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_224());
+ break;
+ case SHA3_256:
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_256());
+ break;
+ case SHA3_384:
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_384());
+ break;
+ case SHA3_512:
+ generator = new PKCS5S2ParametersGenerator(DigestFactory.createSHA3_512());
+ break;
+ case SM3:
+ generator = new PKCS5S2ParametersGenerator(new SM3Digest());
+ break;
+ */
+ // END Android-removed: Unsupported algorithms
+ default:
+ throw new IllegalStateException("unknown digest scheme for PBE PKCS5S2 encryption.");
+ }
+ }
+ else if (type == PKCS12)
+ {
+ switch (hash)
+ {
+ // Android-removed: Unsupported algorithms
+ // case MD2:
+ // generator = new PKCS12ParametersGenerator(new MD2Digest());
+ // break;
+ case MD5:
+ // Android-changed: Use Android digests
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createMD5());
+ generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getMD5());
+ break;
+ case SHA1:
+ // Android-changed: Use Android digests
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA1());
+ generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA1());
+ break;
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ case RIPEMD160:
+ generator = new PKCS12ParametersGenerator(new RIPEMD160Digest());
+ break;
+ case TIGER:
+ generator = new PKCS12ParametersGenerator(new TigerDigest());
+ break;
+ */
+ // END Android-removed: Unsupported algorithms
+ case SHA256:
+ // Android-changed: Use Android digests
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA256());
+ generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA256());
+ break;
+ // Android-removed: Unsupported algorithms
+ // case GOST3411:
+ // generator = new PKCS12ParametersGenerator(new GOST3411Digest());
+ // break;
+ case SHA224:
+ // Android-changed: Use Android digests
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA224());
+ generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA224());
+ break;
+ case SHA384:
+ // Android-changed: Use Android digests
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA384());
+ generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA384());
+ break;
+ case SHA512:
+ // Android-changed: Use Android digests
+ // generator = new PKCS12ParametersGenerator(DigestFactory.createSHA512());
+ generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA512());
+ break;
+ default:
+ throw new IllegalStateException("unknown digest scheme for PBE encryption.");
+ }
+ }
+ else
+ {
+ generator = new OpenSSLPBEParametersGenerator();
+ }
+
+ return generator;
+ }
+
+ /**
+ * construct a key and iv (if necessary) suitable for use with a
+ * Cipher.
+ */
+ public static CipherParameters makePBEParameters(
+ byte[] pbeKey,
+ int scheme,
+ int digest,
+ int keySize,
+ int ivSize,
+ AlgorithmParameterSpec spec,
+ String targetAlgorithm)
+ throws InvalidAlgorithmParameterException
+ {
+ if ((spec == null) || !(spec instanceof PBEParameterSpec))
+ {
+ throw new InvalidAlgorithmParameterException("Need a PBEParameter spec with a PBE key.");
+ }
+
+ PBEParameterSpec pbeParam = (PBEParameterSpec)spec;
+ PBEParametersGenerator generator = makePBEGenerator(scheme, digest);
+ byte[] key = pbeKey;
+ CipherParameters param;
+
+// if (pbeKey.shouldTryWrongPKCS12())
+// {
+// key = new byte[2];
+// }
+
+ generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount());
+
+ if (ivSize != 0)
+ {
+ param = generator.generateDerivedParameters(keySize, ivSize);
+ // BEGIN Android-added: Allow IVs specified in parameters.
+ // PKCS5S2 doesn't specify that the IV must be generated from the password. If the
+ // IV is passed as a parameter, use it.
+ AlgorithmParameterSpec parameterSpecFromPBEParameterSpec =
+ getParameterSpecFromPBEParameterSpec(pbeParam);
+ if ((scheme == PKCS5S2 || scheme == PKCS5S2_UTF8)
+ && parameterSpecFromPBEParameterSpec instanceof IvParameterSpec) {
+ ParametersWithIV parametersWithIV = (ParametersWithIV) param;
+ IvParameterSpec ivParameterSpec =
+ (IvParameterSpec) parameterSpecFromPBEParameterSpec;
+ param = new ParametersWithIV(
+ (KeyParameter) parametersWithIV.getParameters(),
+ ivParameterSpec.getIV());
+ }
+ // END Android-added: Allow IVs specified in parameters.
+ }
+ else
+ {
+ param = generator.generateDerivedParameters(keySize);
+ }
+
+ if (targetAlgorithm.startsWith("DES"))
+ {
+ if (param instanceof ParametersWithIV)
+ {
+ KeyParameter kParam = (KeyParameter)((ParametersWithIV)param).getParameters();
+
+ DESParameters.setOddParity(kParam.getKey());
+ }
+ else
+ {
+ KeyParameter kParam = (KeyParameter)param;
+
+ DESParameters.setOddParity(kParam.getKey());
+ }
+ }
+
+ return param;
+ }
+
+ /**
+ * construct a key and iv (if necessary) suitable for use with a
+ * Cipher.
+ */
+ public static CipherParameters makePBEParameters(
+ BCPBEKey pbeKey,
+ AlgorithmParameterSpec spec,
+ String targetAlgorithm)
+ {
+ if ((spec == null) || !(spec instanceof PBEParameterSpec))
+ {
+ throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key.");
+ }
+
+ PBEParameterSpec pbeParam = (PBEParameterSpec)spec;
+ PBEParametersGenerator generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest());
+ byte[] key = pbeKey.getEncoded();
+ CipherParameters param;
+
+ if (pbeKey.shouldTryWrongPKCS12())
+ {
+ key = new byte[2];
+ }
+
+ generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount());
+
+ if (pbeKey.getIvSize() != 0)
+ {
+ param = generator.generateDerivedParameters(pbeKey.getKeySize(), pbeKey.getIvSize());
+ // BEGIN Android-added: Allow IVs specified in parameters.
+ // PKCS5S2 doesn't specify that the IV must be generated from the password. If the
+ // IV is passed as a parameter, use it.
+ AlgorithmParameterSpec parameterSpecFromPBEParameterSpec =
+ getParameterSpecFromPBEParameterSpec(pbeParam);
+ if ((pbeKey.getType() == PKCS5S2 || pbeKey.getType() == PKCS5S2_UTF8)
+ && parameterSpecFromPBEParameterSpec instanceof IvParameterSpec) {
+ ParametersWithIV parametersWithIV = (ParametersWithIV) param;
+ IvParameterSpec ivParameterSpec =
+ (IvParameterSpec) parameterSpecFromPBEParameterSpec;
+ param = new ParametersWithIV(
+ (KeyParameter) parametersWithIV.getParameters(),
+ ivParameterSpec.getIV());
+ }
+ // END Android-added: Allow IVs specified in parameters.
+ }
+ else
+ {
+ param = generator.generateDerivedParameters(pbeKey.getKeySize());
+ }
+
+ if (targetAlgorithm.startsWith("DES"))
+ {
+ if (param instanceof ParametersWithIV)
+ {
+ KeyParameter kParam = (KeyParameter)((ParametersWithIV)param).getParameters();
+
+ DESParameters.setOddParity(kParam.getKey());
+ }
+ else
+ {
+ KeyParameter kParam = (KeyParameter)param;
+
+ DESParameters.setOddParity(kParam.getKey());
+ }
+ }
+
+ return param;
+ }
+
+ /**
+ * generate a PBE based key suitable for a MAC algorithm, the
+ * key size is chosen according the MAC size, or the hashing algorithm,
+ * whichever is greater.
+ */
+ public static CipherParameters makePBEMacParameters(
+ BCPBEKey pbeKey,
+ AlgorithmParameterSpec spec)
+ {
+ if ((spec == null) || !(spec instanceof PBEParameterSpec))
+ {
+ throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key.");
+ }
+
+ PBEParameterSpec pbeParam = (PBEParameterSpec)spec;
+ PBEParametersGenerator generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest());
+ byte[] key = pbeKey.getEncoded();
+ CipherParameters param;
+
+ generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount());
+
+ param = generator.generateDerivedMacParameters(pbeKey.getKeySize());
+
+ return param;
+ }
+
+ /**
+ * generate a PBE based key suitable for a MAC algorithm, the
+ * key size is chosen according the MAC size, or the hashing algorithm,
+ * whichever is greater.
+ */
+ public static CipherParameters makePBEMacParameters(
+ PBEKeySpec keySpec,
+ int type,
+ int hash,
+ int keySize)
+ {
+ PBEParametersGenerator generator = makePBEGenerator(type, hash);
+ byte[] key;
+ CipherParameters param;
+
+ key = convertPassword(type, keySpec);
+
+ generator.init(key, keySpec.getSalt(), keySpec.getIterationCount());
+
+ param = generator.generateDerivedMacParameters(keySize);
+
+ for (int i = 0; i != key.length; i++)
+ {
+ key[i] = 0;
+ }
+
+ return param;
+ }
+
+ /**
+ * construct a key and iv (if necessary) suitable for use with a
+ * Cipher.
+ */
+ public static CipherParameters makePBEParameters(
+ PBEKeySpec keySpec,
+ int type,
+ int hash,
+ int keySize,
+ int ivSize)
+ {
+ PBEParametersGenerator generator = makePBEGenerator(type, hash);
+ byte[] key;
+ CipherParameters param;
+
+ key = convertPassword(type, keySpec);
+
+ generator.init(key, keySpec.getSalt(), keySpec.getIterationCount());
+
+ if (ivSize != 0)
+ {
+ param = generator.generateDerivedParameters(keySize, ivSize);
+ }
+ else
+ {
+ param = generator.generateDerivedParameters(keySize);
+ }
+
+ for (int i = 0; i != key.length; i++)
+ {
+ key[i] = 0;
+ }
+
+ return param;
+ }
+
+ /**
+ * generate a PBE based key suitable for a MAC algorithm, the
+ * key size is chosen according the MAC size, or the hashing algorithm,
+ * whichever is greater.
+ */
+ public static CipherParameters makePBEMacParameters(
+ SecretKey key,
+ int type,
+ int hash,
+ int keySize,
+ PBEParameterSpec pbeSpec)
+ {
+ PBEParametersGenerator generator = makePBEGenerator(type, hash);
+ CipherParameters param;
+
+ byte[] keyBytes = key.getEncoded();
+
+ generator.init(key.getEncoded(), pbeSpec.getSalt(), pbeSpec.getIterationCount());
+
+ param = generator.generateDerivedMacParameters(keySize);
+
+ for (int i = 0; i != keyBytes.length; i++)
+ {
+ keyBytes[i] = 0;
+ }
+
+ return param;
+ }
+
+ // BEGIN Android-added: Add helper for 1.8 compatibility.
+ /**
+ * Invokes the method {@link PBEParameterSpec#getParameterSpec()} via reflection.
+ *
+ * Needed as the method was introduced in Java 1.8 and Bouncycastle level is 1.5.
+ *
+ * @return the parameter spec, or null if the method is not available.
+ */
+ public static AlgorithmParameterSpec getParameterSpecFromPBEParameterSpec(
+ PBEParameterSpec pbeParameterSpec) {
+ try {
+ Method getParameterSpecMethod = PBE.class.getClassLoader()
+ .loadClass("javax.crypto.spec.PBEParameterSpec")
+ .getMethod("getParameterSpec");
+ return (AlgorithmParameterSpec) getParameterSpecMethod.invoke(pbeParameterSpec);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ // END Android-added: Add helper for 1.8 compatibility.
+
+
+ private static byte[] convertPassword(int type, PBEKeySpec keySpec)
+ {
+ byte[] key;
+
+ if (type == PKCS12)
+ {
+ key = PBEParametersGenerator.PKCS12PasswordToBytes(keySpec.getPassword());
+ }
+ else if (type == PKCS5S2_UTF8 || type == PKCS5S1_UTF8)
+ {
+ key = PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(keySpec.getPassword());
+ }
+ else
+ {
+ key = PBEParametersGenerator.PKCS5PasswordToBytes(keySpec.getPassword());
+ }
+ return key;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBESecretKeyFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBESecretKeyFactory.java
new file mode 100644
index 00000000..3c6d5210
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBESecretKeyFactory.java
@@ -0,0 +1,72 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.PBEKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.crypto.CipherParameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PBESecretKeyFactory
+ extends BaseSecretKeyFactory
+ implements PBE
+{
+ private boolean forCipher;
+ private int scheme;
+ private int digest;
+ private int keySize;
+ private int ivSize;
+
+ public PBESecretKeyFactory(
+ String algorithm,
+ ASN1ObjectIdentifier oid,
+ boolean forCipher,
+ int scheme,
+ int digest,
+ int keySize,
+ int ivSize)
+ {
+ super(algorithm, oid);
+
+ this.forCipher = forCipher;
+ this.scheme = scheme;
+ this.digest = digest;
+ this.keySize = keySize;
+ this.ivSize = ivSize;
+ }
+
+ protected SecretKey engineGenerateSecret(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof PBEKeySpec)
+ {
+ PBEKeySpec pbeSpec = (PBEKeySpec)keySpec;
+ CipherParameters param;
+
+ if (pbeSpec.getSalt() == null)
+ {
+ return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, null);
+ }
+
+ if (forCipher)
+ {
+ param = PBE.Util.makePBEParameters(pbeSpec, scheme, digest, keySize, ivSize);
+ }
+ else
+ {
+ param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize);
+ }
+
+ return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param);
+ }
+
+ throw new InvalidKeySpecException("Invalid KeySpec");
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/SpecUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/SpecUtil.java
new file mode 100644
index 00000000..86a7781a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/SpecUtil.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util;
+
+import java.security.AlgorithmParameters;
+import java.security.spec.AlgorithmParameterSpec;
+
+class SpecUtil
+{
+ static AlgorithmParameterSpec extractSpec(AlgorithmParameters params, Class[] availableSpecs)
+ {
+ try
+ {
+ return params.getParameterSpec(AlgorithmParameterSpec.class);
+ }
+ catch (Exception e)
+ {
+ for (int i = 0; i != availableSpecs.length; i++)
+ {
+ if (availableSpecs[i] == null)
+ {
+ continue;
+ }
+
+ try
+ {
+ return params.getParameterSpec(availableSpecs[i]);
+ }
+ catch (Exception ex)
+ {
+ // try again if possible
+ }
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AlgorithmProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AlgorithmProvider.java
new file mode 100644
index 00000000..2d3f1525
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AlgorithmProvider.java
@@ -0,0 +1,12 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.util;
+
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class AlgorithmProvider
+{
+ public abstract void configure(ConfigurableProvider provider);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java
new file mode 100644
index 00000000..f602b3d7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java
@@ -0,0 +1,62 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.util;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class AsymmetricAlgorithmProvider
+ extends AlgorithmProvider
+{
+ protected void addSignatureAlgorithm(
+ ConfigurableProvider provider,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid)
+ {
+ provider.addAlgorithm("Signature." + algorithm, className);
+ provider.addAlgorithm("Alg.Alias.Signature." + oid, algorithm);
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, algorithm);
+ }
+
+ protected void addSignatureAlgorithm(
+ ConfigurableProvider provider,
+ String digest,
+ String algorithm,
+ String className,
+ ASN1ObjectIdentifier oid)
+ {
+ String mainName = digest + "WITH" + algorithm;
+ String jdk11Variation1 = digest + "with" + algorithm;
+ String jdk11Variation2 = digest + "With" + algorithm;
+ String alias = digest + "/" + algorithm;
+
+ provider.addAlgorithm("Signature." + mainName, className);
+ provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation1, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature." + jdk11Variation2, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature." + alias, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature." + oid, mainName);
+ provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
+ }
+
+ protected void registerOid(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name, AsymmetricKeyInfoConverter keyFactory)
+ {
+ provider.addAlgorithm("Alg.Alias.KeyFactory." + oid, name);
+ provider.addAlgorithm("Alg.Alias.KeyPairGenerator." + oid, name);
+
+ provider.addKeyInfoConverter(oid, keyFactory);
+ }
+
+ protected void registerOidAlgorithmParameters(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name)
+ {
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + oid, name);
+ }
+
+ protected void registerOidAlgorithmParameterGenerator(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name)
+ {
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + oid, name);
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + oid, name);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AsymmetricKeyInfoConverter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AsymmetricKeyInfoConverter.java
new file mode 100644
index 00000000..0d1a6dd9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/AsymmetricKeyInfoConverter.java
@@ -0,0 +1,21 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.util;
+
+import java.io.IOException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface AsymmetricKeyInfoConverter
+{
+ PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException;
+
+ PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/BadBlockException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/BadBlockException.java
new file mode 100644
index 00000000..f9c2bbfc
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/BadBlockException.java
@@ -0,0 +1,25 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.util;
+
+import javax.crypto.BadPaddingException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BadBlockException
+ extends BadPaddingException
+{
+ private final Throwable cause;
+
+ public BadBlockException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/DigestFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/DigestFactory.java
new file mode 100644
index 00000000..0a431a34
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/DigestFactory.java
@@ -0,0 +1,238 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.util;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+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.crypto.Digest;
+// BEGIN Android-added: Use Android digests
+import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+// END Android-added: Use Android digests
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DigestFactory
+{
+ private static Set md5 = new HashSet();
+ private static Set sha1 = new HashSet();
+ private static Set sha224 = new HashSet();
+ private static Set sha256 = new HashSet();
+ private static Set sha384 = new HashSet();
+ private static Set sha512 = new HashSet();
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ private static Set sha512_224 = new HashSet();
+ private static Set sha512_256 = new HashSet();
+ private static Set sha3_224 = new HashSet();
+ private static Set sha3_256 = new HashSet();
+ private static Set sha3_384 = new HashSet();
+ private static Set sha3_512 = new HashSet();
+ */
+ // END Android-removed: Unsupported algorithms
+
+ private static Map oids = new HashMap();
+
+ static
+ {
+ md5.add("MD5");
+ md5.add(PKCSObjectIdentifiers.md5.getId());
+
+ sha1.add("SHA1");
+ sha1.add("SHA-1");
+ sha1.add(OIWObjectIdentifiers.idSHA1.getId());
+
+ sha224.add("SHA224");
+ sha224.add("SHA-224");
+ sha224.add(NISTObjectIdentifiers.id_sha224.getId());
+
+ sha256.add("SHA256");
+ sha256.add("SHA-256");
+ sha256.add(NISTObjectIdentifiers.id_sha256.getId());
+
+ sha384.add("SHA384");
+ sha384.add("SHA-384");
+ sha384.add(NISTObjectIdentifiers.id_sha384.getId());
+
+ sha512.add("SHA512");
+ sha512.add("SHA-512");
+ sha512.add(NISTObjectIdentifiers.id_sha512.getId());
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ sha512_224.add("SHA512(224)");
+ sha512_224.add("SHA-512(224)");
+ sha512_224.add(NISTObjectIdentifiers.id_sha512_224.getId());
+
+ sha512_256.add("SHA512(256)");
+ sha512_256.add("SHA-512(256)");
+ sha512_256.add(NISTObjectIdentifiers.id_sha512_256.getId());
+
+ sha3_224.add("SHA3-224");
+ sha3_224.add(NISTObjectIdentifiers.id_sha3_224.getId());
+
+ sha3_256.add("SHA3-256");
+ sha3_256.add(NISTObjectIdentifiers.id_sha3_256.getId());
+
+ sha3_384.add("SHA3-384");
+ sha3_384.add(NISTObjectIdentifiers.id_sha3_384.getId());
+
+ sha3_512.add("SHA3-512");
+ sha3_512.add(NISTObjectIdentifiers.id_sha3_512.getId());
+ */
+ // END Android-removed: Unsupported algorithms
+
+
+ oids.put("MD5", PKCSObjectIdentifiers.md5);
+ oids.put(PKCSObjectIdentifiers.md5.getId(), PKCSObjectIdentifiers.md5);
+
+ oids.put("SHA1", OIWObjectIdentifiers.idSHA1);
+ oids.put("SHA-1", OIWObjectIdentifiers.idSHA1);
+ oids.put(OIWObjectIdentifiers.idSHA1.getId(), OIWObjectIdentifiers.idSHA1);
+
+ oids.put("SHA224", NISTObjectIdentifiers.id_sha224);
+ oids.put("SHA-224", NISTObjectIdentifiers.id_sha224);
+ oids.put(NISTObjectIdentifiers.id_sha224.getId(), NISTObjectIdentifiers.id_sha224);
+
+ oids.put("SHA256", NISTObjectIdentifiers.id_sha256);
+ oids.put("SHA-256", NISTObjectIdentifiers.id_sha256);
+ oids.put(NISTObjectIdentifiers.id_sha256.getId(), NISTObjectIdentifiers.id_sha256);
+
+ oids.put("SHA384", NISTObjectIdentifiers.id_sha384);
+ oids.put("SHA-384", NISTObjectIdentifiers.id_sha384);
+ oids.put(NISTObjectIdentifiers.id_sha384.getId(), NISTObjectIdentifiers.id_sha384);
+
+ oids.put("SHA512", NISTObjectIdentifiers.id_sha512);
+ oids.put("SHA-512", NISTObjectIdentifiers.id_sha512);
+ oids.put(NISTObjectIdentifiers.id_sha512.getId(), NISTObjectIdentifiers.id_sha512);
+
+ oids.put("SHA512(224)", NISTObjectIdentifiers.id_sha512_224);
+ oids.put("SHA-512(224)", NISTObjectIdentifiers.id_sha512_224);
+ oids.put(NISTObjectIdentifiers.id_sha512_224.getId(), NISTObjectIdentifiers.id_sha512_224);
+
+ oids.put("SHA512(256)", NISTObjectIdentifiers.id_sha512_256);
+ oids.put("SHA-512(256)", NISTObjectIdentifiers.id_sha512_256);
+ oids.put(NISTObjectIdentifiers.id_sha512_256.getId(), NISTObjectIdentifiers.id_sha512_256);
+
+ oids.put("SHA3-224", NISTObjectIdentifiers.id_sha3_224);
+ oids.put(NISTObjectIdentifiers.id_sha3_224.getId(), NISTObjectIdentifiers.id_sha3_224);
+
+ oids.put("SHA3-256", NISTObjectIdentifiers.id_sha3_256);
+ oids.put(NISTObjectIdentifiers.id_sha3_256.getId(), NISTObjectIdentifiers.id_sha3_256);
+
+ oids.put("SHA3-384", NISTObjectIdentifiers.id_sha3_384);
+ oids.put(NISTObjectIdentifiers.id_sha3_384.getId(), NISTObjectIdentifiers.id_sha3_384);
+
+ oids.put("SHA3-512", NISTObjectIdentifiers.id_sha3_512);
+ oids.put(NISTObjectIdentifiers.id_sha3_512.getId(), NISTObjectIdentifiers.id_sha3_512);
+ }
+
+ public static Digest getDigest(
+ String digestName)
+ {
+ digestName = Strings.toUpperCase(digestName);
+
+ if (sha1.contains(digestName))
+ {
+ // Android-changed: Use Android digests
+ // return org.bouncycastle.crypto.util.DigestFactory.createSHA1();
+ return AndroidDigestFactory.getSHA1();
+ }
+ if (md5.contains(digestName))
+ {
+ // Android-changed: Use Android digests
+ // return org.bouncycastle.crypto.util.DigestFactory.createMD5();
+ return AndroidDigestFactory.getMD5();
+ }
+ if (sha224.contains(digestName))
+ {
+ // Android-changed: Use Android digests
+ // return org.bouncycastle.crypto.util.DigestFactory.createSHA224();
+ return AndroidDigestFactory.getSHA224();
+ }
+ if (sha256.contains(digestName))
+ {
+ // Android-changed: Use Android digests
+ // return org.bouncycastle.crypto.util.DigestFactory.createSHA256();
+ return AndroidDigestFactory.getSHA256();
+ }
+ if (sha384.contains(digestName))
+ {
+ // Android-changed: Use Android digests
+ // return org.bouncycastle.crypto.util.DigestFactory.createSHA384();
+ return AndroidDigestFactory.getSHA384();
+ }
+ if (sha512.contains(digestName))
+ {
+ // Android-changed: Use Android digests
+ // return org.bouncycastle.crypto.util.DigestFactory.createSHA512();
+ return AndroidDigestFactory.getSHA512();
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ if (sha512_224.contains(digestName))
+ {
+ return org.bouncycastle.crypto.util.DigestFactory.createSHA512_224();
+ }
+ if (sha512_256.contains(digestName))
+ {
+ return org.bouncycastle.crypto.util.DigestFactory.createSHA512_256();
+ }
+
+ if (sha3_224.contains(digestName))
+ {
+ return org.bouncycastle.crypto.util.DigestFactory.createSHA3_224();
+ }
+ if (sha3_256.contains(digestName))
+ {
+ return org.bouncycastle.crypto.util.DigestFactory.createSHA3_256();
+ }
+ if (sha3_384.contains(digestName))
+ {
+ return org.bouncycastle.crypto.util.DigestFactory.createSHA3_384();
+ }
+ if (sha3_512.contains(digestName))
+ {
+ return org.bouncycastle.crypto.util.DigestFactory.createSHA3_512();
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ return null;
+ }
+
+ public static boolean isSameDigest(
+ String digest1,
+ String digest2)
+ {
+ return (sha1.contains(digest1) && sha1.contains(digest2))
+ || (sha224.contains(digest1) && sha224.contains(digest2))
+ || (sha256.contains(digest1) && sha256.contains(digest2))
+ || (sha384.contains(digest1) && sha384.contains(digest2))
+ || (sha512.contains(digest1) && sha512.contains(digest2))
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ || (sha512_224.contains(digest1) && sha512_224.contains(digest2))
+ || (sha512_256.contains(digest1) && sha512_256.contains(digest2))
+ || (sha3_224.contains(digest1) && sha3_224.contains(digest2))
+ || (sha3_256.contains(digest1) && sha3_256.contains(digest2))
+ || (sha3_384.contains(digest1) && sha3_384.contains(digest2))
+ || (sha3_512.contains(digest1) && sha3_512.contains(digest2))
+ */
+ // END Android-removed: Unsupported algorithms
+ || (md5.contains(digest1) && md5.contains(digest2));
+ }
+
+ public static ASN1ObjectIdentifier getOID(
+ String digestName)
+ {
+ return (ASN1ObjectIdentifier)oids.get(digestName);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/SecretKeyUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/SecretKeyUtil.java
new file mode 100644
index 00000000..de70c7c5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/util/SecretKeyUtil.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.provider.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+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.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.util.Integers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecretKeyUtil
+{
+ private static Map keySizes = new HashMap();
+
+ static
+ {
+ keySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), Integers.valueOf(192));
+
+ keySizes.put(NISTObjectIdentifiers.id_aes128_CBC, Integers.valueOf(128));
+ keySizes.put(NISTObjectIdentifiers.id_aes192_CBC, Integers.valueOf(192));
+ keySizes.put(NISTObjectIdentifiers.id_aes256_CBC, Integers.valueOf(256));
+
+ keySizes.put(NTTObjectIdentifiers.id_camellia128_cbc, Integers.valueOf(128));
+ keySizes.put(NTTObjectIdentifiers.id_camellia192_cbc, Integers.valueOf(192));
+ keySizes.put(NTTObjectIdentifiers.id_camellia256_cbc, Integers.valueOf(256));
+ }
+
+ public static int getKeySize(ASN1ObjectIdentifier oid)
+ {
+ Integer size = (Integer)keySizes.get(oid);
+
+ if (size != null)
+ {
+ return size.intValue();
+ }
+
+ return -1;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/AEADParameterSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/AEADParameterSpec.java
new file mode 100644
index 00000000..e641e6ba
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/AEADParameterSpec.java
@@ -0,0 +1,75 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import javax.crypto.spec.IvParameterSpec;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * ParameterSpec for AEAD modes which allows associated data to be added via an algorithm parameter spec.In normal
+ * circumstances you would only want to use this if you had to work with the pre-JDK1.7 Cipher class as associated
+ * data is ignored for the purposes of returning a Cipher's parameters.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AEADParameterSpec
+ extends IvParameterSpec
+{
+ private final byte[] associatedData;
+ private final int macSizeInBits;
+
+ /**
+ * Base constructor.
+ *
+ * @param nonce nonce/iv to be used
+ * @param macSizeInBits macSize in bits
+ */
+ public AEADParameterSpec(byte[] nonce, int macSizeInBits)
+ {
+ this(nonce, macSizeInBits, null);
+ }
+
+ /**
+ * Base constructor with prepended associated data.
+ *
+ * @param nonce nonce/iv to be used
+ * @param macSizeInBits macSize in bits
+ * @param associatedData associated data to be prepended to the cipher stream.
+ */
+ public AEADParameterSpec(byte[] nonce, int macSizeInBits, byte[] associatedData)
+ {
+ super(nonce);
+
+ this.macSizeInBits = macSizeInBits;
+ this.associatedData = Arrays.clone(associatedData);
+ }
+
+ /**
+ * Return the size of the MAC associated with this parameter spec.
+ *
+ * @return the MAC size in bits.
+ */
+ public int getMacSizeInBits()
+ {
+ return macSizeInBits;
+ }
+
+ /**
+ * Return the associated data associated with this parameter spec.
+ *
+ * @return the associated data, null if there isn't any.
+ */
+ public byte[] getAssociatedData()
+ {
+ return Arrays.clone(associatedData);
+ }
+
+ /**
+ * Return the nonce (same as IV) associated with this parameter spec.
+ *
+ * @return the nonce/IV.
+ */
+ public byte[] getNonce()
+ {
+ return getIV();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java
new file mode 100644
index 00000000..366fb103
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/CompositeAlgorithmSpec.java
@@ -0,0 +1,72 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CompositeAlgorithmSpec
+ implements AlgorithmParameterSpec
+{
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Builder
+ {
+ private List<String> algorithmNames = new ArrayList<String>();
+ private List<AlgorithmParameterSpec> parameterSpecs = new ArrayList<AlgorithmParameterSpec>();
+
+ public Builder()
+ {
+ }
+
+ public Builder add(String algorithmName)
+ {
+ algorithmNames.add(algorithmName);
+ parameterSpecs.add(null);
+
+ return this;
+ }
+
+ public Builder add(String algorithmName, AlgorithmParameterSpec parameterSpec)
+ {
+ algorithmNames.add(algorithmName);
+ parameterSpecs.add(parameterSpec);
+
+ return this;
+ }
+
+ public CompositeAlgorithmSpec build()
+ {
+ if (algorithmNames.isEmpty())
+ {
+ throw new IllegalStateException("cannot call build with no algorithm names added");
+ }
+
+ return new CompositeAlgorithmSpec(this);
+ }
+ }
+
+ private final List<String> algorithmNames;
+ private final List<AlgorithmParameterSpec> parameterSpecs;
+
+ public CompositeAlgorithmSpec(Builder builder)
+ {
+ this.algorithmNames = Collections.unmodifiableList(new ArrayList<String>(builder.algorithmNames));
+ this.parameterSpecs = Collections.unmodifiableList(new ArrayList<AlgorithmParameterSpec>(builder.parameterSpecs));
+ }
+
+ public List<String> getAlgorithmNames()
+ {
+ return algorithmNames;
+ }
+
+ public List<AlgorithmParameterSpec> getParameterSpecs()
+ {
+ return parameterSpecs;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/DHDomainParameterSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/DHDomainParameterSpec.java
new file mode 100644
index 00000000..e59e506c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/DHDomainParameterSpec.java
@@ -0,0 +1,131 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import java.math.BigInteger;
+
+import javax.crypto.spec.DHParameterSpec;
+
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHValidationParameters;
+
+/**
+ * Extension class for DHParameterSpec that wraps a DHDomainParameters object and provides the q domain parameter.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHDomainParameterSpec
+ extends DHParameterSpec
+{
+ private final BigInteger q;
+ private final BigInteger j;
+ private final int m;
+
+ private DHValidationParameters validationParameters;
+
+ /**
+ * Base constructor - use the values in an existing set of domain parameters.
+ *
+ * @param domainParameters the Diffie-Hellman domain parameters to wrap.
+ */
+ public DHDomainParameterSpec(DHParameters domainParameters)
+ {
+ this(domainParameters.getP(), domainParameters.getQ(), domainParameters.getG(), domainParameters.getJ(), domainParameters.getM(), domainParameters.getL());
+ this.validationParameters = domainParameters.getValidationParameters();
+ }
+
+ /**
+ * Minimal constructor for parameters able to be used to verify a public key, or use with MQV.
+ *
+ * @param p the prime p defining the Galois field.
+ * @param g the generator of the multiplicative subgroup of order g.
+ * @param q specifies the prime factor of p - 1
+ */
+ public DHDomainParameterSpec(BigInteger p, BigInteger q, BigInteger g)
+ {
+ this(p, q, g, null, 0);
+ }
+
+ /**
+ * Minimal constructor for parameters able to be used to verify a public key, or use with MQV, and a private value length.
+ *
+ * @param p the prime p defining the Galois field.
+ * @param g the generator of the multiplicative subgroup of order g.
+ * @param q specifies the prime factor of p - 1
+ * @param l the maximum bit length for the private value.
+ */
+ public DHDomainParameterSpec(BigInteger p, BigInteger q, BigInteger g, int l)
+ {
+ this(p, q, g, null, l);
+ }
+
+ /**
+ * X9.42 parameters with private value length.
+ *
+ * @param p the prime p defining the Galois field.
+ * @param g the generator of the multiplicative subgroup of order g.
+ * @param q specifies the prime factor of p - 1
+ * @param j optionally specifies the value that satisfies the equation p = jq+1
+ * @param l the maximum bit length for the private value.
+ */
+ public DHDomainParameterSpec(BigInteger p, BigInteger q, BigInteger g, BigInteger j, int l)
+ {
+ this(p, q, g, j, 0, l);
+ }
+
+ /**
+ * Base constructor - the full domain parameter set.
+ *
+ * @param p the prime p defining the Galois field.
+ * @param g the generator of the multiplicative subgroup of order g.
+ * @param q specifies the prime factor of p - 1
+ * @param j optionally specifies the value that satisfies the equation p = jq+1
+ * @param m the minimum bit length for the private value.
+ * @param l the maximum bit length for the private value.
+ */
+ public DHDomainParameterSpec(BigInteger p, BigInteger q, BigInteger g, BigInteger j, int m, int l)
+ {
+ super(p, g, l);
+ this.q = q;
+ this.j = j;
+ this.m = m;
+ }
+
+ /**
+ * Return the Q value for the domain parameter set.
+ *
+ * @return the value Q.
+ */
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ /**
+ * Return the J value for the domain parameter set if available.
+ *
+ * @return the value J, null otherwise.
+ */
+ public BigInteger getJ()
+ {
+ return j;
+ }
+
+ /**
+ * Return the minimum bitlength for a private value to be generated from these parameters, 0 if not set.
+ *
+ * @return minimum bitlength for private value.
+ */
+ public int getM()
+ {
+ return m;
+ }
+
+ /**
+ * Return the DHDomainParameters object we represent.
+ *
+ * @return the internal DHDomainParameters.
+ */
+ public DHParameters getDomainParameters()
+ {
+ return new DHParameters(getP(), getG(), q, m, getL(), j, validationParameters);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/DHExtendedPrivateKeySpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/DHExtendedPrivateKeySpec.java
new file mode 100644
index 00000000..fd8050cc
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/DHExtendedPrivateKeySpec.java
@@ -0,0 +1,39 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import java.math.BigInteger;
+
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPrivateKeySpec;
+
+/**
+ * A DHPrivateKeySpec that also carries a set of DH domain parameters.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHExtendedPrivateKeySpec
+ extends DHPrivateKeySpec
+{
+ private final DHParameterSpec params;
+
+ /**
+ * Base constructor.
+ *
+ * @param x the private value.
+ * @param params the domain parameter set.
+ */
+ public DHExtendedPrivateKeySpec(BigInteger x, DHParameterSpec params)
+ {
+ super(x, params.getP(), params.getG());
+ this.params = params;
+ }
+
+ /**
+ * Return the domain parameters associated with this key spec.
+ *
+ * @return the Diffie-Hellman domain parameters.
+ */
+ public DHParameterSpec getParams()
+ {
+ return params;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/DHExtendedPublicKeySpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/DHExtendedPublicKeySpec.java
new file mode 100644
index 00000000..5786e21a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/DHExtendedPublicKeySpec.java
@@ -0,0 +1,39 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import java.math.BigInteger;
+
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPublicKeySpec;
+
+/**
+ * A DHPublicKeySpec that also carries a set of DH domain parameters.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHExtendedPublicKeySpec
+ extends DHPublicKeySpec
+{
+ private final DHParameterSpec params;
+
+ /**
+ * Base constructor.
+ *
+ * @param y the public value.
+ * @param params the domain parameter set.
+ */
+ public DHExtendedPublicKeySpec(BigInteger y, DHParameterSpec params)
+ {
+ super(y, params.getP(), params.getG());
+ this.params = params;
+ }
+
+ /**
+ * Return the domain parameters associated with this key spec.
+ *
+ * @return the Diffie-Hellman domain parameters.
+ */
+ public DHParameterSpec getParams()
+ {
+ return params;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/OpenSSHPrivateKeySpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/OpenSSHPrivateKeySpec.java
new file mode 100644
index 00000000..5cac0c77
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/OpenSSHPrivateKeySpec.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.EncodedKeySpec;
+
+/**
+ * OpenSSHPrivateKeySpec holds and encoded OpenSSH private key.
+ * The format of the key can be either ASN.1 or OpenSSH.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OpenSSHPrivateKeySpec
+ extends EncodedKeySpec
+{
+ private final String format;
+
+ /**
+ * Accept an encoded key and determine the format.
+ * <p>
+ * The encoded key should be the Base64 decoded blob between the "---BEGIN and ---END" markers.
+ * This constructor will endeavour to find the OpenSSH format magic value. If it can not then it
+ * will default to ASN.1. It does not attempt to validate the ASN.1
+ * <p>
+ * Example:
+ * OpenSSHPrivateKeySpec privSpec = new OpenSSHPrivateKeySpec(rawPriv);
+ * <p>
+ * KeyFactory kpf = KeyFactory.getInstance("RSA", "BC");
+ * PrivateKey prk = kpf.generatePrivate(privSpec);
+ * <p>
+ * OpenSSHPrivateKeySpec rcPrivateSpec = kpf.getKeySpec(prk, OpenSSHPrivateKeySpec.class);
+ *
+ * @param encodedKey The encoded key.
+ */
+ public OpenSSHPrivateKeySpec(byte[] encodedKey)
+ {
+ super(encodedKey);
+
+ if (encodedKey[0] == 0x30) // DER SEQUENCE
+ {
+ format = "ASN.1";
+ }
+ else if (encodedKey[0] == 'o')
+ {
+ format = "OpenSSH";
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown byte encoding");
+ }
+ }
+
+ /**
+ * Return the format, either OpenSSH for the OpenSSH propriety format or ASN.1.
+ *
+ * @return the format OpenSSH or ASN.1
+ */
+ public String getFormat()
+ {
+ return format;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/OpenSSHPublicKeySpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/OpenSSHPublicKeySpec.java
new file mode 100644
index 00000000..93f553a8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/OpenSSHPublicKeySpec.java
@@ -0,0 +1,79 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.EncodedKeySpec;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * Holds an OpenSSH encoded public key.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OpenSSHPublicKeySpec
+ extends EncodedKeySpec
+{
+ private static final String[] allowedTypes = new String[]{"ssh-rsa", "ssh-ed25519", "ssh-dss"};
+ private final String type;
+
+
+ /**
+ * Construct and instance and determine the OpenSSH public key type.
+ * The current types are ssh-rsa, ssh-ed25519, ssh-dss and ecdsa-*
+ * <p>
+ * It does not validate the key beyond identifying the type.
+ *
+ * @param encodedKey
+ */
+ public OpenSSHPublicKeySpec(byte[] encodedKey)
+ {
+ super(encodedKey);
+
+ //
+ // The type is encoded at the start of the blob.
+ //
+ int pos = 0;
+ int i = (encodedKey[pos++] & 0xFF) << 24;
+ i |= (encodedKey[pos++] & 0xFF) << 16;
+ i |= (encodedKey[pos++] & 0xFF) << 8;
+ i |= (encodedKey[pos++] & 0xFF);
+
+ if ((pos + i) >= encodedKey.length)
+ {
+ throw new IllegalArgumentException("invalid public key blob: type field longer than blob");
+ }
+
+ this.type = Strings.fromByteArray(Arrays.copyOfRange(encodedKey, pos, pos + i));
+
+ if (type.startsWith("ecdsa"))
+ {
+ return; // These have a curve name and digest in them and can't be compared exactly.
+ }
+
+ for (int t = 0; t < allowedTypes.length; t++)
+ {
+ if (allowedTypes[t].equals(this.type))
+ {
+ return;
+ }
+ }
+
+ throw new IllegalArgumentException("unrecognised public key type " + type);
+
+ }
+
+ public String getFormat()
+ {
+ return "OpenSSH";
+ }
+
+ /**
+ * The type of OpenSSH public key.
+ *
+ * @return the type.
+ */
+ public String getType()
+ {
+ return type;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/PBKDF2KeySpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/PBKDF2KeySpec.java
new file mode 100644
index 00000000..f6128f3c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/PBKDF2KeySpec.java
@@ -0,0 +1,56 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import javax.crypto.spec.PBEKeySpec;
+
+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;
+
+/**
+ * Extension of PBEKeySpec which takes into account the PRF algorithm setting available in PKCS#5 PBKDF2.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PBKDF2KeySpec
+ extends PBEKeySpec
+{
+ private static final AlgorithmIdentifier defaultPRF = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA1, DERNull.INSTANCE);
+
+ private AlgorithmIdentifier prf;
+
+ /**
+ * Base constructor.
+ *
+ * @param password password to use as the seed of the PBE key generator.
+ * @param salt salt to use in the generator,
+ * @param iterationCount iteration count to use in the generator.
+ * @param keySize size of the key to be generated (in bits).
+ * @param prf identifier and parameters for the PRF algorithm to use.
+ */
+ public PBKDF2KeySpec(char[] password, byte[] salt, int iterationCount, int keySize, AlgorithmIdentifier prf)
+ {
+ super(password, salt, iterationCount, keySize);
+
+ this.prf = prf;
+ }
+
+ /**
+ * Return true if this spec is for the default PRF (HmacSHA1), false otherwise.
+ *
+ * @return true if this spec uses the default PRF, false otherwise.
+ */
+ public boolean isDefaultPrf()
+ {
+ return defaultPRF.equals(prf);
+ }
+
+ /**
+ * Return an AlgorithmIdentifier representing the PRF.
+ *
+ * @return the PRF's AlgorithmIdentifier.
+ */
+ public AlgorithmIdentifier getPrf()
+ {
+ return prf;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java
new file mode 100644
index 00000000..1e37d43f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java
@@ -0,0 +1,25 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class UserKeyingMaterialSpec
+ implements AlgorithmParameterSpec
+{
+ private final byte[] userKeyingMaterial;
+
+ public UserKeyingMaterialSpec(byte[] userKeyingMaterial)
+ {
+ this.userKeyingMaterial = Arrays.clone(userKeyingMaterial);
+ }
+
+ public byte[] getUserKeyingMaterial()
+ {
+ return Arrays.clone(userKeyingMaterial);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/AlgorithmParametersUtils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/AlgorithmParametersUtils.java
new file mode 100644
index 00000000..343e51b8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/AlgorithmParametersUtils.java
@@ -0,0 +1,67 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.util;
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * General JCA/JCE utility methods.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AlgorithmParametersUtils
+{
+
+
+ private AlgorithmParametersUtils()
+ {
+
+ }
+
+ /**
+ * Extract an ASN.1 encodable from an AlgorithmParameters object.
+ *
+ * @param params the object to get the encoding used to create the return value.
+ * @return an ASN.1 object representing the primitives making up the params parameter.
+ * @throws IOException if an encoding cannot be extracted.
+ */
+ public static ASN1Encodable extractParameters(AlgorithmParameters params)
+ throws IOException
+ {
+ // we try ASN.1 explicitly first just in case and then role back to the default.
+ ASN1Encodable asn1Params;
+ try
+ {
+ asn1Params = ASN1Primitive.fromByteArray(params.getEncoded("ASN.1"));
+ }
+ catch (Exception ex)
+ {
+ asn1Params = ASN1Primitive.fromByteArray(params.getEncoded());
+ }
+
+ return asn1Params;
+ }
+
+ /**
+ * Load an AlgorithmParameters object with the passed in ASN.1 encodable - if possible.
+ *
+ * @param params the AlgorithmParameters object to be initialised.
+ * @param sParams the ASN.1 encodable to initialise params with.
+ * @throws IOException if the parameters cannot be initialised.
+ */
+ public static void loadParameters(AlgorithmParameters params, ASN1Encodable sParams)
+ throws IOException
+ {
+ // we try ASN.1 explicitly first just in case and then role back to the default.
+ try
+ {
+ params.init(sParams.toASN1Primitive().getEncoded(), "ASN.1");
+ }
+ catch (Exception ex)
+ {
+ params.init(sParams.toASN1Primitive().getEncoded());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/AnnotatedPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/AnnotatedPrivateKey.java
new file mode 100644
index 00000000..a2ca6af5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/AnnotatedPrivateKey.java
@@ -0,0 +1,118 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.util;
+
+import java.security.PrivateKey;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Wrapper for a private key that carries annotations that can be used
+ * for tracking or debugging.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AnnotatedPrivateKey
+ implements PrivateKey
+{
+ public static final String LABEL = "label";
+
+ private final PrivateKey key;
+ private final Map<String, Object> annotations;
+
+ AnnotatedPrivateKey(PrivateKey key, String label)
+ {
+ this.key = key;
+ this.annotations = Collections.singletonMap(LABEL, (Object)label);
+ }
+
+ AnnotatedPrivateKey(PrivateKey key, Map<String, Object> annotations)
+ {
+ this.key = key;
+ this.annotations = annotations;
+ }
+
+ public PrivateKey getKey()
+ {
+ return key;
+ }
+
+ public Map<String, Object> getAnnotations()
+ {
+ return annotations;
+ }
+
+ public String getAlgorithm()
+ {
+ return key.getAlgorithm();
+ }
+
+ public Object getAnnotation(String key)
+ {
+ return annotations.get(key);
+ }
+
+ /**
+ * Return a new annotated key with an additional annotation added to it.
+ *
+ * @param name the name of the annotation to add.
+ * @param annotation the object providing the annotation details.
+ * @return a new annotated key with the extra annotation.
+ */
+ public AnnotatedPrivateKey addAnnotation(String name, Object annotation)
+ {
+ Map<String, Object> newAnnotations = new HashMap<String, Object>(annotations);
+
+ newAnnotations.put(name, annotation);
+
+ return new AnnotatedPrivateKey(this.key, Collections.unmodifiableMap(newAnnotations));
+ }
+
+ /**
+ * Return a new annotated key with the named annotation removed.
+ *
+ * @param name the name of the annotation to remove.
+ * @return a new annotated key with the named annotation removed.
+ */
+ public AnnotatedPrivateKey removeAnnotation(String name)
+ {
+ Map<String, Object> newAnnotations = new HashMap<String, Object>(annotations);
+
+ newAnnotations.remove(name);
+
+ return new AnnotatedPrivateKey(this.key, Collections.unmodifiableMap(newAnnotations));
+ }
+
+ public String getFormat()
+ {
+ return key.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ return key.getEncoded();
+ }
+
+ public int hashCode()
+ {
+ return this.key.hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o instanceof AnnotatedPrivateKey)
+ {
+ return this.key.equals(((AnnotatedPrivateKey)o).key);
+ }
+ return this.key.equals(o);
+ }
+
+ public String toString()
+ {
+ if (annotations.containsKey(LABEL))
+ {
+ return annotations.get(LABEL).toString();
+ }
+
+ return key.toString();
+ }
+}
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
new file mode 100644
index 00000000..15130f26
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/BCJcaJceHelper.java
@@ -0,0 +1,43 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.util;
+
+import java.security.Provider;
+import java.security.Security;
+
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+/**
+ * A JCA/JCE helper that refers to the BC provider for all it's needs.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BCJcaJceHelper
+ extends ProviderJcaJceHelper
+{
+ private static volatile Provider bcProvider;
+
+ private static synchronized Provider getBouncyCastleProvider()
+ {
+ final Provider system = Security.getProvider("BC");
+ // Avoid using the old, deprecated system BC provider on Android.
+ // See: https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html
+ if (system instanceof BouncyCastleProvider)
+ {
+ return system;
+ }
+ else if (bcProvider != null)
+ {
+ return bcProvider;
+ }
+ else
+ {
+ bcProvider = new BouncyCastleProvider();
+
+ return bcProvider;
+ }
+ }
+
+ public BCJcaJceHelper()
+ {
+ super(getBouncyCastleProvider());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java
new file mode 100644
index 00000000..9a5edec8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java
@@ -0,0 +1,153 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.util;
+
+import java.security.AlgorithmParameterGenerator;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyFactory;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.cert.CertPathBuilder;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreParameters;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+
+import javax.crypto.Cipher;
+import javax.crypto.ExemptionMechanism;
+import javax.crypto.KeyAgreement;
+import javax.crypto.KeyGenerator;
+import javax.crypto.Mac;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKeyFactory;
+
+/**
+ * {@link JcaJceHelper} that obtains all algorithms using the default JCA/JCE mechanism (i.e.
+ * without specifying a provider).
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DefaultJcaJceHelper
+ implements JcaJceHelper
+{
+ public Cipher createCipher(
+ String algorithm)
+ throws NoSuchAlgorithmException, NoSuchPaddingException
+ {
+ return Cipher.getInstance(algorithm);
+ }
+
+ public Mac createMac(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return Mac.getInstance(algorithm);
+ }
+
+ public KeyAgreement createKeyAgreement(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return KeyAgreement.getInstance(algorithm);
+ }
+
+ public AlgorithmParameterGenerator createAlgorithmParameterGenerator(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return AlgorithmParameterGenerator.getInstance(algorithm);
+ }
+
+ public AlgorithmParameters createAlgorithmParameters(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return AlgorithmParameters.getInstance(algorithm);
+ }
+
+ public KeyGenerator createKeyGenerator(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return KeyGenerator.getInstance(algorithm);
+ }
+
+ public KeyFactory createKeyFactory(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return KeyFactory.getInstance(algorithm);
+ }
+
+ public SecretKeyFactory createSecretKeyFactory(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return SecretKeyFactory.getInstance(algorithm);
+ }
+
+ public KeyPairGenerator createKeyPairGenerator(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return KeyPairGenerator.getInstance(algorithm);
+ }
+
+ /** @deprecated Use createMessageDigest instead */
+ public MessageDigest createDigest(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return MessageDigest.getInstance(algorithm);
+ }
+
+ public MessageDigest createMessageDigest(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return MessageDigest.getInstance(algorithm);
+ }
+
+ public Signature createSignature(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return Signature.getInstance(algorithm);
+ }
+
+ public CertificateFactory createCertificateFactory(String algorithm)
+ throws CertificateException
+ {
+ return CertificateFactory.getInstance(algorithm);
+ }
+
+ public SecureRandom createSecureRandom(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return SecureRandom.getInstance(algorithm);
+ }
+
+ public CertPathBuilder createCertPathBuilder(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return CertPathBuilder.getInstance(algorithm);
+ }
+
+ public CertPathValidator createCertPathValidator(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return CertPathValidator.getInstance(algorithm);
+ }
+
+ public CertStore createCertStore(String type, CertStoreParameters params)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException
+ {
+ return CertStore.getInstance(type, params);
+ }
+
+ public ExemptionMechanism createExemptionMechanism(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return ExemptionMechanism.getInstance(algorithm);
+ }
+
+ public KeyStore createKeyStore(String type)
+ throws KeyStoreException
+ {
+ return KeyStore.getInstance(type);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/ECKeyUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/ECKeyUtil.java
new file mode 100644
index 00000000..4fc2ca13
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/ECKeyUtil.java
@@ -0,0 +1,108 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.util;
+
+import java.io.IOException;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable;
+import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECPoint;
+import com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves;
+
+/**
+ * Utility class for EC Keys.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECKeyUtil
+{
+ /**
+ * Convert an ECPublicKey into an ECPublicKey which always encodes
+ * with point compression.
+ *
+ * @param ecPublicKey the originating public key.
+ * @return a wrapped version of ecPublicKey which uses point compression.
+ */
+ public static ECPublicKey createKeyWithCompression(ECPublicKey ecPublicKey)
+ {
+ return new ECPublicKeyWithCompression(ecPublicKey);
+ }
+
+ private static class ECPublicKeyWithCompression
+ implements ECPublicKey
+ {
+ private final ECPublicKey ecPublicKey;
+
+ public ECPublicKeyWithCompression(ECPublicKey ecPublicKey)
+ {
+ this.ecPublicKey = ecPublicKey;
+ }
+
+ public ECPoint getW()
+ {
+ return ecPublicKey.getW();
+ }
+
+ public String getAlgorithm()
+ {
+ return ecPublicKey.getAlgorithm();
+ }
+
+ public String getFormat()
+ {
+ return ecPublicKey.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(ecPublicKey.getEncoded());
+
+ X962Parameters params = X962Parameters.getInstance(publicKeyInfo.getAlgorithm().getParameters());
+
+ com.android.internal.org.bouncycastle.math.ec.ECCurve curve;
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
+
+ X9ECParameters x9 = CustomNamedCurves.getByOID(oid);
+ if (x9 == null)
+ {
+ x9 = ECNamedCurveTable.getByOID(oid);
+ }
+ curve = x9.getCurve();
+ }
+ else if (params.isImplicitlyCA())
+ {
+ throw new IllegalStateException("unable to identify implictlyCA");
+ }
+ else
+ {
+ X9ECParameters x9 = X9ECParameters.getInstance(params.getParameters());
+ curve = x9.getCurve();
+ }
+
+ com.android.internal.org.bouncycastle.math.ec.ECPoint p = curve.decodePoint(publicKeyInfo.getPublicKeyData().getOctets());
+ ASN1OctetString pEnc = ASN1OctetString.getInstance(new X9ECPoint(p,true).toASN1Primitive());
+
+ try
+ {
+ return new SubjectPublicKeyInfo(publicKeyInfo.getAlgorithm(), pEnc.getOctets()).getEncoded();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("unable to encode EC public key: " + e.getMessage());
+ }
+ }
+
+ public ECParameterSpec getParams()
+ {
+ return ecPublicKey.getParams();
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/JcaJceHelper.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/JcaJceHelper.java
new file mode 100644
index 00000000..8e459bc1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/JcaJceHelper.java
@@ -0,0 +1,95 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.util;
+
+import java.security.AlgorithmParameterGenerator;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyFactory;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.cert.CertPathBuilder;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreParameters;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+
+import javax.crypto.Cipher;
+import javax.crypto.ExemptionMechanism;
+import javax.crypto.KeyAgreement;
+import javax.crypto.KeyGenerator;
+import javax.crypto.Mac;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKeyFactory;
+
+/**
+ * Factory interface for instantiating JCA/JCE primitives.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface JcaJceHelper
+{
+ Cipher createCipher(
+ String algorithm)
+ throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException;
+
+ Mac createMac(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ KeyAgreement createKeyAgreement(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ AlgorithmParameterGenerator createAlgorithmParameterGenerator(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ AlgorithmParameters createAlgorithmParameters(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ KeyGenerator createKeyGenerator(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ KeyFactory createKeyFactory(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ SecretKeyFactory createSecretKeyFactory(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ KeyPairGenerator createKeyPairGenerator(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ /** @deprecated Use createMessageDigest instead */
+ MessageDigest createDigest(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ MessageDigest createMessageDigest(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ Signature createSignature(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ CertificateFactory createCertificateFactory(String algorithm)
+ throws NoSuchProviderException, CertificateException;
+
+ SecureRandom createSecureRandom(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ CertPathBuilder createCertPathBuilder(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ CertPathValidator createCertPathValidator(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ CertStore createCertStore(String type, CertStoreParameters params)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchProviderException;
+
+ ExemptionMechanism createExemptionMechanism(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
+
+ KeyStore createKeyStore(String type)
+ throws KeyStoreException, NoSuchProviderException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/JcaJceUtils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/JcaJceUtils.java
new file mode 100644
index 00000000..8a60ca9d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/JcaJceUtils.java
@@ -0,0 +1,135 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.util;
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+// 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 com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+
+/**
+ * General JCA/JCE utility methods.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JcaJceUtils
+{
+ private JcaJceUtils()
+ {
+
+ }
+
+ /**
+ * Extract an ASN.1 encodable from an AlgorithmParameters object.
+ *
+ * @param params the object to get the encoding used to create the return value.
+ * @return an ASN.1 object representing the primitives making up the params parameter.
+ * @throws IOException if an encoding cannot be extracted.
+ * @deprecated use AlgorithmParametersUtils.extractParameters(AlgorithmParameters params)
+ */
+ public static ASN1Encodable extractParameters(AlgorithmParameters params)
+ throws IOException
+ {
+ // we try ASN.1 explicitly first just in case and then role back to the default.
+ ASN1Encodable asn1Params;
+ try
+ {
+ asn1Params = ASN1Primitive.fromByteArray(params.getEncoded("ASN.1"));
+ }
+ catch (Exception ex)
+ {
+ asn1Params = ASN1Primitive.fromByteArray(params.getEncoded());
+ }
+
+ return asn1Params;
+ }
+
+ /**
+ * Load an AlgorithmParameters object with the passed in ASN.1 encodable - if possible.
+ *
+ * @param params the AlgorithmParameters object to be initialised.
+ * @param sParams the ASN.1 encodable to initialise params with.
+ * @throws IOException if the parameters cannot be initialised.
+ * @deprecated use AlgorithmParametersUtils.loadParameters(AlgorithmParameters params, ASN1Encodable sParams)
+ */
+ public static void loadParameters(AlgorithmParameters params, ASN1Encodable sParams)
+ throws IOException
+ {
+ // we try ASN.1 explicitly first just in case and then role back to the default.
+ try
+ {
+ params.init(sParams.toASN1Primitive().getEncoded(), "ASN.1");
+ }
+ catch (Exception ex)
+ {
+ params.init(sParams.toASN1Primitive().getEncoded());
+ }
+ }
+
+ /**
+ * Attempt to find a standard JCA name for the digest represented by the past in OID.
+ *
+ * @param digestAlgOID the OID of the digest algorithm of interest.
+ * @return a string representing the standard name - the OID as a string if none available.
+ * @deprecated use MessageDigestUtils,getDigestName()
+ */
+ public static String getDigestAlgName(
+ ASN1ObjectIdentifier digestAlgOID)
+ {
+ if (PKCSObjectIdentifiers.md5.equals(digestAlgOID))
+ {
+ return "MD5";
+ }
+ else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID))
+ {
+ return "SHA1";
+ }
+ else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID))
+ {
+ return "SHA224";
+ }
+ else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID))
+ {
+ return "SHA256";
+ }
+ else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID))
+ {
+ return "SHA384";
+ }
+ else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID))
+ {
+ return "SHA512";
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID))
+ {
+ return "RIPEMD128";
+ }
+ else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID))
+ {
+ return "RIPEMD160";
+ }
+ else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID))
+ {
+ return "RIPEMD256";
+ }
+ else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID))
+ {
+ return "GOST3411";
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ else
+ {
+ return digestAlgOID.getId();
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/MessageDigestUtils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/MessageDigestUtils.java
new file mode 100644
index 00000000..a8fe3e70
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/MessageDigestUtils.java
@@ -0,0 +1,73 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
+// import org.bouncycastle.asn1.gnu.GNUObjectIdentifiers;
+// import org.bouncycastle.asn1.iso.ISOIECObjectIdentifiers;
+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.teletrust.TeleTrusTObjectIdentifiers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class MessageDigestUtils
+{
+ private static Map<ASN1ObjectIdentifier, String> digestOidMap = new HashMap<ASN1ObjectIdentifier, String>();
+
+ static
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ // digestOidMap.put(PKCSObjectIdentifiers.md2, "MD2");
+ // digestOidMap.put(PKCSObjectIdentifiers.md4, "MD4");
+ // END Android-removed: Unsupported algorithms
+ digestOidMap.put(PKCSObjectIdentifiers.md5, "MD5");
+ digestOidMap.put(OIWObjectIdentifiers.idSHA1, "SHA-1");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha224, "SHA-224");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha256, "SHA-256");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha384, "SHA-384");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha512, "SHA-512");
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD-128");
+ digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD-160");
+ digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD-128");
+ digestOidMap.put(ISOIECObjectIdentifiers.ripemd128, "RIPEMD-128");
+ digestOidMap.put(ISOIECObjectIdentifiers.ripemd160, "RIPEMD-160");
+ digestOidMap.put(CryptoProObjectIdentifiers.gostR3411, "GOST3411");
+ digestOidMap.put(GNUObjectIdentifiers.Tiger_192, "Tiger");
+ digestOidMap.put(ISOIECObjectIdentifiers.whirlpool, "Whirlpool");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha3_224, "SHA3-224");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha3_256, "SHA3-256");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha3_384, "SHA3-384");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha3_512, "SHA3-512");
+ digestOidMap.put(GMObjectIdentifiers.sm3, "SM3");
+ */
+ // END Android-removed: Unsupported algorithms
+ }
+
+ /**
+ * Attempt to find a standard JCA name for the digest represented by the passed in OID.
+ *
+ * @param digestAlgOID the OID of the digest algorithm of interest.
+ * @return a string representing the standard name - the OID as a string if none available.
+ */
+ public static String getDigestName(ASN1ObjectIdentifier digestAlgOID)
+ {
+ String name = (String)digestOidMap.get(digestAlgOID); // for pre 1.5 JDK
+ if (name != null)
+ {
+ return name;
+ }
+
+ return digestAlgOID.getId();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java
new file mode 100644
index 00000000..090f009a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java
@@ -0,0 +1,160 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.util;
+
+import java.security.AlgorithmParameterGenerator;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyFactory;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.cert.CertPathBuilder;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreParameters;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+
+import javax.crypto.Cipher;
+import javax.crypto.ExemptionMechanism;
+import javax.crypto.KeyAgreement;
+import javax.crypto.KeyGenerator;
+import javax.crypto.Mac;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKeyFactory;
+
+/**
+ * {@link JcaJceHelper} that obtains all algorithms using a specific named provider.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class NamedJcaJceHelper
+ implements JcaJceHelper
+{
+ protected final String providerName;
+
+ public NamedJcaJceHelper(String providerName)
+ {
+ this.providerName = providerName;
+ }
+
+ public Cipher createCipher(
+ String algorithm)
+ throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException
+ {
+ return Cipher.getInstance(algorithm, providerName);
+ }
+
+ public Mac createMac(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return Mac.getInstance(algorithm, providerName);
+ }
+
+ public KeyAgreement createKeyAgreement(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return KeyAgreement.getInstance(algorithm, providerName);
+ }
+
+ public AlgorithmParameterGenerator createAlgorithmParameterGenerator(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return AlgorithmParameterGenerator.getInstance(algorithm, providerName);
+ }
+
+ public AlgorithmParameters createAlgorithmParameters(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return AlgorithmParameters.getInstance(algorithm, providerName);
+ }
+
+ public KeyGenerator createKeyGenerator(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return KeyGenerator.getInstance(algorithm, providerName);
+ }
+
+ public KeyFactory createKeyFactory(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return KeyFactory.getInstance(algorithm, providerName);
+ }
+
+ public SecretKeyFactory createSecretKeyFactory(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return SecretKeyFactory.getInstance(algorithm, providerName);
+ }
+
+ public KeyPairGenerator createKeyPairGenerator(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return KeyPairGenerator.getInstance(algorithm, providerName);
+ }
+
+ /** @deprecated Use createMessageDigest instead */
+ public MessageDigest createDigest(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return MessageDigest.getInstance(algorithm, providerName);
+ }
+
+ public MessageDigest createMessageDigest(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return MessageDigest.getInstance(algorithm, providerName);
+ }
+
+ public Signature createSignature(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return Signature.getInstance(algorithm, providerName);
+ }
+
+ public CertificateFactory createCertificateFactory(String algorithm)
+ throws CertificateException, NoSuchProviderException
+ {
+ return CertificateFactory.getInstance(algorithm, providerName);
+ }
+
+ public SecureRandom createSecureRandom(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return SecureRandom.getInstance(algorithm, providerName);
+ }
+
+ public CertPathBuilder createCertPathBuilder(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return CertPathBuilder.getInstance(algorithm, providerName);
+ }
+
+ public CertPathValidator createCertPathValidator(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return CertPathValidator.getInstance(algorithm, providerName);
+ }
+
+ public CertStore createCertStore(String type, CertStoreParameters params)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchProviderException
+ {
+ return CertStore.getInstance(type, params, providerName);
+ }
+
+ public ExemptionMechanism createExemptionMechanism(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return ExemptionMechanism.getInstance(algorithm, providerName);
+ }
+
+ public KeyStore createKeyStore(String type)
+ throws KeyStoreException, NoSuchProviderException
+ {
+ return KeyStore.getInstance(type, providerName);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/PrivateKeyAnnotator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/PrivateKeyAnnotator.java
new file mode 100644
index 00000000..1496e7ef
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/PrivateKeyAnnotator.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.util;
+
+import java.security.PrivateKey;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Class for instancing AnnotatedPrivateKeys.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PrivateKeyAnnotator
+{
+ /**
+ * Create an AnnotatedPrivateKey with a single annotation using AnnotatedPrivateKey.LABEL as a key.
+ *
+ * @param privKey the private key to be annotated.
+ * @param label the label to be associated with the private key.
+ * @return the newly annotated private key.
+ */
+ public static AnnotatedPrivateKey annotate(PrivateKey privKey, String label)
+ {
+ return new AnnotatedPrivateKey(privKey, label);
+ }
+
+ public static AnnotatedPrivateKey annotate(PrivateKey privKey, Map<String, Object> annotations)
+ {
+ Map savedAnnotations = new HashMap(annotations);
+
+ return new AnnotatedPrivateKey(privKey, Collections.unmodifiableMap(savedAnnotations));
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java
new file mode 100644
index 00000000..c6a6e516
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java
@@ -0,0 +1,160 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jcajce.util;
+
+import java.security.AlgorithmParameterGenerator;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyFactory;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.cert.CertPathBuilder;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreParameters;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+
+import javax.crypto.Cipher;
+import javax.crypto.ExemptionMechanism;
+import javax.crypto.KeyAgreement;
+import javax.crypto.KeyGenerator;
+import javax.crypto.Mac;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKeyFactory;
+
+/**
+ * {@link JcaJceHelper} that obtains all algorithms from a specific {@link Provider} instance.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ProviderJcaJceHelper
+ implements JcaJceHelper
+{
+ protected final Provider provider;
+
+ public ProviderJcaJceHelper(Provider provider)
+ {
+ this.provider = provider;
+ }
+
+ public Cipher createCipher(
+ String algorithm)
+ throws NoSuchAlgorithmException, NoSuchPaddingException
+ {
+ return Cipher.getInstance(algorithm, provider);
+ }
+
+ public Mac createMac(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return Mac.getInstance(algorithm, provider);
+ }
+
+ public KeyAgreement createKeyAgreement(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return KeyAgreement.getInstance(algorithm, provider);
+ }
+
+ public AlgorithmParameterGenerator createAlgorithmParameterGenerator(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return AlgorithmParameterGenerator.getInstance(algorithm, provider);
+ }
+
+ public AlgorithmParameters createAlgorithmParameters(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return AlgorithmParameters.getInstance(algorithm, provider);
+ }
+
+ public KeyGenerator createKeyGenerator(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return KeyGenerator.getInstance(algorithm, provider);
+ }
+
+ public KeyFactory createKeyFactory(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return KeyFactory.getInstance(algorithm, provider);
+ }
+
+ public SecretKeyFactory createSecretKeyFactory(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return SecretKeyFactory.getInstance(algorithm, provider);
+ }
+
+ public KeyPairGenerator createKeyPairGenerator(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return KeyPairGenerator.getInstance(algorithm, provider);
+ }
+
+ /** @deprecated Use createMessageDigest instead */
+ public MessageDigest createDigest(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return MessageDigest.getInstance(algorithm, provider);
+ }
+
+ public MessageDigest createMessageDigest(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return MessageDigest.getInstance(algorithm, provider);
+ }
+
+ public Signature createSignature(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return Signature.getInstance(algorithm, provider);
+ }
+
+ public CertificateFactory createCertificateFactory(String algorithm)
+ throws CertificateException
+ {
+ return CertificateFactory.getInstance(algorithm, provider);
+ }
+
+ public SecureRandom createSecureRandom(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return SecureRandom.getInstance(algorithm, provider);
+ }
+
+ public CertPathBuilder createCertPathBuilder(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return CertPathBuilder.getInstance(algorithm, provider);
+ }
+
+ public CertPathValidator createCertPathValidator(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return CertPathValidator.getInstance(algorithm, provider);
+ }
+
+ public CertStore createCertStore(String type, CertStoreParameters params)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException
+ {
+ return CertStore.getInstance(type, params, provider);
+ }
+
+ public ExemptionMechanism createExemptionMechanism(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return ExemptionMechanism.getInstance(algorithm, provider);
+ }
+
+ public KeyStore createKeyStore(String type)
+ throws KeyStoreException
+ {
+ return KeyStore.getInstance(type, provider);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/ECNamedCurveTable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/ECNamedCurveTable.java
new file mode 100644
index 00000000..aabfac90
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/ECNamedCurveTable.java
@@ -0,0 +1,78 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
+
+/**
+ * a table of locally supported named curves.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECNamedCurveTable
+{
+ /**
+ * return a parameter spec representing the passed in named
+ * curve. The routine returns null if the curve is not present.
+ *
+ * @param name the name of the curve requested
+ * @return a parameter spec for the curve, null if it is not available.
+ */
+ public static ECNamedCurveParameterSpec getParameterSpec(
+ String name)
+ {
+ X9ECParameters ecP = com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves.getByName(name);
+ if (ecP == null)
+ {
+ try
+ {
+ ecP = com.android.internal.org.bouncycastle.crypto.ec.CustomNamedCurves.getByOID(new ASN1ObjectIdentifier(name));
+ }
+ catch (IllegalArgumentException e)
+ {
+ // ignore - not an oid
+ }
+
+ if (ecP == null)
+ {
+ ecP = com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable.getByName(name);
+ if (ecP == null)
+ {
+ try
+ {
+ ecP = com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable.getByOID(new ASN1ObjectIdentifier(name));
+ }
+ catch (IllegalArgumentException e)
+ {
+ // ignore - not an oid
+ }
+ }
+ }
+ }
+
+ if (ecP == null)
+ {
+ return null;
+ }
+
+ return new ECNamedCurveParameterSpec(
+ name,
+ ecP.getCurve(),
+ ecP.getG(),
+ ecP.getN(),
+ ecP.getH(),
+ ecP.getSeed());
+ }
+
+ /**
+ * return an enumeration of the names of the available curves.
+ *
+ * @return an enumeration of the names of the available curves.
+ */
+ public static Enumeration getNames()
+ {
+ return com.android.internal.org.bouncycastle.asn1.x9.ECNamedCurveTable.getNames();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/PKCS10CertificationRequest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/PKCS10CertificationRequest.java
new file mode 100644
index 00000000..b19d5069
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/PKCS10CertificationRequest.java
@@ -0,0 +1,661 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce;
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PSSParameterSpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import 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.CertificationRequest;
+import com.android.internal.org.bouncycastle.asn1.pkcs.CertificationRequestInfo;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
+// Android-removed: Unsupported algorithms
+// 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.x509.X509Name;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * A class for verifying and creating PKCS10 Certification requests.
+ * <pre>
+ * CertificationRequest ::= SEQUENCE {
+ * certificationRequestInfo CertificationRequestInfo,
+ * signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
+ * signature BIT STRING
+ * }
+ *
+ * CertificationRequestInfo ::= SEQUENCE {
+ * version INTEGER { v1(0) } (v1,...),
+ * subject Name,
+ * subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
+ * attributes [0] Attributes{{ CRIAttributes }}
+ * }
+ *
+ * Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
+ *
+ * Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
+ * type ATTRIBUTE.&amp;id({IOSet}),
+ * values SET SIZE(1..MAX) OF ATTRIBUTE.&amp;Type({IOSet}{\@type})
+ * }
+ * </pre>
+ * @deprecated use classes in org.bouncycastle.pkcs.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKCS10CertificationRequest
+ extends CertificationRequest
+{
+ private static Hashtable algorithms = new Hashtable();
+ private static Hashtable params = new Hashtable();
+ private static Hashtable keyAlgorithms = new Hashtable();
+ private static Hashtable oids = new Hashtable();
+ private static Set noParams = new HashSet();
+
+ static
+ {
+ // Android-removed: Unsupported algorithms
+ // algorithms.put("MD2WITHRSAENCRYPTION", new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"));
+ // algorithms.put("MD2WITHRSA", new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"));
+ // END Android-removed: Unsupported algorithms
+ algorithms.put("MD5WITHRSAENCRYPTION", new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"));
+ algorithms.put("MD5WITHRSA", new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"));
+ algorithms.put("RSAWITHMD5", new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"));
+ algorithms.put("SHA1WITHRSAENCRYPTION", new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"));
+ algorithms.put("SHA1WITHRSA", new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"));
+ 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);
+ algorithms.put("RSAWITHSHA1", new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"));
+ // BEGIN Android-removed: Unsupported algorithms
+ // algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
+ // algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
+ // algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
+ // algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
+ // algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
+ // algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
+ // END Android-removed: Unsupported algorithms
+ algorithms.put("SHA1WITHDSA", new ASN1ObjectIdentifier("1.2.840.10040.4.3"));
+ algorithms.put("DSAWITHSHA1", new ASN1ObjectIdentifier("1.2.840.10040.4.3"));
+ 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);
+ algorithms.put("SHA1WITHECDSA", 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);
+ algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1);
+ // BEGIN Android-removed: Unsupported algorithms
+ // algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
+ // algorithms.put("GOST3410WITHGOST3411", 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);
+ // END Android-removed: Unsupported algorithms
+
+ //
+ // 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(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410");
+ // oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410");
+ // 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");
+
+ //
+ // key types
+ //
+ keyAlgorithms.put(PKCSObjectIdentifiers.rsaEncryption, "RSA");
+ keyAlgorithms.put(X9ObjectIdentifiers.id_dsa, "DSA");
+
+ //
+ // 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);
+ noParams.add(OIWObjectIdentifiers.dsaWithSHA1);
+ noParams.add(NISTObjectIdentifiers.dsa_with_sha224);
+ noParams.add(NISTObjectIdentifiers.dsa_with_sha256);
+
+ //
+ // RFC 4491
+ //
+ // BEGIN Android-removed: Unsupported algorithms
+ // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
+ // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
+ // END Android-removed: Unsupported algorithms
+ //
+ // explicit params
+ //
+ AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
+ params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20));
+
+ AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE);
+ params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28));
+
+ AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE);
+ params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32));
+
+ AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE);
+ params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48));
+
+ AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE);
+ params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64));
+ }
+
+ private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int saltSize)
+ {
+ return new RSASSAPSSparams(
+ hashAlgId,
+ new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId),
+ new ASN1Integer(saltSize),
+ new ASN1Integer(1));
+ }
+
+ private static ASN1Sequence toDERSequence(
+ byte[] bytes)
+ {
+ try
+ {
+ ASN1InputStream dIn = new ASN1InputStream(bytes);
+
+ return (ASN1Sequence)dIn.readObject();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("badly encoded request");
+ }
+ }
+
+ /**
+ * construct a PKCS10 certification request from a DER encoded
+ * byte stream.
+ */
+ public PKCS10CertificationRequest(
+ byte[] bytes)
+ {
+ super(toDERSequence(bytes));
+ }
+
+ public PKCS10CertificationRequest(
+ ASN1Sequence sequence)
+ {
+ super(sequence);
+ }
+
+ /**
+ * create a PKCS10 certfication request using the BC provider.
+ */
+ public PKCS10CertificationRequest(
+ String signatureAlgorithm,
+ X509Name subject,
+ PublicKey key,
+ ASN1Set attributes,
+ PrivateKey signingKey)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, SignatureException
+ {
+ this(signatureAlgorithm, subject, key, attributes, signingKey, BouncyCastleProvider.PROVIDER_NAME);
+ }
+
+ private static X509Name convertName(
+ X500Principal name)
+ {
+ try
+ {
+ return new X509Principal(name.getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("can't convert name");
+ }
+ }
+
+ /**
+ * create a PKCS10 certfication request using the BC provider.
+ */
+ public PKCS10CertificationRequest(
+ String signatureAlgorithm,
+ X500Principal subject,
+ PublicKey key,
+ ASN1Set attributes,
+ PrivateKey signingKey)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, SignatureException
+ {
+ this(signatureAlgorithm, convertName(subject), key, attributes, signingKey, BouncyCastleProvider.PROVIDER_NAME);
+ }
+
+ /**
+ * create a PKCS10 certfication request using the named provider.
+ */
+ public PKCS10CertificationRequest(
+ String signatureAlgorithm,
+ X500Principal subject,
+ PublicKey key,
+ ASN1Set attributes,
+ PrivateKey signingKey,
+ String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, SignatureException
+ {
+ this(signatureAlgorithm, convertName(subject), key, attributes, signingKey, provider);
+ }
+
+ /**
+ * create a PKCS10 certfication request using the named provider.
+ */
+ public PKCS10CertificationRequest(
+ String signatureAlgorithm,
+ X509Name subject,
+ PublicKey key,
+ ASN1Set attributes,
+ PrivateKey signingKey,
+ String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, SignatureException
+ {
+ String algorithmName = Strings.toUpperCase(signatureAlgorithm);
+ ASN1ObjectIdentifier sigOID = (ASN1ObjectIdentifier)algorithms.get(algorithmName);
+
+ if (sigOID == null)
+ {
+ try
+ {
+ sigOID = new ASN1ObjectIdentifier(algorithmName);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("Unknown signature type requested");
+ }
+ }
+
+ if (subject == null)
+ {
+ throw new IllegalArgumentException("subject must not be null");
+ }
+
+ if (key == null)
+ {
+ throw new IllegalArgumentException("public key must not be null");
+ }
+
+ if (noParams.contains(sigOID))
+ {
+ this.sigAlgId = new AlgorithmIdentifier(sigOID);
+ }
+ else if (params.containsKey(algorithmName))
+ {
+ this.sigAlgId = new AlgorithmIdentifier(sigOID, (ASN1Encodable)params.get(algorithmName));
+ }
+ else
+ {
+ this.sigAlgId = new AlgorithmIdentifier(sigOID, DERNull.INSTANCE);
+ }
+
+ try
+ {
+ ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(key.getEncoded());
+ this.reqInfo = new CertificationRequestInfo(subject, SubjectPublicKeyInfo.getInstance(seq), attributes);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("can't encode public key");
+ }
+
+ Signature sig;
+ if (provider == null)
+ {
+ sig = Signature.getInstance(signatureAlgorithm);
+ }
+ else
+ {
+ sig = Signature.getInstance(signatureAlgorithm, provider);
+ }
+
+ sig.initSign(signingKey);
+
+ try
+ {
+ sig.update(reqInfo.getEncoded(ASN1Encoding.DER));
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("exception encoding TBS cert request - " + e);
+ }
+
+ this.sigBits = new DERBitString(sig.sign());
+ }
+
+ /**
+ * return the public key associated with the certification request -
+ * the public key is created using the BC provider.
+ */
+ public PublicKey getPublicKey()
+ throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException
+ {
+ return getPublicKey(BouncyCastleProvider.PROVIDER_NAME);
+ }
+
+ public PublicKey getPublicKey(
+ String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException
+ {
+ SubjectPublicKeyInfo subjectPKInfo = reqInfo.getSubjectPublicKeyInfo();
+
+
+ try
+ {
+ X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString(subjectPKInfo).getOctets());
+ AlgorithmIdentifier keyAlg = subjectPKInfo.getAlgorithm();
+ try
+ {
+ if (provider == null)
+ {
+ return KeyFactory.getInstance(keyAlg.getAlgorithm().getId()).generatePublic(xspec);
+ }
+ else
+ {
+ return KeyFactory.getInstance(keyAlg.getAlgorithm().getId(), provider).generatePublic(xspec);
+ }
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ //
+ // try an alternate
+ //
+ if (keyAlgorithms.get(keyAlg.getAlgorithm()) != null)
+ {
+ String keyAlgorithm = (String)keyAlgorithms.get(keyAlg.getAlgorithm());
+
+ if (provider == null)
+ {
+ return KeyFactory.getInstance(keyAlgorithm).generatePublic(xspec);
+ }
+ else
+ {
+ return KeyFactory.getInstance(keyAlgorithm, provider).generatePublic(xspec);
+ }
+ }
+
+ throw e;
+ }
+ }
+ catch (InvalidKeySpecException e)
+ {
+ throw new InvalidKeyException("error decoding public key");
+ }
+ catch (IOException e)
+ {
+ throw new InvalidKeyException("error decoding public key");
+ }
+ }
+
+ /**
+ * verify the request using the BC provider.
+ */
+ public boolean verify()
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, SignatureException
+ {
+ return verify(BouncyCastleProvider.PROVIDER_NAME);
+ }
+
+ /**
+ * verify the request using the passed in provider.
+ */
+ public boolean verify(
+ String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, SignatureException
+ {
+ return verify(this.getPublicKey(provider), provider);
+ }
+
+ /**
+ * verify the request using the passed in public key and the provider..
+ */
+ public boolean verify(
+ PublicKey pubKey,
+ String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, SignatureException
+ {
+ Signature sig;
+
+ try
+ {
+ if (provider == null)
+ {
+ sig = Signature.getInstance(getSignatureName(sigAlgId));
+ }
+ else
+ {
+ sig = Signature.getInstance(getSignatureName(sigAlgId), provider);
+ }
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ //
+ // try an alternate
+ //
+ if (oids.get(sigAlgId.getAlgorithm()) != null)
+ {
+ String signatureAlgorithm = (String)oids.get(sigAlgId.getAlgorithm());
+
+ if (provider == null)
+ {
+ sig = Signature.getInstance(signatureAlgorithm);
+ }
+ else
+ {
+ sig = Signature.getInstance(signatureAlgorithm, provider);
+ }
+ }
+ else
+ {
+ throw e;
+ }
+ }
+
+ setSignatureParameters(sig, sigAlgId.getParameters());
+
+ sig.initVerify(pubKey);
+
+ try
+ {
+ sig.update(reqInfo.getEncoded(ASN1Encoding.DER));
+ }
+ catch (Exception e)
+ {
+ throw new SignatureException("exception encoding TBS cert request - " + e);
+ }
+
+ return sig.verify(sigBits.getOctets());
+ }
+
+ /**
+ * return a DER encoded byte array representing this object
+ */
+ public byte[] getEncoded()
+ {
+ try
+ {
+ return this.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e.toString());
+ }
+ }
+
+ private void setSignatureParameters(
+ Signature signature,
+ ASN1Encodable params)
+ throws NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ if (params != null && !DERNull.INSTANCE.equals(params))
+ {
+ AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider());
+
+ try
+ {
+ sigParams.init(params.toASN1Primitive().getEncoded(ASN1Encoding.DER));
+ }
+ catch (IOException e)
+ {
+ throw new SignatureException("IOException decoding parameters: " + e.getMessage());
+ }
+
+ if (signature.getAlgorithm().endsWith("MGF1"))
+ {
+ try
+ {
+ signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class));
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new SignatureException("Exception extracting parameters: " + e.getMessage());
+ }
+ }
+ }
+ }
+
+ 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 getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "withRSAandMGF1";
+ }
+ }
+
+ return sigAlgId.getAlgorithm().getId();
+ }
+
+ private static String getDigestAlgName(
+ ASN1ObjectIdentifier digestAlgOID)
+ {
+ if (PKCSObjectIdentifiers.md5.equals(digestAlgOID))
+ {
+ return "MD5";
+ }
+ else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID))
+ {
+ return "SHA1";
+ }
+ else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID))
+ {
+ return "SHA224";
+ }
+ else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID))
+ {
+ return "SHA256";
+ }
+ else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID))
+ {
+ return "SHA384";
+ }
+ else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID))
+ {
+ return "SHA512";
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID))
+ {
+ return "RIPEMD128";
+ }
+ else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID))
+ {
+ return "RIPEMD160";
+ }
+ else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID))
+ {
+ return "RIPEMD256";
+ }
+ else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID))
+ {
+ return "GOST3411";
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ else
+ {
+ return digestAlgOID.getId();
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/PrincipalUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/PrincipalUtil.java
new file mode 100644
index 00000000..9194d855
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/PrincipalUtil.java
@@ -0,0 +1,83 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce;
+
+import java.io.IOException;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.x509.TBSCertList;
+import com.android.internal.org.bouncycastle.asn1.x509.TBSCertificateStructure;
+import com.android.internal.org.bouncycastle.asn1.x509.X509Name;
+
+/**
+ * a utility class that will extract X509Principal objects from X.509 certificates.
+ * <p>
+ * Use this in preference to trying to recreate a principal from a String, not all
+ * DNs are what they should be, so it's best to leave them encoded where they
+ * can be.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PrincipalUtil
+{
+ /**
+ * return the issuer of the given cert as an X509PrincipalObject.
+ */
+ public static X509Principal getIssuerX509Principal(
+ X509Certificate cert)
+ throws CertificateEncodingException
+ {
+ try
+ {
+ TBSCertificateStructure tbsCert = TBSCertificateStructure.getInstance(
+ ASN1Primitive.fromByteArray(cert.getTBSCertificate()));
+
+ return new X509Principal(X509Name.getInstance(tbsCert.getIssuer()));
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException(e.toString());
+ }
+ }
+
+ /**
+ * return the subject of the given cert as an X509PrincipalObject.
+ */
+ public static X509Principal getSubjectX509Principal(
+ X509Certificate cert)
+ throws CertificateEncodingException
+ {
+ try
+ {
+ TBSCertificateStructure tbsCert = TBSCertificateStructure.getInstance(
+ ASN1Primitive.fromByteArray(cert.getTBSCertificate()));
+ return new X509Principal(X509Name.getInstance(tbsCert.getSubject()));
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException(e.toString());
+ }
+ }
+
+ /**
+ * return the issuer of the given CRL as an X509PrincipalObject.
+ */
+ public static X509Principal getIssuerX509Principal(
+ X509CRL crl)
+ throws CRLException
+ {
+ try
+ {
+ TBSCertList tbsCertList = TBSCertList.getInstance(
+ ASN1Primitive.fromByteArray(crl.getTBSCertList()));
+
+ return new X509Principal(X509Name.getInstance(tbsCertList.getIssuer()));
+ }
+ catch (IOException e)
+ {
+ throw new CRLException(e.toString());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/X509Principal.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/X509Principal.java
new file mode 100644
index 00000000..758e7702
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/X509Principal.java
@@ -0,0 +1,167 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+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.X509Name;
+
+/**
+ * a general extension of X509Name with a couple of extra methods and
+ * constructors.
+ * <p>
+ * Objects of this type can be created from certificates and CRLs using the
+ * PrincipalUtil class.
+ * </p>
+ * @see com.android.internal.org.bouncycastle.jce.PrincipalUtil
+ * @deprecated use the X500Name class.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509Principal
+ extends X509Name
+ implements Principal
+{
+ private static ASN1Sequence readSequence(
+ ASN1InputStream aIn)
+ throws IOException
+ {
+ try
+ {
+ return ASN1Sequence.getInstance(aIn.readObject());
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new IOException("not an ASN.1 Sequence: " + e);
+ }
+ }
+
+ /**
+ * Constructor from an encoded byte array.
+ */
+ public X509Principal(
+ byte[] bytes)
+ throws IOException
+ {
+ super(readSequence(new ASN1InputStream(bytes)));
+ }
+
+ /**
+ * Constructor from an X509Name object.
+ */
+ public X509Principal(
+ X509Name name)
+ {
+ super((ASN1Sequence)name.toASN1Primitive());
+ }
+
+ /**
+ * Constructor from an X509Name object.
+ */
+ public X509Principal(
+ X500Name name)
+ {
+ super((ASN1Sequence)name.toASN1Primitive());
+ }
+
+ /**
+ * constructor from a table of attributes.
+ * <p>
+ * it's is assumed the table contains OID/String pairs.
+ */
+ public X509Principal(
+ Hashtable attributes)
+ {
+ super(attributes);
+ }
+
+ /**
+ * constructor from a table of attributes and a vector giving the
+ * specific ordering required for encoding or conversion to a string.
+ * <p>
+ * it's is assumed the table contains OID/String pairs.
+ */
+ public X509Principal(
+ Vector ordering,
+ Hashtable attributes)
+ {
+ super(ordering, attributes);
+ }
+
+ /**
+ * constructor from a vector of attribute values and a vector of OIDs.
+ */
+ public X509Principal(
+ Vector oids,
+ Vector values)
+ {
+ super(oids, values);
+ }
+
+ /**
+ * takes an X509 dir name as a string of the format "C=AU,ST=Victoria", or
+ * some such, converting it into an ordered set of name attributes.
+ */
+ public X509Principal(
+ String dirName)
+ {
+ super(dirName);
+ }
+
+ /**
+ * Takes an X509 dir name as a string of the format "C=AU,ST=Victoria", or
+ * some such, converting it into an ordered set of name attributes. If reverse
+ * is false the dir name will be encoded in the order of the (name, value) pairs
+ * presented, otherwise the encoding will start with the last (name, value) pair
+ * and work back.
+ */
+ public X509Principal(
+ boolean reverse,
+ String dirName)
+ {
+ super(reverse, dirName);
+ }
+
+ /**
+ * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
+ * some such, converting it into an ordered set of name attributes. lookUp
+ * should provide a table of lookups, indexed by lowercase only strings and
+ * yielding a ASN1ObjectIdentifier, other than that OID. and numeric oids
+ * will be processed automatically.
+ * <p>
+ * If reverse is true, create the encoded version of the sequence starting
+ * from the last element in the string.
+ */
+ public X509Principal(
+ boolean reverse,
+ Hashtable lookUp,
+ String dirName)
+ {
+ super(reverse, lookUp, dirName);
+ }
+
+ public String getName()
+ {
+ return this.toString();
+ }
+
+ /**
+ * return a DER encoded byte array representing this object
+ */
+ public byte[] getEncoded()
+ {
+ try
+ {
+ return this.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e.toString());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/exception/ExtCertPathBuilderException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/exception/ExtCertPathBuilderException.java
new file mode 100644
index 00000000..4764a415
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/exception/ExtCertPathBuilderException.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.exception;
+
+import java.security.cert.CertPath;
+import java.security.cert.CertPathBuilderException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ExtCertPathBuilderException
+ extends CertPathBuilderException
+ implements ExtException
+{
+ private Throwable cause;
+
+ public ExtCertPathBuilderException(String message, Throwable cause)
+ {
+ super(message);
+ this.cause = cause;
+ }
+
+ public ExtCertPathBuilderException(String msg, Throwable cause,
+ CertPath certPath, int index)
+ {
+ super(msg, cause);
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java
new file mode 100644
index 00000000..7541386f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java
@@ -0,0 +1,39 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.exception;
+
+import java.security.cert.CertPath;
+import java.security.cert.CertPathValidatorException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ExtCertPathValidatorException
+ extends CertPathValidatorException
+ implements ExtException
+{
+
+ private Throwable cause;
+
+ public ExtCertPathValidatorException(String message)
+ {
+ super(message);
+ }
+
+ public ExtCertPathValidatorException(String message, Throwable cause)
+ {
+ super(message);
+ this.cause = cause;
+ }
+
+ public ExtCertPathValidatorException(String msg, Throwable cause,
+ CertPath certPath, int index)
+ {
+ super(msg, cause, certPath, index);
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/exception/ExtException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/exception/ExtException.java
new file mode 100644
index 00000000..642440d9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/exception/ExtException.java
@@ -0,0 +1,23 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.exception;
+
+/**
+ *
+ * This is an extended exception. Java before version 1.4 did not offer the
+ * possibility the attach a cause to an exception. The cause of an exception is
+ * the <code>Throwable</code> object which was thrown and caused the
+ * exception. This interface must be implemented by all exceptions to accomplish
+ * this additional functionality.
+ * @hide This class is not part of the Android public SDK API
+ *
+ */
+public interface ExtException
+{
+
+ /**
+ * Returns the cause of the exception.
+ *
+ * @return The cause of the exception.
+ */
+ Throwable getCause();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/BCKeyStore.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/BCKeyStore.java
new file mode 100644
index 00000000..f2a45b02
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/BCKeyStore.java
@@ -0,0 +1,16 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.interfaces;
+
+import java.security.SecureRandom;
+
+/**
+ * all BC provider keystores implement this interface.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface BCKeyStore
+{
+ /**
+ * set the random source for the key store
+ */
+ public void setRandom(SecureRandom random);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECKey.java
new file mode 100644
index 00000000..cc8044b5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECKey.java
@@ -0,0 +1,17 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.interfaces;
+
+import com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec;
+
+/**
+ * generic interface for an Elliptic Curve Key.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ECKey
+{
+ /**
+ * return a parameter specification representing the EC domain parameters
+ * for the key.
+ */
+ public ECParameterSpec getParameters();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECPointEncoder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECPointEncoder.java
new file mode 100644
index 00000000..06a18687
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECPointEncoder.java
@@ -0,0 +1,22 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.interfaces;
+
+/**
+ * All BC elliptic curve keys implement this interface. You need to
+ * cast the key to get access to it.
+ * <p>
+ * By default BC keys produce encodings without point compression,
+ * to turn this on call setPointFormat() with "COMPRESSED".
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ECPointEncoder
+{
+ /**
+ * Set the formatting for encoding of points. If the String "UNCOMPRESSED" is passed
+ * in point compression will not be used. If the String "COMPRESSED" is passed point
+ * compression will be used. The default is "UNCOMPRESSED".
+ *
+ * @param style the style to use.
+ */
+ public void setPointFormat(String style);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECPrivateKey.java
new file mode 100644
index 00000000..49c8c091
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECPrivateKey.java
@@ -0,0 +1,18 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.interfaces;
+
+import java.math.BigInteger;
+import java.security.PrivateKey;
+
+/**
+ * interface for Elliptic Curve Private keys.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ECPrivateKey
+ extends ECKey, PrivateKey
+{
+ /**
+ * return the private value D.
+ */
+ public BigInteger getD();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECPublicKey.java
new file mode 100644
index 00000000..5f58c028
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/ECPublicKey.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.interfaces;
+
+import java.security.PublicKey;
+
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+
+/**
+ * interface for elliptic curve public keys.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ECPublicKey
+ extends ECKey, PublicKey
+{
+ /**
+ * return the public point Q
+ */
+ public ECPoint getQ();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/PKCS12BagAttributeCarrier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/PKCS12BagAttributeCarrier.java
new file mode 100644
index 00000000..b97384f6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/interfaces/PKCS12BagAttributeCarrier.java
@@ -0,0 +1,23 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.interfaces;
+
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * allow us to set attributes on objects that can go into a PKCS12 store.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PKCS12BagAttributeCarrier
+{
+ void setBagAttribute(
+ ASN1ObjectIdentifier oid,
+ ASN1Encodable attribute);
+
+ ASN1Encodable getBagAttribute(
+ ASN1ObjectIdentifier oid);
+
+ Enumeration getBagAttributeKeys();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/netscape/NetscapeCertRequest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
new file mode 100644
index 00000000..a77431f1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
@@ -0,0 +1,301 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.netscape;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERIA5String;
+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.SubjectPublicKeyInfo;
+
+/**
+ *
+ *
+ * Handles NetScape certificate request (KEYGEN), these are constructed as:
+ * <pre>
+ * SignedPublicKeyAndChallenge ::= SEQUENCE {
+ * publicKeyAndChallenge PublicKeyAndChallenge,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING
+ * }
+ * </pre>
+ *
+ * PublicKey's encoded-format has to be X.509.
+ * @hide This class is not part of the Android public SDK API
+ *
+ **/
+public class NetscapeCertRequest
+ extends ASN1Object
+{
+ AlgorithmIdentifier sigAlg;
+ AlgorithmIdentifier keyAlg;
+ byte sigBits [];
+ String challenge;
+ DERBitString content;
+ PublicKey pubkey ;
+
+ private static ASN1Sequence getReq(
+ byte[] r)
+ throws IOException
+ {
+ ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(r));
+
+ return ASN1Sequence.getInstance(aIn.readObject());
+ }
+
+ public NetscapeCertRequest(
+ byte[] req)
+ throws IOException
+ {
+ this(getReq(req));
+ }
+
+ public NetscapeCertRequest (ASN1Sequence spkac)
+ {
+ try
+ {
+
+ //
+ // SignedPublicKeyAndChallenge ::= SEQUENCE {
+ // publicKeyAndChallenge PublicKeyAndChallenge,
+ // signatureAlgorithm AlgorithmIdentifier,
+ // signature BIT STRING
+ // }
+ //
+ if (spkac.size() != 3)
+ {
+ throw new IllegalArgumentException("invalid SPKAC (size):"
+ + spkac.size());
+ }
+
+ sigAlg = AlgorithmIdentifier.getInstance(spkac.getObjectAt(1));
+ sigBits = ((DERBitString)spkac.getObjectAt(2)).getOctets();
+
+ //
+ // PublicKeyAndChallenge ::= SEQUENCE {
+ // spki SubjectPublicKeyInfo,
+ // challenge IA5STRING
+ // }
+ //
+ ASN1Sequence pkac = (ASN1Sequence)spkac.getObjectAt(0);
+
+ if (pkac.size() != 2)
+ {
+ throw new IllegalArgumentException("invalid PKAC (len): "
+ + pkac.size());
+ }
+
+ challenge = ((DERIA5String)pkac.getObjectAt(1)).getString();
+
+ //this could be dangerous, as ASN.1 decoding/encoding
+ //could potentially alter the bytes
+ content = new DERBitString(pkac);
+
+ SubjectPublicKeyInfo pubkeyinfo = SubjectPublicKeyInfo.getInstance(pkac.getObjectAt(0));
+
+ X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString(
+ pubkeyinfo).getBytes());
+
+ keyAlg = pubkeyinfo.getAlgorithm();
+ pubkey = KeyFactory.getInstance(keyAlg.getAlgorithm().getId())
+ .generatePublic(xspec);
+
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException(e.toString());
+ }
+ }
+
+ public NetscapeCertRequest(
+ String challenge,
+ AlgorithmIdentifier signing_alg,
+ PublicKey pub_key) throws NoSuchAlgorithmException,
+ InvalidKeySpecException, NoSuchProviderException
+ {
+
+ this.challenge = challenge;
+ sigAlg = signing_alg;
+ pubkey = pub_key;
+
+ ASN1EncodableVector content_der = new ASN1EncodableVector();
+ content_der.add(getKeySpec());
+ //content_der.add(new SubjectPublicKeyInfo(sigAlg, new RSAPublicKeyStructure(pubkey.getModulus(), pubkey.getPublicExponent()).getDERObject()));
+ content_der.add(new DERIA5String(challenge));
+
+ try
+ {
+ content = new DERBitString(new DERSequence(content_der));
+ }
+ catch (IOException e)
+ {
+ throw new InvalidKeySpecException("exception encoding key: " + e.toString());
+ }
+ }
+
+ public String getChallenge()
+ {
+ return challenge;
+ }
+
+ public void setChallenge(String value)
+ {
+ challenge = value;
+ }
+
+ public AlgorithmIdentifier getSigningAlgorithm()
+ {
+ return sigAlg;
+ }
+
+ public void setSigningAlgorithm(AlgorithmIdentifier value)
+ {
+ sigAlg = value;
+ }
+
+ public AlgorithmIdentifier getKeyAlgorithm()
+ {
+ return keyAlg;
+ }
+
+ public void setKeyAlgorithm(AlgorithmIdentifier value)
+ {
+ keyAlg = value;
+ }
+
+ public PublicKey getPublicKey()
+ {
+ return pubkey;
+ }
+
+ public void setPublicKey(PublicKey value)
+ {
+ pubkey = value;
+ }
+
+ public boolean verify(String challenge) throws NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException, NoSuchProviderException
+ {
+ if (!challenge.equals(this.challenge))
+ {
+ return false;
+ }
+
+ //
+ // Verify the signature .. shows the response was generated
+ // by someone who knew the associated private key
+ //
+ Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId());
+ sig.initVerify(pubkey);
+ sig.update(content.getBytes());
+
+ return sig.verify(sigBits);
+ }
+
+ public void sign(PrivateKey priv_key) throws NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException, NoSuchProviderException,
+ InvalidKeySpecException
+ {
+ sign(priv_key, null);
+ }
+
+ public void sign(PrivateKey priv_key, SecureRandom rand)
+ throws NoSuchAlgorithmException, InvalidKeyException,
+ SignatureException, NoSuchProviderException,
+ InvalidKeySpecException
+ {
+ Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId());
+
+ if (rand != null)
+ {
+ sig.initSign(priv_key, rand);
+ }
+ else
+ {
+ sig.initSign(priv_key);
+ }
+
+ ASN1EncodableVector pkac = new ASN1EncodableVector();
+
+ pkac.add(getKeySpec());
+ pkac.add(new DERIA5String(challenge));
+
+ try
+ {
+ sig.update(new DERSequence(pkac).getEncoded(ASN1Encoding.DER));
+ }
+ catch (IOException ioe)
+ {
+ throw new SignatureException(ioe.getMessage());
+ }
+
+ sigBits = sig.sign();
+ }
+
+ private ASN1Primitive getKeySpec() throws NoSuchAlgorithmException,
+ InvalidKeySpecException, NoSuchProviderException
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ ASN1Primitive obj = null;
+ try
+ {
+
+ baos.write(pubkey.getEncoded());
+ baos.close();
+
+ ASN1InputStream derin = new ASN1InputStream(
+ new ByteArrayInputStream(baos.toByteArray()));
+
+ obj = derin.readObject();
+ }
+ catch (IOException ioe)
+ {
+ throw new InvalidKeySpecException(ioe.getMessage());
+ }
+ return obj;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector spkac = new ASN1EncodableVector();
+ ASN1EncodableVector pkac = new ASN1EncodableVector();
+
+ try
+ {
+ pkac.add(getKeySpec());
+ }
+ catch (Exception e)
+ {
+ //ignore
+ }
+
+ pkac.add(new DERIA5String(challenge));
+
+ spkac.add(new DERSequence(pkac));
+ spkac.add(sigAlg);
+ spkac.add(new DERBitString(sigBits));
+
+ return new DERSequence(spkac);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/AnnotatedException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/AnnotatedException.java
new file mode 100644
index 00000000..d0327fe3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/AnnotatedException.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import com.android.internal.org.bouncycastle.jce.exception.ExtException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AnnotatedException
+ extends Exception
+ implements ExtException
+{
+ private Throwable _underlyingException;
+
+ public AnnotatedException(String string, Throwable e)
+ {
+ super(string);
+
+ _underlyingException = e;
+ }
+
+ public AnnotatedException(String string)
+ {
+ this(string, null);
+ }
+
+ Throwable getUnderlyingException()
+ {
+ return _underlyingException;
+ }
+
+ public Throwable getCause()
+ {
+ return _underlyingException;
+ }
+}
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
new file mode 100644
index 00000000..2f3f1ea2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java
@@ -0,0 +1,431 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.PrivilegedAction;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+// import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers;
+// import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.ClassUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers;
+// import org.bouncycastle.pqc.jcajce.provider.mceliece.McElieceCCA2KeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.mceliece.McElieceKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.newhope.NHKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.qtesla.QTESLAKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.rainbow.RainbowKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.sphincs.Sphincs256KeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSMTKeyFactorySpi;
+// import org.bouncycastle.pqc.jcajce.provider.lms.LMSKeyFactorySpi;
+
+/**
+ * To add the provider at runtime use:
+ * <pre>
+ * import java.security.Security;
+ * import org.bouncycastle.jce.provider.BouncyCastleProvider;
+ *
+ * Security.addProvider(new BouncyCastleProvider());
+ * </pre>
+ * The provider can also be configured as part of your environment via
+ * static registration by adding an entry to the java.security properties
+ * file (found in $JAVA_HOME/jre/lib/security/java.security, where
+ * $JAVA_HOME is the location of your JDK/JRE distribution). You'll find
+ * detailed instructions in the file but basically it comes down to adding
+ * a line:
+ * <pre>
+ * <code>
+ * security.provider.&lt;n&gt;=org.bouncycastle.jce.provider.BouncyCastleProvider
+ * </code>
+ * </pre>
+ * Where &lt;n&gt; is the preference you want the provider at (1 being the
+ * most preferred).
+ * <p>Note: JCE algorithm names should be upper-case only so the case insensitive
+ * test for getInstance works.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class BouncyCastleProvider extends Provider
+ implements ConfigurableProvider
+{
+ private static String info = "BouncyCastle Security Provider v1.68";
+
+ public static final String PROVIDER_NAME = "BC";
+
+ public static final ProviderConfiguration CONFIGURATION = new BouncyCastleProviderConfiguration();
+
+ private static final Map keyInfoConverters = new HashMap();
+
+ private static final Class revChkClass = ClassUtil.loadClass(BouncyCastleProvider.class, "java.security.cert.PKIXRevocationChecker");
+
+ /*
+ * Configurable symmetric ciphers
+ */
+ private static final String SYMMETRIC_PACKAGE = "com.android.internal.org.bouncycastle.jcajce.provider.symmetric.";
+
+ private static final String[] SYMMETRIC_GENERIC =
+ {
+ // Android-changed: Remove unsupported algorithms, add our own version of PBEv2 AlgParams
+ // "PBEPBKDF1", "PBEPBKDF2", "PBEPKCS12", "TLSKDF", "SCRYPT"
+ "PBEPBKDF2", "PBEPKCS12", "PBES2AlgorithmParameters"
+ };
+
+ private static final String[] SYMMETRIC_MACS =
+ {
+ // Android-removed: Unsupported algorithms
+ // "SipHash", "Poly1305"
+ };
+
+ private static final String[] SYMMETRIC_CIPHERS =
+ {
+ // Android-changed: Unsupported algorithms
+ // "AES", "ARC4", "ARIA", "Blowfish", "Camellia", "CAST5", "CAST6", "ChaCha", "DES", "DESede",
+ // "GOST28147", "Grainv1", "Grain128", "HC128", "HC256", "IDEA", "Noekeon", "RC2", "RC5",
+ // "RC6", "Rijndael", "Salsa20", "SEED", "Serpent", "Shacal2", "Skipjack", "SM4", "TEA", "Twofish", "Threefish",
+ // "VMPC", "VMPCKSA3", "XTEA", "XSalsa20", "OpenSSLPBKDF", "DSTU7624", "GOST3412_2015"
+ "AES", "ARC4", "Blowfish", "DES", "DESede", "RC2", "Twofish",
+ };
+
+ /*
+ * Configurable asymmetric ciphers
+ */
+ private static final String ASYMMETRIC_PACKAGE = "com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.";
+
+ // this one is required for GNU class path - it needs to be loaded first as the
+ // later ones configure it.
+ private static final String[] ASYMMETRIC_GENERIC =
+ {
+ // Android-changed: Unsupported algorithms
+ // "X509", "IES", "COMPOSITE"
+ "X509"
+ };
+
+ private static final String[] ASYMMETRIC_CIPHERS =
+ {
+ // Android-changed: Unsupported algorithms
+ // "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145", "GM", "EdEC"
+ "DSA", "DH", "EC", "RSA",
+ };
+
+ /*
+ * Configurable digests
+ */
+ private static final String DIGEST_PACKAGE = "com.android.internal.org.bouncycastle.jcajce.provider.digest.";
+ private static final String[] DIGESTS =
+ {
+ // Android-changed: Unsupported algorithms
+ // "GOST3411", "Keccak", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224",
+ // "SHA256", "SHA384", "SHA512", "SHA3", "Skein", "SM3", "Tiger", "Whirlpool", "Blake2b", "Blake2s", "DSTU7564",
+ // "Haraka"
+ "MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512",
+ };
+
+ /*
+ * Configurable keystores
+ */
+ private static final String KEYSTORE_PACKAGE = "com.android.internal.org.bouncycastle.jcajce.provider.keystore.";
+ private static final String[] KEYSTORES =
+ {
+ "BC", "BCFKS", "PKCS12"
+ };
+
+ // Android-removed: Unsupported algorithms
+ // /*
+ // * Configurable secure random
+ // */
+ // private static final String SECURE_RANDOM_PACKAGE = "org.bouncycastle.jcajce.provider.drbg.";
+ // private static final String[] SECURE_RANDOMS =
+ // {
+ // "DRBG"
+ // };
+
+ /**
+ * Construct a new provider. This should only be required when
+ * using runtime registration of the provider using the
+ * <code>Security.addProvider()</code> mechanism.
+ */
+ public BouncyCastleProvider()
+ {
+ super(PROVIDER_NAME, 1.68, info);
+
+ AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ setup();
+ return null;
+ }
+ });
+ }
+
+ private void setup()
+ {
+ loadAlgorithms(DIGEST_PACKAGE, DIGESTS);
+
+ loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_GENERIC);
+
+ loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_MACS);
+
+ loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_CIPHERS);
+
+ loadAlgorithms(ASYMMETRIC_PACKAGE, ASYMMETRIC_GENERIC);
+
+ loadAlgorithms(ASYMMETRIC_PACKAGE, ASYMMETRIC_CIPHERS);
+
+ loadAlgorithms(KEYSTORE_PACKAGE, KEYSTORES);
+
+ // Android-removed: Unsupported algorithms
+ /*
+ loadAlgorithms(SECURE_RANDOM_PACKAGE, SECURE_RANDOMS);
+
+ loadPQCKeys(); // so we can handle certificates containing them.
+
+ //
+ // X509Store
+ //
+ put("X509Store.CERTIFICATE/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCertCollection");
+ put("X509Store.ATTRIBUTECERTIFICATE/COLLECTION", "org.bouncycastle.jce.provider.X509StoreAttrCertCollection");
+ put("X509Store.CRL/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCRLCollection");
+ put("X509Store.CERTIFICATEPAIR/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCertPairCollection");
+
+ put("X509Store.CERTIFICATE/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCerts");
+ put("X509Store.CRL/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCRLs");
+ put("X509Store.ATTRIBUTECERTIFICATE/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPAttrCerts");
+ put("X509Store.CERTIFICATEPAIR/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCertPairs");
+
+ //
+ // X509StreamParser
+ //
+ put("X509StreamParser.CERTIFICATE", "org.bouncycastle.jce.provider.X509CertParser");
+ put("X509StreamParser.ATTRIBUTECERTIFICATE", "org.bouncycastle.jce.provider.X509AttrCertParser");
+ put("X509StreamParser.CRL", "org.bouncycastle.jce.provider.X509CRLParser");
+ put("X509StreamParser.CERTIFICATEPAIR", "org.bouncycastle.jce.provider.X509CertPairParser");
+
+ //
+ // cipher engines
+ //
+ put("Cipher.BROKENPBEWITHMD5ANDDES", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$BrokePBEWithMD5AndDES");
+
+ put("Cipher.BROKENPBEWITHSHA1ANDDES", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$BrokePBEWithSHA1AndDES");
+
+
+ put("Cipher.OLDPBEWITHSHAANDTWOFISH-CBC", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$OldPBEWithSHAAndTwofish");
+
+ // Certification Path API
+ put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi");
+ put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
+ put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
+ put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
+
+ if (revChkClass != null)
+ {
+ put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
+ put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi_8");
+ put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi_8");
+ put("CertPathValidator.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi_8");
+ put("CertPathBuilder.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi_8");
+ }
+ else
+ {
+ put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi");
+ put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi");
+ put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
+ put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
+ put("CertPathValidator.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
+ put("CertPathBuilder.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ put("CertPathValidator.PKIX", "com.android.internal.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi");
+ put("CertPathBuilder.PKIX", "com.android.internal.org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi");
+ put("CertStore.Collection", "com.android.internal.org.bouncycastle.jce.provider.CertStoreCollectionSpi");
+ // BEGIN Android-removed: Unsupported algorithms
+ // put("CertStore.LDAP", "org.bouncycastle.jce.provider.X509LDAPCertStoreSpi");
+ // put("CertStore.Multi", "org.bouncycastle.jce.provider.MultiCertStoreSpi");
+ // put("Alg.Alias.CertStore.X509LDAP", "LDAP");
+ // END Android-removed: Unsupported algorithms
+ }
+
+ private void loadAlgorithms(String packageName, String[] names)
+ {
+ for (int i = 0; i != names.length; i++)
+ {
+ Class clazz = ClassUtil.loadClass(BouncyCastleProvider.class, packageName + names[i] + "$Mappings");
+
+ if (clazz != null)
+ {
+ try
+ {
+ ((AlgorithmProvider)clazz.newInstance()).configure(this);
+ }
+ catch (Exception e)
+ { // this should never ever happen!!
+ throw new InternalError("cannot create instance of "
+ + packageName + names[i] + "$Mappings : " + e);
+ }
+ }
+ }
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ private void loadPQCKeys()
+ {
+ addKeyInfoConverter(PQCObjectIdentifiers.sphincs256, new Sphincs256KeyFactorySpi());
+ addKeyInfoConverter(PQCObjectIdentifiers.newHope, new NHKeyFactorySpi());
+ addKeyInfoConverter(PQCObjectIdentifiers.xmss, new XMSSKeyFactorySpi());
+ addKeyInfoConverter(IsaraObjectIdentifiers.id_alg_xmss, new XMSSKeyFactorySpi());
+ addKeyInfoConverter(PQCObjectIdentifiers.xmss_mt, new XMSSMTKeyFactorySpi());
+ addKeyInfoConverter(IsaraObjectIdentifiers.id_alg_xmssmt, new XMSSMTKeyFactorySpi());
+ addKeyInfoConverter(PQCObjectIdentifiers.mcEliece, new McElieceKeyFactorySpi());
+ addKeyInfoConverter(PQCObjectIdentifiers.mcElieceCca2, new McElieceCCA2KeyFactorySpi());
+ addKeyInfoConverter(PQCObjectIdentifiers.rainbow, new RainbowKeyFactorySpi());
+ addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_I, new QTESLAKeyFactorySpi());
+ addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_III, new QTESLAKeyFactorySpi());
+ addKeyInfoConverter(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, new LMSKeyFactorySpi());
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ public void setParameter(String parameterName, Object parameter)
+ {
+ synchronized (CONFIGURATION)
+ {
+ ((BouncyCastleProviderConfiguration)CONFIGURATION).setParameter(parameterName, parameter);
+ }
+ }
+
+ public boolean hasAlgorithm(String type, String name)
+ {
+ return containsKey(type + "." + name) || containsKey("Alg.Alias." + type + "." + name);
+ }
+
+ public void addAlgorithm(String key, String value)
+ {
+ if (containsKey(key))
+ {
+ throw new IllegalStateException("duplicate provider key (" + key + ") found");
+ }
+
+ put(key, value);
+ }
+
+ public void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className)
+ {
+ addAlgorithm(type + "." + oid, className);
+ addAlgorithm(type + ".OID." + oid, className);
+ }
+
+ public void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter)
+ {
+ synchronized (keyInfoConverters)
+ {
+ keyInfoConverters.put(oid, keyInfoConverter);
+ }
+ }
+
+ public AsymmetricKeyInfoConverter getKeyInfoConverter(ASN1ObjectIdentifier oid)
+ {
+ return (AsymmetricKeyInfoConverter)keyInfoConverters.get(oid);
+ }
+
+ public void addAttributes(String key, Map<String, String> attributeMap)
+ {
+ for (Iterator it = attributeMap.keySet().iterator(); it.hasNext();)
+ {
+ String attributeName = (String)it.next();
+ String attributeKey = key + " " + attributeName;
+ if (containsKey(attributeKey))
+ {
+ throw new IllegalStateException("duplicate provider attribute key (" + attributeKey + ") found");
+ }
+
+ put(attributeKey, attributeMap.get(attributeName));
+ }
+ }
+
+ private static AsymmetricKeyInfoConverter getAsymmetricKeyInfoConverter(ASN1ObjectIdentifier algorithm)
+ {
+ synchronized (keyInfoConverters)
+ {
+ return (AsymmetricKeyInfoConverter)keyInfoConverters.get(algorithm);
+ }
+ }
+
+ public static PublicKey getPublicKey(SubjectPublicKeyInfo publicKeyInfo)
+ throws IOException
+ {
+ // Android-added: BC KeyFactories have been removed, so load them the standard way
+ try {
+ return KeyFactory
+ .getInstance(
+ publicKeyInfo.getAlgorithmId().getAlgorithm().getId())
+ .generatePublic(
+ new X509EncodedKeySpec(publicKeyInfo.getEncoded()));
+ } catch (java.security.NoSuchAlgorithmException ex) {
+ // Maintaining compatibility with upstream logic: if appropriate algorithm not found
+ // ("converter" in Android-removed section) return null instead of throwing.
+ return null;
+ } catch (java.security.spec.InvalidKeySpecException ex) {
+ throw new IOException(ex);
+ }
+ // Android-removed: see above
+ /*
+ AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(publicKeyInfo.getAlgorithm().getAlgorithm());
+
+ if (converter == null)
+ {
+ return null;
+ }
+
+ return converter.generatePublic(publicKeyInfo);
+ */
+ }
+
+ public static PrivateKey getPrivateKey(PrivateKeyInfo privateKeyInfo)
+ throws IOException
+ {
+ // Android-added: BC KeyFactories have been removed, so load them the standard way
+ try {
+ return KeyFactory
+ .getInstance(
+ privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm().getId())
+ .generatePrivate(
+ new PKCS8EncodedKeySpec(privateKeyInfo.getEncoded()));
+ } catch (java.security.NoSuchAlgorithmException ex) {
+ // Maintaining compatibility with upstream logic: if appropriate algorithm not found
+ // ("converter" in Android-removed section) return null instead of throwing.
+ return null;
+ } catch (java.security.spec.InvalidKeySpecException ex) {
+ throw new IOException(ex);
+ }
+ // Android-removed: see above
+ /*
+ AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm());
+
+ if (converter == null)
+ {
+ return null;
+ }
+
+ return converter.generatePrivate(privateKeyInfo);
+ */
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java
new file mode 100644
index 00000000..4d19fe5a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java
@@ -0,0 +1,229 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.security.Permission;
+import java.security.spec.DSAParameterSpec;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.crypto.spec.DHParameterSpec;
+
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DSAParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
+import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConfigurationPermission;
+import com.android.internal.org.bouncycastle.jcajce.spec.DHDomainParameterSpec;
+import com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec;
+
+class BouncyCastleProviderConfiguration
+ implements ProviderConfiguration
+{
+ private static Permission BC_EC_LOCAL_PERMISSION = new ProviderConfigurationPermission(
+ BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.THREAD_LOCAL_EC_IMPLICITLY_CA);
+ private static Permission BC_EC_PERMISSION = new ProviderConfigurationPermission(
+ BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.EC_IMPLICITLY_CA);
+ private static Permission BC_DH_LOCAL_PERMISSION = new ProviderConfigurationPermission(
+ BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS);
+ private static Permission BC_DH_PERMISSION = new ProviderConfigurationPermission(
+ BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.DH_DEFAULT_PARAMS);
+ private static Permission BC_EC_CURVE_PERMISSION = new ProviderConfigurationPermission(
+ BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.ACCEPTABLE_EC_CURVES);
+ private static Permission BC_ADDITIONAL_EC_CURVE_PERMISSION = new ProviderConfigurationPermission(
+ BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.ADDITIONAL_EC_PARAMETERS);
+
+ private ThreadLocal ecThreadSpec = new ThreadLocal();
+ private ThreadLocal dhThreadSpec = new ThreadLocal();
+
+ private volatile ECParameterSpec ecImplicitCaParams;
+ private volatile Object dhDefaultParams;
+ private volatile Set acceptableNamedCurves = new HashSet();
+ private volatile Map additionalECParameters = new HashMap();
+
+ void setParameter(String parameterName, Object parameter)
+ {
+ SecurityManager securityManager = System.getSecurityManager();
+
+ if (parameterName.equals(ConfigurableProvider.THREAD_LOCAL_EC_IMPLICITLY_CA))
+ {
+ ECParameterSpec curveSpec;
+
+ if (securityManager != null)
+ {
+ securityManager.checkPermission(BC_EC_LOCAL_PERMISSION);
+ }
+
+ if (parameter instanceof ECParameterSpec || parameter == null)
+ {
+ curveSpec = (ECParameterSpec)parameter;
+ }
+ else // assume java.security.spec
+ {
+ curveSpec = EC5Util.convertSpec((java.security.spec.ECParameterSpec)parameter);
+ }
+
+ if (curveSpec == null)
+ {
+ ecThreadSpec.remove();
+ }
+ else
+ {
+ ecThreadSpec.set(curveSpec);
+ }
+ }
+ else if (parameterName.equals(ConfigurableProvider.EC_IMPLICITLY_CA))
+ {
+ if (securityManager != null)
+ {
+ securityManager.checkPermission(BC_EC_PERMISSION);
+ }
+
+ if (parameter instanceof ECParameterSpec || parameter == null)
+ {
+ ecImplicitCaParams = (ECParameterSpec)parameter;
+ }
+ else // assume java.security.spec
+ {
+ ecImplicitCaParams = EC5Util.convertSpec((java.security.spec.ECParameterSpec)parameter);
+ }
+ }
+ else if (parameterName.equals(ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS))
+ {
+ Object dhSpec;
+
+ if (securityManager != null)
+ {
+ securityManager.checkPermission(BC_DH_LOCAL_PERMISSION);
+ }
+
+ if (parameter instanceof DHParameterSpec || parameter instanceof DHParameterSpec[] || parameter == null)
+ {
+ dhSpec = parameter;
+ }
+ else
+ {
+ throw new IllegalArgumentException("not a valid DHParameterSpec");
+ }
+
+ if (dhSpec == null)
+ {
+ dhThreadSpec.remove();
+ }
+ else
+ {
+ dhThreadSpec.set(dhSpec);
+ }
+ }
+ else if (parameterName.equals(ConfigurableProvider.DH_DEFAULT_PARAMS))
+ {
+ if (securityManager != null)
+ {
+ securityManager.checkPermission(BC_DH_PERMISSION);
+ }
+
+ if (parameter instanceof DHParameterSpec || parameter instanceof DHParameterSpec[] || parameter == null)
+ {
+ dhDefaultParams = parameter;
+ }
+ else
+ {
+ throw new IllegalArgumentException("not a valid DHParameterSpec or DHParameterSpec[]");
+ }
+ }
+ else if (parameterName.equals(ConfigurableProvider.ACCEPTABLE_EC_CURVES))
+ {
+ if (securityManager != null)
+ {
+ securityManager.checkPermission(BC_EC_CURVE_PERMISSION);
+ }
+
+ this.acceptableNamedCurves = (Set)parameter;
+ }
+ else if (parameterName.equals(ConfigurableProvider.ADDITIONAL_EC_PARAMETERS))
+ {
+ if (securityManager != null)
+ {
+ securityManager.checkPermission(BC_ADDITIONAL_EC_CURVE_PERMISSION);
+ }
+
+ this.additionalECParameters = (Map)parameter;
+ }
+ }
+
+ public ECParameterSpec getEcImplicitlyCa()
+ {
+ ECParameterSpec spec = (ECParameterSpec)ecThreadSpec.get();
+
+ if (spec != null)
+ {
+ return spec;
+ }
+
+ return ecImplicitCaParams;
+ }
+
+ public DHParameterSpec getDHDefaultParameters(int keySize)
+ {
+ Object params = dhThreadSpec.get();
+ if (params == null)
+ {
+ params = dhDefaultParams;
+ }
+
+ if (params instanceof DHParameterSpec)
+ {
+ DHParameterSpec spec = (DHParameterSpec)params;
+
+ if (spec.getP().bitLength() == keySize)
+ {
+ return spec;
+ }
+ }
+ else if (params instanceof DHParameterSpec[])
+ {
+ DHParameterSpec[] specs = (DHParameterSpec[])params;
+
+ for (int i = 0; i != specs.length; i++)
+ {
+ if (specs[i].getP().bitLength() == keySize)
+ {
+ return specs[i];
+ }
+ }
+ }
+
+ DHParameters dhParams = CryptoServicesRegistrar.getSizedProperty(CryptoServicesRegistrar.Property.DH_DEFAULT_PARAMS, keySize);
+ if (dhParams != null)
+ {
+ return new DHDomainParameterSpec(dhParams);
+ }
+
+ return null;
+ }
+
+ public DSAParameterSpec getDSADefaultParameters(int keySize)
+ {
+ DSAParameters dsaParams = CryptoServicesRegistrar.getSizedProperty(CryptoServicesRegistrar.Property.DSA_DEFAULT_PARAMS, keySize);
+ if (dsaParams != null)
+ {
+ return new DSAParameterSpec(dsaParams.getP(), dsaParams.getQ(), dsaParams.getG());
+ }
+
+ return null;
+ }
+
+ public Set getAcceptableNamedCurves()
+ {
+ return Collections.unmodifiableSet(acceptableNamedCurves);
+ }
+
+ public Map getAdditionalECParameters()
+ {
+ return Collections.unmodifiableMap(additionalECParameters);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertBlocklist.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertBlocklist.java
new file mode 100644
index 00000000..185f4b69
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertBlocklist.java
@@ -0,0 +1,238 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.Closeable;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertBlocklist {
+ private static final Logger logger = Logger.getLogger(CertBlocklist.class.getName());
+
+ // public for testing
+ public final Set<BigInteger> serialBlocklist;
+ public final Set<byte[]> pubkeyBlocklist;
+
+ public CertBlocklist() {
+ String androidData = System.getenv("ANDROID_DATA");
+ String blocklistRoot = androidData + "/misc/keychain/";
+ // TODO(b/162575432): change these paths to use inclusive language
+ String defaultPubkeyBlocklistPath = blocklistRoot + "pubkey_blacklist.txt";
+ String defaultSerialBlocklistPath = blocklistRoot + "serial_blacklist.txt";
+
+ pubkeyBlocklist = readPublicKeyBlockList(defaultPubkeyBlocklistPath);
+ serialBlocklist = readSerialBlockList(defaultSerialBlocklistPath);
+ }
+
+ /** Test only interface, not for public use */
+ public CertBlocklist(String pubkeyBlocklistPath, String serialBlocklistPath) {
+ pubkeyBlocklist = readPublicKeyBlockList(pubkeyBlocklistPath);
+ serialBlocklist = readSerialBlockList(serialBlocklistPath);
+ }
+
+ private static boolean isHex(String value) {
+ try {
+ new BigInteger(value, 16);
+ return true;
+ } catch (NumberFormatException e) {
+ logger.log(Level.WARNING, "Could not parse hex value " + value, e);
+ return false;
+ }
+ }
+
+ private static boolean isPubkeyHash(String value) {
+ if (value.length() != 40) {
+ logger.log(Level.WARNING, "Invalid pubkey hash length: " + value.length());
+ return false;
+ }
+ return isHex(value);
+ }
+
+ private static String readBlocklist(String path) {
+ try {
+ return readFileAsString(path);
+ } catch (FileNotFoundException ignored) {
+ } catch (IOException e) {
+ logger.log(Level.WARNING, "Could not read blocklist", e);
+ }
+ return "";
+ }
+
+ // From IoUtils.readFileAsString
+ private static String readFileAsString(String path) throws IOException {
+ return readFileAsBytes(path).toString("UTF-8");
+ }
+
+ // Based on IoUtils.readFileAsBytes
+ private static ByteArrayOutputStream readFileAsBytes(String path) throws IOException {
+ RandomAccessFile f = null;
+ try {
+ f = new RandomAccessFile(path, "r");
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream((int) f.length());
+ byte[] buffer = new byte[8192];
+ while (true) {
+ int byteCount = f.read(buffer);
+ if (byteCount == -1) {
+ return bytes;
+ }
+ bytes.write(buffer, 0, byteCount);
+ }
+ } finally {
+ closeQuietly(f);
+ }
+ }
+
+ // Base on IoUtils.closeQuietly
+ private static void closeQuietly(Closeable closeable) {
+ if (closeable != null) {
+ try {
+ closeable.close();
+ } catch (RuntimeException rethrown) {
+ throw rethrown;
+ } catch (Exception ignored) {
+ }
+ }
+ }
+
+ private static Set<BigInteger> readSerialBlockList(String path) {
+
+ /* Start out with a base set of known bad values.
+ *
+ * WARNING: Do not add short serials to this list!
+ *
+ * Since this currently doesn't compare the serial + issuer, you
+ * should only add serials that have enough entropy here. Short
+ * serials may inadvertently match a certificate that was issued
+ * not in compliance with the Baseline Requirements.
+ */
+ Set<BigInteger> bl = new HashSet<BigInteger>(Arrays.asList(
+ // From http://src.chromium.org/viewvc/chrome/trunk/src/net/base/x509_certificate.cc?revision=78748&view=markup
+ // Not a real certificate. For testing only.
+ new BigInteger("077a59bcd53459601ca6907267a6dd1c", 16),
+ new BigInteger("047ecbe9fca55f7bd09eae36e10cae1e", 16),
+ new BigInteger("d8f35f4eb7872b2dab0692e315382fb0", 16),
+ new BigInteger("b0b7133ed096f9b56fae91c874bd3ac0", 16),
+ new BigInteger("9239d5348f40d1695a745470e1f23f43", 16),
+ new BigInteger("e9028b9578e415dc1a710a2b88154447", 16),
+ new BigInteger("d7558fdaf5f1105bb213282b707729a3", 16),
+ new BigInteger("f5c86af36162f13a64f54f6dc9587c06", 16),
+ new BigInteger("392a434f0e07df1f8aa305de34e0c229", 16),
+ new BigInteger("3e75ced46b693021218830ae86a82a71", 16)
+ ));
+
+ // attempt to augment it with values taken from gservices
+ String serialBlocklist = readBlocklist(path);
+ if (!serialBlocklist.equals("")) {
+ for(String value : serialBlocklist.split(",")) {
+ try {
+ bl.add(new BigInteger(value, 16));
+ } catch (NumberFormatException e) {
+ logger.log(Level.WARNING, "Tried to blocklist invalid serial number " + value, e);
+ }
+ }
+ }
+
+ // whether that succeeds or fails, send it on its merry way
+ return Collections.unmodifiableSet(bl);
+ }
+
+ private static Set<byte[]> readPublicKeyBlockList(String path) {
+
+ // start out with a base set of known bad values
+ Set<byte[]> bl = new HashSet<byte[]>(Arrays.asList(
+ // From http://src.chromium.org/viewvc/chrome/branches/782/src/net/base/x509_certificate.cc?r1=98750&r2=98749&pathrev=98750
+ // C=NL, O=DigiNotar, CN=DigiNotar Root CA/emailAddress=info@diginotar.nl
+ "410f36363258f30b347d12ce4863e433437806a8".getBytes(),
+ // Subject: CN=DigiNotar Cyber CA
+ // Issuer: CN=GTE CyberTrust Global Root
+ "ba3e7bd38cd7e1e6b9cd4c219962e59d7a2f4e37".getBytes(),
+ // Subject: CN=DigiNotar Services 1024 CA
+ // Issuer: CN=Entrust.net
+ "e23b8d105f87710a68d9248050ebefc627be4ca6".getBytes(),
+ // Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2
+ // Issuer: CN=Staat der Nederlanden Organisatie CA - G2
+ "7b2e16bc39bcd72b456e9f055d1de615b74945db".getBytes(),
+ // Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven
+ // Issuer: CN=Staat der Nederlanden Overheid CA
+ "e8f91200c65cee16e039b9f883841661635f81c5".getBytes(),
+ // From http://src.chromium.org/viewvc/chrome?view=rev&revision=108479
+ // Subject: O=Digicert Sdn. Bhd.
+ // Issuer: CN=GTE CyberTrust Global Root
+ "0129bcd5b448ae8d2496d1c3e19723919088e152".getBytes(),
+ // Subject: CN=e-islem.kktcmerkezbankasi.org/emailAddress=ileti@kktcmerkezbankasi.org
+ // Issuer: CN=T\xC3\x9CRKTRUST Elektronik Sunucu Sertifikas\xC4\xB1 Hizmetleri
+ "5f3ab33d55007054bc5e3e5553cd8d8465d77c61".getBytes(),
+ // Subject: CN=*.EGO.GOV.TR 93
+ // Issuer: CN=T\xC3\x9CRKTRUST Elektronik Sunucu Sertifikas\xC4\xB1 Hizmetleri
+ "783333c9687df63377efceddd82efa9101913e8e".getBytes(),
+ // Subject: Subject: C=FR, O=DG Tr\xC3\xA9sor, CN=AC DG Tr\xC3\xA9sor SSL
+ // Issuer: C=FR, O=DGTPE, CN=AC DGTPE Signature Authentification
+ "3ecf4bbbe46096d514bb539bb913d77aa4ef31bf".getBytes()
+ ));
+
+ // attempt to augment it with values taken from gservices
+ String pubkeyBlocklist = readBlocklist(path);
+ if (!pubkeyBlocklist.equals("")) {
+ for (String value : pubkeyBlocklist.split(",")) {
+ value = value.trim();
+ if (isPubkeyHash(value)) {
+ bl.add(value.getBytes());
+ } else {
+ logger.log(Level.WARNING, "Tried to blocklist invalid pubkey " + value);
+ }
+ }
+ }
+
+ return bl;
+ }
+
+ public boolean isPublicKeyBlockListed(PublicKey publicKey) {
+ byte[] encoded = publicKey.getEncoded();
+ Digest digest = AndroidDigestFactory.getSHA1();
+ digest.update(encoded, 0, encoded.length);
+ byte[] out = new byte[digest.getDigestSize()];
+ digest.doFinal(out, 0);
+ for (byte[] blocklisted : pubkeyBlocklist) {
+ if (Arrays.equals(blocklisted, Hex.encode(out))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean isSerialNumberBlockListed(BigInteger serial) {
+ return serialBlocklist.contains(serial);
+ }
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
new file mode 100644
index 00000000..e6aa3075
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
@@ -0,0 +1,1434 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.URI;
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.PublicKey;
+import java.security.cert.CRLException;
+import java.security.cert.CertPath;
+import java.security.cert.CertPathBuilderException;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.PolicyQualifierInfo;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.security.cert.X509CRLSelector;
+import java.security.cert.X509CertSelector;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPublicKey;
+import java.security.spec.DSAPublicKeySpec;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.internal.org.bouncycastle.asn1.ASN1GeneralizedTime;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1OutputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1String;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x500.style.RFC4519Style;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.CRLDistPoint;
+import com.android.internal.org.bouncycastle.asn1.x509.CRLReason;
+import com.android.internal.org.bouncycastle.asn1.x509.DistributionPoint;
+import com.android.internal.org.bouncycastle.asn1.x509.DistributionPointName;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+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.PolicyInformation;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.jcajce.PKIXCRLStore;
+import com.android.internal.org.bouncycastle.jcajce.PKIXCRLStoreSelector;
+import com.android.internal.org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
+import com.android.internal.org.bouncycastle.jcajce.PKIXCertStore;
+import com.android.internal.org.bouncycastle.jcajce.PKIXCertStoreSelector;
+import com.android.internal.org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
+import com.android.internal.org.bouncycastle.jcajce.PKIXExtendedParameters;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.jce.exception.ExtCertPathBuilderException;
+import com.android.internal.org.bouncycastle.jce.exception.ExtCertPathValidatorException;
+import com.android.internal.org.bouncycastle.util.Properties;
+import com.android.internal.org.bouncycastle.util.Selector;
+import com.android.internal.org.bouncycastle.util.Store;
+import com.android.internal.org.bouncycastle.util.StoreException;
+import com.android.internal.org.bouncycastle.x509.X509AttributeCertificate;
+import com.android.internal.org.bouncycastle.x509.extension.X509ExtensionUtil;
+
+class CertPathValidatorUtilities
+{
+ protected static final String CERTIFICATE_POLICIES = Extension.certificatePolicies.getId();
+ protected static final String BASIC_CONSTRAINTS = Extension.basicConstraints.getId();
+ protected static final String POLICY_MAPPINGS = Extension.policyMappings.getId();
+ protected static final String SUBJECT_ALTERNATIVE_NAME = Extension.subjectAlternativeName.getId();
+ protected static final String NAME_CONSTRAINTS = Extension.nameConstraints.getId();
+ protected static final String KEY_USAGE = Extension.keyUsage.getId();
+ protected static final String INHIBIT_ANY_POLICY = Extension.inhibitAnyPolicy.getId();
+ protected static final String ISSUING_DISTRIBUTION_POINT = Extension.issuingDistributionPoint.getId();
+ protected static final String DELTA_CRL_INDICATOR = Extension.deltaCRLIndicator.getId();
+ protected static final String POLICY_CONSTRAINTS = Extension.policyConstraints.getId();
+ protected static final String FRESHEST_CRL = Extension.freshestCRL.getId();
+ protected static final String CRL_DISTRIBUTION_POINTS = Extension.cRLDistributionPoints.getId();
+ protected static final String AUTHORITY_KEY_IDENTIFIER = Extension.authorityKeyIdentifier.getId();
+
+ protected static final String ANY_POLICY = "2.5.29.32.0";
+
+ protected static final String CRL_NUMBER = Extension.cRLNumber.getId();
+
+ /*
+ * key usage bits
+ */
+ protected static final int KEY_CERT_SIGN = 5;
+ protected static final int CRL_SIGN = 6;
+
+ protected static final String[] crlReasons = new String[]{
+ "unspecified",
+ "keyCompromise",
+ "cACompromise",
+ "affiliationChanged",
+ "superseded",
+ "cessationOfOperation",
+ "certificateHold",
+ "unknown",
+ "removeFromCRL",
+ "privilegeWithdrawn",
+ "aACompromise"};
+
+ static Collection findTargets(PKIXExtendedBuilderParameters paramsPKIX) throws CertPathBuilderException
+ {
+ PKIXExtendedParameters baseParams = paramsPKIX.getBaseParameters();
+ PKIXCertStoreSelector certSelect = baseParams.getTargetConstraints();
+ LinkedHashSet targets = new LinkedHashSet();
+
+ try
+ {
+ CertPathValidatorUtilities.findCertificates(targets, certSelect, baseParams.getCertificateStores());
+ CertPathValidatorUtilities.findCertificates(targets, certSelect, baseParams.getCertStores());
+ }
+ catch (AnnotatedException e)
+ {
+ throw new ExtCertPathBuilderException("Error finding target certificate.", e);
+ }
+
+ if (!targets.isEmpty())
+ {
+ return targets;
+ }
+
+ Certificate target = certSelect.getCertificate();
+ if (null == target)
+ {
+ throw new CertPathBuilderException("No certificate found matching targetConstraints.");
+ }
+
+ return Collections.singleton(target);
+ }
+
+ /**
+ * Search the given Set of TrustAnchor's for one that is the
+ * issuer of the given X509 certificate. Uses the default provider
+ * for signature verification.
+ *
+ * @param cert the X509 certificate
+ * @param trustAnchors a Set of TrustAnchor's
+ * @return the <code>TrustAnchor</code> object if found or
+ * <code>null</code> if not.
+ * @throws AnnotatedException if a TrustAnchor was found but the signature verification
+ * on the given certificate has thrown an exception.
+ */
+ protected static TrustAnchor findTrustAnchor(
+ X509Certificate cert,
+ Set trustAnchors)
+ throws AnnotatedException
+ {
+ return findTrustAnchor(cert, trustAnchors, null);
+ }
+
+ /**
+ * Search the given Set of TrustAnchor's for one that is the
+ * issuer of the given X509 certificate. Uses the specified
+ * provider for signature verification, or the default provider
+ * if null.
+ *
+ * @param cert the X509 certificate
+ * @param trustAnchors a Set of TrustAnchor's
+ * @param sigProvider the provider to use for signature verification
+ * @return the <code>TrustAnchor</code> object if found or
+ * <code>null</code> if not.
+ * @throws AnnotatedException if a TrustAnchor was found but the signature verification
+ * on the given certificate has thrown an exception.
+ */
+ protected static TrustAnchor findTrustAnchor(
+ X509Certificate cert,
+ Set trustAnchors,
+ String sigProvider)
+ throws AnnotatedException
+ {
+ TrustAnchor trust = null;
+ PublicKey trustPublicKey = null;
+ Exception invalidKeyEx = null;
+
+ X509CertSelector certSelectX509 = new X509CertSelector();
+
+ final X500Principal certIssuerPrincipal = cert.getIssuerX500Principal();
+ certSelectX509.setSubject(certIssuerPrincipal);
+
+ X500Name certIssuerName = null;
+
+ Iterator iter = trustAnchors.iterator();
+ while (iter.hasNext() && trust == null)
+ {
+ trust = (TrustAnchor)iter.next();
+ if (trust.getTrustedCert() != null)
+ {
+ if (certSelectX509.match(trust.getTrustedCert()))
+ {
+ trustPublicKey = trust.getTrustedCert().getPublicKey();
+ }
+ else
+ {
+ trust = null;
+ }
+ }
+ else if (trust.getCA() != null
+ && trust.getCAName() != null
+ && trust.getCAPublicKey() != null)
+ {
+ if (certIssuerName == null)
+ {
+ certIssuerName = X500Name.getInstance(certIssuerPrincipal.getEncoded());
+ }
+
+ try
+ {
+ X500Name caName = X500Name.getInstance(trust.getCA().getEncoded());
+
+ if (certIssuerName.equals(caName))
+ {
+ trustPublicKey = trust.getCAPublicKey();
+ }
+ else
+ {
+ trust = null;
+ }
+ }
+ catch (IllegalArgumentException ex)
+ {
+ trust = null;
+ }
+ }
+ else
+ {
+ trust = null;
+ }
+
+ if (trustPublicKey != null)
+ {
+ try
+ {
+ verifyX509Certificate(cert, trustPublicKey, sigProvider);
+ }
+ catch (Exception ex)
+ {
+ invalidKeyEx = ex;
+ trust = null;
+ trustPublicKey = null;
+ }
+ }
+ }
+
+ if (trust == null && invalidKeyEx != null)
+ {
+ throw new AnnotatedException("TrustAnchor found but certificate validation failed.", invalidKeyEx);
+ }
+
+ return trust;
+ }
+
+ static boolean isIssuerTrustAnchor(
+ X509Certificate cert,
+ Set trustAnchors,
+ String sigProvider)
+ throws AnnotatedException
+ {
+ try
+ {
+ return findTrustAnchor(cert, trustAnchors, sigProvider) != null;
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ }
+
+ static List<PKIXCertStore> getAdditionalStoresFromAltNames(
+ byte[] issuerAlternativeName,
+ Map<GeneralName, PKIXCertStore> altNameCertStoreMap)
+ throws CertificateParsingException
+ {
+ // if in the IssuerAltName extension an URI
+ // is given, add an additional X.509 store
+ if (issuerAlternativeName == null)
+ {
+ return Collections.EMPTY_LIST;
+ }
+
+ GeneralNames issuerAltName = GeneralNames.getInstance(ASN1OctetString.getInstance(issuerAlternativeName).getOctets());
+
+ GeneralName[] names = issuerAltName.getNames();
+ List<PKIXCertStore> stores = new ArrayList<PKIXCertStore>();
+
+ for (int i = 0; i != names.length; i++)
+ {
+ GeneralName altName = names[i];
+
+ PKIXCertStore altStore = altNameCertStoreMap.get(altName);
+ if (altStore != null)
+ {
+ stores.add(altStore);
+ }
+ }
+
+ return stores;
+ }
+
+ protected static Date getValidityDate(PKIXExtendedParameters paramsPKIX, Date currentDate)
+ {
+ Date validityDate = paramsPKIX.getValidityDate();
+
+ return null == validityDate ? currentDate : validityDate;
+ }
+
+ protected static boolean isSelfIssued(X509Certificate cert)
+ {
+ return cert.getSubjectDN().equals(cert.getIssuerDN());
+ }
+
+ /**
+ * Extract the value of the given extension, if it exists.
+ *
+ * @param ext The extension object.
+ * @param oid The object identifier to obtain.
+ * @throws AnnotatedException if the extension cannot be read.
+ */
+ protected static ASN1Primitive getExtensionValue(java.security.cert.X509Extension ext, String oid)
+ throws AnnotatedException
+ {
+ byte[] bytes = ext.getExtensionValue(oid);
+
+ return null == bytes ? null : getObject(oid, bytes);
+ }
+
+ private static ASN1Primitive getObject(String oid, byte[] ext) throws AnnotatedException
+ {
+ try
+ {
+ ASN1OctetString octs = ASN1OctetString.getInstance(ext);
+
+ return ASN1Primitive.fromByteArray(octs.getOctets());
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("exception processing extension " + oid, e);
+ }
+ }
+
+ protected static AlgorithmIdentifier getAlgorithmIdentifier(PublicKey key) throws CertPathValidatorException
+ {
+ try
+ {
+ return SubjectPublicKeyInfo.getInstance(key.getEncoded()).getAlgorithm();
+ }
+ catch (Exception e)
+ {
+ throw new ExtCertPathValidatorException("Subject public key cannot be decoded.", e);
+ }
+ }
+
+ // crl checking
+
+
+ //
+ // policy checking
+ //
+
+ protected static final Set getQualifierSet(ASN1Sequence qualifiers)
+ throws CertPathValidatorException
+ {
+ Set pq = new HashSet();
+
+ if (qualifiers == null)
+ {
+ return pq;
+ }
+
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ ASN1OutputStream aOut = ASN1OutputStream.create(bOut);
+
+ Enumeration e = qualifiers.getObjects();
+ while (e.hasMoreElements())
+ {
+ try
+ {
+ aOut.writeObject((ASN1Encodable)e.nextElement());
+
+ pq.add(new PolicyQualifierInfo(bOut.toByteArray()));
+ }
+ catch (IOException ex)
+ {
+ throw new ExtCertPathValidatorException("Policy qualifier info cannot be decoded.", ex);
+ }
+
+ bOut.reset();
+ }
+
+ return pq;
+ }
+
+ protected static PKIXPolicyNode removePolicyNode(
+ PKIXPolicyNode validPolicyTree,
+ List[] policyNodes,
+ PKIXPolicyNode _node)
+ {
+ PKIXPolicyNode _parent = (PKIXPolicyNode)_node.getParent();
+
+ if (validPolicyTree == null)
+ {
+ return null;
+ }
+
+ if (_parent == null)
+ {
+ for (int j = 0; j < policyNodes.length; j++)
+ {
+ policyNodes[j] = new ArrayList();
+ }
+
+ return null;
+ }
+ else
+ {
+ _parent.removeChild(_node);
+ removePolicyNodeRecurse(policyNodes, _node);
+
+ return validPolicyTree;
+ }
+ }
+
+ private static void removePolicyNodeRecurse(
+ List[] policyNodes,
+ PKIXPolicyNode _node)
+ {
+ policyNodes[_node.getDepth()].remove(_node);
+
+ if (_node.hasChildren())
+ {
+ Iterator _iter = _node.getChildren();
+ while (_iter.hasNext())
+ {
+ PKIXPolicyNode _child = (PKIXPolicyNode)_iter.next();
+ removePolicyNodeRecurse(policyNodes, _child);
+ }
+ }
+ }
+
+
+ protected static boolean processCertD1i(
+ int index,
+ List[] policyNodes,
+ ASN1ObjectIdentifier pOid,
+ Set pq)
+ {
+ List policyNodeVec = policyNodes[index - 1];
+
+ for (int j = 0; j < policyNodeVec.size(); j++)
+ {
+ PKIXPolicyNode node = (PKIXPolicyNode)policyNodeVec.get(j);
+ Set expectedPolicies = node.getExpectedPolicies();
+
+ if (expectedPolicies.contains(pOid.getId()))
+ {
+ Set childExpectedPolicies = new HashSet();
+ childExpectedPolicies.add(pOid.getId());
+
+ PKIXPolicyNode child = new PKIXPolicyNode(new ArrayList(),
+ index,
+ childExpectedPolicies,
+ node,
+ pq,
+ pOid.getId(),
+ false);
+ node.addChild(child);
+ policyNodes[index].add(child);
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ protected static void processCertD1ii(
+ int index,
+ List[] policyNodes,
+ ASN1ObjectIdentifier _poid,
+ Set _pq)
+ {
+ List policyNodeVec = policyNodes[index - 1];
+
+ for (int j = 0; j < policyNodeVec.size(); j++)
+ {
+ PKIXPolicyNode _node = (PKIXPolicyNode)policyNodeVec.get(j);
+
+ if (ANY_POLICY.equals(_node.getValidPolicy()))
+ {
+ Set _childExpectedPolicies = new HashSet();
+ _childExpectedPolicies.add(_poid.getId());
+
+ PKIXPolicyNode _child = new PKIXPolicyNode(new ArrayList(),
+ index,
+ _childExpectedPolicies,
+ _node,
+ _pq,
+ _poid.getId(),
+ false);
+ _node.addChild(_child);
+ policyNodes[index].add(_child);
+ return;
+ }
+ }
+ }
+
+ protected static void prepareNextCertB1(
+ int i,
+ List[] policyNodes,
+ String id_p,
+ Map m_idp,
+ X509Certificate cert
+ )
+ throws AnnotatedException, CertPathValidatorException
+ {
+ boolean idp_found = false;
+ Iterator nodes_i = policyNodes[i].iterator();
+ while (nodes_i.hasNext())
+ {
+ PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
+ if (node.getValidPolicy().equals(id_p))
+ {
+ idp_found = true;
+ node.expectedPolicies = (Set)m_idp.get(id_p);
+ break;
+ }
+ }
+
+ if (!idp_found)
+ {
+ nodes_i = policyNodes[i].iterator();
+ while (nodes_i.hasNext())
+ {
+ PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
+ if (ANY_POLICY.equals(node.getValidPolicy()))
+ {
+ Set pq = null;
+ ASN1Sequence policies = null;
+ try
+ {
+ policies = DERSequence.getInstance(getExtensionValue(cert, CERTIFICATE_POLICIES));
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("Certificate policies cannot be decoded.", e);
+ }
+ Enumeration e = policies.getObjects();
+ while (e.hasMoreElements())
+ {
+ PolicyInformation pinfo = null;
+
+ try
+ {
+ pinfo = PolicyInformation.getInstance(e.nextElement());
+ }
+ catch (Exception ex)
+ {
+ throw new AnnotatedException("Policy information cannot be decoded.", ex);
+ }
+ if (ANY_POLICY.equals(pinfo.getPolicyIdentifier().getId()))
+ {
+ try
+ {
+ pq = getQualifierSet(pinfo.getPolicyQualifiers());
+ }
+ catch (CertPathValidatorException ex)
+ {
+ throw new ExtCertPathValidatorException(
+ "Policy qualifier info set could not be built.", ex);
+ }
+ break;
+ }
+ }
+ boolean ci = false;
+ if (cert.getCriticalExtensionOIDs() != null)
+ {
+ ci = cert.getCriticalExtensionOIDs().contains(CERTIFICATE_POLICIES);
+ }
+
+ PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent();
+ if (ANY_POLICY.equals(p_node.getValidPolicy()))
+ {
+ PKIXPolicyNode c_node = new PKIXPolicyNode(
+ new ArrayList(), i,
+ (Set)m_idp.get(id_p),
+ p_node, pq, id_p, ci);
+ p_node.addChild(c_node);
+ policyNodes[i].add(c_node);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ protected static PKIXPolicyNode prepareNextCertB2(
+ int i,
+ List[] policyNodes,
+ String id_p,
+ PKIXPolicyNode validPolicyTree)
+ {
+ Iterator nodes_i = policyNodes[i].iterator();
+ while (nodes_i.hasNext())
+ {
+ PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
+ if (node.getValidPolicy().equals(id_p))
+ {
+ PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent();
+ p_node.removeChild(node);
+ nodes_i.remove();
+ for (int k = (i - 1); k >= 0; k--)
+ {
+ List nodes = policyNodes[k];
+ for (int l = 0; l < nodes.size(); l++)
+ {
+ PKIXPolicyNode node2 = (PKIXPolicyNode)nodes.get(l);
+ if (!node2.hasChildren())
+ {
+ validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node2);
+ if (validPolicyTree == null)
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return validPolicyTree;
+ }
+
+ protected static boolean isAnyPolicy(
+ Set policySet)
+ {
+ return policySet == null || policySet.contains(ANY_POLICY) || policySet.isEmpty();
+ }
+
+ /**
+ * Return a Collection of all certificates or attribute certificates found in the X509Store's
+ * that are matching the certSelect criteriums.
+ *
+ * @param certs
+ * a {@link LinkedHashSet} to which the certificates will be added.
+ * @param certSelect
+ * a {@link Selector} object that will be used to select the certificates
+ * @param certStores
+ * a List containing only {@link Store} objects. These are used to search for
+ * certificates.
+ * @return a Collection of all found {@link X509Certificate} May be empty but never
+ * <code>null</code>.
+ */
+ protected static void findCertificates(LinkedHashSet certs, PKIXCertStoreSelector certSelect, List certStores)
+ throws AnnotatedException
+ {
+ Iterator iter = certStores.iterator();
+ while (iter.hasNext())
+ {
+ Object obj = iter.next();
+
+ // BEGIN Android-removed: Unknown reason
+ /*
+ if (obj instanceof Store)
+ {
+ Store certStore = (Store)obj;
+ try
+ {
+ certs.addAll(certStore.getMatches(certSelect));
+ }
+ catch (StoreException e)
+ {
+ throw new AnnotatedException("Problem while picking certificates from X.509 store.", e);
+ }
+ }
+ else
+ */
+ // END Android-removed: Unknown reason
+ {
+ CertStore certStore = (CertStore)obj;
+ try
+ {
+ certs.addAll(PKIXCertStoreSelector.getCertificates(certSelect, certStore));
+ }
+ catch (CertStoreException e)
+ {
+ throw new AnnotatedException("Problem while picking certificates from certificate store.", e);
+ }
+ }
+ }
+ }
+
+ static List<PKIXCRLStore> getAdditionalStoresFromCRLDistributionPoint(
+ CRLDistPoint crldp, Map<GeneralName, PKIXCRLStore> namedCRLStoreMap, Date validDate, JcaJceHelper helper)
+ throws AnnotatedException
+ {
+ if (null == crldp)
+ {
+ return Collections.EMPTY_LIST;
+ }
+
+ DistributionPoint dps[];
+ try
+ {
+ dps = crldp.getDistributionPoints();
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("Distribution points could not be read.", e);
+ }
+
+ List<PKIXCRLStore> stores = new ArrayList<PKIXCRLStore>();
+
+ for (int i = 0; i < dps.length; i++)
+ {
+ DistributionPointName dpn = dps[i].getDistributionPoint();
+ // look for URIs in fullName
+ if (dpn != null && dpn.getType() == DistributionPointName.FULL_NAME)
+ {
+ GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames();
+
+ for (int j = 0; j < genNames.length; j++)
+ {
+ PKIXCRLStore store = namedCRLStoreMap.get(genNames[j]);
+ if (store != null)
+ {
+ stores.add(store);
+ }
+ }
+ }
+ }
+
+ // if the named CRL store is empty, and we're told to check with CRLDP
+ if (stores.isEmpty() && Properties.isOverrideSet("com.android.internal.org.bouncycastle.x509.enableCRLDP"))
+ {
+ CertificateFactory certFact;
+ try
+ {
+ certFact = helper.createCertificateFactory("X.509");
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("cannot create certificate factory: " + e.getMessage(), e);
+ }
+
+ for (int i = 0; i < dps.length; i++)
+ {
+ DistributionPointName dpn = dps[i].getDistributionPoint();
+ // look for URIs in fullName
+ if (dpn != null && dpn.getType() == DistributionPointName.FULL_NAME)
+ {
+ GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames();
+
+ for (int j = 0; j < genNames.length; j++)
+ {
+ GeneralName name = genNames[i];
+ if (name.getTagNo() == GeneralName.uniformResourceIdentifier)
+ {
+ try
+ {
+ // BEGIN Android-removed
+ /*
+ URI distributionPoint = new URI(((ASN1String)name.getName()).getString());
+ PKIXCRLStore store = CrlCache.getCrl(certFact, validDate, distributionPoint);
+ if (store != null)
+ {
+ stores.add(store);
+ }
+ */
+ // END Android-removed
+ break;
+ }
+ catch (Exception e)
+ {
+ // ignore... TODO: maybe log
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return stores;
+ }
+
+ /**
+ * Add the CRL issuers from the cRLIssuer field of the distribution point or
+ * from the certificate if not given to the issuer criterion of the
+ * <code>selector</code>.
+ * <p>
+ * The <code>issuerPrincipals</code> are a collection with a single
+ * <code>X500Name</code> for <code>X509Certificate</code>s.
+ * </p>
+ * @param dp The distribution point.
+ * @param issuerPrincipals The issuers of the certificate or attribute
+ * certificate which contains the distribution point.
+ * @param selector The CRL selector.
+ * @throws AnnotatedException if an exception occurs while processing.
+ * @throws ClassCastException if <code>issuerPrincipals</code> does not
+ * contain only <code>X500Name</code>s.
+ */
+ protected static void getCRLIssuersFromDistributionPoint(
+ DistributionPoint dp,
+ Collection issuerPrincipals,
+ X509CRLSelector selector)
+ throws AnnotatedException
+ {
+ List issuers = new ArrayList();
+ // indirect CRL
+ if (dp.getCRLIssuer() != null)
+ {
+ GeneralName genNames[] = dp.getCRLIssuer().getNames();
+ // look for a DN
+ for (int j = 0; j < genNames.length; j++)
+ {
+ if (genNames[j].getTagNo() == GeneralName.directoryName)
+ {
+ try
+ {
+ issuers.add(X500Name.getInstance(genNames[j].getName().toASN1Primitive().getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new AnnotatedException(
+ "CRL issuer information from distribution point cannot be decoded.", e);
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * certificate issuer is CRL issuer, distributionPoint field MUST be
+ * present.
+ */
+ if (dp.getDistributionPoint() == null)
+ {
+ throw new AnnotatedException(
+ "CRL issuer is omitted from distribution point but no distributionPoint field present.");
+ }
+ // add and check issuer principals
+ for (Iterator it = issuerPrincipals.iterator(); it.hasNext(); )
+ {
+ issuers.add(it.next());
+ }
+ }
+ // TODO: is not found although this should correctly add the rel name. selector of Sun is buggy here or PKI test case is invalid
+ // distributionPoint
+// if (dp.getDistributionPoint() != null)
+// {
+// // look for nameRelativeToCRLIssuer
+// if (dp.getDistributionPoint().getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER)
+// {
+// // append fragment to issuer, only one
+// // issuer can be there, if this is given
+// if (issuers.size() != 1)
+// {
+// throw new AnnotatedException(
+// "nameRelativeToCRLIssuer field is given but more than one CRL issuer is given.");
+// }
+// ASN1Encodable relName = dp.getDistributionPoint().getName();
+// Iterator it = issuers.iterator();
+// List issuersTemp = new ArrayList(issuers.size());
+// while (it.hasNext())
+// {
+// Enumeration e = null;
+// try
+// {
+// e = ASN1Sequence.getInstance(
+// new ASN1InputStream(((X500Principal) it.next())
+// .getEncoded()).readObject()).getObjects();
+// }
+// catch (IOException ex)
+// {
+// throw new AnnotatedException(
+// "Cannot decode CRL issuer information.", ex);
+// }
+// ASN1EncodableVector v = new ASN1EncodableVector();
+// while (e.hasMoreElements())
+// {
+// v.add((ASN1Encodable) e.nextElement());
+// }
+// v.add(relName);
+// issuersTemp.add(new X500Principal(new DERSequence(v)
+// .getDEREncoded()));
+// }
+// issuers.clear();
+// issuers.addAll(issuersTemp);
+// }
+// }
+ Iterator it = issuers.iterator();
+ while (it.hasNext())
+ {
+ try
+ {
+ selector.addIssuerName(((X500Name)it.next()).getEncoded());
+ }
+ catch (IOException ex)
+ {
+ throw new AnnotatedException(
+ "Cannot decode CRL issuer information.", ex);
+ }
+ }
+ }
+
+ private static BigInteger getSerialNumber(Object cert)
+ {
+ return ((X509Certificate)cert).getSerialNumber();
+ }
+
+ protected static void getCertStatus(
+ Date validDate,
+ X509CRL crl,
+ Object cert,
+ CertStatus certStatus)
+ throws AnnotatedException
+ {
+ boolean isIndirect;
+ try
+ {
+ isIndirect = X509CRLObject.isIndirectCRL(crl);
+ }
+ catch (CRLException exception)
+ {
+ throw new AnnotatedException("Failed check for indirect CRL.", exception);
+ }
+
+ X509CRLEntry crl_entry;
+ if (isIndirect)
+ {
+ crl_entry = crl.getRevokedCertificate(getSerialNumber(cert));
+
+ if (crl_entry == null)
+ {
+ return;
+ }
+
+ X500Principal certificateIssuer = crl_entry.getCertificateIssuer();
+
+ X500Name certIssuer;
+ if (certificateIssuer == null)
+ {
+ certIssuer = PrincipalUtils.getIssuerPrincipal(crl);
+ }
+ else
+ {
+ certIssuer = PrincipalUtils.getX500Name(certificateIssuer);
+ }
+
+ if (!PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(certIssuer))
+ {
+ return;
+ }
+ }
+ else if (!PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(PrincipalUtils.getIssuerPrincipal(crl)))
+ {
+ return; // not for our issuer, ignore
+ }
+ else
+ {
+ crl_entry = crl.getRevokedCertificate(getSerialNumber(cert));
+
+ if (crl_entry == null)
+ {
+ return;
+ }
+ }
+
+ ASN1Enumerated reasonCode = null;
+ if (crl_entry.hasExtensions())
+ {
+ if (crl_entry.hasUnsupportedCriticalExtension())
+ {
+ throw new AnnotatedException("CRL entry has unsupported critical extensions.");
+ }
+
+ try
+ {
+ reasonCode = ASN1Enumerated
+ .getInstance(CertPathValidatorUtilities.getExtensionValue(crl_entry, Extension.reasonCode.getId()));
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("Reason code CRL entry extension could not be decoded.", e);
+ }
+ }
+
+ int reasonCodeValue = (null == reasonCode)
+ ? CRLReason.unspecified
+ : reasonCode.intValueExact();
+
+ // for reason keyCompromise, caCompromise, aACompromise or unspecified
+ if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime())
+ || reasonCodeValue == CRLReason.unspecified
+ || reasonCodeValue == CRLReason.keyCompromise
+ || reasonCodeValue == CRLReason.cACompromise
+ || reasonCodeValue == CRLReason.aACompromise)
+ {
+ // (i) or (j)
+ certStatus.setCertStatus(reasonCodeValue);
+ certStatus.setRevocationDate(crl_entry.getRevocationDate());
+ }
+ }
+
+ /**
+ * Fetches delta CRLs according to RFC 3280 section 5.2.4.
+ *
+ * @param validityDate The date for which the delta CRLs must be valid.
+ * @param completeCRL The complete CRL the delta CRL is for.
+ * @return A <code>Set</code> of <code>X509CRL</code>s with delta CRLs.
+ * @throws AnnotatedException if an exception occurs while picking the delta
+ * CRLs.
+ */
+ protected static Set getDeltaCRLs(Date validityDate,
+ X509CRL completeCRL,
+ List<CertStore> certStores,
+ List<PKIXCRLStore> pkixCrlStores,
+ JcaJceHelper helper)
+ throws AnnotatedException
+ {
+ X509CRLSelector baseDeltaSelect = new X509CRLSelector();
+ // 5.2.4 (a)
+ try
+ {
+ baseDeltaSelect.addIssuerName(PrincipalUtils.getIssuerPrincipal(completeCRL).getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new AnnotatedException("Cannot extract issuer from CRL.", e);
+ }
+
+ BigInteger completeCRLNumber = null;
+ try
+ {
+ ASN1Primitive derObject = CertPathValidatorUtilities.getExtensionValue(completeCRL, CRL_NUMBER);
+ if (derObject != null)
+ {
+ completeCRLNumber = ASN1Integer.getInstance(derObject).getPositiveValue();
+ }
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException(
+ "CRL number extension could not be extracted from CRL.", e);
+ }
+
+ // 5.2.4 (b)
+ byte[] idp;
+ try
+ {
+ idp = completeCRL.getExtensionValue(ISSUING_DISTRIBUTION_POINT);
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("Issuing distribution point extension value could not be read.", e);
+ }
+
+ // 5.2.4 (d)
+
+ baseDeltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber.add(BigInteger.valueOf(1)));
+
+ PKIXCRLStoreSelector.Builder selBuilder = new PKIXCRLStoreSelector.Builder(baseDeltaSelect);
+
+ selBuilder.setIssuingDistributionPoint(idp);
+ selBuilder.setIssuingDistributionPointEnabled(true);
+
+ // 5.2.4 (c)
+ selBuilder.setMaxBaseCRLNumber(completeCRLNumber);
+
+ PKIXCRLStoreSelector deltaSelect = selBuilder.build();
+
+ // find delta CRLs
+ Set temp = PKIXCRLUtil.findCRLs(deltaSelect, validityDate, certStores, pkixCrlStores);
+
+ // if the named CRL store is empty, and we're told to check with CRLDP
+ if (temp.isEmpty() && Properties.isOverrideSet("com.android.internal.org.bouncycastle.x509.enableCRLDP"))
+ {
+ CertificateFactory certFact;
+ try
+ {
+ certFact = helper.createCertificateFactory("X.509");
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("cannot create certificate factory: " + e.getMessage(), e);
+ }
+
+ CRLDistPoint id = CRLDistPoint.getInstance(idp);
+ DistributionPoint[] dps = id.getDistributionPoints();
+ for (int i = 0; i < dps.length; i++)
+ {
+ DistributionPointName dpn = dps[i].getDistributionPoint();
+ // look for URIs in fullName
+ if (dpn != null && dpn.getType() == DistributionPointName.FULL_NAME)
+ {
+ GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames();
+
+ for (int j = 0; j < genNames.length; j++)
+ {
+ GeneralName name = genNames[i];
+ if (name.getTagNo() == GeneralName.uniformResourceIdentifier)
+ {
+ try
+ {
+ // BEGIN Android-removed
+ /*
+ PKIXCRLStore store = CrlCache.getCrl(certFact, validityDate,
+ new URI(((ASN1String)name.getName()).getString()));
+ if (store != null)
+ {
+ temp = PKIXCRLUtil.findCRLs(deltaSelect, validityDate, Collections.EMPTY_LIST,
+ Collections.singletonList(store));
+ }
+ */
+ // END Android-removed
+ break;
+ }
+ catch (Exception e)
+ {
+ // ignore... TODO: maybe log
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Set result = new HashSet();
+
+ for (Iterator it = temp.iterator(); it.hasNext(); )
+ {
+ X509CRL crl = (X509CRL)it.next();
+
+ if (isDeltaCRL(crl))
+ {
+ result.add(crl);
+ }
+ }
+
+ return result;
+ }
+
+ private static boolean isDeltaCRL(X509CRL crl)
+ {
+ Set critical = crl.getCriticalExtensionOIDs();
+
+ if (critical == null)
+ {
+ return false;
+ }
+
+ return critical.contains(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR);
+ }
+
+ /**
+ * Fetches complete CRLs according to RFC 3280.
+ *
+ * @param dp The distribution point for which the complete CRL
+ * @param cert The <code>X509Certificate</code> for
+ * which the CRL should be searched.
+ * @param currentDate The date for which the delta CRLs must be valid.
+ * @param paramsPKIX The extended PKIX parameters.
+ * @return A <code>Set</code> of <code>X509CRL</code>s with complete
+ * CRLs.
+ * @throws AnnotatedException if an exception occurs while picking the CRLs
+ * or no CRLs are found.
+ */
+ protected static Set getCompleteCRLs(PKIXCertRevocationCheckerParameters params, DistributionPoint dp, Object cert,
+ PKIXExtendedParameters paramsPKIX, Date validityDate)
+ throws AnnotatedException, RecoverableCertPathValidatorException
+ {
+ X509CRLSelector baseCrlSelect = new X509CRLSelector();
+
+ try
+ {
+ Set issuers = new HashSet();
+ issuers.add(PrincipalUtils.getEncodedIssuerPrincipal(cert));
+
+ CertPathValidatorUtilities.getCRLIssuersFromDistributionPoint(dp, issuers, baseCrlSelect);
+ }
+ catch (AnnotatedException e)
+ {
+ throw new AnnotatedException("Could not get issuer information from distribution point.", e);
+ }
+
+ if (cert instanceof X509Certificate)
+ {
+ baseCrlSelect.setCertificateChecking((X509Certificate)cert);
+ }
+
+ PKIXCRLStoreSelector crlSelect = new PKIXCRLStoreSelector.Builder(baseCrlSelect).setCompleteCRLEnabled(true)
+ .build();
+
+ Set crls = PKIXCRLUtil.findCRLs(crlSelect, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores());
+
+ checkCRLsNotEmpty(params, crls, cert);
+
+ return crls;
+ }
+
+ protected static Date getValidCertDateFromValidityModel(Date validityDate, int validityModel, CertPath certPath,
+ int index) throws AnnotatedException
+ {
+ if (PKIXExtendedParameters.CHAIN_VALIDITY_MODEL != validityModel || index <= 0)
+ {
+ // use given signing/encryption/... time (or current date)
+ return validityDate;
+ }
+
+ X509Certificate issuedCert = (X509Certificate)certPath.getCertificates().get(index - 1);
+
+ if (index - 1 == 0)
+ {
+ // use time when cert was issued, if available
+ ASN1GeneralizedTime dateOfCertgen = null;
+ try
+ {
+ byte[] extBytes = ((X509Certificate)certPath.getCertificates().get(index - 1))
+ .getExtensionValue(ISISMTTObjectIdentifiers.id_isismtt_at_dateOfCertGen.getId());
+ if (extBytes != null)
+ {
+ dateOfCertgen = ASN1GeneralizedTime.getInstance(ASN1Primitive.fromByteArray(extBytes));
+ }
+ }
+ catch (IOException e)
+ {
+ throw new AnnotatedException("Date of cert gen extension could not be read.");
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new AnnotatedException("Date of cert gen extension could not be read.");
+ }
+ if (dateOfCertgen != null)
+ {
+ try
+ {
+ return dateOfCertgen.getDate();
+ }
+ catch (ParseException e)
+ {
+ throw new AnnotatedException("Date from date of cert gen extension could not be parsed.", e);
+ }
+ }
+ }
+
+ return issuedCert.getNotBefore();
+ }
+
+ /**
+ * Return the next working key inheriting DSA parameters if necessary.
+ * <p>
+ * This methods inherits DSA parameters from the indexed certificate or
+ * previous certificates in the certificate chain to the returned
+ * <code>PublicKey</code>. The list is searched upwards, meaning the end
+ * certificate is at position 0 and previous certificates are following.
+ * </p>
+ * <p>
+ * If the indexed certificate does not contain a DSA key this method simply
+ * returns the public key. If the DSA key already contains DSA parameters
+ * the key is also only returned.
+ * </p>
+ *
+ * @param certs The certification path.
+ * @param index The index of the certificate which contains the public key
+ * which should be extended with DSA parameters.
+ * @return The public key of the certificate in list position
+ * <code>index</code> extended with DSA parameters if applicable.
+ * @throws AnnotatedException if DSA parameters cannot be inherited.
+ */
+ protected static PublicKey getNextWorkingKey(List certs, int index, JcaJceHelper helper)
+ throws CertPathValidatorException
+ {
+ Certificate cert = (Certificate)certs.get(index);
+ PublicKey pubKey = cert.getPublicKey();
+ if (!(pubKey instanceof DSAPublicKey))
+ {
+ return pubKey;
+ }
+ DSAPublicKey dsaPubKey = (DSAPublicKey)pubKey;
+ if (dsaPubKey.getParams() != null)
+ {
+ return dsaPubKey;
+ }
+ for (int i = index + 1; i < certs.size(); i++)
+ {
+ X509Certificate parentCert = (X509Certificate)certs.get(i);
+ pubKey = parentCert.getPublicKey();
+ if (!(pubKey instanceof DSAPublicKey))
+ {
+ throw new CertPathValidatorException(
+ "DSA parameters cannot be inherited from previous certificate.");
+ }
+ DSAPublicKey prevDSAPubKey = (DSAPublicKey)pubKey;
+ if (prevDSAPubKey.getParams() == null)
+ {
+ continue;
+ }
+ DSAParams dsaParams = prevDSAPubKey.getParams();
+ DSAPublicKeySpec dsaPubKeySpec = new DSAPublicKeySpec(
+ dsaPubKey.getY(), dsaParams.getP(), dsaParams.getQ(), dsaParams.getG());
+ try
+ {
+ KeyFactory keyFactory = helper.createKeyFactory("DSA");
+ return keyFactory.generatePublic(dsaPubKeySpec);
+ }
+ catch (Exception exception)
+ {
+ throw new RuntimeException(exception.getMessage());
+ }
+ }
+ throw new CertPathValidatorException("DSA parameters cannot be inherited from previous certificate.");
+ }
+
+ /**
+ * Find the issuer certificates of a given certificate.
+ *
+ * @param cert The certificate for which an issuer should be found.
+ * @return A <code>Collection</code> object containing the issuer
+ * <code>X509Certificate</code>s. Never <code>null</code>.
+ * @throws AnnotatedException if an error occurs.
+ */
+ static Collection findIssuerCerts(
+ X509Certificate cert,
+ List<CertStore> certStores,
+ List<PKIXCertStore> pkixCertStores)
+ throws AnnotatedException
+ {
+ X509CertSelector selector = new X509CertSelector();
+
+ try
+ {
+ selector.setSubject(PrincipalUtils.getIssuerPrincipal(cert).getEncoded());
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException(
+ "Subject criteria for certificate selector to find issuer certificate could not be set.", e);
+ }
+
+ try
+ {
+ byte[] akiExtensionValue = cert.getExtensionValue(AUTHORITY_KEY_IDENTIFIER);
+ if (akiExtensionValue != null)
+ {
+ ASN1OctetString aki = ASN1OctetString.getInstance(akiExtensionValue);
+ byte[] authorityKeyIdentifier = AuthorityKeyIdentifier.getInstance(aki.getOctets()).getKeyIdentifier();
+ if (authorityKeyIdentifier != null)
+ {
+ selector.setSubjectKeyIdentifier(new DEROctetString(authorityKeyIdentifier).getEncoded());
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ // authority key identifier could not be retrieved from target cert, just search without it
+ }
+
+ PKIXCertStoreSelector certSelect = new PKIXCertStoreSelector.Builder(selector).build();
+ LinkedHashSet certs = new LinkedHashSet();
+
+ try
+ {
+ CertPathValidatorUtilities.findCertificates(certs, certSelect, certStores);
+ CertPathValidatorUtilities.findCertificates(certs, certSelect, pkixCertStores);
+ }
+ catch (AnnotatedException e)
+ {
+ throw new AnnotatedException("Issuer certificate cannot be searched.", e);
+ }
+
+ // issuers cannot be verified because possible DSA inheritance parameters are missing
+
+ return certs;
+ }
+
+ protected static void verifyX509Certificate(X509Certificate cert, PublicKey publicKey, String sigProvider)
+ throws GeneralSecurityException
+ {
+ if (sigProvider == null)
+ {
+ cert.verify(publicKey);
+ }
+ else
+ {
+ cert.verify(publicKey, sigProvider);
+ }
+ }
+
+ static void checkCRLsNotEmpty(PKIXCertRevocationCheckerParameters params, Set crls, Object cert)
+ throws RecoverableCertPathValidatorException
+ {
+ if (crls.isEmpty())
+ {
+ if (cert instanceof X509AttributeCertificate)
+ {
+ X509AttributeCertificate aCert = (X509AttributeCertificate)cert;
+
+ throw new RecoverableCertPathValidatorException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\"", null,
+ params.getCertPath(), params.getIndex());
+ }
+ else
+ {
+ X509Certificate xCert = (X509Certificate)cert;
+
+ throw new RecoverableCertPathValidatorException("No CRLs found for issuer \"" + RFC4519Style.INSTANCE.toString(PrincipalUtils.getIssuerPrincipal(xCert)) + "\"", null,
+ params.getCertPath(), params.getIndex());
+ }
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertStatus.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertStatus.java
new file mode 100644
index 00000000..2b616ac1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertStatus.java
@@ -0,0 +1,47 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.util.Date;
+
+class CertStatus
+{
+ public static final int UNREVOKED = 11;
+
+ public static final int UNDETERMINED = 12;
+
+ int certStatus = UNREVOKED;
+
+ Date revocationDate = null;
+
+ /**
+ * @return Returns the revocationDate.
+ */
+ public Date getRevocationDate()
+ {
+ return revocationDate;
+ }
+
+ /**
+ * @param revocationDate The revocationDate to set.
+ */
+ public void setRevocationDate(Date revocationDate)
+ {
+ this.revocationDate = revocationDate;
+ }
+
+ /**
+ * @return Returns the certStatus.
+ */
+ public int getCertStatus()
+ {
+ return certStatus;
+ }
+
+ /**
+ * @param certStatus The certStatus to set.
+ */
+ public void setCertStatus(int certStatus)
+ {
+ this.certStatus = certStatus;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertStoreCollectionSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertStoreCollectionSpi.java
new file mode 100644
index 00000000..5c29a24b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertStoreCollectionSpi.java
@@ -0,0 +1,108 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.cert.CRL;
+import java.security.cert.CRLSelector;
+import java.security.cert.CertSelector;
+import java.security.cert.CertStoreException;
+import java.security.cert.CertStoreParameters;
+import java.security.cert.CertStoreSpi;
+import java.security.cert.Certificate;
+import java.security.cert.CollectionCertStoreParameters;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertStoreCollectionSpi extends CertStoreSpi
+{
+ private CollectionCertStoreParameters params;
+
+ public CertStoreCollectionSpi(CertStoreParameters params)
+ throws InvalidAlgorithmParameterException
+ {
+ super(params);
+
+ if (!(params instanceof CollectionCertStoreParameters))
+ {
+ throw new InvalidAlgorithmParameterException("com.android.internal.org.bouncycastle.jce.provider.CertStoreCollectionSpi: parameter must be a CollectionCertStoreParameters object\n" + params.toString());
+ }
+
+ this.params = (CollectionCertStoreParameters)params;
+ }
+
+ public Collection engineGetCertificates(
+ CertSelector selector)
+ throws CertStoreException
+ {
+ List col = new ArrayList();
+ Iterator iter = params.getCollection().iterator();
+
+ if (selector == null)
+ {
+ while (iter.hasNext())
+ {
+ Object obj = iter.next();
+
+ if (obj instanceof Certificate)
+ {
+ col.add(obj);
+ }
+ }
+ }
+ else
+ {
+ while (iter.hasNext())
+ {
+ Object obj = iter.next();
+
+ if ((obj instanceof Certificate) && selector.match((Certificate)obj))
+ {
+ col.add(obj);
+ }
+ }
+ }
+
+ return col;
+ }
+
+
+ public Collection engineGetCRLs(
+ CRLSelector selector)
+ throws CertStoreException
+ {
+ List col = new ArrayList();
+ Iterator iter = params.getCollection().iterator();
+
+ if (selector == null)
+ {
+ while (iter.hasNext())
+ {
+ Object obj = iter.next();
+
+ if (obj instanceof CRL)
+ {
+ col.add(obj);
+ }
+ }
+ }
+ else
+ {
+ while (iter.hasNext())
+ {
+ Object obj = iter.next();
+
+ if ((obj instanceof CRL) && selector.match((CRL)obj))
+ {
+ col.add(obj);
+ }
+ }
+ }
+
+ return col;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/DHUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/DHUtil.java
new file mode 100644
index 00000000..77ba6b3f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/DHUtil.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.interfaces.DHPublicKey;
+
+import com.android.internal.org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import com.android.internal.org.bouncycastle.crypto.params.DHParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.crypto.params.DHPublicKeyParameters;
+
+/**
+ * utility class for converting jce/jca DH objects
+ * objects into their org.bouncycastle.crypto counterparts.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DHUtil
+{
+ static public AsymmetricKeyParameter generatePublicKeyParameter(
+ PublicKey key)
+ throws InvalidKeyException
+ {
+ if (key instanceof DHPublicKey)
+ {
+ DHPublicKey k = (DHPublicKey)key;
+
+ return new DHPublicKeyParameters(k.getY(),
+ new DHParameters(k.getParams().getP(), k.getParams().getG(), null, k.getParams().getL()));
+ }
+
+ throw new InvalidKeyException("can't identify DH public key.");
+ }
+
+ static public AsymmetricKeyParameter generatePrivateKeyParameter(
+ PrivateKey key)
+ throws InvalidKeyException
+ {
+ if (key instanceof DHPrivateKey)
+ {
+ DHPrivateKey k = (DHPrivateKey)key;
+
+ return new DHPrivateKeyParameters(k.getX(),
+ new DHParameters(k.getParams().getP(), k.getParams().getG(), null, k.getParams().getL()));
+ }
+
+ throw new InvalidKeyException("can't identify DH private key.");
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/ExtCRLException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/ExtCRLException.java
new file mode 100644
index 00000000..54b357ab
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/ExtCRLException.java
@@ -0,0 +1,21 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.security.cert.CRLException;
+
+class ExtCRLException
+ extends CRLException
+{
+ Throwable cause;
+
+ ExtCRLException(String message, Throwable cause)
+ {
+ super(message);
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPrivateKey.java
new file mode 100644
index 00000000..18c6e32a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPrivateKey.java
@@ -0,0 +1,191 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPrivateKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.pkcs.DHParameter;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x9.DHDomainParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.params.DHPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
+import com.android.internal.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JCEDHPrivateKey
+ implements DHPrivateKey, PKCS12BagAttributeCarrier
+{
+ static final long serialVersionUID = 311058815616901812L;
+
+ BigInteger x;
+
+ private DHParameterSpec dhSpec;
+ private PrivateKeyInfo info;
+
+ private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
+ protected JCEDHPrivateKey()
+ {
+ }
+
+ JCEDHPrivateKey(
+ DHPrivateKey key)
+ {
+ this.x = key.getX();
+ this.dhSpec = key.getParams();
+ }
+
+ JCEDHPrivateKey(
+ DHPrivateKeySpec spec)
+ {
+ this.x = spec.getX();
+ this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
+ }
+
+ JCEDHPrivateKey(
+ PrivateKeyInfo info)
+ throws IOException
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(info.getPrivateKeyAlgorithm().getParameters());
+ ASN1Integer derX = ASN1Integer.getInstance(info.parsePrivateKey());
+ ASN1ObjectIdentifier id = info.getPrivateKeyAlgorithm().getAlgorithm();
+
+ this.info = info;
+ this.x = derX.getValue();
+
+ if (id.equals(PKCSObjectIdentifiers.dhKeyAgreement))
+ {
+ DHParameter params = DHParameter.getInstance(seq);
+
+ if (params.getL() != null)
+ {
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue());
+ }
+ else
+ {
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
+ }
+ }
+ else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
+ {
+ DHDomainParameters params = DHDomainParameters.getInstance(seq);
+
+ this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue());
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown algorithm type: " + id);
+ }
+ }
+
+ JCEDHPrivateKey(
+ DHPrivateKeyParameters params)
+ {
+ this.x = params.getX();
+ this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG(), params.getParameters().getL());
+ }
+
+ public String getAlgorithm()
+ {
+ return "DH";
+ }
+
+ /**
+ * return the encoding format we produce in getEncoded().
+ *
+ * @return the string "PKCS#8"
+ */
+ public String getFormat()
+ {
+ return "PKCS#8";
+ }
+
+ /**
+ * Return a PKCS8 representation of the key. The sequence returned
+ * represents a full PrivateKeyInfo object.
+ *
+ * @return a PKCS8 representation of the key.
+ */
+ public byte[] getEncoded()
+ {
+ try
+ {
+ if (info != null)
+ {
+ return info.getEncoded(ASN1Encoding.DER);
+ }
+
+ PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL())), new ASN1Integer(getX()));
+
+ return info.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ public DHParameterSpec getParams()
+ {
+ return dhSpec;
+ }
+
+ public BigInteger getX()
+ {
+ return x;
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ x = (BigInteger)in.readObject();
+
+ this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt());
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.writeObject(this.getX());
+ out.writeObject(dhSpec.getP());
+ out.writeObject(dhSpec.getG());
+ out.writeInt(dhSpec.getL());
+ }
+
+ public void setBagAttribute(
+ ASN1ObjectIdentifier oid,
+ ASN1Encodable attribute)
+ {
+ attrCarrier.setBagAttribute(oid, attribute);
+ }
+
+ public ASN1Encodable getBagAttribute(
+ ASN1ObjectIdentifier oid)
+ {
+ return attrCarrier.getBagAttribute(oid);
+ }
+
+ public Enumeration getBagAttributeKeys()
+ {
+ return attrCarrier.getBagAttributeKeys();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPublicKey.java
new file mode 100644
index 00000000..f15f091b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEDHPublicKey.java
@@ -0,0 +1,182 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPublicKeySpec;
+
+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.pkcs.DHParameter;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x9.DHDomainParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.params.DHPublicKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JCEDHPublicKey
+ implements DHPublicKey
+{
+ static final long serialVersionUID = -216691575254424324L;
+
+ private BigInteger y;
+ private DHParameterSpec dhSpec;
+ private SubjectPublicKeyInfo info;
+
+ JCEDHPublicKey(
+ DHPublicKeySpec spec)
+ {
+ this.y = spec.getY();
+ this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
+ }
+
+ JCEDHPublicKey(
+ DHPublicKey key)
+ {
+ this.y = key.getY();
+ this.dhSpec = key.getParams();
+ }
+
+ JCEDHPublicKey(
+ DHPublicKeyParameters params)
+ {
+ this.y = params.getY();
+ this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG(), params.getParameters().getL());
+ }
+
+ JCEDHPublicKey(
+ BigInteger y,
+ DHParameterSpec dhSpec)
+ {
+ this.y = y;
+ this.dhSpec = dhSpec;
+ }
+
+ JCEDHPublicKey(
+ SubjectPublicKeyInfo info)
+ {
+ this.info = info;
+
+ ASN1Integer derY;
+ try
+ {
+ derY = (ASN1Integer)info.parsePublicKey();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("invalid info structure in DH public key");
+ }
+
+ this.y = derY.getValue();
+
+ ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithmId().getParameters());
+ ASN1ObjectIdentifier id = info.getAlgorithmId().getAlgorithm();
+
+ // we need the PKCS check to handle older keys marked with the X9 oid.
+ if (id.equals(PKCSObjectIdentifiers.dhKeyAgreement) || isPKCSParam(seq))
+ {
+ DHParameter params = DHParameter.getInstance(seq);
+
+ if (params.getL() != null)
+ {
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue());
+ }
+ else
+ {
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
+ }
+ }
+ else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
+ {
+ DHDomainParameters params = DHDomainParameters.getInstance(seq);
+
+ this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue());
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown algorithm type: " + id);
+ }
+ }
+
+ public String getAlgorithm()
+ {
+ return "DH";
+ }
+
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ public byte[] getEncoded()
+ {
+ if (info != null)
+ {
+ return KeyUtil.getEncodedSubjectPublicKeyInfo(info);
+ }
+
+ return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL())), new ASN1Integer(y));
+ }
+
+ public DHParameterSpec getParams()
+ {
+ return dhSpec;
+ }
+
+ public BigInteger getY()
+ {
+ return y;
+ }
+
+ private boolean isPKCSParam(ASN1Sequence seq)
+ {
+ if (seq.size() == 2)
+ {
+ return true;
+ }
+
+ if (seq.size() > 3)
+ {
+ return false;
+ }
+
+ ASN1Integer l = ASN1Integer.getInstance(seq.getObjectAt(2));
+ ASN1Integer p = ASN1Integer.getInstance(seq.getObjectAt(0));
+
+ if (l.getValue().compareTo(BigInteger.valueOf(p.getValue().bitLength())) > 0)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ this.y = (BigInteger)in.readObject();
+ this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt());
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.writeObject(this.getY());
+ out.writeObject(dhSpec.getP());
+ out.writeObject(dhSpec.getG());
+ out.writeInt(dhSpec.getL());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPrivateKey.java
new file mode 100644
index 00000000..fd3fd5c1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPrivateKey.java
@@ -0,0 +1,476 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.interfaces.ECPrivateKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPrivateKeySpec;
+import java.security.spec.EllipticCurve;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.sec.ECPrivateKeyStructure;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECPoint;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
+import com.android.internal.org.bouncycastle.jce.interfaces.ECPointEncoder;
+import com.android.internal.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
+import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveSpec;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JCEECPrivateKey
+ implements ECPrivateKey, com.android.internal.org.bouncycastle.jce.interfaces.ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder
+{
+ private String algorithm = "EC";
+ private BigInteger d;
+ private ECParameterSpec ecSpec;
+ private boolean withCompression;
+
+ private DERBitString publicKey;
+
+ private PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
+ protected JCEECPrivateKey()
+ {
+ }
+
+ public JCEECPrivateKey(
+ ECPrivateKey key)
+ {
+ this.d = key.getS();
+ this.algorithm = key.getAlgorithm();
+ this.ecSpec = key.getParams();
+ }
+
+ public JCEECPrivateKey(
+ String algorithm,
+ com.android.internal.org.bouncycastle.jce.spec.ECPrivateKeySpec spec)
+ {
+ this.algorithm = algorithm;
+ this.d = spec.getD();
+
+ if (spec.getParams() != null) // can be null if implicitlyCA
+ {
+ ECCurve curve = spec.getParams().getCurve();
+ EllipticCurve ellipticCurve;
+
+ ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed());
+
+ this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams());
+ }
+ else
+ {
+ this.ecSpec = null;
+ }
+ }
+
+
+ public JCEECPrivateKey(
+ String algorithm,
+ ECPrivateKeySpec spec)
+ {
+ this.algorithm = algorithm;
+ this.d = spec.getS();
+ this.ecSpec = spec.getParams();
+ }
+
+ public JCEECPrivateKey(
+ String algorithm,
+ JCEECPrivateKey key)
+ {
+ this.algorithm = algorithm;
+ this.d = key.d;
+ this.ecSpec = key.ecSpec;
+ this.withCompression = key.withCompression;
+ this.attrCarrier = key.attrCarrier;
+ this.publicKey = key.publicKey;
+ }
+
+ public JCEECPrivateKey(
+ String algorithm,
+ ECPrivateKeyParameters params,
+ JCEECPublicKey pubKey,
+ ECParameterSpec spec)
+ {
+ this.algorithm = algorithm;
+ this.d = params.getD();
+
+ if (spec == null)
+ {
+ ECDomainParameters dp = params.getParameters();
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed());
+
+ this.ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ EC5Util.convertPoint(dp.getG()),
+ dp.getN(),
+ dp.getH().intValue());
+ }
+ else
+ {
+ this.ecSpec = spec;
+ }
+
+ publicKey = getPublicKeyDetails(pubKey);
+ }
+
+ public JCEECPrivateKey(
+ String algorithm,
+ ECPrivateKeyParameters params,
+ JCEECPublicKey pubKey,
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec spec)
+ {
+ this.algorithm = algorithm;
+ this.d = params.getD();
+
+ if (spec == null)
+ {
+ ECDomainParameters dp = params.getParameters();
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed());
+
+ this.ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ EC5Util.convertPoint(dp.getG()),
+ dp.getN(),
+ dp.getH().intValue());
+ }
+ else
+ {
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed());
+
+ this.ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ EC5Util.convertPoint(spec.getG()),
+ spec.getN(),
+ spec.getH().intValue());
+ }
+
+ publicKey = getPublicKeyDetails(pubKey);
+ }
+
+ public JCEECPrivateKey(
+ String algorithm,
+ ECPrivateKeyParameters params)
+ {
+ this.algorithm = algorithm;
+ this.d = params.getD();
+ this.ecSpec = null;
+ }
+
+ JCEECPrivateKey(
+ PrivateKeyInfo info)
+ throws IOException
+ {
+ populateFromPrivKeyInfo(info);
+ }
+
+ private void populateFromPrivKeyInfo(PrivateKeyInfo info)
+ throws IOException
+ {
+ X962Parameters params = X962Parameters.getInstance(info.getPrivateKeyAlgorithm().getParameters());
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters());
+ X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ if (ecP == null) // GOST Curve
+ {
+ ECDomainParameters gParam = ECGOST3410NamedCurves.getByOID(oid);
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(gParam.getCurve(), gParam.getSeed());
+
+ ecSpec = new ECNamedCurveSpec(
+ ECGOST3410NamedCurves.getName(oid),
+ ellipticCurve,
+ EC5Util.convertPoint(gParam.getG()),
+ gParam.getN(),
+ gParam.getH());
+ }
+ else
+ */
+ // END Android-removed: Unsupported algorithms
+ {
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed());
+
+ ecSpec = new ECNamedCurveSpec(
+ ECUtil.getCurveName(oid),
+ ellipticCurve,
+ EC5Util.convertPoint(ecP.getG()),
+ ecP.getN(),
+ ecP.getH());
+ }
+ }
+ else if (params.isImplicitlyCA())
+ {
+ ecSpec = null;
+ }
+ else
+ {
+ X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed());
+
+ this.ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ EC5Util.convertPoint(ecP.getG()),
+ ecP.getN(),
+ ecP.getH().intValue());
+ }
+
+ ASN1Encodable privKey = info.parsePrivateKey();
+ if (privKey instanceof ASN1Integer)
+ {
+ ASN1Integer derD = ASN1Integer.getInstance(privKey);
+
+ this.d = derD.getValue();
+ }
+ else
+ {
+ ECPrivateKeyStructure ec = new ECPrivateKeyStructure((ASN1Sequence)privKey);
+
+ this.d = ec.getKey();
+ this.publicKey = ec.getPublicKey();
+ }
+ }
+
+ public String getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ /**
+ * return the encoding format we produce in getEncoded().
+ *
+ * @return the string "PKCS#8"
+ */
+ public String getFormat()
+ {
+ return "PKCS#8";
+ }
+
+ /**
+ * Return a PKCS8 representation of the key. The sequence returned
+ * represents a full PrivateKeyInfo object.
+ *
+ * @return a PKCS8 representation of the key.
+ */
+ public byte[] getEncoded()
+ {
+ X962Parameters params;
+
+ if (ecSpec instanceof ECNamedCurveSpec)
+ {
+ ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName());
+ if (curveOid == null) // guess it's the OID
+ {
+ curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName());
+ }
+ params = new X962Parameters(curveOid);
+ }
+ else if (ecSpec == null)
+ {
+ params = new X962Parameters(DERNull.INSTANCE);
+ }
+ else
+ {
+ ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve());
+
+ X9ECParameters ecP = new X9ECParameters(
+ curve,
+ new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), withCompression),
+ ecSpec.getOrder(),
+ BigInteger.valueOf(ecSpec.getCofactor()),
+ ecSpec.getCurve().getSeed());
+
+ params = new X962Parameters(ecP);
+ }
+
+ PrivateKeyInfo info;
+ ECPrivateKeyStructure keyStructure;
+
+ if (publicKey != null)
+ {
+ keyStructure = new ECPrivateKeyStructure(this.getS(), publicKey, params);
+ }
+ else
+ {
+ keyStructure = new ECPrivateKeyStructure(this.getS(), params);
+ }
+
+ try
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ // if (algorithm.equals("ECGOST3410"))
+ // {
+ // info = new PrivateKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params.toASN1Primitive()), keyStructure.toASN1Primitive());
+ // }
+ // else
+ // END Android-removed: Unsupported algorithms
+ {
+
+ info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params.toASN1Primitive()), keyStructure.toASN1Primitive());
+ }
+
+ return info.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ public ECParameterSpec getParams()
+ {
+ return ecSpec;
+ }
+
+ public com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec getParameters()
+ {
+ if (ecSpec == null)
+ {
+ return null;
+ }
+
+ return EC5Util.convertSpec(ecSpec);
+ }
+
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec()
+ {
+ if (ecSpec != null)
+ {
+ return EC5Util.convertSpec(ecSpec);
+ }
+
+ return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+ }
+
+ public BigInteger getS()
+ {
+ return d;
+ }
+
+ public BigInteger getD()
+ {
+ return d;
+ }
+
+ public void setBagAttribute(
+ ASN1ObjectIdentifier oid,
+ ASN1Encodable attribute)
+ {
+ attrCarrier.setBagAttribute(oid, attribute);
+ }
+
+ public ASN1Encodable getBagAttribute(
+ ASN1ObjectIdentifier oid)
+ {
+ return attrCarrier.getBagAttribute(oid);
+ }
+
+ public Enumeration getBagAttributeKeys()
+ {
+ return attrCarrier.getBagAttributeKeys();
+ }
+
+ public void setPointFormat(String style)
+ {
+ withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof JCEECPrivateKey))
+ {
+ return false;
+ }
+
+ JCEECPrivateKey other = (JCEECPrivateKey)o;
+
+ return getD().equals(other.getD()) && (engineGetSpec().equals(other.engineGetSpec()));
+ }
+
+ public int hashCode()
+ {
+ return getD().hashCode() ^ engineGetSpec().hashCode();
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append("EC Private Key").append(nl);
+ buf.append(" S: ").append(this.d.toString(16)).append(nl);
+
+ return buf.toString();
+
+ }
+
+ private DERBitString getPublicKeyDetails(JCEECPublicKey pub)
+ {
+ try
+ {
+ SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded()));
+
+ return info.getPublicKeyData();
+ }
+ catch (IOException e)
+ { // should never happen
+ return null;
+ }
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ byte[] enc = (byte[])in.readObject();
+
+ populateFromPrivKeyInfo(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc)));
+
+ this.algorithm = (String)in.readObject();
+ this.withCompression = in.readBoolean();
+ this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
+ attrCarrier.readObject(in);
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.writeObject(this.getEncoded());
+ out.writeObject(algorithm);
+ out.writeBoolean(withCompression);
+
+ attrCarrier.writeObject(out);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPublicKey.java
new file mode 100644
index 00000000..46cd2358
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPublicKey.java
@@ -0,0 +1,523 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.EllipticCurve;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
+// import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x9.X962Parameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECParameters;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ECPoint;
+import com.android.internal.org.bouncycastle.asn1.x9.X9IntegerConverter;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.params.ECDomainParameters;
+import com.android.internal.org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jce.ECGOST3410NamedCurveTable;
+import com.android.internal.org.bouncycastle.jce.interfaces.ECPointEncoder;
+// Android-removed: Unsupported algorithms
+// import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
+import com.android.internal.org.bouncycastle.jce.spec.ECNamedCurveSpec;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JCEECPublicKey
+ implements ECPublicKey, com.android.internal.org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder
+{
+ private String algorithm = "EC";
+ private com.android.internal.org.bouncycastle.math.ec.ECPoint q;
+ private ECParameterSpec ecSpec;
+ private boolean withCompression;
+ // Android-removed: Unsupported algorithms
+ // private GOST3410PublicKeyAlgParameters gostParams;
+
+ public JCEECPublicKey(
+ String algorithm,
+ JCEECPublicKey key)
+ {
+ this.algorithm = algorithm;
+ this.q = key.q;
+ this.ecSpec = key.ecSpec;
+ this.withCompression = key.withCompression;
+ // Android-removed: Unsupported algorithms
+ // this.gostParams = key.gostParams;
+ }
+
+ public JCEECPublicKey(
+ String algorithm,
+ ECPublicKeySpec spec)
+ {
+ this.algorithm = algorithm;
+ this.ecSpec = spec.getParams();
+ this.q = EC5Util.convertPoint(ecSpec, spec.getW());
+ }
+
+ public JCEECPublicKey(
+ String algorithm,
+ com.android.internal.org.bouncycastle.jce.spec.ECPublicKeySpec spec)
+ {
+ this.algorithm = algorithm;
+ this.q = spec.getQ();
+
+ if (spec.getParams() != null) // can be null if implictlyCa
+ {
+ ECCurve curve = spec.getParams().getCurve();
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed());
+
+ this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams());
+ }
+ else
+ {
+ if (q.getCurve() == null)
+ {
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+
+ q = s.getCurve().createPoint(q.getAffineXCoord().toBigInteger(), q.getAffineYCoord().toBigInteger());
+ }
+ this.ecSpec = null;
+ }
+ }
+
+ public JCEECPublicKey(
+ String algorithm,
+ ECPublicKeyParameters params,
+ ECParameterSpec spec)
+ {
+ ECDomainParameters dp = params.getParameters();
+
+ this.algorithm = algorithm;
+ this.q = params.getQ();
+
+ if (spec == null)
+ {
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed());
+
+ this.ecSpec = createSpec(ellipticCurve, dp);
+ }
+ else
+ {
+ this.ecSpec = spec;
+ }
+ }
+
+ public JCEECPublicKey(
+ String algorithm,
+ ECPublicKeyParameters params,
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec spec)
+ {
+ ECDomainParameters dp = params.getParameters();
+
+ this.algorithm = algorithm;
+ this.q = params.getQ();
+
+ if (spec == null)
+ {
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed());
+
+ this.ecSpec = createSpec(ellipticCurve, dp);
+ }
+ else
+ {
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed());
+
+ this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec);
+ }
+ }
+
+ /*
+ * called for implicitCA
+ */
+ public JCEECPublicKey(
+ String algorithm,
+ ECPublicKeyParameters params)
+ {
+ this.algorithm = algorithm;
+ this.q = params.getQ();
+ this.ecSpec = null;
+ }
+
+ private ECParameterSpec createSpec(EllipticCurve ellipticCurve, ECDomainParameters dp)
+ {
+ return new ECParameterSpec(
+ ellipticCurve,
+ EC5Util.convertPoint(dp.getG()),
+ dp.getN(),
+ dp.getH().intValue());
+ }
+
+ public JCEECPublicKey(
+ ECPublicKey key)
+ {
+ this.algorithm = key.getAlgorithm();
+ this.ecSpec = key.getParams();
+ this.q = EC5Util.convertPoint(this.ecSpec, key.getW());
+ }
+
+ JCEECPublicKey(
+ SubjectPublicKeyInfo info)
+ {
+ populateFromPubKeyInfo(info);
+ }
+
+ private void populateFromPubKeyInfo(SubjectPublicKeyInfo info)
+ {
+ AlgorithmIdentifier algID = info.getAlgorithm();
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+
+ if (algID.getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3410_2001))
+ {
+ DERBitString bits = info.getPublicKeyData();
+ ASN1OctetString key;
+ this.algorithm = "ECGOST3410";
+
+ try
+ {
+ key = (ASN1OctetString) ASN1Primitive.fromByteArray(bits.getBytes());
+ }
+ catch (IOException ex)
+ {
+ throw new IllegalArgumentException("error recovering public key");
+ }
+
+ byte[] keyEnc = key.getOctets();
+
+ byte[] x9Encoding = new byte[65];
+ x9Encoding[0] = 0x04;
+ for (int i = 1; i <= 32; ++i)
+ {
+ x9Encoding[i ] = keyEnc[32 - i];
+ x9Encoding[i + 32] = keyEnc[64 - i];
+ }
+
+ gostParams = GOST3410PublicKeyAlgParameters.getInstance(algID.getParameters());
+
+ ECNamedCurveParameterSpec spec = ECGOST3410NamedCurveTable.getParameterSpec(ECGOST3410NamedCurves.getName(gostParams.getPublicKeyParamSet()));
+
+ ECCurve curve = spec.getCurve();
+ EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getSeed());
+
+ this.q = curve.decodePoint(x9Encoding);
+
+ ecSpec = new ECNamedCurveSpec(
+ ECGOST3410NamedCurves.getName(gostParams.getPublicKeyParamSet()),
+ ellipticCurve,
+ EC5Util.convertPoint(spec.getG()),
+ spec.getN(),
+ spec.getH());
+ }
+ else
+ */
+ // END Android-removed: Unsupported algorithms
+ {
+ X962Parameters params = X962Parameters.getInstance(algID.getParameters());
+ ECCurve curve;
+ EllipticCurve ellipticCurve;
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
+ X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
+
+ curve = ecP.getCurve();
+ ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
+
+ ecSpec = new ECNamedCurveSpec(
+ ECUtil.getCurveName(oid),
+ ellipticCurve,
+ EC5Util.convertPoint(ecP.getG()),
+ ecP.getN(),
+ ecP.getH());
+ }
+ else if (params.isImplicitlyCA())
+ {
+ ecSpec = null;
+ curve = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getCurve();
+ }
+ else
+ {
+ X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
+
+ curve = ecP.getCurve();
+ ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
+
+ this.ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ EC5Util.convertPoint(ecP.getG()),
+ ecP.getN(),
+ ecP.getH().intValue());
+ }
+
+ DERBitString bits = info.getPublicKeyData();
+ byte[] data = bits.getBytes();
+ ASN1OctetString key = new DEROctetString(data);
+
+ //
+ // extra octet string - one of our old certs...
+ //
+ if (data[0] == 0x04 && data[1] == data.length - 2
+ && (data[2] == 0x02 || data[2] == 0x03))
+ {
+ int qLength = new X9IntegerConverter().getByteLength(curve);
+
+ if (qLength >= data.length - 3)
+ {
+ try
+ {
+ key = (ASN1OctetString) ASN1Primitive.fromByteArray(data);
+ }
+ catch (IOException ex)
+ {
+ throw new IllegalArgumentException("error recovering public key");
+ }
+ }
+ }
+ X9ECPoint derQ = new X9ECPoint(curve, key);
+
+ this.q = derQ.getPoint();
+ }
+ }
+
+ public String getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ public byte[] getEncoded()
+ {
+ ASN1Encodable params;
+ SubjectPublicKeyInfo info;
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ if (algorithm.equals("ECGOST3410"))
+ {
+ if (gostParams != null)
+ {
+ params = gostParams;
+ }
+ else
+ {
+ if (ecSpec instanceof ECNamedCurveSpec)
+ {
+ params = new GOST3410PublicKeyAlgParameters(
+ ECGOST3410NamedCurves.getOID(((ECNamedCurveSpec)ecSpec).getName()),
+ CryptoProObjectIdentifiers.gostR3411_94_CryptoProParamSet);
+ }
+ else
+ { // strictly speaking this may not be applicable...
+ ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve());
+
+ X9ECParameters ecP = new X9ECParameters(
+ curve,
+ new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), withCompression),
+ ecSpec.getOrder(),
+ BigInteger.valueOf(ecSpec.getCofactor()),
+ ecSpec.getCurve().getSeed());
+
+ params = new X962Parameters(ecP);
+ }
+ }
+
+ BigInteger bX = this.q.getAffineXCoord().toBigInteger();
+ BigInteger bY = this.q.getAffineYCoord().toBigInteger();
+
+ byte[] encKey = new byte[64];
+ extractBytes(encKey, 0, bX);
+ extractBytes(encKey, 32, bY);
+
+ try
+ {
+ info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params), new DEROctetString(encKey));
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+ else
+ */
+ // END Android-removed: Unsupported algorithms
+ {
+ if (ecSpec instanceof ECNamedCurveSpec)
+ {
+ ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName());
+ if (curveOid == null)
+ {
+ curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName());
+ }
+ params = new X962Parameters(curveOid);
+ }
+ else if (ecSpec == null)
+ {
+ params = new X962Parameters(DERNull.INSTANCE);
+ }
+ else
+ {
+ ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve());
+
+ X9ECParameters ecP = new X9ECParameters(
+ curve,
+ new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), withCompression),
+ ecSpec.getOrder(),
+ BigInteger.valueOf(ecSpec.getCofactor()),
+ ecSpec.getCurve().getSeed());
+
+ params = new X962Parameters(ecP);
+ }
+
+ byte[] pubKeyOctets = this.getQ().getEncoded(withCompression);
+
+ info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), pubKeyOctets);
+ }
+
+ return KeyUtil.getEncodedSubjectPublicKeyInfo(info);
+ }
+
+ private void extractBytes(byte[] encKey, int offSet, BigInteger bI)
+ {
+ byte[] val = bI.toByteArray();
+ if (val.length < 32)
+ {
+ byte[] tmp = new byte[32];
+ System.arraycopy(val, 0, tmp, tmp.length - val.length, val.length);
+ val = tmp;
+ }
+
+ for (int i = 0; i != 32; i++)
+ {
+ encKey[offSet + i] = val[val.length - 1 - i];
+ }
+ }
+
+ public ECParameterSpec getParams()
+ {
+ return ecSpec;
+ }
+
+ public com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec getParameters()
+ {
+ if (ecSpec == null) // implictlyCA
+ {
+ return null;
+ }
+
+ return EC5Util.convertSpec(ecSpec);
+ }
+
+ public ECPoint getW()
+ {
+ return EC5Util.convertPoint(q);
+ }
+
+ public com.android.internal.org.bouncycastle.math.ec.ECPoint getQ()
+ {
+ if (ecSpec == null)
+ {
+ return q.getDetachedPoint();
+ }
+
+ return q;
+ }
+
+ public com.android.internal.org.bouncycastle.math.ec.ECPoint engineGetQ()
+ {
+ return q;
+ }
+
+ com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec()
+ {
+ if (ecSpec != null)
+ {
+ return EC5Util.convertSpec(ecSpec);
+ }
+
+ return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append("EC Public Key").append(nl);
+ buf.append(" X: ").append(this.q.getAffineXCoord().toBigInteger().toString(16)).append(nl);
+ buf.append(" Y: ").append(this.q.getAffineYCoord().toBigInteger().toString(16)).append(nl);
+
+ return buf.toString();
+
+ }
+
+ public void setPointFormat(String style)
+ {
+ withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof JCEECPublicKey))
+ {
+ return false;
+ }
+
+ JCEECPublicKey other = (JCEECPublicKey)o;
+
+ return engineGetQ().equals(other.engineGetQ()) && (engineGetSpec().equals(other.engineGetSpec()));
+ }
+
+ public int hashCode()
+ {
+ return engineGetQ().hashCode() ^ engineGetSpec().hashCode();
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ byte[] enc = (byte[])in.readObject();
+
+ populateFromPubKeyInfo(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc)));
+
+ this.algorithm = (String)in.readObject();
+ this.withCompression = in.readBoolean();
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.writeObject(this.getEncoded());
+ out.writeObject(algorithm);
+ out.writeBoolean(withCompression);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JDKDSAPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JDKDSAPrivateKey.java
new file mode 100644
index 00000000..70599c05
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JDKDSAPrivateKey.java
@@ -0,0 +1,182 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.DSAPrivateKeySpec;
+import java.util.Enumeration;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.DSAParameter;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
+import com.android.internal.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JDKDSAPrivateKey
+ implements DSAPrivateKey, PKCS12BagAttributeCarrier
+{
+ private static final long serialVersionUID = -4677259546958385734L;
+
+ BigInteger x;
+ DSAParams dsaSpec;
+
+ private PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
+ protected JDKDSAPrivateKey()
+ {
+ }
+
+ JDKDSAPrivateKey(
+ DSAPrivateKey key)
+ {
+ this.x = key.getX();
+ this.dsaSpec = key.getParams();
+ }
+
+ JDKDSAPrivateKey(
+ DSAPrivateKeySpec spec)
+ {
+ this.x = spec.getX();
+ this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG());
+ }
+
+ JDKDSAPrivateKey(
+ PrivateKeyInfo info)
+ throws IOException
+ {
+ DSAParameter params = DSAParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters());
+ ASN1Integer derX = ASN1Integer.getInstance(info.parsePrivateKey());
+
+ this.x = derX.getValue();
+ this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG());
+ }
+
+ JDKDSAPrivateKey(
+ DSAPrivateKeyParameters params)
+ {
+ this.x = params.getX();
+ this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG());
+ }
+
+ public String getAlgorithm()
+ {
+ return "DSA";
+ }
+
+ /**
+ * return the encoding format we produce in getEncoded().
+ *
+ * @return the string "PKCS#8"
+ */
+ public String getFormat()
+ {
+ return "PKCS#8";
+ }
+
+ /**
+ * Return a PKCS8 representation of the key. The sequence returned
+ * represents a full PrivateKeyInfo object.
+ *
+ * @return a PKCS8 representation of the key.
+ */
+ public byte[] getEncoded()
+ {
+ try
+ {
+ PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG())), new ASN1Integer(getX()));
+
+ return info.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ public DSAParams getParams()
+ {
+ return dsaSpec;
+ }
+
+ public BigInteger getX()
+ {
+ return x;
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof DSAPrivateKey))
+ {
+ return false;
+ }
+
+ DSAPrivateKey other = (DSAPrivateKey)o;
+
+ return this.getX().equals(other.getX())
+ && this.getParams().getG().equals(other.getParams().getG())
+ && this.getParams().getP().equals(other.getParams().getP())
+ && this.getParams().getQ().equals(other.getParams().getQ());
+ }
+
+ public int hashCode()
+ {
+ return this.getX().hashCode() ^ this.getParams().getG().hashCode()
+ ^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode();
+ }
+
+ public void setBagAttribute(
+ ASN1ObjectIdentifier oid,
+ ASN1Encodable attribute)
+ {
+ attrCarrier.setBagAttribute(oid, attribute);
+ }
+
+ public ASN1Encodable getBagAttribute(
+ ASN1ObjectIdentifier oid)
+ {
+ return attrCarrier.getBagAttribute(oid);
+ }
+
+ public Enumeration getBagAttributeKeys()
+ {
+ return attrCarrier.getBagAttributeKeys();
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ this.x = (BigInteger)in.readObject();
+ this.dsaSpec = new DSAParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject());
+ this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
+ attrCarrier.readObject(in);
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.writeObject(x);
+ out.writeObject(dsaSpec.getP());
+ out.writeObject(dsaSpec.getQ());
+ out.writeObject(dsaSpec.getG());
+
+ attrCarrier.writeObject(out);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JDKDSAPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JDKDSAPublicKey.java
new file mode 100644
index 00000000..f86d2be4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JDKDSAPublicKey.java
@@ -0,0 +1,181 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPublicKey;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.DSAPublicKeySpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.DSAParameter;
+import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import com.android.internal.org.bouncycastle.crypto.params.DSAPublicKeyParameters;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JDKDSAPublicKey
+ implements DSAPublicKey
+{
+ private static final long serialVersionUID = 1752452449903495175L;
+
+ private BigInteger y;
+ private DSAParams dsaSpec;
+
+ JDKDSAPublicKey(
+ DSAPublicKeySpec spec)
+ {
+ this.y = spec.getY();
+ this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG());
+ }
+
+ JDKDSAPublicKey(
+ DSAPublicKey key)
+ {
+ this.y = key.getY();
+ this.dsaSpec = key.getParams();
+ }
+
+ JDKDSAPublicKey(
+ DSAPublicKeyParameters params)
+ {
+ this.y = params.getY();
+ this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG());
+ }
+
+ JDKDSAPublicKey(
+ BigInteger y,
+ DSAParameterSpec dsaSpec)
+ {
+ this.y = y;
+ this.dsaSpec = dsaSpec;
+ }
+
+ JDKDSAPublicKey(
+ SubjectPublicKeyInfo info)
+ {
+
+ ASN1Integer derY;
+
+ try
+ {
+ derY = (ASN1Integer)info.parsePublicKey();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("invalid info structure in DSA public key");
+ }
+
+ this.y = derY.getValue();
+
+ if (isNotNull(info.getAlgorithm().getParameters()))
+ {
+ DSAParameter params = DSAParameter.getInstance(info.getAlgorithm().getParameters());
+
+ this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG());
+ }
+ }
+
+ private boolean isNotNull(ASN1Encodable parameters)
+ {
+ return parameters != null && !DERNull.INSTANCE.equals(parameters);
+ }
+
+ public String getAlgorithm()
+ {
+ return "DSA";
+ }
+
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ public byte[] getEncoded()
+ {
+ try
+ {
+ if (dsaSpec == null)
+ {
+ return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa), new ASN1Integer(y)).getEncoded(ASN1Encoding.DER);
+ }
+
+ return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG())), new ASN1Integer(y)).getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ public DSAParams getParams()
+ {
+ return dsaSpec;
+ }
+
+ public BigInteger getY()
+ {
+ return y;
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append("DSA Public Key").append(nl);
+ buf.append(" y: ").append(this.getY().toString(16)).append(nl);
+
+ return buf.toString();
+ }
+
+ public int hashCode()
+ {
+ return this.getY().hashCode() ^ this.getParams().getG().hashCode()
+ ^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode();
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof DSAPublicKey))
+ {
+ return false;
+ }
+
+ DSAPublicKey other = (DSAPublicKey)o;
+
+ return this.getY().equals(other.getY())
+ && this.getParams().getG().equals(other.getParams().getG())
+ && this.getParams().getP().equals(other.getParams().getP())
+ && this.getParams().getQ().equals(other.getParams().getQ());
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ this.y = (BigInteger)in.readObject();
+ this.dsaSpec = new DSAParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject());
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.writeObject(y);
+ out.writeObject(dsaSpec.getP());
+ out.writeObject(dsaSpec.getQ());
+ out.writeObject(dsaSpec.getG());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JDKPKCS12StoreParameter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JDKPKCS12StoreParameter.java
new file mode 100644
index 00000000..dd2798f9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JDKPKCS12StoreParameter.java
@@ -0,0 +1,53 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.OutputStream;
+import java.security.KeyStore;
+import java.security.KeyStore.LoadStoreParameter;
+import java.security.KeyStore.ProtectionParameter;
+
+/**
+ * @deprecated use org.bouncycastle.jcajce.config.PKCS12StoreParameter
+ * @hide This class is not part of the Android public SDK API
+ */
+public class JDKPKCS12StoreParameter implements LoadStoreParameter
+{
+ private OutputStream outputStream;
+ private ProtectionParameter protectionParameter;
+ private boolean useDEREncoding;
+
+ public OutputStream getOutputStream()
+ {
+ return outputStream;
+ }
+
+ public ProtectionParameter getProtectionParameter()
+ {
+ return protectionParameter;
+ }
+
+ public boolean isUseDEREncoding()
+ {
+ return useDEREncoding;
+ }
+
+ public void setOutputStream(OutputStream outputStream)
+ {
+ this.outputStream = outputStream;
+ }
+
+ public void setPassword(char[] password)
+ {
+ this.protectionParameter = new KeyStore.PasswordProtection(password);
+ }
+
+ public void setProtectionParameter(ProtectionParameter protectionParameter)
+ {
+ this.protectionParameter = protectionParameter;
+ }
+
+ public void setUseDEREncoding(boolean useDEREncoding)
+ {
+ this.useDEREncoding = useDEREncoding;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PEMUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PEMUtil.java
new file mode 100644
index 00000000..ee709e1f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PEMUtil.java
@@ -0,0 +1,98 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.util.encoders.Base64;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PEMUtil
+{
+ private final String _header1;
+ private final String _header2;
+ private final String _footer1;
+ private final String _footer2;
+
+ PEMUtil(
+ String type)
+ {
+ _header1 = "-----BEGIN " + type + "-----";
+ _header2 = "-----BEGIN X509 " + type + "-----";
+ _footer1 = "-----END " + type + "-----";
+ _footer2 = "-----END X509 " + type + "-----";
+ }
+
+ private String readLine(
+ InputStream in)
+ throws IOException
+ {
+ int c;
+ StringBuffer l = new StringBuffer();
+
+ do
+ {
+ while (((c = in.read()) != '\r') && c != '\n' && (c >= 0))
+ {
+ if (c == '\r')
+ {
+ continue;
+ }
+
+ l.append((char)c);
+ }
+ }
+ while (c >= 0 && l.length() == 0);
+
+ if (c < 0)
+ {
+ return null;
+ }
+
+ return l.toString();
+ }
+
+ ASN1Sequence readPEMObject(
+ InputStream in)
+ throws IOException
+ {
+ String line;
+ StringBuffer pemBuf = new StringBuffer();
+
+ while ((line = readLine(in)) != null)
+ {
+ if (line.startsWith(_header1) || line.startsWith(_header2))
+ {
+ break;
+ }
+ }
+
+ while ((line = readLine(in)) != null)
+ {
+ if (line.startsWith(_footer1) || line.startsWith(_footer2))
+ {
+ break;
+ }
+
+ pemBuf.append(line);
+ }
+
+ if (pemBuf.length() != 0)
+ {
+ ASN1Primitive o = new ASN1InputStream(Base64.decode(pemBuf.toString())).readObject();
+ if (!(o instanceof ASN1Sequence))
+ {
+ throw new IOException("malformed PEM data encountered");
+ }
+
+ return (ASN1Sequence)o;
+ }
+
+ return null;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCRLUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCRLUtil.java
new file mode 100644
index 00000000..c5fec2b5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCRLUtil.java
@@ -0,0 +1,120 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import com.android.internal.org.bouncycastle.jcajce.PKIXCRLStore;
+import com.android.internal.org.bouncycastle.jcajce.PKIXCRLStoreSelector;
+import com.android.internal.org.bouncycastle.util.Store;
+import com.android.internal.org.bouncycastle.util.StoreException;
+
+abstract class PKIXCRLUtil
+{
+ static Set findCRLs(PKIXCRLStoreSelector crlselect, Date validityDate, List certStores, List pkixCrlStores)
+ throws AnnotatedException
+ {
+ HashSet initialSet = new HashSet();
+
+ // get complete CRL(s)
+ try
+ {
+ findCRLs(initialSet, crlselect, pkixCrlStores);
+ findCRLs(initialSet, crlselect, certStores);
+ }
+ catch (AnnotatedException e)
+ {
+ throw new AnnotatedException("Exception obtaining complete CRLs.", e);
+ }
+
+ Set finalSet = new HashSet();
+
+ // based on RFC 5280 6.3.3
+ for (Iterator it = initialSet.iterator(); it.hasNext();)
+ {
+ X509CRL crl = (X509CRL)it.next();
+
+ if (crl.getNextUpdate().after(validityDate))
+ {
+ X509Certificate cert = crlselect.getCertificateChecking();
+
+ if (null == cert || crl.getThisUpdate().before(cert.getNotAfter()))
+ {
+ finalSet.add(crl);
+ }
+ }
+ }
+
+ return finalSet;
+ }
+
+ /**
+ * Add to a HashSet any and all CRLs found in the X509Store's that are matching the crlSelect
+ * critera.
+ *
+ * @param crls
+ * the {@link HashSet} to add the CRLs to.
+ * @param crlSelect
+ * a {@link com.android.internal.org.bouncycastle.jcajce.PKIXCRLStoreSelector} object that will be used to
+ * select the CRLs
+ * @param crlStores
+ * a List containing only {@link Store} objects. These are used to search for CRLs
+ */
+ private static void findCRLs(HashSet crls, PKIXCRLStoreSelector crlSelect, List crlStores) throws AnnotatedException
+ {
+ AnnotatedException lastException = null;
+ boolean foundValidStore = false;
+
+ Iterator iter = crlStores.iterator();
+ while (iter.hasNext())
+ {
+ Object obj = iter.next();
+
+ // BEGIN Android-removed: Unknown reason
+ /*
+ if (obj instanceof Store)
+ {
+ Store store = (Store)obj;
+
+ try
+ {
+ crls.addAll(store.getMatches(crlSelect));
+ foundValidStore = true;
+ }
+ catch (StoreException e)
+ {
+ lastException = new AnnotatedException("Exception searching in X.509 CRL store.", e);
+ }
+ }
+ else
+ */
+ // END Android-removed: Unknown reason
+ {
+ CertStore store = (CertStore)obj;
+
+ try
+ {
+ crls.addAll(PKIXCRLStoreSelector.getCRLs(crlSelect, store));
+ foundValidStore = true;
+ }
+ catch (CertStoreException e)
+ {
+ lastException = new AnnotatedException("Exception searching in X.509 CRL store.", e);
+ }
+ }
+ }
+
+ if (!foundValidStore && lastException != null)
+ {
+ throw lastException;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java
new file mode 100644
index 00000000..5a9df5f8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java
@@ -0,0 +1,273 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.cert.CertPath;
+import java.security.cert.CertPathBuilderException;
+import java.security.cert.CertPathBuilderResult;
+import java.security.cert.CertPathBuilderSpi;
+import java.security.cert.CertPathParameters;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.PKIXCertPathBuilderResult;
+import java.security.cert.PKIXCertPathValidatorResult;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.jcajce.PKIXCertStore;
+import com.android.internal.org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
+import com.android.internal.org.bouncycastle.jcajce.PKIXExtendedParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory;
+import com.android.internal.org.bouncycastle.x509.ExtendedPKIXBuilderParameters;
+import com.android.internal.org.bouncycastle.x509.ExtendedPKIXParameters;
+
+/**
+ * Implements the PKIX CertPathBuilding algorithm for BouncyCastle.
+ *
+ * @see CertPathBuilderSpi
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKIXCertPathBuilderSpi
+ extends CertPathBuilderSpi
+{
+ private final boolean isForCRLCheck;
+
+ public PKIXCertPathBuilderSpi()
+ {
+ this(false);
+ }
+
+ PKIXCertPathBuilderSpi(boolean isForCRLCheck)
+ {
+ this.isForCRLCheck = isForCRLCheck;
+ }
+
+ /**
+ * Build and validate a CertPath using the given parameter.
+ *
+ * @param params PKIXBuilderParameters object containing all information to
+ * build the CertPath
+ */
+ public CertPathBuilderResult engineBuild(CertPathParameters params)
+ throws CertPathBuilderException, InvalidAlgorithmParameterException
+ {
+ PKIXExtendedBuilderParameters paramsPKIX;
+ if (params instanceof PKIXBuilderParameters)
+ {
+ PKIXExtendedParameters.Builder paramsPKIXBldr = new PKIXExtendedParameters.Builder((PKIXBuilderParameters)params);
+ PKIXExtendedBuilderParameters.Builder paramsBldrPKIXBldr;
+
+ if (params instanceof ExtendedPKIXParameters)
+ {
+ ExtendedPKIXBuilderParameters extPKIX = (ExtendedPKIXBuilderParameters)params;
+
+ for (Iterator it = extPKIX.getAdditionalStores().iterator(); it.hasNext();)
+ {
+ paramsPKIXBldr.addCertificateStore((PKIXCertStore)it.next());
+ }
+ paramsBldrPKIXBldr = new PKIXExtendedBuilderParameters.Builder(paramsPKIXBldr.build());
+
+ paramsBldrPKIXBldr.addExcludedCerts(extPKIX.getExcludedCerts());
+ paramsBldrPKIXBldr.setMaxPathLength(extPKIX.getMaxPathLength());
+ }
+ else
+ {
+ paramsBldrPKIXBldr = new PKIXExtendedBuilderParameters.Builder((PKIXBuilderParameters)params);
+ }
+
+ paramsPKIX = paramsBldrPKIXBldr.build();
+ }
+ else if (params instanceof PKIXExtendedBuilderParameters)
+ {
+ paramsPKIX = (PKIXExtendedBuilderParameters)params;
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException(
+ "Parameters must be an instance of "
+ + PKIXBuilderParameters.class.getName() + " or "
+ + PKIXExtendedBuilderParameters.class.getName() + ".");
+ }
+
+ Collection targets;
+ Iterator targetIter;
+ List certPathList = new ArrayList();
+ X509Certificate cert;
+
+ // search target certificates
+ targets = CertPathValidatorUtilities.findTargets(paramsPKIX);
+
+ CertPathBuilderResult result = null;
+
+ // check all potential target certificates
+ targetIter = targets.iterator();
+ while (targetIter.hasNext() && result == null)
+ {
+ cert = (X509Certificate) targetIter.next();
+ result = build(cert, paramsPKIX, certPathList);
+ }
+
+ if (result == null && certPathException != null)
+ {
+ if (certPathException instanceof AnnotatedException)
+ {
+ throw new CertPathBuilderException(certPathException.getMessage(), certPathException.getCause());
+ }
+ throw new CertPathBuilderException(
+ "Possible certificate chain could not be validated.",
+ certPathException);
+ }
+
+ if (result == null && certPathException == null)
+ {
+ throw new CertPathBuilderException(
+ "Unable to find certificate chain.");
+ }
+
+ return result;
+ }
+
+ private Exception certPathException;
+
+ protected CertPathBuilderResult build(X509Certificate tbvCert,
+ PKIXExtendedBuilderParameters pkixParams, List tbvPath)
+ {
+ // If tbvCert is readily present in tbvPath, it indicates having run
+ // into a cycle in the
+ // PKI graph.
+ if (tbvPath.contains(tbvCert))
+ {
+ return null;
+ }
+ // step out, the certificate is not allowed to appear in a certification
+ // chain.
+ if (pkixParams.getExcludedCerts().contains(tbvCert))
+ {
+ return null;
+ }
+ // test if certificate path exceeds maximum length
+ if (pkixParams.getMaxPathLength() != -1)
+ {
+ if (tbvPath.size() - 1 > pkixParams.getMaxPathLength())
+ {
+ return null;
+ }
+ }
+
+ tbvPath.add(tbvCert);
+
+ CertificateFactory cFact;
+ PKIXCertPathValidatorSpi validator;
+ CertPathBuilderResult builderResult = null;
+
+ try
+ {
+ cFact = new CertificateFactory();
+ validator = new PKIXCertPathValidatorSpi(isForCRLCheck);
+ }
+ catch (Exception e)
+ {
+ // cannot happen
+ throw new RuntimeException("Exception creating support classes.");
+ }
+
+ try
+ {
+ // check whether the issuer of <tbvCert> is a TrustAnchor
+ if (CertPathValidatorUtilities.isIssuerTrustAnchor(tbvCert, pkixParams.getBaseParameters().getTrustAnchors(),
+ pkixParams.getBaseParameters().getSigProvider()))
+ {
+ // exception message from possibly later tried certification
+ // chains
+ CertPath certPath = null;
+ PKIXCertPathValidatorResult result = null;
+ try
+ {
+ certPath = cFact.engineGenerateCertPath(tbvPath);
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException(
+ "Certification path could not be constructed from certificate list.",
+ e);
+ }
+
+ try
+ {
+ result = (PKIXCertPathValidatorResult) validator.engineValidate(
+ certPath, pkixParams);
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException(
+ "Certification path could not be validated.", e);
+ }
+
+ return new PKIXCertPathBuilderResult(certPath, result
+ .getTrustAnchor(), result.getPolicyTree(), result
+ .getPublicKey());
+
+ }
+ else
+ {
+ List stores = new ArrayList();
+
+
+ stores.addAll(pkixParams.getBaseParameters().getCertificateStores());
+
+ // add additional X.509 stores from locations in certificate
+ try
+ {
+ stores.addAll(CertPathValidatorUtilities.getAdditionalStoresFromAltNames(
+ tbvCert.getExtensionValue(Extension.issuerAlternativeName.getId()), pkixParams.getBaseParameters().getNamedCertificateStoreMap()));
+ }
+ catch (CertificateParsingException e)
+ {
+ throw new AnnotatedException(
+ "No additional X.509 stores can be added from certificate locations.",
+ e);
+ }
+ Collection issuers = new HashSet();
+ // try to get the issuer certificate from one
+ // of the stores
+ try
+ {
+ issuers.addAll(CertPathValidatorUtilities.findIssuerCerts(tbvCert, pkixParams.getBaseParameters().getCertStores(), stores));
+ }
+ catch (AnnotatedException e)
+ {
+ throw new AnnotatedException(
+ "Cannot find issuer certificate for certificate in certification path.",
+ e);
+ }
+ if (issuers.isEmpty())
+ {
+ throw new AnnotatedException(
+ "No issuer certificate for certificate in certification path found.");
+ }
+ Iterator it = issuers.iterator();
+
+ while (it.hasNext() && builderResult == null)
+ {
+ X509Certificate issuer = (X509Certificate) it.next();
+ builderResult = build(issuer, pkixParams, tbvPath);
+ }
+ }
+ }
+ catch (AnnotatedException e)
+ {
+ certPathException = e;
+ }
+ if (builderResult == null)
+ {
+ tbvPath.remove(tbvCert);
+ }
+ return builderResult;
+ }
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
new file mode 100644
index 00000000..fe1bd4f3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
@@ -0,0 +1,568 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.PublicKey;
+import java.security.cert.CertPath;
+import java.security.cert.CertPathParameters;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.CertPathValidatorResult;
+import java.security.cert.CertPathValidatorSpi;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.PKIXCertPathChecker;
+import java.security.cert.PKIXCertPathValidatorResult;
+import java.security.cert.PKIXParameters;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Date;
+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.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.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.TBSCertificate;
+import com.android.internal.org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
+import com.android.internal.org.bouncycastle.jcajce.PKIXExtendedParameters;
+// BEGIN Android-removed:
+// import org.bouncycastle.jcajce.interfaces.BCX509Certificate;
+import com.android.internal.org.bouncycastle.jcajce.util.BCJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.jce.exception.ExtCertPathValidatorException;
+import com.android.internal.org.bouncycastle.x509.ExtendedPKIXParameters;
+
+/**
+ * CertPathValidatorSpi implementation for X.509 Certificate validation � la RFC
+ * 3280.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKIXCertPathValidatorSpi
+ extends CertPathValidatorSpi
+{
+ private final JcaJceHelper helper = new BCJcaJceHelper();
+ private final boolean isForCRLCheck;
+
+ public PKIXCertPathValidatorSpi()
+ {
+ this(false);
+ }
+
+ public PKIXCertPathValidatorSpi(boolean isForCRLCheck)
+ {
+ this.isForCRLCheck = isForCRLCheck;
+ }
+ // BEGIN Android-added: Avoid loading blocklist during class init
+ private static class NoPreloadHolder {
+ private final static CertBlocklist blocklist = new CertBlocklist();
+ }
+ // END Android-added: Avoid loading blocklist during class init
+
+ public CertPathValidatorResult engineValidate(
+ CertPath certPath,
+ CertPathParameters params)
+ throws CertPathValidatorException,
+ InvalidAlgorithmParameterException
+ {
+ PKIXExtendedParameters paramsPKIX;
+ if (params instanceof PKIXParameters)
+ {
+ PKIXExtendedParameters.Builder paramsPKIXBldr = new PKIXExtendedParameters.Builder((PKIXParameters)params);
+
+ if (params instanceof ExtendedPKIXParameters)
+ {
+ ExtendedPKIXParameters extPKIX = (ExtendedPKIXParameters)params;
+
+ paramsPKIXBldr.setUseDeltasEnabled(extPKIX.isUseDeltasEnabled());
+ paramsPKIXBldr.setValidityModel(extPKIX.getValidityModel());
+ }
+
+ paramsPKIX = paramsPKIXBldr.build();
+ }
+ else if (params instanceof PKIXExtendedBuilderParameters)
+ {
+ paramsPKIX = ((PKIXExtendedBuilderParameters)params).getBaseParameters();
+ }
+ else if (params instanceof PKIXExtendedParameters)
+ {
+ paramsPKIX = (PKIXExtendedParameters)params;
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("Parameters must be a " + PKIXParameters.class.getName() + " instance.");
+ }
+
+ if (paramsPKIX.getTrustAnchors() == null)
+ {
+ throw new InvalidAlgorithmParameterException(
+ "trustAnchors is null, this is not allowed for certification path validation.");
+ }
+
+ //
+ // 6.1.1 - inputs
+ //
+
+ //
+ // (a)
+ //
+ List certs = certPath.getCertificates();
+ int n = certs.size();
+
+ if (certs.isEmpty())
+ {
+ throw new CertPathValidatorException("Certification path is empty.", null, certPath, -1);
+ }
+ // BEGIN Android-added: Support blocklisting known-bad certs
+ {
+ X509Certificate cert = (X509Certificate) certs.get(0);
+
+ if (cert != null) {
+ BigInteger serial = cert.getSerialNumber();
+ if (NoPreloadHolder.blocklist.isSerialNumberBlockListed(serial)) {
+ // emulate CRL exception message in RFC3280CertPathUtilities.checkCRLs
+ String message = "Certificate revocation of serial 0x" + serial.toString(16);
+ System.out.println(message);
+ AnnotatedException e = new AnnotatedException(message);
+ throw new CertPathValidatorException(e.getMessage(), e, certPath, 0);
+ }
+ }
+ }
+ // END Android-added: Support blocklisting known-bad certs
+
+ //
+ // (b)
+ //
+ final Date currentDate = new Date();
+ final Date validityDate = CertPathValidatorUtilities.getValidityDate(paramsPKIX, currentDate);
+
+ //
+ // (c)
+ //
+ Set userInitialPolicySet = paramsPKIX.getInitialPolicies();
+
+ //
+ // (d)
+ //
+ TrustAnchor trust;
+ try
+ {
+ trust = CertPathValidatorUtilities.findTrustAnchor((X509Certificate) certs.get(certs.size() - 1),
+ paramsPKIX.getTrustAnchors(), paramsPKIX.getSigProvider());
+
+ if (trust == null)
+ {
+ throw new CertPathValidatorException("Trust anchor for certification path not found.", null, certPath, -1);
+ }
+
+ checkCertificate(trust.getTrustedCert());
+ }
+ catch (AnnotatedException e)
+ {
+ throw new CertPathValidatorException(e.getMessage(), e.getUnderlyingException(), certPath, certs.size() - 1);
+ }
+
+ // RFC 5280 - CRLs must originate from the same trust anchor as the target certificate.
+ paramsPKIX = new PKIXExtendedParameters.Builder(paramsPKIX).setTrustAnchor(trust).build();
+
+ //
+ // (e), (f), (g) are part of the paramsPKIX object.
+ //
+ Iterator certIter;
+ int index = 0;
+ int i;
+ // Certificate for each interation of the validation loop
+ // Signature information for each iteration of the validation loop
+ //
+ // 6.1.2 - setup
+ //
+
+ //
+ // (a)
+ //
+ List[] policyNodes = new ArrayList[n + 1];
+ for (int j = 0; j < policyNodes.length; j++)
+ {
+ policyNodes[j] = new ArrayList();
+ }
+
+ Set policySet = new HashSet();
+
+ policySet.add(RFC3280CertPathUtilities.ANY_POLICY);
+
+ PKIXPolicyNode validPolicyTree = new PKIXPolicyNode(new ArrayList(), 0, policySet, null, new HashSet(),
+ RFC3280CertPathUtilities.ANY_POLICY, false);
+
+ policyNodes[0].add(validPolicyTree);
+
+ //
+ // (b) and (c)
+ //
+ PKIXNameConstraintValidator nameConstraintValidator = new PKIXNameConstraintValidator();
+
+ // (d)
+ //
+ int explicitPolicy;
+ Set acceptablePolicies = new HashSet();
+
+ if (paramsPKIX.isExplicitPolicyRequired())
+ {
+ explicitPolicy = 0;
+ }
+ else
+ {
+ explicitPolicy = n + 1;
+ }
+
+ //
+ // (e)
+ //
+ int inhibitAnyPolicy;
+
+ if (paramsPKIX.isAnyPolicyInhibited())
+ {
+ inhibitAnyPolicy = 0;
+ }
+ else
+ {
+ inhibitAnyPolicy = n + 1;
+ }
+
+ //
+ // (f)
+ //
+ int policyMapping;
+
+ if (paramsPKIX.isPolicyMappingInhibited())
+ {
+ policyMapping = 0;
+ }
+ else
+ {
+ policyMapping = n + 1;
+ }
+
+ //
+ // (g), (h), (i), (j)
+ //
+ PublicKey workingPublicKey;
+ X500Name workingIssuerName;
+
+ X509Certificate sign = trust.getTrustedCert();
+ try
+ {
+ if (sign != null)
+ {
+ workingIssuerName = PrincipalUtils.getSubjectPrincipal(sign);
+ workingPublicKey = sign.getPublicKey();
+ }
+ else
+ {
+ workingIssuerName = PrincipalUtils.getCA(trust);
+ workingPublicKey = trust.getCAPublicKey();
+ }
+ }
+ catch (RuntimeException ex)
+ {
+ throw new ExtCertPathValidatorException("Subject of trust anchor could not be (re)encoded.", ex, certPath,
+ -1);
+ }
+
+ AlgorithmIdentifier workingAlgId = null;
+ try
+ {
+ workingAlgId = CertPathValidatorUtilities.getAlgorithmIdentifier(workingPublicKey);
+ }
+ catch (CertPathValidatorException e)
+ {
+ throw new ExtCertPathValidatorException(
+ "Algorithm identifier of public key of trust anchor could not be read.", e, certPath, -1);
+ }
+ ASN1ObjectIdentifier workingPublicKeyAlgorithm = workingAlgId.getAlgorithm();
+ ASN1Encodable workingPublicKeyParameters = workingAlgId.getParameters();
+
+ //
+ // (k)
+ //
+ int maxPathLength = n;
+
+ //
+ // 6.1.3
+ //
+
+ if (paramsPKIX.getTargetConstraints() != null
+ && !paramsPKIX.getTargetConstraints().match((X509Certificate) certs.get(0)))
+ {
+ throw new ExtCertPathValidatorException(
+ "Target certificate in certification path does not match targetConstraints.", null, certPath, 0);
+ }
+
+ //
+ // initialize CertPathChecker's
+ //
+ List pathCheckers = paramsPKIX.getCertPathCheckers();
+ certIter = pathCheckers.iterator();
+ while (certIter.hasNext())
+ {
+ ((PKIXCertPathChecker) certIter.next()).init(false);
+ }
+
+ //
+ // initialize RevocationChecker
+ //
+ ProvCrlRevocationChecker revocationChecker;
+ if (paramsPKIX.isRevocationEnabled())
+ {
+ revocationChecker = new ProvCrlRevocationChecker(helper);
+ }
+ else
+ {
+ revocationChecker = null;
+ }
+
+ X509Certificate cert = null;
+
+ for (index = certs.size() - 1; index >= 0; index--)
+ {
+ // BEGIN Android-added: Support blocklisting known-bad certs
+ if (NoPreloadHolder.blocklist.isPublicKeyBlockListed(workingPublicKey)) {
+ // emulate CRL exception message in RFC3280CertPathUtilities.checkCRLs
+ String message = "Certificate revocation of public key " + workingPublicKey;
+ System.out.println(message);
+ AnnotatedException e = new AnnotatedException(message);
+ throw new CertPathValidatorException(e.getMessage(), e, certPath, index);
+ }
+ // END Android-added: Support blocklisting known-bad certs
+ // try
+ // {
+ //
+ // i as defined in the algorithm description
+ //
+ i = n - index;
+
+ //
+ // set certificate to be checked in this round
+ // sign and workingPublicKey and workingIssuerName are set
+ // at the end of the for loop and initialized the
+ // first time from the TrustAnchor
+ //
+ cert = (X509Certificate) certs.get(index);
+ boolean verificationAlreadyPerformed = (index == certs.size() - 1);
+
+ try
+ {
+ checkCertificate(cert);
+ }
+ catch (AnnotatedException e)
+ {
+ throw new CertPathValidatorException(e.getMessage(), e.getUnderlyingException(), certPath, index);
+ }
+
+ //
+ // 6.1.3
+ //
+
+ RFC3280CertPathUtilities.processCertA(certPath, paramsPKIX, validityDate, revocationChecker, index,
+ workingPublicKey, verificationAlreadyPerformed, workingIssuerName, sign);
+
+ RFC3280CertPathUtilities.processCertBC(certPath, index, nameConstraintValidator, isForCRLCheck);
+
+ validPolicyTree = RFC3280CertPathUtilities.processCertD(certPath, index, acceptablePolicies,
+ validPolicyTree, policyNodes, inhibitAnyPolicy, isForCRLCheck);
+
+ validPolicyTree = RFC3280CertPathUtilities.processCertE(certPath, index, validPolicyTree);
+
+ RFC3280CertPathUtilities.processCertF(certPath, index, validPolicyTree, explicitPolicy);
+
+ //
+ // 6.1.4
+ //
+ if (i != n)
+ {
+ if (cert != null && cert.getVersion() == 1)
+ {
+ // we've found the trust anchor at the top of the path, ignore and keep going
+ if ((i == 1) && cert.equals(trust.getTrustedCert()))
+ {
+ continue;
+ }
+ throw new CertPathValidatorException("Version 1 certificates can't be used as CA ones.", null,
+ certPath, index);
+ }
+
+ RFC3280CertPathUtilities.prepareNextCertA(certPath, index);
+
+ validPolicyTree = RFC3280CertPathUtilities.prepareCertB(certPath, index, policyNodes, validPolicyTree,
+ policyMapping);
+
+ RFC3280CertPathUtilities.prepareNextCertG(certPath, index, nameConstraintValidator);
+
+ // (h)
+ explicitPolicy = RFC3280CertPathUtilities.prepareNextCertH1(certPath, index, explicitPolicy);
+ policyMapping = RFC3280CertPathUtilities.prepareNextCertH2(certPath, index, policyMapping);
+ inhibitAnyPolicy = RFC3280CertPathUtilities.prepareNextCertH3(certPath, index, inhibitAnyPolicy);
+
+ //
+ // (i)
+ //
+ explicitPolicy = RFC3280CertPathUtilities.prepareNextCertI1(certPath, index, explicitPolicy);
+ policyMapping = RFC3280CertPathUtilities.prepareNextCertI2(certPath, index, policyMapping);
+
+ // (j)
+ inhibitAnyPolicy = RFC3280CertPathUtilities.prepareNextCertJ(certPath, index, inhibitAnyPolicy);
+
+ // (k)
+ RFC3280CertPathUtilities.prepareNextCertK(certPath, index);
+
+ // (l)
+ maxPathLength = RFC3280CertPathUtilities.prepareNextCertL(certPath, index, maxPathLength);
+
+ // (m)
+ maxPathLength = RFC3280CertPathUtilities.prepareNextCertM(certPath, index, maxPathLength);
+
+ // (n)
+ RFC3280CertPathUtilities.prepareNextCertN(certPath, index);
+
+ Set criticalExtensions = cert.getCriticalExtensionOIDs();
+ if (criticalExtensions != null)
+ {
+ criticalExtensions = new HashSet(criticalExtensions);
+
+ // these extensions are handled by the algorithm
+ criticalExtensions.remove(RFC3280CertPathUtilities.KEY_USAGE);
+ criticalExtensions.remove(RFC3280CertPathUtilities.CERTIFICATE_POLICIES);
+ criticalExtensions.remove(RFC3280CertPathUtilities.POLICY_MAPPINGS);
+ criticalExtensions.remove(RFC3280CertPathUtilities.INHIBIT_ANY_POLICY);
+ criticalExtensions.remove(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT);
+ criticalExtensions.remove(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR);
+ criticalExtensions.remove(RFC3280CertPathUtilities.POLICY_CONSTRAINTS);
+ criticalExtensions.remove(RFC3280CertPathUtilities.BASIC_CONSTRAINTS);
+ criticalExtensions.remove(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME);
+ criticalExtensions.remove(RFC3280CertPathUtilities.NAME_CONSTRAINTS);
+ }
+ else
+ {
+ criticalExtensions = new HashSet();
+ }
+
+ // (o)
+ RFC3280CertPathUtilities.prepareNextCertO(certPath, index, criticalExtensions, pathCheckers);
+
+ // set signing certificate for next round
+ sign = cert;
+
+ // (c)
+ workingIssuerName = PrincipalUtils.getSubjectPrincipal(sign);
+
+ // (d)
+ try
+ {
+ workingPublicKey = CertPathValidatorUtilities.getNextWorkingKey(certPath.getCertificates(), index, helper);
+ }
+ catch (CertPathValidatorException e)
+ {
+ throw new CertPathValidatorException("Next working key could not be retrieved.", e, certPath, index);
+ }
+
+ workingAlgId = CertPathValidatorUtilities.getAlgorithmIdentifier(workingPublicKey);
+ // (f)
+ workingPublicKeyAlgorithm = workingAlgId.getAlgorithm();
+ // (e)
+ workingPublicKeyParameters = workingAlgId.getParameters();
+ }
+ }
+
+ //
+ // 6.1.5 Wrap-up procedure
+ //
+
+ explicitPolicy = RFC3280CertPathUtilities.wrapupCertA(explicitPolicy, cert);
+
+ explicitPolicy = RFC3280CertPathUtilities.wrapupCertB(certPath, index + 1, explicitPolicy);
+
+ //
+ // (c) (d) and (e) are already done
+ //
+
+ //
+ // (f)
+ //
+ Set criticalExtensions = cert.getCriticalExtensionOIDs();
+
+ if (criticalExtensions != null)
+ {
+ criticalExtensions = new HashSet(criticalExtensions);
+ // these extensions are handled by the algorithm
+ criticalExtensions.remove(RFC3280CertPathUtilities.KEY_USAGE);
+ criticalExtensions.remove(RFC3280CertPathUtilities.CERTIFICATE_POLICIES);
+ criticalExtensions.remove(RFC3280CertPathUtilities.POLICY_MAPPINGS);
+ criticalExtensions.remove(RFC3280CertPathUtilities.INHIBIT_ANY_POLICY);
+ criticalExtensions.remove(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT);
+ criticalExtensions.remove(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR);
+ criticalExtensions.remove(RFC3280CertPathUtilities.POLICY_CONSTRAINTS);
+ criticalExtensions.remove(RFC3280CertPathUtilities.BASIC_CONSTRAINTS);
+ criticalExtensions.remove(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME);
+ criticalExtensions.remove(RFC3280CertPathUtilities.NAME_CONSTRAINTS);
+ criticalExtensions.remove(RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS);
+ criticalExtensions.remove(Extension.extendedKeyUsage.getId());
+ }
+ else
+ {
+ criticalExtensions = new HashSet();
+ }
+
+ RFC3280CertPathUtilities.wrapupCertF(certPath, index + 1, pathCheckers, criticalExtensions);
+
+ PKIXPolicyNode intersection = RFC3280CertPathUtilities.wrapupCertG(certPath, paramsPKIX, userInitialPolicySet,
+ index + 1, policyNodes, validPolicyTree, acceptablePolicies);
+
+ if ((explicitPolicy > 0) || (intersection != null))
+ {
+ return new PKIXCertPathValidatorResult(trust, intersection, cert.getPublicKey());
+ }
+
+ throw new CertPathValidatorException("Path processing failed on policy.", null, certPath, index);
+ }
+
+ static void checkCertificate(X509Certificate cert)
+ throws AnnotatedException
+ {
+ // BEGIN Android-removed:
+ /*
+ if (cert instanceof BCX509Certificate)
+ {
+ RuntimeException cause = null;
+ try
+ {
+ if (null != ((BCX509Certificate)cert).getTBSCertificateNative())
+ {
+ return;
+ }
+ }
+ catch (RuntimeException e)
+ {
+ cause = e;
+ }
+
+ throw new AnnotatedException("unable to process TBSCertificate", cause);
+ }
+ */
+ // END Android-removed:
+ try
+ {
+ TBSCertificate.getInstance(cert.getTBSCertificate());
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new AnnotatedException("unable to process TBSCertificate", e);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new AnnotatedException(e.getMessage());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java
new file mode 100644
index 00000000..74679123
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java
@@ -0,0 +1,139 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+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.GeneralName;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralSubtree;
+import com.android.internal.org.bouncycastle.asn1.x509.NameConstraintValidatorException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKIXNameConstraintValidator
+{
+ com.android.internal.org.bouncycastle.asn1.x509.PKIXNameConstraintValidator validator = new com.android.internal.org.bouncycastle.asn1.x509.PKIXNameConstraintValidator();
+
+ public PKIXNameConstraintValidator()
+ {
+ }
+
+ public int hashCode()
+ {
+ return validator.hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof PKIXNameConstraintValidator))
+ {
+ return false;
+ }
+ PKIXNameConstraintValidator constraintValidator = (PKIXNameConstraintValidator)o;
+ return this.validator.equals(constraintValidator.validator);
+ }
+
+ public void checkPermittedDN(ASN1Sequence dns)
+ throws PKIXNameConstraintValidatorException
+ {
+ try
+ {
+ this.validator.checkPermittedDN(X500Name.getInstance(dns));
+ }
+ catch (NameConstraintValidatorException e)
+ {
+ throw new PKIXNameConstraintValidatorException(e.getMessage(), e);
+ }
+ }
+
+ public void checkExcludedDN(ASN1Sequence dns)
+ throws PKIXNameConstraintValidatorException
+ {
+ try
+ {
+ this.validator.checkExcludedDN(X500Name.getInstance(dns));
+ }
+ catch (NameConstraintValidatorException e)
+ {
+ throw new PKIXNameConstraintValidatorException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Checks if the given GeneralName is in the permitted set.
+ *
+ * @param name The GeneralName
+ * @throws PKIXNameConstraintValidatorException
+ * If the <code>name</code>
+ */
+ public void checkPermitted(GeneralName name)
+ throws PKIXNameConstraintValidatorException
+ {
+ try
+ {
+ validator.checkPermitted(name);
+ }
+ catch (NameConstraintValidatorException e)
+ {
+ throw new PKIXNameConstraintValidatorException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Check if the given GeneralName is contained in the excluded set.
+ *
+ * @param name The GeneralName.
+ * @throws PKIXNameConstraintValidatorException
+ * If the <code>name</code> is
+ * excluded.
+ */
+ public void checkExcluded(GeneralName name)
+ throws PKIXNameConstraintValidatorException
+ {
+ try
+ {
+ validator.checkExcluded(name);
+ }
+ catch (NameConstraintValidatorException e)
+ {
+ throw new PKIXNameConstraintValidatorException(e.getMessage(), e);
+ }
+ }
+
+ public void intersectPermittedSubtree(GeneralSubtree permitted)
+ {
+ validator.intersectPermittedSubtree(permitted);
+ }
+
+ /**
+ * Updates the permitted set of these name constraints with the intersection
+ * with the given subtree.
+ *
+ * @param permitted The permitted subtrees
+ */
+
+ public void intersectPermittedSubtree(GeneralSubtree[] permitted)
+ {
+ validator.intersectPermittedSubtree(permitted);
+ }
+
+ public void intersectEmptyPermittedSubtree(int nameType)
+ {
+ validator.intersectEmptyPermittedSubtree(nameType);
+ }
+
+ /**
+ * Adds a subtree to the excluded set of these name constraints.
+ *
+ * @param subtree A subtree with an excluded GeneralName.
+ */
+ public void addExcludedSubtree(GeneralSubtree subtree)
+ {
+ validator.addExcludedSubtree(subtree);
+ }
+
+ public String toString()
+ {
+ return validator.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java
new file mode 100644
index 00000000..ebcb3633
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKIXNameConstraintValidatorException
+ extends Exception
+{
+ private Throwable cause;
+
+ public PKIXNameConstraintValidatorException(String msg)
+ {
+ super(msg);
+ }
+
+ public PKIXNameConstraintValidatorException(String msg, Throwable e)
+ {
+ super(msg);
+
+ this.cause = e;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXPolicyNode.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXPolicyNode.java
new file mode 100644
index 00000000..763e5536
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXPolicyNode.java
@@ -0,0 +1,177 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.security.cert.PolicyNode;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PKIXPolicyNode
+ implements PolicyNode
+{
+ protected List children;
+ protected int depth;
+ protected Set expectedPolicies;
+ protected PolicyNode parent;
+ protected Set policyQualifiers;
+ protected String validPolicy;
+ protected boolean critical;
+
+ /*
+ *
+ * CONSTRUCTORS
+ *
+ */
+
+ public PKIXPolicyNode(
+ List _children,
+ int _depth,
+ Set _expectedPolicies,
+ PolicyNode _parent,
+ Set _policyQualifiers,
+ String _validPolicy,
+ boolean _critical)
+ {
+ children = _children;
+ depth = _depth;
+ expectedPolicies = _expectedPolicies;
+ parent = _parent;
+ policyQualifiers = _policyQualifiers;
+ validPolicy = _validPolicy;
+ critical = _critical;
+ }
+
+ public void addChild(
+ PKIXPolicyNode _child)
+ {
+ children.add(_child);
+ _child.setParent(this);
+ }
+
+ public Iterator getChildren()
+ {
+ return children.iterator();
+ }
+
+ public int getDepth()
+ {
+ return depth;
+ }
+
+ public Set getExpectedPolicies()
+ {
+ return expectedPolicies;
+ }
+
+ public PolicyNode getParent()
+ {
+ return parent;
+ }
+
+ public Set getPolicyQualifiers()
+ {
+ return policyQualifiers;
+ }
+
+ public String getValidPolicy()
+ {
+ return validPolicy;
+ }
+
+ public boolean hasChildren()
+ {
+ return !children.isEmpty();
+ }
+
+ public boolean isCritical()
+ {
+ return critical;
+ }
+
+ public void removeChild(PKIXPolicyNode _child)
+ {
+ children.remove(_child);
+ }
+
+ public void setCritical(boolean _critical)
+ {
+ critical = _critical;
+ }
+
+ public void setParent(PKIXPolicyNode _parent)
+ {
+ parent = _parent;
+ }
+
+ public String toString()
+ {
+ return toString("");
+ }
+
+ public String toString(String _indent)
+ {
+ StringBuffer _buf = new StringBuffer();
+ _buf.append(_indent);
+ _buf.append(validPolicy);
+ _buf.append(" {\n");
+
+ for(int i = 0; i < children.size(); i++)
+ {
+ _buf.append(((PKIXPolicyNode)children.get(i)).toString(_indent + " "));
+ }
+
+ _buf.append(_indent);
+ _buf.append("}\n");
+ return _buf.toString();
+ }
+
+ public Object clone()
+ {
+ return copy();
+ }
+
+ public PKIXPolicyNode copy()
+ {
+ Set _expectedPolicies = new HashSet();
+ Iterator _iter = expectedPolicies.iterator();
+ while (_iter.hasNext())
+ {
+ _expectedPolicies.add(new String((String)_iter.next()));
+ }
+
+ Set _policyQualifiers = new HashSet();
+ _iter = policyQualifiers.iterator();
+ while (_iter.hasNext())
+ {
+ _policyQualifiers.add(new String((String)_iter.next()));
+ }
+
+ PKIXPolicyNode _node = new PKIXPolicyNode(new ArrayList(),
+ depth,
+ _expectedPolicies,
+ null,
+ _policyQualifiers,
+ new String(validPolicy),
+ critical);
+
+ _iter = children.iterator();
+ while (_iter.hasNext())
+ {
+ PKIXPolicyNode _child = ((PKIXPolicyNode)_iter.next()).copy();
+ _child.setParent(_node);
+ _node.addChild(_child);
+ }
+
+ return _node;
+ }
+
+ public void setExpectedPolicies(Set expectedPolicies)
+ {
+ this.expectedPolicies = expectedPolicies;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PrincipalUtils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PrincipalUtils.java
new file mode 100644
index 00000000..9cd9a2b2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PrincipalUtils.java
@@ -0,0 +1,142 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x500.X500NameStyle;
+// import org.bouncycastle.jcajce.interfaces.BCX509Certificate;
+import com.android.internal.org.bouncycastle.x509.X509AttributeCertificate;
+
+class PrincipalUtils
+{
+ static X500Name getCA(TrustAnchor trustAnchor)
+ {
+ return getX500Name(notNull(trustAnchor).getCA());
+ }
+
+ /**
+ * Returns the issuer of an attribute certificate or certificate.
+ *
+ * @param cert The attribute certificate or certificate.
+ * @return The issuer as <code>X500Principal</code>.
+ */
+ static X500Name getEncodedIssuerPrincipal(Object cert)
+ {
+ if (cert instanceof X509Certificate)
+ {
+ return getIssuerPrincipal((X509Certificate)cert);
+ }
+ else
+ {
+ return getX500Name((X500Principal)((X509AttributeCertificate)cert).getIssuer().getPrincipals()[0]);
+ }
+ }
+
+ static X500Name getIssuerPrincipal(X509Certificate certificate)
+ {
+ // BEGIN Android-removed: unsupported
+ /*
+ if (certificate instanceof BCX509Certificate)
+ {
+ return notNull(((BCX509Certificate)certificate).getIssuerX500Name());
+ }
+ */
+ // END Android-removed: unsupported
+ return getX500Name(notNull(certificate).getIssuerX500Principal());
+ }
+
+ static X500Name getIssuerPrincipal(X509CRL crl)
+ {
+ return getX500Name(notNull(crl).getIssuerX500Principal());
+ }
+
+ static X500Name getSubjectPrincipal(X509Certificate certificate)
+ {
+ // BEGIN Android-removed: unsupported
+ /*
+ if (certificate instanceof BCX509Certificate)
+ {
+ return notNull(((BCX509Certificate)certificate).getSubjectX500Name());
+ }
+ */
+ // END Android-removed: unsupported
+ return getX500Name(notNull(certificate).getSubjectX500Principal());
+ }
+
+ static X500Name getX500Name(X500Principal principal)
+ {
+ X500Name name = X500Name.getInstance(getEncoded(principal));
+ return notNull(name);
+ }
+
+ static X500Name getX500Name(X500NameStyle style, X500Principal principal)
+ {
+ X500Name name = X500Name.getInstance(style, getEncoded(principal));
+ return notNull(name);
+ }
+
+ private static byte[] getEncoded(X500Principal principal)
+ {
+ byte[] encoding = notNull(principal).getEncoded();
+ return notNull(encoding);
+ }
+
+ private static byte[] notNull(byte[] encoding)
+ {
+ if (null == encoding)
+ {
+ throw new IllegalStateException();
+ }
+ return encoding;
+ }
+
+ private static TrustAnchor notNull(TrustAnchor trustAnchor)
+ {
+ if (null == trustAnchor)
+ {
+ throw new IllegalStateException();
+ }
+ return trustAnchor;
+ }
+
+ private static X509Certificate notNull(X509Certificate certificate)
+ {
+ if (null == certificate)
+ {
+ throw new IllegalStateException();
+ }
+ return certificate;
+ }
+
+ private static X509CRL notNull(X509CRL crl)
+ {
+ if (null == crl)
+ {
+ throw new IllegalStateException();
+ }
+ return crl;
+ }
+
+ private static X500Name notNull(X500Name name)
+ {
+ if (null == name)
+ {
+ throw new IllegalStateException();
+ }
+ return name;
+ }
+
+ private static X500Principal notNull(X500Principal principal)
+ {
+ if (null == principal)
+ {
+ throw new IllegalStateException();
+ }
+ return principal;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/ProvCrlRevocationChecker.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/ProvCrlRevocationChecker.java
new file mode 100644
index 00000000..fd7640e9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/ProvCrlRevocationChecker.java
@@ -0,0 +1,68 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+import com.android.internal.org.bouncycastle.jcajce.PKIXCertRevocationChecker;
+import com.android.internal.org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+
+class ProvCrlRevocationChecker
+ implements PKIXCertRevocationChecker
+{
+ private final JcaJceHelper helper;
+
+ private PKIXCertRevocationCheckerParameters params;
+ private Date currentDate = null;
+
+ public ProvCrlRevocationChecker(JcaJceHelper helper)
+ {
+ this.helper = helper;
+ }
+
+ public void setParameter(String name, Object value)
+ {
+
+ }
+
+ public void initialize(PKIXCertRevocationCheckerParameters params)
+ {
+ this.params = params;
+ this.currentDate = new Date();
+ }
+
+ public void init(boolean forForward)
+ throws CertPathValidatorException
+ {
+ if (forForward)
+ {
+ throw new CertPathValidatorException("forward checking not supported");
+ }
+
+ this.params = null;
+ this.currentDate = new Date();
+ }
+
+ public void check(Certificate certificate)
+ throws CertPathValidatorException
+ {
+ try
+ {
+ RFC3280CertPathUtilities.checkCRLs(params, params.getParamsPKIX(), currentDate, params.getValidDate(),
+ (X509Certificate)certificate, params.getSigningCert(), params.getWorkingPublicKey(),
+ params.getCertPath().getCertificates(), helper);
+ }
+ catch (AnnotatedException e)
+ {
+ Throwable cause = e;
+ if (null != e.getCause())
+ {
+ cause = e.getCause();
+ }
+ throw new CertPathValidatorException(e.getMessage(), cause, params.getCertPath(), params.getIndex());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
new file mode 100644
index 00000000..64da5710
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
@@ -0,0 +1,2534 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.PublicKey;
+import java.security.cert.CertPath;
+import java.security.cert.CertPathBuilderException;
+import java.security.cert.CertPathBuilderSpi;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.PKIXCertPathChecker;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CertSelector;
+import java.security.cert.X509Certificate;
+import java.security.cert.X509Extension;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimeZone;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1String;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.x500.RDN;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x500.style.BCStyle;
+import com.android.internal.org.bouncycastle.asn1.x509.BasicConstraints;
+import com.android.internal.org.bouncycastle.asn1.x509.CRLDistPoint;
+import com.android.internal.org.bouncycastle.asn1.x509.CRLReason;
+import com.android.internal.org.bouncycastle.asn1.x509.DistributionPoint;
+import com.android.internal.org.bouncycastle.asn1.x509.DistributionPointName;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+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.GeneralSubtree;
+import com.android.internal.org.bouncycastle.asn1.x509.IssuingDistributionPoint;
+import com.android.internal.org.bouncycastle.asn1.x509.NameConstraints;
+import com.android.internal.org.bouncycastle.asn1.x509.PolicyInformation;
+import com.android.internal.org.bouncycastle.jcajce.PKIXCRLStore;
+import com.android.internal.org.bouncycastle.jcajce.PKIXCertRevocationChecker;
+import com.android.internal.org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
+import com.android.internal.org.bouncycastle.jcajce.PKIXCertStoreSelector;
+import com.android.internal.org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
+import com.android.internal.org.bouncycastle.jcajce.PKIXExtendedParameters;
+import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.ClassUtil;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.jce.exception.ExtCertPathValidatorException;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+class RFC3280CertPathUtilities
+{
+ private static final Class revChkClass = ClassUtil.loadClass(RFC3280CertPathUtilities.class, "java.security.cert.PKIXRevocationChecker");
+
+ /**
+ * If the complete CRL includes an issuing distribution point (IDP) CRL
+ * extension check the following:
+ * <p>
+ * (i) If the distribution point name is present in the IDP CRL extension
+ * and the distribution field is present in the DP, then verify that one of
+ * the names in the IDP matches one of the names in the DP. If the
+ * distribution point name is present in the IDP CRL extension and the
+ * distribution field is omitted from the DP, then verify that one of the
+ * names in the IDP matches one of the names in the cRLIssuer field of the
+ * DP.
+ * </p>
+ * <p>
+ * (ii) If the onlyContainsUserCerts boolean is asserted in the IDP CRL
+ * extension, verify that the certificate does not include the basic
+ * constraints extension with the cA boolean asserted.
+ * </p>
+ * <p>
+ * (iii) If the onlyContainsCACerts boolean is asserted in the IDP CRL
+ * extension, verify that the certificate includes the basic constraints
+ * extension with the cA boolean asserted.
+ * </p>
+ * <p>
+ * (iv) Verify that the onlyContainsAttributeCerts boolean is not asserted.
+ * </p>
+ *
+ * @param dp The distribution point.
+ * @param cert The certificate.
+ * @param crl The CRL.
+ * @throws AnnotatedException if one of the conditions is not met or an error occurs.
+ */
+ protected static void processCRLB2(
+ DistributionPoint dp,
+ Object cert,
+ X509CRL crl)
+ throws AnnotatedException
+ {
+ IssuingDistributionPoint idp = null;
+ try
+ {
+ idp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl,
+ RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT));
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e);
+ }
+ // (b) (2) (i)
+ // distribution point name is present
+ if (idp != null)
+ {
+ if (idp.getDistributionPoint() != null)
+ {
+ // make list of names
+ DistributionPointName dpName = IssuingDistributionPoint.getInstance(idp).getDistributionPoint();
+ List names = new ArrayList();
+
+ if (dpName.getType() == DistributionPointName.FULL_NAME)
+ {
+ GeneralName[] genNames = GeneralNames.getInstance(dpName.getName()).getNames();
+ for (int j = 0; j < genNames.length; j++)
+ {
+ names.add(genNames[j]);
+ }
+ }
+ if (dpName.getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER)
+ {
+ ASN1EncodableVector vec = new ASN1EncodableVector();
+ try
+ {
+ Enumeration e = ASN1Sequence.getInstance(PrincipalUtils.getIssuerPrincipal(crl)).getObjects();
+ while (e.hasMoreElements())
+ {
+ vec.add((ASN1Encodable)e.nextElement());
+ }
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("Could not read CRL issuer.", e);
+ }
+ vec.add(dpName.getName());
+ names.add(new GeneralName(X500Name.getInstance(new DERSequence(vec))));
+ }
+ boolean matches = false;
+ // verify that one of the names in the IDP matches one
+ // of the names in the DP.
+ if (dp.getDistributionPoint() != null)
+ {
+ dpName = dp.getDistributionPoint();
+ GeneralName[] genNames = null;
+ if (dpName.getType() == DistributionPointName.FULL_NAME)
+ {
+ genNames = GeneralNames.getInstance(dpName.getName()).getNames();
+ }
+ if (dpName.getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER)
+ {
+ if (dp.getCRLIssuer() != null)
+ {
+ genNames = dp.getCRLIssuer().getNames();
+ }
+ else
+ {
+ genNames = new GeneralName[1];
+ try
+ {
+ genNames[0] = new GeneralName(PrincipalUtils.getEncodedIssuerPrincipal(cert));
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("Could not read certificate issuer.", e);
+ }
+ }
+ for (int j = 0; j < genNames.length; j++)
+ {
+ Enumeration e = ASN1Sequence.getInstance(genNames[j].getName().toASN1Primitive()).getObjects();
+ ASN1EncodableVector vec = new ASN1EncodableVector();
+ while (e.hasMoreElements())
+ {
+ vec.add((ASN1Encodable)e.nextElement());
+ }
+ vec.add(dpName.getName());
+ genNames[j] = new GeneralName(X500Name.getInstance(new DERSequence(vec)));
+ }
+ }
+ if (genNames != null)
+ {
+ for (int j = 0; j < genNames.length; j++)
+ {
+ if (names.contains(genNames[j]))
+ {
+ matches = true;
+ break;
+ }
+ }
+ }
+ if (!matches)
+ {
+ throw new AnnotatedException(
+ "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point.");
+ }
+ }
+ // verify that one of the names in
+ // the IDP matches one of the names in the cRLIssuer field of
+ // the DP
+ else
+ {
+ if (dp.getCRLIssuer() == null)
+ {
+ throw new AnnotatedException("Either the cRLIssuer or the distributionPoint field must "
+ + "be contained in DistributionPoint.");
+ }
+ GeneralName[] genNames = dp.getCRLIssuer().getNames();
+ for (int j = 0; j < genNames.length; j++)
+ {
+ if (names.contains(genNames[j]))
+ {
+ matches = true;
+ break;
+ }
+ }
+ if (!matches)
+ {
+ throw new AnnotatedException(
+ "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point.");
+ }
+ }
+ }
+ BasicConstraints bc = null;
+ try
+ {
+ bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue((X509Extension)cert,
+ BASIC_CONSTRAINTS));
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("Basic constraints extension could not be decoded.", e);
+ }
+
+ if (cert instanceof X509Certificate)
+ {
+ // (b) (2) (ii)
+ if (idp.onlyContainsUserCerts() && (bc != null && bc.isCA()))
+ {
+ throw new AnnotatedException("CA Cert CRL only contains user certificates.");
+ }
+
+ // (b) (2) (iii)
+ if (idp.onlyContainsCACerts() && (bc == null || !bc.isCA()))
+ {
+ throw new AnnotatedException("End CRL only contains CA certificates.");
+ }
+ }
+
+ // (b) (2) (iv)
+ if (idp.onlyContainsAttributeCerts())
+ {
+ throw new AnnotatedException("onlyContainsAttributeCerts boolean is asserted.");
+ }
+ }
+ }
+
+ /**
+ * If the DP includes cRLIssuer, then verify that the issuer field in the
+ * complete CRL matches cRLIssuer in the DP and that the complete CRL
+ * contains an issuing distribution point extension with the indirectCRL
+ * boolean asserted. Otherwise, verify that the CRL issuer matches the
+ * certificate issuer.
+ *
+ * @param dp The distribution point.
+ * @param cert The certificate ot attribute certificate.
+ * @param crl The CRL for <code>cert</code>.
+ * @throws AnnotatedException if one of the above conditions does not apply or an error
+ * occurs.
+ */
+ protected static void processCRLB1(
+ DistributionPoint dp,
+ Object cert,
+ X509CRL crl)
+ throws AnnotatedException
+ {
+ ASN1Primitive idp = CertPathValidatorUtilities.getExtensionValue(crl, ISSUING_DISTRIBUTION_POINT);
+ boolean isIndirect = false;
+ if (idp != null)
+ {
+ if (IssuingDistributionPoint.getInstance(idp).isIndirectCRL())
+ {
+ isIndirect = true;
+ }
+ }
+ byte[] issuerBytes;
+
+ try
+ {
+ issuerBytes = PrincipalUtils.getIssuerPrincipal(crl).getEncoded();
+ }
+ catch (IOException e)
+ {
+ throw new AnnotatedException("Exception encoding CRL issuer: " + e.getMessage(), e);
+ }
+
+ boolean matchIssuer = false;
+ if (dp.getCRLIssuer() != null)
+ {
+ GeneralName genNames[] = dp.getCRLIssuer().getNames();
+ for (int j = 0; j < genNames.length; j++)
+ {
+ if (genNames[j].getTagNo() == GeneralName.directoryName)
+ {
+ try
+ {
+ if (Arrays.areEqual(genNames[j].getName().toASN1Primitive().getEncoded(), issuerBytes))
+ {
+ matchIssuer = true;
+ }
+ }
+ catch (IOException e)
+ {
+ throw new AnnotatedException(
+ "CRL issuer information from distribution point cannot be decoded.", e);
+ }
+ }
+ }
+ if (matchIssuer && !isIndirect)
+ {
+ throw new AnnotatedException("Distribution point contains cRLIssuer field but CRL is not indirect.");
+ }
+ if (!matchIssuer)
+ {
+ throw new AnnotatedException("CRL issuer of CRL does not match CRL issuer of distribution point.");
+ }
+ }
+ else
+ {
+ if (PrincipalUtils.getIssuerPrincipal(crl).equals(
+ PrincipalUtils.getEncodedIssuerPrincipal(cert)))
+ {
+ matchIssuer = true;
+ }
+ }
+ if (!matchIssuer)
+ {
+ throw new AnnotatedException("Cannot find matching CRL issuer for certificate.");
+ }
+ }
+
+ protected static ReasonsMask processCRLD(
+ X509CRL crl,
+ DistributionPoint dp)
+ throws AnnotatedException
+ {
+ IssuingDistributionPoint idp = null;
+ try
+ {
+ idp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl,
+ RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT));
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e);
+ }
+ // (d) (1)
+ if (idp != null && idp.getOnlySomeReasons() != null && dp.getReasons() != null)
+ {
+ return new ReasonsMask(dp.getReasons()).intersect(new ReasonsMask(idp.getOnlySomeReasons()));
+ }
+ // (d) (4)
+ if ((idp == null || idp.getOnlySomeReasons() == null) && dp.getReasons() == null)
+ {
+ return ReasonsMask.allReasons;
+ }
+ // (d) (2) and (d)(3)
+ return (dp.getReasons() == null
+ ? ReasonsMask.allReasons
+ : new ReasonsMask(dp.getReasons())).intersect(idp == null
+ ? ReasonsMask.allReasons
+ : new ReasonsMask(idp.getOnlySomeReasons()));
+
+ }
+
+ public static final String CERTIFICATE_POLICIES = Extension.certificatePolicies.getId();
+
+ public static final String POLICY_MAPPINGS = Extension.policyMappings.getId();
+
+ public static final String INHIBIT_ANY_POLICY = Extension.inhibitAnyPolicy.getId();
+
+ public static final String ISSUING_DISTRIBUTION_POINT = Extension.issuingDistributionPoint.getId();
+
+ public static final String FRESHEST_CRL = Extension.freshestCRL.getId();
+
+ public static final String DELTA_CRL_INDICATOR = Extension.deltaCRLIndicator.getId();
+
+ public static final String POLICY_CONSTRAINTS = Extension.policyConstraints.getId();
+
+ public static final String BASIC_CONSTRAINTS = Extension.basicConstraints.getId();
+
+ public static final String CRL_DISTRIBUTION_POINTS = Extension.cRLDistributionPoints.getId();
+
+ public static final String SUBJECT_ALTERNATIVE_NAME = Extension.subjectAlternativeName.getId();
+
+ public static final String NAME_CONSTRAINTS = Extension.nameConstraints.getId();
+
+ public static final String AUTHORITY_KEY_IDENTIFIER = Extension.authorityKeyIdentifier.getId();
+
+ public static final String KEY_USAGE = Extension.keyUsage.getId();
+
+ public static final String CRL_NUMBER = Extension.cRLNumber.getId();
+
+ public static final String ANY_POLICY = "2.5.29.32.0";
+
+ /*
+ * key usage bits
+ */
+ protected static final int KEY_CERT_SIGN = 5;
+
+ protected static final int CRL_SIGN = 6;
+
+ /**
+ * Obtain and validate the certification path for the complete CRL issuer.
+ * If a key usage extension is present in the CRL issuer's certificate,
+ * verify that the cRLSign bit is set.
+ *
+ * @param crl CRL which contains revocation information for the certificate
+ * <code>cert</code>.
+ * @param cert The attribute certificate or certificate to check if it is
+ * revoked.
+ * @param defaultCRLSignCert The issuer certificate of the certificate <code>cert</code>.
+ * @param defaultCRLSignKey The public key of the issuer certificate
+ * <code>defaultCRLSignCert</code>.
+ * @param paramsPKIX paramsPKIX PKIX parameters.
+ * @param certPathCerts The certificates on the certification path.
+ * @return A <code>Set</code> with all keys of possible CRL issuer
+ * certificates.
+ * @throws AnnotatedException if the CRL is not valid or the status cannot be checked or
+ * some error occurs.
+ */
+ protected static Set processCRLF(
+ X509CRL crl,
+ Object cert,
+ X509Certificate defaultCRLSignCert,
+ PublicKey defaultCRLSignKey,
+ PKIXExtendedParameters paramsPKIX,
+ List certPathCerts,
+ JcaJceHelper helper)
+ throws AnnotatedException
+ {
+ // (f)
+
+ // get issuer from CRL
+ X509CertSelector certSelector = new X509CertSelector();
+ try
+ {
+ byte[] issuerPrincipal = PrincipalUtils.getIssuerPrincipal(crl).getEncoded();
+ certSelector.setSubject(issuerPrincipal);
+ }
+ catch (IOException e)
+ {
+ throw new AnnotatedException(
+ "Subject criteria for certificate selector to find issuer certificate for CRL could not be set.", e);
+ }
+
+ PKIXCertStoreSelector selector = new PKIXCertStoreSelector.Builder(certSelector).build();
+
+ // get CRL signing certs
+ LinkedHashSet coll = new LinkedHashSet();
+ try
+ {
+ CertPathValidatorUtilities.findCertificates(coll, selector, paramsPKIX.getCertificateStores());
+ CertPathValidatorUtilities.findCertificates(coll, selector, paramsPKIX.getCertStores());
+ }
+ catch (AnnotatedException e)
+ {
+ throw new AnnotatedException("Issuer certificate for CRL cannot be searched.", e);
+ }
+
+ coll.add(defaultCRLSignCert);
+
+ Iterator cert_it = coll.iterator();
+
+ List validCerts = new ArrayList();
+ List validKeys = new ArrayList();
+
+ while (cert_it.hasNext())
+ {
+ X509Certificate signingCert = (X509Certificate)cert_it.next();
+
+ /*
+ * CA of the certificate, for which this CRL is checked, has also
+ * signed CRL, so skip the path validation, because is already done
+ */
+ if (signingCert.equals(defaultCRLSignCert))
+ {
+ validCerts.add(signingCert);
+ validKeys.add(defaultCRLSignKey);
+ continue;
+ }
+ try
+ {
+ // BEGIN Android-changed:
+ // CertPathBuilderSpi builder = (revChkClass != null)
+ // ? new PKIXCertPathBuilderSpi_8(true) : new PKIXCertPathBuilderSpi(true);
+ // END Android-changed:
+ CertPathBuilderSpi builder = new PKIXCertPathBuilderSpi(true);
+ X509CertSelector tmpCertSelector = new X509CertSelector();
+ tmpCertSelector.setCertificate(signingCert);
+
+ PKIXExtendedParameters.Builder paramsBuilder = new PKIXExtendedParameters.Builder(paramsPKIX)
+ .setTargetConstraints(new PKIXCertStoreSelector.Builder(tmpCertSelector).build());
+
+ /*
+ * if signingCert is placed not higher on the cert path a
+ * dependency loop results. CRL for cert is checked, but
+ * signingCert is needed for checking the CRL which is dependent
+ * on checking cert because it is higher in the cert path and so
+ * signing signingCert transitively. so, revocation is disabled,
+ * forgery attacks of the CRL are detected in this outer loop
+ * for all other it must be enabled to prevent forgery attacks
+ */
+ if (certPathCerts.contains(signingCert))
+ {
+ paramsBuilder.setRevocationEnabled(false);
+ }
+ else
+ {
+ paramsBuilder.setRevocationEnabled(true);
+ }
+
+ PKIXExtendedBuilderParameters extParams = new PKIXExtendedBuilderParameters.Builder(paramsBuilder.build()).build();
+
+ List certs = builder.engineBuild(extParams).getCertPath().getCertificates();
+ validCerts.add(signingCert);
+ validKeys.add(CertPathValidatorUtilities.getNextWorkingKey(certs, 0, helper));
+ }
+ catch (CertPathBuilderException e)
+ {
+ throw new AnnotatedException("CertPath for CRL signer failed to validate.", e);
+ }
+ catch (CertPathValidatorException e)
+ {
+ throw new AnnotatedException("Public key of issuer certificate of CRL could not be retrieved.", e);
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException(e.getMessage());
+ }
+ }
+
+ Set checkKeys = new HashSet();
+
+ AnnotatedException lastException = null;
+ for (int i = 0; i < validCerts.size(); i++)
+ {
+ X509Certificate signCert = (X509Certificate)validCerts.get(i);
+ boolean[] keyUsage = signCert.getKeyUsage();
+
+ if (keyUsage != null && (keyUsage.length <= CRL_SIGN || !keyUsage[CRL_SIGN]))
+ {
+ lastException = new AnnotatedException(
+ "Issuer certificate key usage extension does not permit CRL signing.");
+ }
+ else
+ {
+ checkKeys.add(validKeys.get(i));
+ }
+ }
+
+ if (checkKeys.isEmpty() && lastException == null)
+ {
+ throw new AnnotatedException("Cannot find a valid issuer certificate.");
+ }
+ if (checkKeys.isEmpty() && lastException != null)
+ {
+ throw lastException;
+ }
+
+ return checkKeys;
+ }
+
+ protected static PublicKey processCRLG(
+ X509CRL crl,
+ Set keys)
+ throws AnnotatedException
+ {
+ Exception lastException = null;
+ for (Iterator it = keys.iterator(); it.hasNext();)
+ {
+ PublicKey key = (PublicKey)it.next();
+ try
+ {
+ crl.verify(key);
+ return key;
+ }
+ catch (Exception e)
+ {
+ lastException = e;
+ }
+ }
+ throw new AnnotatedException("Cannot verify CRL.", lastException);
+ }
+
+ protected static X509CRL processCRLH(
+ Set deltacrls,
+ PublicKey key)
+ throws AnnotatedException
+ {
+ Exception lastException = null;
+
+ for (Iterator it = deltacrls.iterator(); it.hasNext();)
+ {
+ X509CRL crl = (X509CRL)it.next();
+ try
+ {
+ crl.verify(key);
+ return crl;
+ }
+ catch (Exception e)
+ {
+ lastException = e;
+ }
+ }
+
+ if (lastException != null)
+ {
+ throw new AnnotatedException("Cannot verify delta CRL.", lastException);
+ }
+ return null;
+ }
+
+ /**
+ * If use-deltas is set, verify the issuer and scope of the delta CRL.
+ *
+ * @param deltaCRL The delta CRL.
+ * @param completeCRL The complete CRL.
+ * @param pkixParams The PKIX paramaters.
+ * @throws AnnotatedException if an exception occurs.
+ */
+ protected static void processCRLC(
+ X509CRL deltaCRL,
+ X509CRL completeCRL,
+ PKIXExtendedParameters pkixParams)
+ throws AnnotatedException
+ {
+ if (deltaCRL == null)
+ {
+ return;
+ }
+
+ if (deltaCRL.hasUnsupportedCriticalExtension())
+ {
+ throw new AnnotatedException("delta CRL has unsupported critical extensions");
+ }
+
+ IssuingDistributionPoint completeidp = null;
+ try
+ {
+ completeidp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(
+ completeCRL, RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT));
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e);
+ }
+
+ if (pkixParams.isUseDeltasEnabled())
+ {
+ // (c) (1)
+ if (!PrincipalUtils.getIssuerPrincipal(deltaCRL).equals(PrincipalUtils.getIssuerPrincipal(completeCRL)))
+ {
+ throw new AnnotatedException("Complete CRL issuer does not match delta CRL issuer.");
+ }
+
+ // (c) (2)
+ IssuingDistributionPoint deltaidp = null;
+ try
+ {
+ deltaidp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(
+ deltaCRL, ISSUING_DISTRIBUTION_POINT));
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException(
+ "Issuing distribution point extension from delta CRL could not be decoded.", e);
+ }
+
+ boolean match = false;
+ if (completeidp == null)
+ {
+ if (deltaidp == null)
+ {
+ match = true;
+ }
+ }
+ else
+ {
+ if (completeidp.equals(deltaidp))
+ {
+ match = true;
+ }
+ }
+ if (!match)
+ {
+ throw new AnnotatedException(
+ "Issuing distribution point extension from delta CRL and complete CRL does not match.");
+ }
+
+ // (c) (3)
+ ASN1Primitive completeKeyIdentifier = null;
+ try
+ {
+ completeKeyIdentifier = CertPathValidatorUtilities.getExtensionValue(
+ completeCRL, AUTHORITY_KEY_IDENTIFIER);
+ }
+ catch (AnnotatedException e)
+ {
+ throw new AnnotatedException(
+ "Authority key identifier extension could not be extracted from complete CRL.", e);
+ }
+
+ ASN1Primitive deltaKeyIdentifier = null;
+ try
+ {
+ deltaKeyIdentifier = CertPathValidatorUtilities.getExtensionValue(
+ deltaCRL, AUTHORITY_KEY_IDENTIFIER);
+ }
+ catch (AnnotatedException e)
+ {
+ throw new AnnotatedException(
+ "Authority key identifier extension could not be extracted from delta CRL.", e);
+ }
+
+ if (completeKeyIdentifier == null)
+ {
+ throw new AnnotatedException("CRL authority key identifier is null.");
+ }
+
+ if (deltaKeyIdentifier == null)
+ {
+ throw new AnnotatedException("Delta CRL authority key identifier is null.");
+ }
+
+ if (!completeKeyIdentifier.equals(deltaKeyIdentifier))
+ {
+ throw new AnnotatedException(
+ "Delta CRL authority key identifier does not match complete CRL authority key identifier.");
+ }
+ }
+ }
+
+ protected static void processCRLI(
+ Date validDate,
+ X509CRL deltacrl,
+ Object cert,
+ CertStatus certStatus,
+ PKIXExtendedParameters pkixParams)
+ throws AnnotatedException
+ {
+ if (pkixParams.isUseDeltasEnabled() && deltacrl != null)
+ {
+ CertPathValidatorUtilities.getCertStatus(validDate, deltacrl, cert, certStatus);
+ }
+ }
+
+ protected static void processCRLJ(
+ Date validDate,
+ X509CRL completecrl,
+ Object cert,
+ CertStatus certStatus)
+ throws AnnotatedException
+ {
+ if (certStatus.getCertStatus() == CertStatus.UNREVOKED)
+ {
+ CertPathValidatorUtilities.getCertStatus(validDate, completecrl, cert, certStatus);
+ }
+ }
+
+ protected static PKIXPolicyNode prepareCertB(
+ CertPath certPath,
+ int index,
+ List[] policyNodes,
+ PKIXPolicyNode validPolicyTree,
+ int policyMapping)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ int n = certs.size();
+ // i as defined in the algorithm description
+ int i = n - index;
+ // (b)
+ //
+ ASN1Sequence pm = null;
+ try
+ {
+ pm = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ RFC3280CertPathUtilities.POLICY_MAPPINGS));
+ }
+ catch (AnnotatedException ex)
+ {
+ throw new ExtCertPathValidatorException("Policy mappings extension could not be decoded.", ex, certPath,
+ index);
+ }
+ PKIXPolicyNode _validPolicyTree = validPolicyTree;
+ if (pm != null)
+ {
+ ASN1Sequence mappings = (ASN1Sequence)pm;
+ Map m_idp = new HashMap();
+ Set s_idp = new HashSet();
+
+ for (int j = 0; j < mappings.size(); j++)
+ {
+ ASN1Sequence mapping = (ASN1Sequence)mappings.getObjectAt(j);
+ String id_p = ((ASN1ObjectIdentifier)mapping.getObjectAt(0)).getId();
+ String sd_p = ((ASN1ObjectIdentifier)mapping.getObjectAt(1)).getId();
+ Set tmp;
+
+ if (!m_idp.containsKey(id_p))
+ {
+ tmp = new HashSet();
+ tmp.add(sd_p);
+ m_idp.put(id_p, tmp);
+ s_idp.add(id_p);
+ }
+ else
+ {
+ tmp = (Set)m_idp.get(id_p);
+ tmp.add(sd_p);
+ }
+ }
+
+ Iterator it_idp = s_idp.iterator();
+ while (it_idp.hasNext())
+ {
+ String id_p = (String)it_idp.next();
+
+ //
+ // (1)
+ //
+ if (policyMapping > 0)
+ {
+ boolean idp_found = false;
+ Iterator nodes_i = policyNodes[i].iterator();
+ while (nodes_i.hasNext())
+ {
+ PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
+ if (node.getValidPolicy().equals(id_p))
+ {
+ idp_found = true;
+ node.expectedPolicies = (Set)m_idp.get(id_p);
+ break;
+ }
+ }
+
+ if (!idp_found)
+ {
+ nodes_i = policyNodes[i].iterator();
+ while (nodes_i.hasNext())
+ {
+ PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
+ if (RFC3280CertPathUtilities.ANY_POLICY.equals(node.getValidPolicy()))
+ {
+ Set pq = null;
+ ASN1Sequence policies = null;
+ try
+ {
+ policies = (ASN1Sequence)CertPathValidatorUtilities.getExtensionValue(cert,
+ RFC3280CertPathUtilities.CERTIFICATE_POLICIES);
+ }
+ catch (AnnotatedException e)
+ {
+ throw new ExtCertPathValidatorException(
+ "Certificate policies extension could not be decoded.", e, certPath, index);
+ }
+ Enumeration e = policies.getObjects();
+ while (e.hasMoreElements())
+ {
+ PolicyInformation pinfo = null;
+ try
+ {
+ pinfo = PolicyInformation.getInstance(e.nextElement());
+ }
+ catch (Exception ex)
+ {
+ throw new CertPathValidatorException(
+ "Policy information could not be decoded.", ex, certPath, index);
+ }
+ if (RFC3280CertPathUtilities.ANY_POLICY.equals(pinfo.getPolicyIdentifier().getId()))
+ {
+ try
+ {
+ pq = CertPathValidatorUtilities
+ .getQualifierSet(pinfo.getPolicyQualifiers());
+ }
+ catch (CertPathValidatorException ex)
+ {
+
+ throw new ExtCertPathValidatorException(
+ "Policy qualifier info set could not be decoded.", ex, certPath,
+ index);
+ }
+ break;
+ }
+ }
+ boolean ci = false;
+ if (cert.getCriticalExtensionOIDs() != null)
+ {
+ ci = cert.getCriticalExtensionOIDs().contains(
+ RFC3280CertPathUtilities.CERTIFICATE_POLICIES);
+ }
+
+ PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent();
+ if (RFC3280CertPathUtilities.ANY_POLICY.equals(p_node.getValidPolicy()))
+ {
+ PKIXPolicyNode c_node = new PKIXPolicyNode(new ArrayList(), i, (Set)m_idp
+ .get(id_p), p_node, pq, id_p, ci);
+ p_node.addChild(c_node);
+ policyNodes[i].add(c_node);
+ }
+ break;
+ }
+ }
+ }
+
+ //
+ // (2)
+ //
+ }
+ else if (policyMapping <= 0)
+ {
+ Iterator nodes_i = policyNodes[i].iterator();
+ while (nodes_i.hasNext())
+ {
+ PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
+ if (node.getValidPolicy().equals(id_p))
+ {
+ PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent();
+ p_node.removeChild(node);
+ nodes_i.remove();
+ for (int k = (i - 1); k >= 0; k--)
+ {
+ List nodes = policyNodes[k];
+ for (int l = 0; l < nodes.size(); l++)
+ {
+ PKIXPolicyNode node2 = (PKIXPolicyNode)nodes.get(l);
+ if (!node2.hasChildren())
+ {
+ _validPolicyTree = CertPathValidatorUtilities.removePolicyNode(
+ _validPolicyTree, policyNodes, node2);
+ if (_validPolicyTree == null)
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return _validPolicyTree;
+ }
+
+ protected static void prepareNextCertA(
+ CertPath certPath,
+ int index)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ //
+ //
+ // (a) check the policy mappings
+ //
+ ASN1Sequence pm = null;
+ try
+ {
+ pm = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ RFC3280CertPathUtilities.POLICY_MAPPINGS));
+ }
+ catch (AnnotatedException ex)
+ {
+ throw new ExtCertPathValidatorException("Policy mappings extension could not be decoded.", ex, certPath,
+ index);
+ }
+ if (pm != null)
+ {
+ ASN1Sequence mappings = pm;
+
+ for (int j = 0; j < mappings.size(); j++)
+ {
+ ASN1ObjectIdentifier issuerDomainPolicy = null;
+ ASN1ObjectIdentifier subjectDomainPolicy = null;
+ try
+ {
+ ASN1Sequence mapping = ASN1Sequence.getInstance(mappings.getObjectAt(j));
+
+ issuerDomainPolicy = ASN1ObjectIdentifier.getInstance(mapping.getObjectAt(0));
+ subjectDomainPolicy = ASN1ObjectIdentifier.getInstance(mapping.getObjectAt(1));
+ }
+ catch (Exception e)
+ {
+ throw new ExtCertPathValidatorException("Policy mappings extension contents could not be decoded.",
+ e, certPath, index);
+ }
+
+ if (RFC3280CertPathUtilities.ANY_POLICY.equals(issuerDomainPolicy.getId()))
+ {
+
+ throw new CertPathValidatorException("IssuerDomainPolicy is anyPolicy", null, certPath, index);
+ }
+
+ if (RFC3280CertPathUtilities.ANY_POLICY.equals(subjectDomainPolicy.getId()))
+ {
+
+ throw new CertPathValidatorException("SubjectDomainPolicy is anyPolicy", null, certPath, index);
+ }
+ }
+ }
+ }
+
+ protected static void processCertF(
+ CertPath certPath,
+ int index,
+ PKIXPolicyNode validPolicyTree,
+ int explicitPolicy)
+ throws CertPathValidatorException
+ {
+ //
+ // (f)
+ //
+ if (explicitPolicy <= 0 && validPolicyTree == null)
+ {
+ throw new ExtCertPathValidatorException("No valid policy tree found when one expected.", null, certPath,
+ index);
+ }
+ }
+
+ protected static PKIXPolicyNode processCertE(
+ CertPath certPath,
+ int index,
+ PKIXPolicyNode validPolicyTree)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ //
+ // (e)
+ //
+ ASN1Sequence certPolicies = null;
+ try
+ {
+ certPolicies = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ RFC3280CertPathUtilities.CERTIFICATE_POLICIES));
+ }
+ catch (AnnotatedException e)
+ {
+ throw new ExtCertPathValidatorException("Could not read certificate policies extension from certificate.",
+ e, certPath, index);
+ }
+ if (certPolicies == null)
+ {
+ validPolicyTree = null;
+ }
+ return validPolicyTree;
+ }
+
+ protected static void processCertBC(
+ CertPath certPath,
+ int index,
+ PKIXNameConstraintValidator nameConstraintValidator,
+ boolean isForCRLCheck)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ int n = certs.size();
+ // i as defined in the algorithm description
+ int i = n - index;
+ //
+ // (b), (c) permitted and excluded subtree checking.
+ //
+ // 4.2.1.10 Name constraints are not applied to self-issued certificates (unless
+ // the certificate is the final certificate in the path)
+ // as we use the validator for path CRL checking, we need to flag when the
+ // certificate is self issued, but not really the last one in the path we are actually
+ // checking.
+ if (!(CertPathValidatorUtilities.isSelfIssued(cert) && ((i < n) || isForCRLCheck)))
+ {
+ X500Name principal = PrincipalUtils.getSubjectPrincipal(cert);
+ ASN1Sequence dns;
+
+ try
+ {
+ dns = ASN1Sequence.getInstance(principal);
+ }
+ catch (Exception e)
+ {
+ throw new CertPathValidatorException("Exception extracting subject name when checking subtrees.", e,
+ certPath, index);
+ }
+
+ try
+ {
+ nameConstraintValidator.checkPermittedDN(dns);
+ nameConstraintValidator.checkExcludedDN(dns);
+ }
+ catch (PKIXNameConstraintValidatorException e)
+ {
+ throw new CertPathValidatorException("Subtree check for certificate subject failed.", e, certPath,
+ index);
+ }
+
+ GeneralNames altName = null;
+ try
+ {
+ altName = GeneralNames.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME));
+ }
+ catch (Exception e)
+ {
+ throw new CertPathValidatorException("Subject alternative name extension could not be decoded.", e,
+ certPath, index);
+ }
+ RDN[] emails = X500Name.getInstance(dns).getRDNs(BCStyle.EmailAddress);
+ for (int eI = 0; eI != emails.length; eI++)
+ {
+ // TODO: this should take into account multi-valued RDNs
+ String email = ((ASN1String)emails[eI].getFirst().getValue()).getString();
+ GeneralName emailAsGeneralName = new GeneralName(GeneralName.rfc822Name, email);
+ try
+ {
+ nameConstraintValidator.checkPermitted(emailAsGeneralName);
+ nameConstraintValidator.checkExcluded(emailAsGeneralName);
+ }
+ catch (PKIXNameConstraintValidatorException ex)
+ {
+ throw new CertPathValidatorException(
+ "Subtree check for certificate subject alternative email failed.", ex, certPath, index);
+ }
+ }
+ if (altName != null)
+ {
+ GeneralName[] genNames = null;
+ try
+ {
+ genNames = altName.getNames();
+ }
+ catch (Exception e)
+ {
+ throw new CertPathValidatorException("Subject alternative name contents could not be decoded.", e,
+ certPath, index);
+ }
+ for (int j = 0; j < genNames.length; j++)
+ {
+
+ try
+ {
+ nameConstraintValidator.checkPermitted(genNames[j]);
+ nameConstraintValidator.checkExcluded(genNames[j]);
+ }
+ catch (PKIXNameConstraintValidatorException e)
+ {
+ throw new CertPathValidatorException(
+ "Subtree check for certificate subject alternative name failed.", e, certPath, index);
+ }
+ }
+ }
+ }
+ }
+
+ protected static PKIXPolicyNode processCertD(
+ CertPath certPath,
+ int index,
+ Set acceptablePolicies,
+ PKIXPolicyNode validPolicyTree,
+ List[] policyNodes,
+ int inhibitAnyPolicy,
+ boolean isForCRLCheck)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ int n = certs.size();
+ // i as defined in the algorithm description
+ int i = n - index;
+ //
+ // (d) policy Information checking against initial policy and
+ // policy mapping
+ //
+ ASN1Sequence certPolicies = null;
+ try
+ {
+ certPolicies = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ RFC3280CertPathUtilities.CERTIFICATE_POLICIES));
+ }
+ catch (AnnotatedException e)
+ {
+ throw new ExtCertPathValidatorException("Could not read certificate policies extension from certificate.",
+ e, certPath, index);
+ }
+ if (certPolicies != null && validPolicyTree != null)
+ {
+ //
+ // (d) (1)
+ //
+ Enumeration e = certPolicies.getObjects();
+ Set pols = new HashSet();
+
+ while (e.hasMoreElements())
+ {
+ PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement());
+ ASN1ObjectIdentifier pOid = pInfo.getPolicyIdentifier();
+
+ pols.add(pOid.getId());
+
+ if (!RFC3280CertPathUtilities.ANY_POLICY.equals(pOid.getId()))
+ {
+ Set pq = null;
+ try
+ {
+ pq = CertPathValidatorUtilities.getQualifierSet(pInfo.getPolicyQualifiers());
+ }
+ catch (CertPathValidatorException ex)
+ {
+ throw new ExtCertPathValidatorException("Policy qualifier info set could not be build.", ex,
+ certPath, index);
+ }
+
+ boolean match = CertPathValidatorUtilities.processCertD1i(i, policyNodes, pOid, pq);
+
+ if (!match)
+ {
+ CertPathValidatorUtilities.processCertD1ii(i, policyNodes, pOid, pq);
+ }
+ }
+ }
+
+ if (acceptablePolicies.isEmpty() || acceptablePolicies.contains(RFC3280CertPathUtilities.ANY_POLICY))
+ {
+ acceptablePolicies.clear();
+ acceptablePolicies.addAll(pols);
+ }
+ else
+ {
+ Iterator it = acceptablePolicies.iterator();
+ Set t1 = new HashSet();
+
+ while (it.hasNext())
+ {
+ Object o = it.next();
+
+ if (pols.contains(o))
+ {
+ t1.add(o);
+ }
+ }
+ acceptablePolicies.clear();
+ acceptablePolicies.addAll(t1);
+ }
+
+ //
+ // (d) (2)
+ //
+ if ((inhibitAnyPolicy > 0) || ((i < n || isForCRLCheck) && CertPathValidatorUtilities.isSelfIssued(cert)))
+ {
+ e = certPolicies.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement());
+
+ if (RFC3280CertPathUtilities.ANY_POLICY.equals(pInfo.getPolicyIdentifier().getId()))
+ {
+ Set _apq = CertPathValidatorUtilities.getQualifierSet(pInfo.getPolicyQualifiers());
+ List _nodes = policyNodes[i - 1];
+
+ for (int k = 0; k < _nodes.size(); k++)
+ {
+ PKIXPolicyNode _node = (PKIXPolicyNode)_nodes.get(k);
+
+ Iterator _policySetIter = _node.getExpectedPolicies().iterator();
+ while (_policySetIter.hasNext())
+ {
+ Object _tmp = _policySetIter.next();
+
+ String _policy;
+ if (_tmp instanceof String)
+ {
+ _policy = (String)_tmp;
+ }
+ else if (_tmp instanceof ASN1ObjectIdentifier)
+ {
+ _policy = ((ASN1ObjectIdentifier)_tmp).getId();
+ }
+ else
+ {
+ continue;
+ }
+
+ boolean _found = false;
+ Iterator _childrenIter = _node.getChildren();
+
+ while (_childrenIter.hasNext())
+ {
+ PKIXPolicyNode _child = (PKIXPolicyNode)_childrenIter.next();
+
+ if (_policy.equals(_child.getValidPolicy()))
+ {
+ _found = true;
+ }
+ }
+
+ if (!_found)
+ {
+ Set _newChildExpectedPolicies = new HashSet();
+ _newChildExpectedPolicies.add(_policy);
+
+ PKIXPolicyNode _newChild = new PKIXPolicyNode(new ArrayList(), i,
+ _newChildExpectedPolicies, _node, _apq, _policy, false);
+ _node.addChild(_newChild);
+ policyNodes[i].add(_newChild);
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ PKIXPolicyNode _validPolicyTree = validPolicyTree;
+ //
+ // (d) (3)
+ //
+ for (int j = (i - 1); j >= 0; j--)
+ {
+ List nodes = policyNodes[j];
+
+ for (int k = 0; k < nodes.size(); k++)
+ {
+ PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k);
+ if (!node.hasChildren())
+ {
+ _validPolicyTree = CertPathValidatorUtilities.removePolicyNode(_validPolicyTree, policyNodes,
+ node);
+ if (_validPolicyTree == null)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ //
+ // d (4)
+ //
+ Set criticalExtensionOids = cert.getCriticalExtensionOIDs();
+
+ if (criticalExtensionOids != null)
+ {
+ boolean critical = criticalExtensionOids.contains(RFC3280CertPathUtilities.CERTIFICATE_POLICIES);
+
+ List nodes = policyNodes[i];
+ for (int j = 0; j < nodes.size(); j++)
+ {
+ PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(j);
+ node.setCritical(critical);
+ }
+ }
+ return _validPolicyTree;
+ }
+ return null;
+ }
+
+ protected static void processCertA(
+ CertPath certPath,
+ PKIXExtendedParameters paramsPKIX,
+ Date validityDate,
+ PKIXCertRevocationChecker revocationChecker,
+ int index,
+ PublicKey workingPublicKey,
+ boolean verificationAlreadyPerformed,
+ X500Name workingIssuerName,
+ X509Certificate sign)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ //
+ // (a) verify
+ //
+ if (!verificationAlreadyPerformed)
+ {
+ try
+ {
+ // (a) (1)
+ //
+ CertPathValidatorUtilities.verifyX509Certificate(cert, workingPublicKey,
+ paramsPKIX.getSigProvider());
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new ExtCertPathValidatorException("Could not validate certificate signature.", e, certPath, index);
+ }
+ }
+
+ final Date validCertDate;
+ try
+ {
+ validCertDate = CertPathValidatorUtilities.getValidCertDateFromValidityModel(validityDate,
+ paramsPKIX.getValidityModel(), certPath, index);
+ }
+ catch (AnnotatedException e)
+ {
+ throw new ExtCertPathValidatorException("Could not validate time of certificate.", e, certPath, index);
+ }
+
+ // (a) (2)
+ //
+ try
+ {
+ cert.checkValidity(validCertDate);
+ }
+ catch (CertificateExpiredException e)
+ {
+ throw new ExtCertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index);
+ }
+ catch (CertificateNotYetValidException e)
+ {
+ throw new ExtCertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index);
+ }
+
+ //
+ // (a) (3)
+ //
+ if (revocationChecker != null)
+ {
+ revocationChecker.initialize(new PKIXCertRevocationCheckerParameters(paramsPKIX, validCertDate, certPath,
+ index, sign, workingPublicKey));
+
+ revocationChecker.check(cert);
+ }
+
+ //
+ // (a) (4) name chaining
+ //
+ X500Name issuer = PrincipalUtils.getIssuerPrincipal(cert);
+ if (!issuer.equals(workingIssuerName))
+ {
+ throw new ExtCertPathValidatorException("IssuerName(" + issuer + ") does not match SubjectName("
+ + workingIssuerName + ") of signing certificate.", null, certPath, index);
+ }
+ }
+
+ protected static int prepareNextCertI1(
+ CertPath certPath,
+ int index,
+ int explicitPolicy)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ //
+ // (i)
+ //
+ ASN1Sequence pc = null;
+ try
+ {
+ pc = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
+ }
+ catch (Exception e)
+ {
+ throw new ExtCertPathValidatorException("Policy constraints extension cannot be decoded.", e, certPath,
+ index);
+ }
+
+ int tmpInt;
+
+ if (pc != null)
+ {
+ Enumeration policyConstraints = pc.getObjects();
+
+ while (policyConstraints.hasMoreElements())
+ {
+ try
+ {
+ ASN1TaggedObject constraint = ASN1TaggedObject.getInstance(policyConstraints.nextElement());
+ if (constraint.getTagNo() == 0)
+ {
+ tmpInt = ASN1Integer.getInstance(constraint, false).intValueExact();
+ if (tmpInt < explicitPolicy)
+ {
+ return tmpInt;
+ }
+ break;
+ }
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ExtCertPathValidatorException("Policy constraints extension contents cannot be decoded.",
+ e, certPath, index);
+ }
+ }
+ }
+ return explicitPolicy;
+ }
+
+ protected static int prepareNextCertI2(
+ CertPath certPath,
+ int index,
+ int policyMapping)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ //
+ // (i)
+ //
+ ASN1Sequence pc = null;
+ try
+ {
+ pc = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
+ }
+ catch (Exception e)
+ {
+ throw new ExtCertPathValidatorException("Policy constraints extension cannot be decoded.", e, certPath,
+ index);
+ }
+
+ int tmpInt;
+
+ if (pc != null)
+ {
+ Enumeration policyConstraints = pc.getObjects();
+
+ while (policyConstraints.hasMoreElements())
+ {
+ try
+ {
+ ASN1TaggedObject constraint = ASN1TaggedObject.getInstance(policyConstraints.nextElement());
+ if (constraint.getTagNo() == 1)
+ {
+ tmpInt = ASN1Integer.getInstance(constraint, false).intValueExact();
+ if (tmpInt < policyMapping)
+ {
+ return tmpInt;
+ }
+ break;
+ }
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ExtCertPathValidatorException("Policy constraints extension contents cannot be decoded.",
+ e, certPath, index);
+ }
+ }
+ }
+ return policyMapping;
+ }
+
+ protected static void prepareNextCertG(
+ CertPath certPath,
+ int index,
+ PKIXNameConstraintValidator nameConstraintValidator)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ //
+ // (g) handle the name constraints extension
+ //
+ NameConstraints nc = null;
+ try
+ {
+ ASN1Sequence ncSeq = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ RFC3280CertPathUtilities.NAME_CONSTRAINTS));
+ if (ncSeq != null)
+ {
+ nc = NameConstraints.getInstance(ncSeq);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new ExtCertPathValidatorException("Name constraints extension could not be decoded.", e, certPath,
+ index);
+ }
+ if (nc != null)
+ {
+
+ //
+ // (g) (1) permitted subtrees
+ //
+ GeneralSubtree[] permitted = nc.getPermittedSubtrees();
+ if (permitted != null)
+ {
+ try
+ {
+ nameConstraintValidator.intersectPermittedSubtree(permitted);
+ }
+ catch (Exception ex)
+ {
+ throw new ExtCertPathValidatorException(
+ "Permitted subtrees cannot be build from name constraints extension.", ex, certPath, index);
+ }
+ }
+
+ //
+ // (g) (2) excluded subtrees
+ //
+ GeneralSubtree[] excluded = nc.getExcludedSubtrees();
+ if (excluded != null)
+ {
+ for (int i = 0; i != excluded.length; i++)
+ try
+ {
+ nameConstraintValidator.addExcludedSubtree(excluded[i]);
+ }
+ catch (Exception ex)
+ {
+ throw new ExtCertPathValidatorException(
+ "Excluded subtrees cannot be build from name constraints extension.", ex, certPath, index);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks a distribution point for revocation information for the certificate <code>cert</code>.
+ *
+ * @param dp
+ * The distribution point to consider.
+ * @param paramsPKIX
+ * PKIX parameters.
+ * @param currentDate
+ * The date at which this check is being run.
+ * @param validityDate
+ * The date when the certificate revocation status should be checked.
+ * @param cert
+ * Certificate to check if it is revoked.
+ * @param defaultCRLSignCert
+ * The issuer certificate of the certificate <code>cert</code>.
+ * @param defaultCRLSignKey
+ * The public key of the issuer certificate <code>defaultCRLSignCert</code>.
+ * @param certStatus
+ * The current certificate revocation status.
+ * @param reasonMask
+ * The reasons mask which is already checked.
+ * @param certPathCerts
+ * The certificates of the certification path.
+ * @throws AnnotatedException
+ * if the certificate is revoked or the status cannot be checked or some error
+ * occurs.
+ */
+ private static void checkCRL(
+ PKIXCertRevocationCheckerParameters params,
+ DistributionPoint dp,
+ PKIXExtendedParameters paramsPKIX,
+ Date currentDate,
+ Date validityDate,
+ X509Certificate cert,
+ X509Certificate defaultCRLSignCert,
+ PublicKey defaultCRLSignKey,
+ CertStatus certStatus,
+ ReasonsMask reasonMask,
+ List certPathCerts,
+ JcaJceHelper helper)
+ throws AnnotatedException, RecoverableCertPathValidatorException
+ {
+ if (currentDate == null)
+ {
+ boolean debug = true;
+ }
+ if (validityDate.getTime() > currentDate.getTime())
+ {
+ throw new AnnotatedException("Validation time is in future.");
+ }
+
+ // (a)
+ /*
+ * We always get timely valid CRLs, so there is no step (a) (1).
+ * "locally cached" CRLs are assumed to be in getStore(), additional
+ * CRLs must be enabled in the ExtendedPKIXParameters and are in
+ * getAdditionalStore()
+ */
+
+ Set crls = CertPathValidatorUtilities.getCompleteCRLs(params, dp, cert, paramsPKIX, validityDate);
+ boolean validCrlFound = false;
+ AnnotatedException lastException = null;
+ Iterator crl_iter = crls.iterator();
+
+ while (crl_iter.hasNext() && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonMask.isAllReasons())
+ {
+ try
+ {
+ X509CRL crl = (X509CRL)crl_iter.next();
+
+ // (d)
+ ReasonsMask interimReasonsMask = RFC3280CertPathUtilities.processCRLD(crl, dp);
+
+ // (e)
+ /*
+ * The reasons mask is updated at the end, so only valid CRLs
+ * can update it. If this CRL does not contain new reasons it
+ * must be ignored.
+ */
+ if (!interimReasonsMask.hasNewReasons(reasonMask))
+ {
+ continue;
+ }
+
+ // (f)
+ Set keys = RFC3280CertPathUtilities.processCRLF(crl, cert, defaultCRLSignCert, defaultCRLSignKey,
+ paramsPKIX, certPathCerts, helper);
+ // (g)
+ PublicKey key = RFC3280CertPathUtilities.processCRLG(crl, keys);
+
+ X509CRL deltaCRL = null;
+
+ if (paramsPKIX.isUseDeltasEnabled())
+ {
+ // get delta CRLs
+ Set deltaCRLs = CertPathValidatorUtilities.getDeltaCRLs(validityDate, crl, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores(), helper);
+ // we only want one valid delta CRL
+ // (h)
+ deltaCRL = RFC3280CertPathUtilities.processCRLH(deltaCRLs, key);
+ }
+
+ /*
+ * CRL must be be valid at the current time, not the validation
+ * time. If a certificate is revoked with reason keyCompromise,
+ * cACompromise, it can be used for forgery, also for the past.
+ * This reason may not be contained in older CRLs.
+ */
+
+ /*
+ * in the chain model signatures stay valid also after the
+ * certificate has been expired, so they do not have to be in
+ * the CRL validity time
+ */
+
+ if (paramsPKIX.getValidityModel() != PKIXExtendedParameters.CHAIN_VALIDITY_MODEL)
+ {
+ /*
+ * if a certificate has expired, but was revoked, it is not
+ * more in the CRL, so it would be regarded as valid if the
+ * first check is not done
+ */
+ if (cert.getNotAfter().getTime() < crl.getThisUpdate().getTime())
+ {
+ throw new AnnotatedException("No valid CRL for current time found.");
+ }
+ }
+
+ RFC3280CertPathUtilities.processCRLB1(dp, cert, crl);
+
+ // (b) (2)
+ RFC3280CertPathUtilities.processCRLB2(dp, cert, crl);
+
+ // (c)
+ RFC3280CertPathUtilities.processCRLC(deltaCRL, crl, paramsPKIX);
+
+ // (i)
+ RFC3280CertPathUtilities.processCRLI(validityDate, deltaCRL, cert, certStatus, paramsPKIX);
+
+ // (j)
+ RFC3280CertPathUtilities.processCRLJ(validityDate, crl, cert, certStatus);
+
+ // (k)
+ if (certStatus.getCertStatus() == CRLReason.removeFromCRL)
+ {
+ certStatus.setCertStatus(CertStatus.UNREVOKED);
+ }
+
+ // update reasons mask
+ reasonMask.addReasons(interimReasonsMask);
+
+ Set criticalExtensions = crl.getCriticalExtensionOIDs();
+ if (criticalExtensions != null)
+ {
+ criticalExtensions = new HashSet(criticalExtensions);
+ criticalExtensions.remove(Extension.issuingDistributionPoint.getId());
+ criticalExtensions.remove(Extension.deltaCRLIndicator.getId());
+
+ if (!criticalExtensions.isEmpty())
+ {
+ throw new AnnotatedException("CRL contains unsupported critical extensions.");
+ }
+ }
+
+ if (deltaCRL != null)
+ {
+ criticalExtensions = deltaCRL.getCriticalExtensionOIDs();
+ if (criticalExtensions != null)
+ {
+ criticalExtensions = new HashSet(criticalExtensions);
+ criticalExtensions.remove(Extension.issuingDistributionPoint.getId());
+ criticalExtensions.remove(Extension.deltaCRLIndicator.getId());
+ if (!criticalExtensions.isEmpty())
+ {
+ throw new AnnotatedException("Delta CRL contains unsupported critical extension.");
+ }
+ }
+ }
+
+ validCrlFound = true;
+ }
+ catch (AnnotatedException e)
+ {
+ lastException = e;
+ }
+ }
+ if (!validCrlFound)
+ {
+ throw lastException;
+ }
+ }
+
+ /**
+ * Checks a certificate if it is revoked.
+ *
+ * @param paramsPKIX
+ * PKIX parameters.
+ * @param currentDate
+ * The date at which this check is being run.
+ * @param validityDate
+ * The date when the certificate revocation status should be checked.
+ * @param cert
+ * Certificate to check if it is revoked.
+ * @param sign
+ * The issuer certificate of the certificate <code>cert</code>.
+ * @param workingPublicKey
+ * The public key of the issuer certificate <code>sign</code>.
+ * @param certPathCerts
+ * The certificates of the certification path.
+ * @throws AnnotatedException
+ * if the certificate is revoked or the status cannot be checked or some error
+ * occurs.
+ */
+ protected static void checkCRLs(
+ PKIXCertRevocationCheckerParameters params,
+ PKIXExtendedParameters paramsPKIX,
+ Date currentDate,
+ Date validityDate,
+ X509Certificate cert,
+ X509Certificate sign,
+ PublicKey workingPublicKey,
+ List certPathCerts,
+ JcaJceHelper helper)
+ throws AnnotatedException, RecoverableCertPathValidatorException
+ {
+ AnnotatedException lastException = null;
+ CRLDistPoint crldp = null;
+ try
+ {
+ crldp = CRLDistPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS));
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("CRL distribution point extension could not be read.", e);
+ }
+
+ PKIXExtendedParameters.Builder paramsBldr = new PKIXExtendedParameters.Builder(paramsPKIX);
+ try
+ {
+ List extras = CertPathValidatorUtilities.getAdditionalStoresFromCRLDistributionPoint(crldp,
+ paramsPKIX.getNamedCRLStoreMap(), validityDate, helper);
+ for (Iterator it = extras.iterator(); it.hasNext();)
+ {
+ paramsBldr.addCRLStore((PKIXCRLStore)it.next());
+ }
+ }
+ catch (AnnotatedException e)
+ {
+ throw new AnnotatedException(
+ "No additional CRL locations could be decoded from CRL distribution point extension.", e);
+ }
+ CertStatus certStatus = new CertStatus();
+ ReasonsMask reasonsMask = new ReasonsMask();
+ PKIXExtendedParameters finalParams = paramsBldr.build();
+
+ boolean validCrlFound = false;
+ // for each distribution point
+ if (crldp != null)
+ {
+ DistributionPoint dps[] = null;
+ try
+ {
+ dps = crldp.getDistributionPoints();
+ }
+ catch (Exception e)
+ {
+ throw new AnnotatedException("Distribution points could not be read.", e);
+ }
+ if (dps != null)
+ {
+ for (int i = 0; i < dps.length && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonsMask.isAllReasons(); i++)
+ {
+ try
+ {
+ checkCRL(params, dps[i], finalParams, currentDate, validityDate, cert, sign, workingPublicKey,
+ certStatus, reasonsMask, certPathCerts, helper);
+ validCrlFound = true;
+ }
+ catch (AnnotatedException e)
+ {
+ lastException = e;
+ }
+ }
+ }
+ }
+
+ /*
+ * If the revocation status has not been determined, repeat the process
+ * above with any available CRLs not specified in a distribution point
+ * but issued by the certificate issuer.
+ */
+
+ if (certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonsMask.isAllReasons())
+ {
+ try
+ {
+ /*
+ * assume a DP with both the reasons and the cRLIssuer fields
+ * omitted and a distribution point name of the certificate
+ * issuer.
+ */
+ X500Name issuer;
+ try
+ {
+ issuer = PrincipalUtils.getIssuerPrincipal(cert);
+ }
+ catch (RuntimeException e)
+ {
+ throw new AnnotatedException("Issuer from certificate for CRL could not be reencoded.", e);
+ }
+ DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames(
+ new GeneralName(GeneralName.directoryName, issuer))), null, null);
+ PKIXExtendedParameters paramsPKIXClone = (PKIXExtendedParameters)paramsPKIX.clone();
+ checkCRL(params, dp, paramsPKIXClone, currentDate, validityDate, cert, sign, workingPublicKey,
+ certStatus, reasonsMask, certPathCerts, helper);
+ validCrlFound = true;
+ }
+ catch (AnnotatedException e)
+ {
+ lastException = e;
+ }
+ }
+
+ if (!validCrlFound)
+ {
+ if (lastException instanceof AnnotatedException)
+ {
+ throw lastException;
+ }
+
+ throw new AnnotatedException("No valid CRL found.", lastException);
+ }
+ if (certStatus.getCertStatus() != CertStatus.UNREVOKED)
+ {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
+ df.setTimeZone(TimeZone.getTimeZone("UTC"));
+ String message = "Certificate revocation after " + df.format(certStatus.getRevocationDate());
+ message += ", reason: " + crlReasons[certStatus.getCertStatus()];
+ throw new AnnotatedException(message);
+ }
+ if (!reasonsMask.isAllReasons() && certStatus.getCertStatus() == CertStatus.UNREVOKED)
+ {
+ certStatus.setCertStatus(CertStatus.UNDETERMINED);
+ }
+ if (certStatus.getCertStatus() == CertStatus.UNDETERMINED)
+ {
+ throw new AnnotatedException("Certificate status could not be determined.");
+ }
+ }
+
+ protected static int prepareNextCertJ(
+ CertPath certPath,
+ int index,
+ int inhibitAnyPolicy)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ //
+ // (j)
+ //
+ ASN1Integer iap = null;
+ try
+ {
+ iap = ASN1Integer.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ RFC3280CertPathUtilities.INHIBIT_ANY_POLICY));
+ }
+ catch (Exception e)
+ {
+ throw new ExtCertPathValidatorException("Inhibit any-policy extension cannot be decoded.", e, certPath,
+ index);
+ }
+
+ if (iap != null)
+ {
+ int _inhibitAnyPolicy = iap.intValueExact();
+
+ if (_inhibitAnyPolicy < inhibitAnyPolicy)
+ {
+ return _inhibitAnyPolicy;
+ }
+ }
+ return inhibitAnyPolicy;
+ }
+
+ protected static void prepareNextCertK(
+ CertPath certPath,
+ int index)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ //
+ // (k)
+ //
+ BasicConstraints bc = null;
+ try
+ {
+ bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ RFC3280CertPathUtilities.BASIC_CONSTRAINTS));
+ }
+ catch (Exception e)
+ {
+ throw new ExtCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath,
+ index);
+ }
+ if (bc != null)
+ {
+ if (!(bc.isCA()))
+ {
+ throw new CertPathValidatorException("Not a CA certificate", null, certPath, index);
+ }
+ }
+ else
+ {
+ throw new CertPathValidatorException("Intermediate certificate lacks BasicConstraints", null, certPath, index);
+ }
+ }
+
+ protected static int prepareNextCertL(
+ CertPath certPath,
+ int index,
+ int maxPathLength)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ //
+ // (l)
+ //
+ if (!CertPathValidatorUtilities.isSelfIssued(cert))
+ {
+ if (maxPathLength <= 0)
+ {
+ throw new ExtCertPathValidatorException("Max path length not greater than zero", null, certPath, index);
+ }
+
+ return maxPathLength - 1;
+ }
+ return maxPathLength;
+ }
+
+ protected static int prepareNextCertM(
+ CertPath certPath,
+ int index,
+ int maxPathLength)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+
+ //
+ // (m)
+ //
+ BasicConstraints bc = null;
+ try
+ {
+ bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ RFC3280CertPathUtilities.BASIC_CONSTRAINTS));
+ }
+ catch (Exception e)
+ {
+ throw new ExtCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath,
+ index);
+ }
+ if (bc != null)
+ {
+ BigInteger _pathLengthConstraint = bc.getPathLenConstraint();
+
+ if (_pathLengthConstraint != null)
+ {
+ int _plc = _pathLengthConstraint.intValue();
+
+ if (_plc < maxPathLength)
+ {
+ return _plc;
+ }
+ }
+ }
+ return maxPathLength;
+ }
+
+ protected static void prepareNextCertN(
+ CertPath certPath,
+ int index)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+
+ //
+ // (n)
+ //
+ boolean[] keyUsage = cert.getKeyUsage();
+
+ if (keyUsage != null && (keyUsage.length <= KEY_CERT_SIGN || !keyUsage[KEY_CERT_SIGN]))
+ {
+ throw new ExtCertPathValidatorException(
+ "Issuer certificate keyusage extension is critical and does not permit key signing.", null,
+ certPath, index);
+ }
+ }
+
+ protected static void prepareNextCertO(
+ CertPath certPath,
+ int index,
+ Set criticalExtensions,
+ List pathCheckers)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ //
+ // (o)
+ //
+
+ Iterator tmpIter;
+ tmpIter = pathCheckers.iterator();
+ while (tmpIter.hasNext())
+ {
+ try
+ {
+ ((PKIXCertPathChecker)tmpIter.next()).check(cert, criticalExtensions);
+ }
+ catch (CertPathValidatorException e)
+ {
+ throw new CertPathValidatorException(e.getMessage(), e.getCause(), certPath, index);
+ }
+ }
+ if (!criticalExtensions.isEmpty())
+ {
+ throw new ExtCertPathValidatorException("Certificate has unsupported critical extension: " + criticalExtensions, null, certPath,
+ index);
+ }
+ }
+
+ protected static int prepareNextCertH1(
+ CertPath certPath,
+ int index,
+ int explicitPolicy)
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ //
+ // (h)
+ //
+ if (!CertPathValidatorUtilities.isSelfIssued(cert))
+ {
+ //
+ // (1)
+ //
+ if (explicitPolicy != 0)
+ {
+ return explicitPolicy - 1;
+ }
+ }
+ return explicitPolicy;
+ }
+
+ protected static int prepareNextCertH2(
+ CertPath certPath,
+ int index,
+ int policyMapping)
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ //
+ // (h)
+ //
+ if (!CertPathValidatorUtilities.isSelfIssued(cert))
+ {
+ //
+ // (2)
+ //
+ if (policyMapping != 0)
+ {
+ return policyMapping - 1;
+ }
+ }
+ return policyMapping;
+ }
+
+ protected static int prepareNextCertH3(
+ CertPath certPath,
+ int index,
+ int inhibitAnyPolicy)
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ //
+ // (h)
+ //
+ if (!CertPathValidatorUtilities.isSelfIssued(cert))
+ {
+ //
+ // (3)
+ //
+ if (inhibitAnyPolicy != 0)
+ {
+ return inhibitAnyPolicy - 1;
+ }
+ }
+ return inhibitAnyPolicy;
+ }
+
+ protected static final String[] crlReasons = new String[]
+ {
+ "unspecified",
+ "keyCompromise",
+ "cACompromise",
+ "affiliationChanged",
+ "superseded",
+ "cessationOfOperation",
+ "certificateHold",
+ "unknown",
+ "removeFromCRL",
+ "privilegeWithdrawn",
+ "aACompromise"};
+
+ protected static int wrapupCertA(
+ int explicitPolicy,
+ X509Certificate cert)
+ {
+ //
+ // (a)
+ //
+ if (!CertPathValidatorUtilities.isSelfIssued(cert) && (explicitPolicy != 0))
+ {
+ explicitPolicy--;
+ }
+ return explicitPolicy;
+ }
+
+ protected static int wrapupCertB(
+ CertPath certPath,
+ int index,
+ int explicitPolicy)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ //
+ // (b)
+ //
+ int tmpInt;
+ ASN1Sequence pc = null;
+ try
+ {
+ pc = ASN1Sequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
+ RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
+ }
+ catch (AnnotatedException e)
+ {
+ throw new ExtCertPathValidatorException("Policy constraints could not be decoded.", e, certPath, index);
+ }
+ if (pc != null)
+ {
+ Enumeration policyConstraints = pc.getObjects();
+
+ while (policyConstraints.hasMoreElements())
+ {
+ ASN1TaggedObject constraint = (ASN1TaggedObject)policyConstraints.nextElement();
+ switch (constraint.getTagNo())
+ {
+ case 0:
+ try
+ {
+ tmpInt = ASN1Integer.getInstance(constraint, false).intValueExact();
+ }
+ catch (Exception e)
+ {
+ throw new ExtCertPathValidatorException(
+ "Policy constraints requireExplicitPolicy field could not be decoded.", e, certPath,
+ index);
+ }
+ if (tmpInt == 0)
+ {
+ return 0;
+ }
+ break;
+ }
+ }
+ }
+ return explicitPolicy;
+ }
+
+ protected static void wrapupCertF(
+ CertPath certPath,
+ int index,
+ List pathCheckers,
+ Set criticalExtensions)
+ throws CertPathValidatorException
+ {
+ List certs = certPath.getCertificates();
+ X509Certificate cert = (X509Certificate)certs.get(index);
+ Iterator tmpIter;
+ tmpIter = pathCheckers.iterator();
+ while (tmpIter.hasNext())
+ {
+ try
+ {
+ ((PKIXCertPathChecker)tmpIter.next()).check(cert, criticalExtensions);
+ }
+ catch (CertPathValidatorException e)
+ {
+ throw new ExtCertPathValidatorException(e.getMessage(), e, certPath, index);
+ }
+ catch (Exception e)
+ {
+ throw new CertPathValidatorException("Additional certificate path checker failed.", e, certPath, index);
+ }
+ }
+
+ if (!criticalExtensions.isEmpty())
+ {
+ throw new ExtCertPathValidatorException("Certificate has unsupported critical extension: " + criticalExtensions, null, certPath,
+ index);
+ }
+ }
+
+ protected static PKIXPolicyNode wrapupCertG(
+ CertPath certPath,
+ PKIXExtendedParameters paramsPKIX,
+ Set userInitialPolicySet,
+ int index,
+ List[] policyNodes,
+ PKIXPolicyNode validPolicyTree,
+ Set acceptablePolicies)
+ throws CertPathValidatorException
+ {
+ int n = certPath.getCertificates().size();
+ //
+ // (g)
+ //
+ PKIXPolicyNode intersection;
+
+ //
+ // (g) (i)
+ //
+ if (validPolicyTree == null)
+ {
+ if (paramsPKIX.isExplicitPolicyRequired())
+ {
+ throw new ExtCertPathValidatorException("Explicit policy requested but none available.", null,
+ certPath, index);
+ }
+ intersection = null;
+ }
+ else if (CertPathValidatorUtilities.isAnyPolicy(userInitialPolicySet)) // (g)
+ // (ii)
+ {
+ if (paramsPKIX.isExplicitPolicyRequired())
+ {
+ if (acceptablePolicies.isEmpty())
+ {
+ throw new ExtCertPathValidatorException("Explicit policy requested but none available.", null,
+ certPath, index);
+ }
+ else
+ {
+ Set _validPolicyNodeSet = new HashSet();
+
+ for (int j = 0; j < policyNodes.length; j++)
+ {
+ List _nodeDepth = policyNodes[j];
+
+ for (int k = 0; k < _nodeDepth.size(); k++)
+ {
+ PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k);
+
+ if (RFC3280CertPathUtilities.ANY_POLICY.equals(_node.getValidPolicy()))
+ {
+ Iterator _iter = _node.getChildren();
+ while (_iter.hasNext())
+ {
+ _validPolicyNodeSet.add(_iter.next());
+ }
+ }
+ }
+ }
+
+ Iterator _vpnsIter = _validPolicyNodeSet.iterator();
+ while (_vpnsIter.hasNext())
+ {
+ PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next();
+ String _validPolicy = _node.getValidPolicy();
+
+ if (!acceptablePolicies.contains(_validPolicy))
+ {
+ // validPolicyTree =
+ // removePolicyNode(validPolicyTree, policyNodes,
+ // _node);
+ }
+ }
+ if (validPolicyTree != null)
+ {
+ for (int j = (n - 1); j >= 0; j--)
+ {
+ List nodes = policyNodes[j];
+
+ for (int k = 0; k < nodes.size(); k++)
+ {
+ PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k);
+ if (!node.hasChildren())
+ {
+ validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree,
+ policyNodes, node);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ intersection = validPolicyTree;
+ }
+ else
+ {
+ //
+ // (g) (iii)
+ //
+ // This implementation is not exactly same as the one described in
+ // RFC3280.
+ // However, as far as the validation result is concerned, both
+ // produce
+ // adequate result. The only difference is whether AnyPolicy is
+ // remain
+ // in the policy tree or not.
+ //
+ // (g) (iii) 1
+ //
+ Set _validPolicyNodeSet = new HashSet();
+
+ for (int j = 0; j < policyNodes.length; j++)
+ {
+ List _nodeDepth = policyNodes[j];
+
+ for (int k = 0; k < _nodeDepth.size(); k++)
+ {
+ PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k);
+
+ if (RFC3280CertPathUtilities.ANY_POLICY.equals(_node.getValidPolicy()))
+ {
+ Iterator _iter = _node.getChildren();
+ while (_iter.hasNext())
+ {
+ PKIXPolicyNode _c_node = (PKIXPolicyNode)_iter.next();
+ if (!RFC3280CertPathUtilities.ANY_POLICY.equals(_c_node.getValidPolicy()))
+ {
+ _validPolicyNodeSet.add(_c_node);
+ }
+ }
+ }
+ }
+ }
+
+ //
+ // (g) (iii) 2
+ //
+ Iterator _vpnsIter = _validPolicyNodeSet.iterator();
+ while (_vpnsIter.hasNext())
+ {
+ PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next();
+ String _validPolicy = _node.getValidPolicy();
+
+ if (!userInitialPolicySet.contains(_validPolicy))
+ {
+ validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree, policyNodes, _node);
+ }
+ }
+
+ //
+ // (g) (iii) 4
+ //
+ if (validPolicyTree != null)
+ {
+ for (int j = (n - 1); j >= 0; j--)
+ {
+ List nodes = policyNodes[j];
+
+ for (int k = 0; k < nodes.size(); k++)
+ {
+ PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k);
+ if (!node.hasChildren())
+ {
+ validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree, policyNodes,
+ node);
+ }
+ }
+ }
+ }
+
+ intersection = validPolicyTree;
+ }
+ return intersection;
+ }
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/ReasonsMask.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/ReasonsMask.java
new file mode 100644
index 00000000..3367bbe5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/ReasonsMask.java
@@ -0,0 +1,102 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import com.android.internal.org.bouncycastle.asn1.x509.ReasonFlags;
+
+/**
+ * This class helps to handle CRL revocation reasons mask. Each CRL handles a
+ * certain set of revocation reasons.
+ */
+class ReasonsMask
+{
+ private int _reasons;
+
+ /**
+ * Constructs are reason mask with the reasons.
+ *
+ * @param reasons The reasons.
+ */
+ ReasonsMask(ReasonFlags reasons)
+ {
+ _reasons = reasons.intValue();
+ }
+
+ private ReasonsMask(int reasons)
+ {
+ _reasons = reasons;
+ }
+
+ /**
+ * A reason mask with no reason.
+ *
+ */
+ ReasonsMask()
+ {
+ this(0);
+ }
+
+ /**
+ * A mask with all revocation reasons.
+ */
+ static final ReasonsMask allReasons = new ReasonsMask(ReasonFlags.aACompromise
+ | ReasonFlags.affiliationChanged | ReasonFlags.cACompromise
+ | ReasonFlags.certificateHold | ReasonFlags.cessationOfOperation
+ | ReasonFlags.keyCompromise | ReasonFlags.privilegeWithdrawn
+ | ReasonFlags.unused | ReasonFlags.superseded);
+
+ /**
+ * Adds all reasons from the reasons mask to this mask.
+ *
+ * @param mask The reasons mask to add.
+ */
+ void addReasons(ReasonsMask mask)
+ {
+ _reasons = _reasons | mask.getReasons();
+ }
+
+ /**
+ * Returns <code>true</code> if this reasons mask contains all possible
+ * reasons.
+ *
+ * @return <code>true</code> if this reasons mask contains all possible
+ * reasons.
+ */
+ boolean isAllReasons()
+ {
+ return _reasons == allReasons._reasons ? true : false;
+ }
+
+ /**
+ * Intersects this mask with the given reasons mask.
+ *
+ * @param mask The mask to intersect with.
+ * @return The intersection of this and the given mask.
+ */
+ ReasonsMask intersect(ReasonsMask mask)
+ {
+ ReasonsMask _mask = new ReasonsMask();
+ _mask.addReasons(new ReasonsMask(_reasons & mask.getReasons()));
+ return _mask;
+ }
+
+ /**
+ * Returns <code>true</code> if the passed reasons mask has new reasons.
+ *
+ * @param mask The reasons mask which should be tested for new reasons.
+ * @return <code>true</code> if the passed reasons mask has new reasons.
+ */
+ boolean hasNewReasons(ReasonsMask mask)
+ {
+ return ((_reasons | mask.getReasons() ^ _reasons) != 0);
+ }
+
+ /**
+ * Returns the reasons in this mask.
+ *
+ * @return Returns the reasons.
+ */
+ int getReasons()
+ {
+ return _reasons;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/RecoverableCertPathValidatorException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/RecoverableCertPathValidatorException.java
new file mode 100644
index 00000000..d0b30b45
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/RecoverableCertPathValidatorException.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.security.cert.CertPath;
+import java.security.cert.CertPathValidatorException;
+
+class RecoverableCertPathValidatorException
+ extends CertPathValidatorException
+{
+ public RecoverableCertPathValidatorException(String msg, Throwable cause, CertPath certPath, int index)
+ {
+ super(msg, cause, certPath, index);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/WrappedRevocationChecker.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/WrappedRevocationChecker.java
new file mode 100644
index 00000000..4b13e64f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/WrappedRevocationChecker.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.Certificate;
+import java.security.cert.PKIXCertPathChecker;
+
+import com.android.internal.org.bouncycastle.jcajce.PKIXCertRevocationChecker;
+import com.android.internal.org.bouncycastle.jcajce.PKIXCertRevocationCheckerParameters;
+
+class WrappedRevocationChecker
+ implements PKIXCertRevocationChecker
+{
+ private final PKIXCertPathChecker checker;
+
+ public WrappedRevocationChecker(PKIXCertPathChecker checker)
+ {
+ this.checker = checker;
+ }
+
+ public void setParameter(String name, Object value)
+ {
+ // ignore.
+ }
+
+ public void initialize(PKIXCertRevocationCheckerParameters params)
+ throws CertPathValidatorException
+ {
+ checker.init(false);
+ }
+
+ public void check(Certificate cert)
+ throws CertPathValidatorException
+ {
+ checker.check(cert);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CRLEntryObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CRLEntryObject.java
new file mode 100644
index 00000000..0efb8205
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CRLEntryObject.java
@@ -0,0 +1,321 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CRLException;
+import java.security.cert.X509CRLEntry;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.util.ASN1Dump;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.CRLReason;
+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.TBSCertList;
+import com.android.internal.org.bouncycastle.asn1.x509.X509Extension;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * The following extensions are listed in RFC 2459 as relevant to CRL Entries
+ *
+ * ReasonCode Hode Instruction Code Invalidity Date Certificate Issuer
+ * (critical)
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509CRLEntryObject extends X509CRLEntry
+{
+ private TBSCertList.CRLEntry c;
+
+ private X500Name certificateIssuer;
+ private int hashValue;
+ private boolean isHashValueSet;
+
+ public X509CRLEntryObject(TBSCertList.CRLEntry c)
+ {
+ this.c = c;
+ this.certificateIssuer = null;
+ }
+
+ /**
+ * Constructor for CRLEntries of indirect CRLs. If <code>isIndirect</code>
+ * is <code>false</code> {@link #getCertificateIssuer()} will always
+ * return <code>null</code>, <code>previousCertificateIssuer</code> is
+ * ignored. If this <code>isIndirect</code> is specified and this CRLEntry
+ * has no certificate issuer CRL entry extension
+ * <code>previousCertificateIssuer</code> is returned by
+ * {@link #getCertificateIssuer()}.
+ *
+ * @param c
+ * TBSCertList.CRLEntry object.
+ * @param isIndirect
+ * <code>true</code> if the corresponding CRL is a indirect
+ * CRL.
+ * @param previousCertificateIssuer
+ * Certificate issuer of the previous CRLEntry.
+ */
+ public X509CRLEntryObject(
+ TBSCertList.CRLEntry c,
+ boolean isIndirect,
+ X500Name previousCertificateIssuer)
+ {
+ this.c = c;
+ this.certificateIssuer = loadCertificateIssuer(isIndirect, previousCertificateIssuer);
+ }
+
+ /**
+ * Will return true if any extensions are present and marked as critical as
+ * we currently don't handle any extensions!
+ */
+ public boolean hasUnsupportedCriticalExtension()
+ {
+ Set extns = getCriticalExtensionOIDs();
+
+ return extns != null && !extns.isEmpty();
+ }
+
+ private X500Name loadCertificateIssuer(boolean isIndirect, X500Name previousCertificateIssuer)
+ {
+ if (!isIndirect)
+ {
+ return null;
+ }
+
+ Extension ext = getExtension(Extension.certificateIssuer);
+ if (ext == null)
+ {
+ return previousCertificateIssuer;
+ }
+
+ try
+ {
+ GeneralName[] names = GeneralNames.getInstance(ext.getParsedValue()).getNames();
+ for (int i = 0; i < names.length; i++)
+ {
+ if (names[i].getTagNo() == GeneralName.directoryName)
+ {
+ return X500Name.getInstance(names[i].getName());
+ }
+ }
+ return null;
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+
+ public X500Principal getCertificateIssuer()
+ {
+ if (certificateIssuer == null)
+ {
+ return null;
+ }
+ try
+ {
+ return new X500Principal(certificateIssuer.getEncoded());
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ private Set getExtensionOIDs(boolean critical)
+ {
+ Extensions extensions = c.getExtensions();
+
+ if (extensions != null)
+ {
+ Set set = new HashSet();
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (critical == ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+
+ return null;
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(true);
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(false);
+ }
+
+ private Extension getExtension(ASN1ObjectIdentifier oid)
+ {
+ Extensions exts = c.getExtensions();
+
+ if (exts != null)
+ {
+ return exts.getExtension(oid);
+ }
+
+ return null;
+ }
+
+ public byte[] getExtensionValue(String oid)
+ {
+ Extension ext = getExtension(new ASN1ObjectIdentifier(oid));
+
+ if (ext != null)
+ {
+ try
+ {
+ return ext.getExtnValue().getEncoded();
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("error encoding " + e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Cache the hashCode value - calculating it with the standard method.
+ * @return calculated hashCode.
+ */
+ public int hashCode()
+ {
+ if (!isHashValueSet)
+ {
+ hashValue = super.hashCode();
+ isHashValueSet = true;
+ }
+
+ return hashValue;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (o instanceof X509CRLEntryObject)
+ {
+ X509CRLEntryObject other = (X509CRLEntryObject)o;
+
+ return this.c.equals(other.c);
+ }
+
+ return super.equals(this);
+ }
+
+ public byte[] getEncoded()
+ throws CRLException
+ {
+ try
+ {
+ return c.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CRLException(e.toString());
+ }
+ }
+
+ public BigInteger getSerialNumber()
+ {
+ return c.getUserCertificate().getValue();
+ }
+
+ public Date getRevocationDate()
+ {
+ return c.getRevocationDate().getDate();
+ }
+
+ public boolean hasExtensions()
+ {
+ return c.getExtensions() != null;
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append(" userCertificate: ").append(this.getSerialNumber()).append(nl);
+ buf.append(" revocationDate: ").append(this.getRevocationDate()).append(nl);
+ buf.append(" certificateIssuer: ").append(this.getCertificateIssuer()).append(nl);
+
+ Extensions extensions = c.getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+ if (e.hasMoreElements())
+ {
+ buf.append(" crlEntryExtensions:").append(nl);
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+ if (ext.getExtnValue() != null)
+ {
+ byte[] octs = ext.getExtnValue().getOctets();
+ ASN1InputStream dIn = new ASN1InputStream(octs);
+ buf.append(" critical(").append(ext.isCritical()).append(") ");
+ try
+ {
+ if (oid.equals(X509Extension.reasonCode))
+ {
+ buf.append(CRLReason.getInstance(ASN1Enumerated.getInstance(dIn.readObject()))).append(nl);
+ }
+ else if (oid.equals(X509Extension.certificateIssuer))
+ {
+ buf.append("Certificate issuer: ").append(GeneralNames.getInstance(dIn.readObject())).append(nl);
+ }
+ else
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl);
+ }
+ }
+ catch (Exception ex)
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append("*****").append(nl);
+ }
+ }
+ else
+ {
+ buf.append(nl);
+ }
+ }
+ }
+ }
+
+ return buf.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CRLObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CRLObject.java
new file mode 100644
index 00000000..e20ba04f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CRLObject.java
@@ -0,0 +1,666 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CRLException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.util.ASN1Dump;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x509.CRLDistPoint;
+import com.android.internal.org.bouncycastle.asn1.x509.CRLNumber;
+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.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.jce.X509Principal;
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * The following extensions are listed in RFC 2459 as relevant to CRLs
+ *
+ * Authority Key Identifier
+ * Issuer Alternative Name
+ * CRL Number
+ * Delta CRL Indicator (critical)
+ * Issuing Distribution Point (critical)
+ * @deprecated Do not use this class directly - either use org.bouncycastle.cert (bcpkix) or CertificateFactory.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509CRLObject
+ extends X509CRL
+{
+ private CertificateList c;
+ private String sigAlgName;
+ private byte[] sigAlgParams;
+ private boolean isIndirect;
+ private boolean isHashCodeSet = false;
+ private int hashCodeValue;
+
+ public static boolean isIndirectCRL(X509CRL crl)
+ throws CRLException
+ {
+ try
+ {
+ byte[] idp = crl.getExtensionValue(Extension.issuingDistributionPoint.getId());
+ return idp != null
+ && IssuingDistributionPoint.getInstance(ASN1OctetString.getInstance(idp).getOctets()).isIndirectCRL();
+ }
+ catch (Exception e)
+ {
+ throw new ExtCRLException(
+ "Exception reading IssuingDistributionPoint", e);
+ }
+ }
+
+ public X509CRLObject(
+ CertificateList c)
+ throws CRLException
+ {
+ this.c = c;
+
+ try
+ {
+ this.sigAlgName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
+
+ if (c.getSignatureAlgorithm().getParameters() != null)
+ {
+ this.sigAlgParams = ((ASN1Encodable)c.getSignatureAlgorithm().getParameters()).toASN1Primitive().getEncoded(ASN1Encoding.DER);
+ }
+ else
+ {
+ this.sigAlgParams = null;
+ }
+
+ this.isIndirect = isIndirectCRL(this);
+ }
+ catch (Exception e)
+ {
+ throw new CRLException("CRL contents invalid: " + e);
+ }
+ }
+
+ /**
+ * Will return true if any extensions are present and marked
+ * as critical as we currently dont handle any extensions!
+ */
+ public boolean hasUnsupportedCriticalExtension()
+ {
+ Set extns = getCriticalExtensionOIDs();
+
+ if (extns == null)
+ {
+ return false;
+ }
+
+ extns.remove(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT);
+ extns.remove(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR);
+
+ return !extns.isEmpty();
+ }
+
+ private Set getExtensionOIDs(boolean critical)
+ {
+ if (this.getVersion() == 2)
+ {
+ Extensions extensions = c.getTBSCertList().getExtensions();
+
+ if (extensions != null)
+ {
+ Set set = new HashSet();
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (critical == ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+ }
+
+ return null;
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(true);
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(false);
+ }
+
+ public byte[] getExtensionValue(String oid)
+ {
+ Extensions exts = c.getTBSCertList().getExtensions();
+
+ if (exts != null)
+ {
+ Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
+
+ if (ext != null)
+ {
+ try
+ {
+ return ext.getExtnValue().getEncoded();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException("error parsing " + e.toString());
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public byte[] getEncoded()
+ throws CRLException
+ {
+ try
+ {
+ return c.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CRLException(e.toString());
+ }
+ }
+
+ public void verify(PublicKey key)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ Signature sig;
+
+ try
+ {
+ sig = Signature.getInstance(getSigAlgName(), BouncyCastleProvider.PROVIDER_NAME);
+ }
+ catch (Exception e)
+ {
+ sig = Signature.getInstance(getSigAlgName());
+ }
+
+ doVerify(key, sig);
+ }
+
+ public void verify(PublicKey key, String sigProvider)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ Signature sig;
+
+ if (sigProvider != null)
+ {
+ sig = Signature.getInstance(getSigAlgName(), sigProvider);
+ }
+ else
+ {
+ sig = Signature.getInstance(getSigAlgName());
+ }
+
+ doVerify(key, sig);
+ }
+
+ public void verify(PublicKey key, Provider sigProvider)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
+ Signature sig;
+
+ if (sigProvider != null)
+ {
+ sig = Signature.getInstance(getSigAlgName(), sigProvider);
+ }
+ else
+ {
+ sig = Signature.getInstance(getSigAlgName());
+ }
+
+ doVerify(key, sig);
+ }
+
+ private void doVerify(PublicKey key, Signature sig)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
+ if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature()))
+ {
+ throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList.");
+ }
+
+ sig.initVerify(key);
+ sig.update(this.getTBSCertList());
+
+ if (!sig.verify(this.getSignature()))
+ {
+ throw new SignatureException("CRL does not verify with supplied public key.");
+ }
+ }
+
+ public int getVersion()
+ {
+ return c.getVersionNumber();
+ }
+
+ public Principal getIssuerDN()
+ {
+ return new X509Principal(X500Name.getInstance(c.getIssuer().toASN1Primitive()));
+ }
+
+ public X500Principal getIssuerX500Principal()
+ {
+ try
+ {
+ return new X500Principal(c.getIssuer().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("can't encode issuer DN");
+ }
+ }
+
+ public Date getThisUpdate()
+ {
+ return c.getThisUpdate().getDate();
+ }
+
+ public Date getNextUpdate()
+ {
+ if (c.getNextUpdate() != null)
+ {
+ return c.getNextUpdate().getDate();
+ }
+
+ return null;
+ }
+
+ private Set loadCRLEntries()
+ {
+ Set entrySet = new HashSet();
+ Enumeration certs = c.getRevokedCertificateEnumeration();
+
+ X500Name previousCertificateIssuer = null; // the issuer
+ while (certs.hasMoreElements())
+ {
+ TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement();
+ X509CRLEntryObject crlEntry = new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer);
+ entrySet.add(crlEntry);
+ if (isIndirect && entry.hasExtensions())
+ {
+ Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
+
+ if (currentCaName != null)
+ {
+ previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
+ }
+ }
+ }
+
+ return entrySet;
+ }
+
+ public X509CRLEntry getRevokedCertificate(BigInteger serialNumber)
+ {
+ Enumeration certs = c.getRevokedCertificateEnumeration();
+
+ X500Name previousCertificateIssuer = null; // the issuer
+ while (certs.hasMoreElements())
+ {
+ TBSCertList.CRLEntry entry = (TBSCertList.CRLEntry)certs.nextElement();
+
+ if (entry.getUserCertificate().hasValue(serialNumber))
+ {
+ return new X509CRLEntryObject(entry, isIndirect, previousCertificateIssuer);
+ }
+
+ if (isIndirect && entry.hasExtensions())
+ {
+ Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
+
+ if (currentCaName != null)
+ {
+ previousCertificateIssuer = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public Set getRevokedCertificates()
+ {
+ Set entrySet = loadCRLEntries();
+
+ if (!entrySet.isEmpty())
+ {
+ return Collections.unmodifiableSet(entrySet);
+ }
+
+ return null;
+ }
+
+ public byte[] getTBSCertList()
+ throws CRLException
+ {
+ try
+ {
+ return c.getTBSCertList().getEncoded("DER");
+ }
+ catch (IOException e)
+ {
+ throw new CRLException(e.toString());
+ }
+ }
+
+ public byte[] getSignature()
+ {
+ return c.getSignature().getOctets();
+ }
+
+ public String getSigAlgName()
+ {
+ return sigAlgName;
+ }
+
+ public String getSigAlgOID()
+ {
+ return c.getSignatureAlgorithm().getAlgorithm().getId();
+ }
+
+ public byte[] getSigAlgParams()
+ {
+ if (sigAlgParams != null)
+ {
+ byte[] tmp = new byte[sigAlgParams.length];
+
+ System.arraycopy(sigAlgParams, 0, tmp, 0, tmp.length);
+
+ return tmp;
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns a string representation of this CRL.
+ *
+ * @return a string representation of this CRL.
+ */
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append(" Version: ").append(this.getVersion()).append(
+ nl);
+ buf.append(" IssuerDN: ").append(this.getIssuerDN())
+ .append(nl);
+ buf.append(" This update: ").append(this.getThisUpdate())
+ .append(nl);
+ buf.append(" Next update: ").append(this.getNextUpdate())
+ .append(nl);
+ buf.append(" Signature Algorithm: ").append(this.getSigAlgName())
+ .append(nl);
+
+ byte[] sig = this.getSignature();
+
+ buf.append(" Signature: ").append(
+ new String(Hex.encode(sig, 0, 20))).append(nl);
+ for (int i = 20; i < sig.length; i += 20)
+ {
+ if (i < sig.length - 20)
+ {
+ buf.append(" ").append(
+ new String(Hex.encode(sig, i, 20))).append(nl);
+ }
+ else
+ {
+ buf.append(" ").append(
+ new String(Hex.encode(sig, i, sig.length - i))).append(nl);
+ }
+ }
+
+ Extensions extensions = c.getTBSCertList().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ if (e.hasMoreElements())
+ {
+ buf.append(" Extensions: ").append(nl);
+ }
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.getExtnValue() != null)
+ {
+ byte[] octs = ext.getExtnValue().getOctets();
+ ASN1InputStream dIn = new ASN1InputStream(octs);
+ buf.append(" critical(").append(
+ ext.isCritical()).append(") ");
+ try
+ {
+ if (oid.equals(Extension.cRLNumber))
+ {
+ buf.append(
+ new CRLNumber(ASN1Integer.getInstance(
+ dIn.readObject()).getPositiveValue()))
+ .append(nl);
+ }
+ else if (oid.equals(Extension.deltaCRLIndicator))
+ {
+ buf.append(
+ "Base CRL: "
+ + new CRLNumber(ASN1Integer.getInstance(
+ dIn.readObject()).getPositiveValue()))
+ .append(nl);
+ }
+ else if (oid
+ .equals(Extension.issuingDistributionPoint))
+ {
+ buf.append(
+ IssuingDistributionPoint.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid
+ .equals(Extension.cRLDistributionPoints))
+ {
+ buf.append(
+ CRLDistPoint.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid.equals(Extension.freshestCRL))
+ {
+ buf.append(
+ CRLDistPoint.getInstance(dIn.readObject())).append(nl);
+ }
+ else
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append(
+ ASN1Dump.dumpAsString(dIn.readObject()))
+ .append(nl);
+ }
+ }
+ catch (Exception ex)
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append("*****").append(nl);
+ }
+ }
+ else
+ {
+ buf.append(nl);
+ }
+ }
+ }
+ Set set = getRevokedCertificates();
+ if (set != null)
+ {
+ Iterator it = set.iterator();
+ while (it.hasNext())
+ {
+ buf.append(it.next());
+ buf.append(nl);
+ }
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Checks whether the given certificate is on this CRL.
+ *
+ * @param cert the certificate to check for.
+ * @return true if the given certificate is on this CRL,
+ * false otherwise.
+ */
+ public boolean isRevoked(Certificate cert)
+ {
+ if (!cert.getType().equals("X.509"))
+ {
+ throw new RuntimeException("X.509 CRL used with non X.509 Cert");
+ }
+
+ Enumeration certs = c.getRevokedCertificateEnumeration();
+
+ X500Name caName = c.getIssuer();
+
+ if (certs != null)
+ {
+ BigInteger serial = ((X509Certificate)cert).getSerialNumber();
+
+ while (certs.hasMoreElements())
+ {
+ TBSCertList.CRLEntry entry = TBSCertList.CRLEntry.getInstance(certs.nextElement());
+
+ if (isIndirect && entry.hasExtensions())
+ {
+ Extension currentCaName = entry.getExtensions().getExtension(Extension.certificateIssuer);
+
+ if (currentCaName != null)
+ {
+ caName = X500Name.getInstance(GeneralNames.getInstance(currentCaName.getParsedValue()).getNames()[0].getName());
+ }
+ }
+
+ if (entry.getUserCertificate().hasValue(serial))
+ {
+ X500Name issuer;
+
+ if (cert instanceof X509Certificate)
+ {
+ issuer = X500Name.getInstance(((X509Certificate)cert).getIssuerX500Principal().getEncoded());
+ }
+ else
+ {
+ try
+ {
+ issuer = com.android.internal.org.bouncycastle.asn1.x509.Certificate.getInstance(cert.getEncoded()).getIssuer();
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new RuntimeException("Cannot process certificate");
+ }
+ }
+
+ if (!caName.equals(issuer))
+ {
+ return false;
+ }
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public boolean equals(Object other)
+ {
+ if (this == other)
+ {
+ return true;
+ }
+
+ if (!(other instanceof X509CRL))
+ {
+ return false;
+ }
+
+ if (other instanceof X509CRLObject)
+ {
+ X509CRLObject crlObject = (X509CRLObject)other;
+
+ if (isHashCodeSet)
+ {
+ boolean otherIsHashCodeSet = crlObject.isHashCodeSet;
+ if (otherIsHashCodeSet)
+ {
+ if (crlObject.hashCodeValue != hashCodeValue)
+ {
+ return false;
+ }
+ }
+ }
+
+ return this.c.equals(crlObject.c);
+ }
+
+ return super.equals(other);
+ }
+
+ public int hashCode()
+ {
+ if (!isHashCodeSet)
+ {
+ isHashCodeSet = true;
+ hashCodeValue = super.hashCode();
+ }
+
+ return hashCodeValue;
+ }
+}
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CertificateObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CertificateObject.java
new file mode 100644
index 00000000..10c90b70
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CertificateObject.java
@@ -0,0 +1,932 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1String;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.DERIA5String;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+import com.android.internal.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.misc.NetscapeCertType;
+import com.android.internal.org.bouncycastle.asn1.misc.NetscapeRevocationURL;
+import com.android.internal.org.bouncycastle.asn1.misc.VerisignCzagExtension;
+import com.android.internal.org.bouncycastle.asn1.util.ASN1Dump;
+import com.android.internal.org.bouncycastle.asn1.x500.X500Name;
+import com.android.internal.org.bouncycastle.asn1.x500.style.RFC4519Style;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.BasicConstraints;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.internal.org.bouncycastle.asn1.x509.KeyUsage;
+// BEGIN Android-added: Unknown reason
+import com.android.internal.org.bouncycastle.asn1.x509.X509Name;
+// END Android-added: Unknown reason
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
+import com.android.internal.org.bouncycastle.jce.X509Principal;
+import com.android.internal.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Integers;
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @deprecated Do not use this class directly - either use org.bouncycastle.cert (bcpkix) or CertificateFactory.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509CertificateObject
+ extends X509Certificate
+ implements PKCS12BagAttributeCarrier
+{
+ private com.android.internal.org.bouncycastle.asn1.x509.Certificate c;
+ private BasicConstraints basicConstraints;
+ private boolean[] keyUsage;
+ private boolean hashValueSet;
+ private int hashValue;
+
+ private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
+ public X509CertificateObject(
+ com.android.internal.org.bouncycastle.asn1.x509.Certificate c)
+ throws CertificateParsingException
+ {
+ this.c = c;
+
+ try
+ {
+ byte[] bytes = this.getExtensionBytes("2.5.29.19");
+
+ if (bytes != null)
+ {
+ basicConstraints = BasicConstraints.getInstance(ASN1Primitive.fromByteArray(bytes));
+ }
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException("cannot construct BasicConstraints: " + e);
+ }
+
+ try
+ {
+ byte[] bytes = this.getExtensionBytes("2.5.29.15");
+ if (bytes != null)
+ {
+ ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes));
+
+ bytes = bits.getBytes();
+ int length = (bytes.length * 8) - bits.getPadBits();
+
+ keyUsage = new boolean[(length < 9) ? 9 : length];
+
+ for (int i = 0; i != length; i++)
+ {
+ keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ }
+ }
+ else
+ {
+ keyUsage = null;
+ }
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException("cannot construct KeyUsage: " + e);
+ }
+ }
+
+ public void checkValidity()
+ throws CertificateExpiredException, CertificateNotYetValidException
+ {
+ this.checkValidity(new Date());
+ }
+
+ public void checkValidity(
+ Date date)
+ throws CertificateExpiredException, CertificateNotYetValidException
+ {
+ if (date.getTime() > this.getNotAfter().getTime()) // for other VM compatibility
+ {
+ throw new CertificateExpiredException("certificate expired on " + c.getEndDate().getTime());
+ }
+
+ if (date.getTime() < this.getNotBefore().getTime())
+ {
+ throw new CertificateNotYetValidException("certificate not valid till " + c.getStartDate().getTime());
+ }
+ }
+
+ public int getVersion()
+ {
+ return c.getVersionNumber();
+ }
+
+ public BigInteger getSerialNumber()
+ {
+ return c.getSerialNumber().getValue();
+ }
+
+ public Principal getIssuerDN()
+ {
+ return new X509Principal(c.getIssuer());
+ }
+
+ public X500Principal getIssuerX500Principal()
+ {
+ try
+ {
+ return new X500Principal(c.getIssuer().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("can't encode issuer DN");
+ }
+ }
+
+ public Principal getSubjectDN()
+ {
+ return new X509Principal(c.getSubject());
+ }
+
+ public X500Principal getSubjectX500Principal()
+ {
+ try
+ {
+ return new X500Principal(c.getSubject().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("can't encode issuer DN");
+ }
+ }
+
+ public Date getNotBefore()
+ {
+ return c.getStartDate().getDate();
+ }
+
+ public Date getNotAfter()
+ {
+ return c.getEndDate().getDate();
+ }
+
+ public byte[] getTBSCertificate()
+ throws CertificateEncodingException
+ {
+ try
+ {
+ return c.getTBSCertificate().getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException(e.toString());
+ }
+ }
+
+ public byte[] getSignature()
+ {
+ return c.getSignature().getOctets();
+ }
+
+ /**
+ * return a more "meaningful" representation for the signature algorithm used in
+ * the certficate.
+ */
+ public String getSigAlgName()
+ {
+ Provider prov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);
+
+ if (prov != null)
+ {
+ String algName = prov.getProperty("Alg.Alias.Signature." + this.getSigAlgOID());
+
+ if (algName != null)
+ {
+ return algName;
+ }
+ }
+
+ Provider[] provs = Security.getProviders();
+
+ //
+ // search every provider looking for a real algorithm
+ //
+ for (int i = 0; i != provs.length; i++)
+ {
+ String algName = provs[i].getProperty("Alg.Alias.Signature." + this.getSigAlgOID());
+ if (algName != null)
+ {
+ return algName;
+ }
+ }
+
+ return this.getSigAlgOID();
+ }
+
+ /**
+ * return the object identifier for the signature.
+ */
+ public String getSigAlgOID()
+ {
+ return c.getSignatureAlgorithm().getAlgorithm().getId();
+ }
+
+ /**
+ * return the signature parameters, or null if there aren't any.
+ */
+ public byte[] getSigAlgParams()
+ {
+ if (c.getSignatureAlgorithm().getParameters() != null)
+ {
+ try
+ {
+ return c.getSignatureAlgorithm().getParameters().toASN1Primitive().getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public boolean[] getIssuerUniqueID()
+ {
+ DERBitString id = c.getTBSCertificate().getIssuerUniqueId();
+
+ if (id != null)
+ {
+ byte[] bytes = id.getBytes();
+ boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
+
+ for (int i = 0; i != boolId.length; i++)
+ {
+ boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ }
+
+ return boolId;
+ }
+
+ return null;
+ }
+
+ public boolean[] getSubjectUniqueID()
+ {
+ DERBitString id = c.getTBSCertificate().getSubjectUniqueId();
+
+ if (id != null)
+ {
+ byte[] bytes = id.getBytes();
+ boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
+
+ for (int i = 0; i != boolId.length; i++)
+ {
+ boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ }
+
+ return boolId;
+ }
+
+ return null;
+ }
+
+ public boolean[] getKeyUsage()
+ {
+ return keyUsage;
+ }
+
+ public List getExtendedKeyUsage()
+ throws CertificateParsingException
+ {
+ byte[] bytes = this.getExtensionBytes("2.5.29.37");
+
+ if (bytes != null)
+ {
+ try
+ {
+ ASN1InputStream dIn = new ASN1InputStream(bytes);
+ ASN1Sequence seq = (ASN1Sequence)dIn.readObject();
+ List list = new ArrayList();
+
+ for (int i = 0; i != seq.size(); i++)
+ {
+ list.add(((ASN1ObjectIdentifier)seq.getObjectAt(i)).getId());
+ }
+
+ return Collections.unmodifiableList(list);
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException("error processing extended key usage extension");
+ }
+ }
+
+ return null;
+ }
+
+ public int getBasicConstraints()
+ {
+ if (basicConstraints != null)
+ {
+ if (basicConstraints.isCA())
+ {
+ if (basicConstraints.getPathLenConstraint() == null)
+ {
+ return Integer.MAX_VALUE;
+ }
+ else
+ {
+ return basicConstraints.getPathLenConstraint().intValue();
+ }
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ return -1;
+ }
+
+ public Collection getSubjectAlternativeNames()
+ throws CertificateParsingException
+ {
+ return getAlternativeNames(getExtensionBytes(Extension.subjectAlternativeName.getId()));
+ }
+
+ public Collection getIssuerAlternativeNames()
+ throws CertificateParsingException
+ {
+ return getAlternativeNames(getExtensionBytes(Extension.issuerAlternativeName.getId()));
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ if (this.getVersion() == 3)
+ {
+ Set set = new HashSet();
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+ }
+
+ return null;
+ }
+
+ private byte[] getExtensionBytes(String oid)
+ {
+ Extensions exts = c.getTBSCertificate().getExtensions();
+
+ if (exts != null)
+ {
+ Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
+ if (ext != null)
+ {
+ return ext.getExtnValue().getOctets();
+ }
+ }
+
+ return null;
+ }
+
+ public byte[] getExtensionValue(String oid)
+ {
+ Extensions exts = c.getTBSCertificate().getExtensions();
+
+ if (exts != null)
+ {
+ Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
+
+ if (ext != null)
+ {
+ try
+ {
+ return ext.getExtnValue().getEncoded();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException("error parsing " + e.toString());
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ if (this.getVersion() == 3)
+ {
+ Set set = new HashSet();
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (!ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+ }
+
+ return null;
+ }
+
+ public boolean hasUnsupportedCriticalExtension()
+ {
+ if (this.getVersion() == 3)
+ {
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ String oidId = oid.getId();
+
+ if (oidId.equals(RFC3280CertPathUtilities.KEY_USAGE)
+ || oidId.equals(RFC3280CertPathUtilities.CERTIFICATE_POLICIES)
+ || oidId.equals(RFC3280CertPathUtilities.POLICY_MAPPINGS)
+ || oidId.equals(RFC3280CertPathUtilities.INHIBIT_ANY_POLICY)
+ || oidId.equals(RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS)
+ || oidId.equals(RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT)
+ || oidId.equals(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR)
+ || oidId.equals(RFC3280CertPathUtilities.POLICY_CONSTRAINTS)
+ || oidId.equals(RFC3280CertPathUtilities.BASIC_CONSTRAINTS)
+ || oidId.equals(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME)
+ || oidId.equals(RFC3280CertPathUtilities.NAME_CONSTRAINTS))
+ {
+ continue;
+ }
+
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.isCritical())
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public PublicKey getPublicKey()
+ {
+ try
+ {
+ return BouncyCastleProvider.getPublicKey(c.getSubjectPublicKeyInfo());
+ }
+ catch (IOException e)
+ {
+ return null; // should never happen...
+ }
+ }
+
+ // BEGIN Android-added: Cache encoded certificates
+ private byte[] encoded;
+ // END Android-added: Cache encoded certificates
+ public byte[] getEncoded()
+ throws CertificateEncodingException
+ {
+ try
+ {
+ // BEGIN Android-changed: Cache encoded certificates
+ if (encoded == null) {
+ encoded = c.getEncoded(ASN1Encoding.DER);
+ }
+ return encoded;
+ // END Android-changed: Cache encoded certificates
+ }
+ catch (IOException e)
+ {
+ throw new CertificateEncodingException(e.toString());
+ }
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (!(o instanceof Certificate))
+ {
+ return false;
+ }
+
+ Certificate other = (Certificate)o;
+
+ try
+ {
+ byte[] b1 = this.getEncoded();
+ byte[] b2 = other.getEncoded();
+
+ return Arrays.areEqual(b1, b2);
+ }
+ catch (CertificateEncodingException e)
+ {
+ return false;
+ }
+ }
+
+ public synchronized int hashCode()
+ {
+ if (!hashValueSet)
+ {
+ hashValue = calculateHashCode();
+ hashValueSet = true;
+ }
+
+ return hashValue;
+ }
+
+ private int calculateHashCode()
+ {
+ try
+ {
+ int hashCode = 0;
+ byte[] certData = this.getEncoded();
+ for (int i = 1; i < certData.length; i++)
+ {
+ hashCode += certData[i] * i;
+ }
+ return hashCode;
+ }
+ catch (CertificateEncodingException e)
+ {
+ return 0;
+ }
+ }
+
+ public void setBagAttribute(
+ ASN1ObjectIdentifier oid,
+ ASN1Encodable attribute)
+ {
+ attrCarrier.setBagAttribute(oid, attribute);
+ }
+
+ public ASN1Encodable getBagAttribute(
+ ASN1ObjectIdentifier oid)
+ {
+ return attrCarrier.getBagAttribute(oid);
+ }
+
+ public Enumeration getBagAttributeKeys()
+ {
+ return attrCarrier.getBagAttributeKeys();
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = Strings.lineSeparator();
+
+ buf.append(" [0] Version: ").append(this.getVersion()).append(nl);
+ buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl);
+ buf.append(" IssuerDN: ").append(this.getIssuerDN()).append(nl);
+ buf.append(" Start Date: ").append(this.getNotBefore()).append(nl);
+ buf.append(" Final Date: ").append(this.getNotAfter()).append(nl);
+ buf.append(" SubjectDN: ").append(this.getSubjectDN()).append(nl);
+ buf.append(" Public Key: ").append(this.getPublicKey()).append(nl);
+ buf.append(" Signature Algorithm: ").append(this.getSigAlgName()).append(nl);
+
+ byte[] sig = this.getSignature();
+
+ buf.append(" Signature: ").append(new String(Hex.encode(sig, 0, 20))).append(nl);
+ for (int i = 20; i < sig.length; i += 20)
+ {
+ if (i < sig.length - 20)
+ {
+ buf.append(" ").append(new String(Hex.encode(sig, i, 20))).append(nl);
+ }
+ else
+ {
+ buf.append(" ").append(new String(Hex.encode(sig, i, sig.length - i))).append(nl);
+ }
+ }
+
+ Extensions extensions = c.getTBSCertificate().getExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ if (e.hasMoreElements())
+ {
+ buf.append(" Extensions: \n");
+ }
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.getExtnValue() != null)
+ {
+ byte[] octs = ext.getExtnValue().getOctets();
+ ASN1InputStream dIn = new ASN1InputStream(octs);
+ buf.append(" critical(").append(ext.isCritical()).append(") ");
+ try
+ {
+ if (oid.equals(Extension.basicConstraints))
+ {
+ buf.append(BasicConstraints.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid.equals(Extension.keyUsage))
+ {
+ buf.append(KeyUsage.getInstance(dIn.readObject())).append(nl);
+ }
+ else if (oid.equals(MiscObjectIdentifiers.netscapeCertType))
+ {
+ buf.append(new NetscapeCertType((DERBitString)dIn.readObject())).append(nl);
+ }
+ else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL))
+ {
+ buf.append(new NetscapeRevocationURL((DERIA5String)dIn.readObject())).append(nl);
+ }
+ else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension))
+ {
+ buf.append(new VerisignCzagExtension((DERIA5String)dIn.readObject())).append(nl);
+ }
+ else
+ {
+ buf.append(oid.getId());
+ buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl);
+ //buf.append(" value = ").append("*****").append(nl);
+ }
+ }
+ catch (Exception ex)
+ {
+ buf.append(oid.getId());
+ // buf.append(" value = ").append(new String(Hex.encode(ext.getExtnValue().getOctets()))).append(nl);
+ buf.append(" value = ").append("*****").append(nl);
+ }
+ }
+ else
+ {
+ buf.append(nl);
+ }
+ }
+ }
+
+ return buf.toString();
+ }
+
+ public final void verify(
+ PublicKey key)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ Signature signature;
+ String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
+
+ try
+ {
+ signature = Signature.getInstance(sigName, BouncyCastleProvider.PROVIDER_NAME);
+ }
+ catch (Exception e)
+ {
+ signature = Signature.getInstance(sigName);
+ }
+
+ checkSignature(key, signature);
+ }
+
+ public final void verify(
+ PublicKey key,
+ String sigProvider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
+ Signature signature;
+
+ if (sigProvider != null)
+ {
+ signature = Signature.getInstance(sigName, sigProvider);
+ }
+ else
+ {
+ signature = Signature.getInstance(sigName);
+ }
+
+ checkSignature(key, signature);
+ }
+
+ public final void verify(
+ PublicKey key,
+ Provider sigProvider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
+ String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
+ Signature signature;
+
+ if (sigProvider != null)
+ {
+ signature = Signature.getInstance(sigName, sigProvider);
+ }
+ else
+ {
+ signature = Signature.getInstance(sigName);
+ }
+
+ checkSignature(key, signature);
+ }
+
+ private void checkSignature(
+ PublicKey key,
+ Signature signature)
+ throws CertificateException, NoSuchAlgorithmException,
+ SignatureException, InvalidKeyException
+ {
+ if (!isAlgIdEqual(c.getSignatureAlgorithm(), c.getTBSCertificate().getSignature()))
+ {
+ throw new CertificateException("signature algorithm in TBS cert not same as outer cert");
+ }
+
+ ASN1Encodable params = c.getSignatureAlgorithm().getParameters();
+
+ // TODO This should go after the initVerify?
+ X509SignatureUtil.setSignatureParameters(signature, params);
+
+ signature.initVerify(key);
+
+ signature.update(this.getTBSCertificate());
+
+ if (!signature.verify(this.getSignature()))
+ {
+ throw new SignatureException("certificate does not verify with supplied key");
+ }
+ }
+
+ private boolean isAlgIdEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2)
+ {
+ if (!id1.getAlgorithm().equals(id2.getAlgorithm()))
+ {
+ return false;
+ }
+
+ if (id1.getParameters() == null)
+ {
+ if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ if (id2.getParameters() == null)
+ {
+ if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ return id1.getParameters().equals(id2.getParameters());
+ }
+
+ private static Collection getAlternativeNames(byte[] extVal)
+ throws CertificateParsingException
+ {
+ if (extVal == null)
+ {
+ return null;
+ }
+ try
+ {
+ Collection temp = new ArrayList();
+ Enumeration it = ASN1Sequence.getInstance(extVal).getObjects();
+ while (it.hasMoreElements())
+ {
+ GeneralName genName = GeneralName.getInstance(it.nextElement());
+ List list = new ArrayList();
+ list.add(Integers.valueOf(genName.getTagNo()));
+ switch (genName.getTagNo())
+ {
+ case GeneralName.ediPartyName:
+ case GeneralName.x400Address:
+ case GeneralName.otherName:
+ list.add(genName.getEncoded());
+ break;
+ case GeneralName.directoryName:
+ // BEGIN Android-changed: Unknown reason
+ list.add(X509Name.getInstance(genName.getName()).toString(true, X509Name.DefaultSymbols));
+ // END Android-changed: Unknown reason
+ break;
+ case GeneralName.dNSName:
+ case GeneralName.rfc822Name:
+ case GeneralName.uniformResourceIdentifier:
+ list.add(((ASN1String)genName.getName()).getString());
+ break;
+ case GeneralName.registeredID:
+ list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId());
+ break;
+ case GeneralName.iPAddress:
+ byte[] addrBytes = DEROctetString.getInstance(genName.getName()).getOctets();
+ final String addr;
+ try
+ {
+ addr = InetAddress.getByAddress(addrBytes).getHostAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ continue;
+ }
+ list.add(addr);
+ break;
+ default:
+ throw new IOException("Bad tag number: " + genName.getTagNo());
+ }
+
+ temp.add(Collections.unmodifiableList(list));
+ }
+ if (temp.size() == 0)
+ {
+ return null;
+ }
+ return Collections.unmodifiableCollection(temp);
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException(e.getMessage());
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509SignatureUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509SignatureUtil.java
new file mode 100644
index 00000000..ec886c78
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509SignatureUtil.java
@@ -0,0 +1,148 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.provider;
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.PSSParameterSpec;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Null;
+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.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;
+import com.android.internal.org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
+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;
+
+class X509SignatureUtil
+{
+ private static final ASN1Null derNull = DERNull.INSTANCE;
+
+ static void setSignatureParameters(
+ Signature signature,
+ ASN1Encodable params)
+ throws NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ if (params != null && !derNull.equals(params))
+ {
+ AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider());
+
+ try
+ {
+ sigParams.init(params.toASN1Primitive().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new SignatureException("IOException decoding parameters: " + e.getMessage());
+ }
+
+ if (signature.getAlgorithm().endsWith("MGF1"))
+ {
+ try
+ {
+ signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class));
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new SignatureException("Exception extracting parameters: " + e.getMessage());
+ }
+ }
+ }
+ }
+
+ static String getSignatureName(
+ AlgorithmIdentifier sigAlgId)
+ {
+ ASN1Encodable params = sigAlgId.getParameters();
+
+ if (params != null && !derNull.equals(params))
+ {
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params);
+
+ return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "withRSAandMGF1";
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ if (sigAlgId.getAlgorithm().equals(X9ObjectIdentifiers.ecdsa_with_SHA2))
+ {
+ ASN1Sequence ecDsaParams = ASN1Sequence.getInstance(params);
+
+ return getDigestAlgName(ASN1ObjectIdentifier.getInstance(ecDsaParams.getObjectAt(0))) + "withECDSA";
+ }
+ }
+
+ return sigAlgId.getAlgorithm().getId();
+ }
+
+ /**
+ * Return the digest algorithm using one of the standard JCA string
+ * representations rather the the algorithm identifier (if possible).
+ */
+ private static String getDigestAlgName(
+ ASN1ObjectIdentifier digestAlgOID)
+ {
+ if (PKCSObjectIdentifiers.md5.equals(digestAlgOID))
+ {
+ return "MD5";
+ }
+ else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID))
+ {
+ return "SHA1";
+ }
+ else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID))
+ {
+ return "SHA224";
+ }
+ else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID))
+ {
+ return "SHA256";
+ }
+ else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID))
+ {
+ return "SHA384";
+ }
+ else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID))
+ {
+ return "SHA512";
+ }
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID))
+ {
+ return "RIPEMD128";
+ }
+ else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID))
+ {
+ return "RIPEMD160";
+ }
+ else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID))
+ {
+ return "RIPEMD256";
+ }
+ else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID))
+ {
+ return "GOST3411";
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+ else
+ {
+ return digestAlgOID.getId();
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECKeySpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECKeySpec.java
new file mode 100644
index 00000000..3abe3944
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECKeySpec.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.spec;
+
+import java.security.spec.KeySpec;
+
+/**
+ * base class for an Elliptic Curve Key Spec
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECKeySpec
+ implements KeySpec
+{
+ private ECParameterSpec spec;
+
+ protected ECKeySpec(
+ ECParameterSpec spec)
+ {
+ this.spec = spec;
+ }
+
+ /**
+ * return the domain parameters for the curve
+ */
+ public ECParameterSpec getParams()
+ {
+ return spec;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveGenParameterSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveGenParameterSpec.java
new file mode 100644
index 00000000..6d11743f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveGenParameterSpec.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * Named curve generation spec
+ * <p>
+ * If you are using JDK 1.5 you should be looking at ECGenParameterSpec.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECNamedCurveGenParameterSpec
+ implements AlgorithmParameterSpec
+{
+ private String name;
+
+ public ECNamedCurveGenParameterSpec(
+ String name)
+ {
+ this.name = name;
+ }
+
+ /**
+ * return the name of the curve the EC domain parameters belong to.
+ */
+ public String getName()
+ {
+ return name;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveParameterSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveParameterSpec.java
new file mode 100644
index 00000000..0ec146f6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveParameterSpec.java
@@ -0,0 +1,64 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.spec;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+
+/**
+ * specification signifying that the curve parameters can also be
+ * referred to by name.
+ * <p>
+ * If you are using JDK 1.5 you should be looking at {@link ECNamedCurveSpec}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECNamedCurveParameterSpec
+ extends ECParameterSpec
+{
+ private String name;
+
+ public ECNamedCurveParameterSpec(
+ String name,
+ ECCurve curve,
+ ECPoint G,
+ BigInteger n)
+ {
+ super(curve, G, n);
+
+ this.name = name;
+ }
+
+ public ECNamedCurveParameterSpec(
+ String name,
+ ECCurve curve,
+ ECPoint G,
+ BigInteger n,
+ BigInteger h)
+ {
+ super(curve, G, n, h);
+
+ this.name = name;
+ }
+
+ public ECNamedCurveParameterSpec(
+ String name,
+ ECCurve curve,
+ ECPoint G,
+ BigInteger n,
+ BigInteger h,
+ byte[] seed)
+ {
+ super(curve, G, n, h, seed);
+
+ this.name = name;
+ }
+
+ /**
+ * return the name of the curve the EC domain parameters belong to.
+ */
+ public String getName()
+ {
+ return name;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveSpec.java
new file mode 100644
index 00000000..401ef673
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECNamedCurveSpec.java
@@ -0,0 +1,119 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.spec;
+
+import java.math.BigInteger;
+import java.security.spec.ECField;
+import java.security.spec.ECFieldF2m;
+import java.security.spec.ECFieldFp;
+import java.security.spec.ECPoint;
+import java.security.spec.EllipticCurve;
+
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import com.android.internal.org.bouncycastle.math.ec.ECAlgorithms;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.field.FiniteField;
+import com.android.internal.org.bouncycastle.math.field.Polynomial;
+import com.android.internal.org.bouncycastle.math.field.PolynomialExtensionField;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * specification signifying that the curve parameters can also be
+ * referred to by name.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECNamedCurveSpec
+ extends java.security.spec.ECParameterSpec
+{
+ private String name;
+
+ private static EllipticCurve convertCurve(
+ ECCurve curve,
+ byte[] seed)
+ {
+ ECField field = convertField(curve.getField());
+ BigInteger a = curve.getA().toBigInteger(), b = curve.getB().toBigInteger();
+ return new EllipticCurve(field, a, b, seed);
+ }
+
+ private static ECField convertField(FiniteField field)
+ {
+ if (ECAlgorithms.isFpField(field))
+ {
+ return new ECFieldFp(field.getCharacteristic());
+ }
+ else //if (ECAlgorithms.isF2mField(curveField))
+ {
+ Polynomial poly = ((PolynomialExtensionField)field).getMinimalPolynomial();
+ int[] exponents = poly.getExponentsPresent();
+ int[] ks = Arrays.reverse(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
+ return new ECFieldF2m(poly.getDegree(), ks);
+ }
+ }
+
+ public ECNamedCurveSpec(
+ String name,
+ ECCurve curve,
+ com.android.internal.org.bouncycastle.math.ec.ECPoint g,
+ BigInteger n)
+ {
+ super(convertCurve(curve, null), EC5Util.convertPoint(g), n, 1);
+
+ this.name = name;
+ }
+
+ public ECNamedCurveSpec(
+ String name,
+ EllipticCurve curve,
+ ECPoint g,
+ BigInteger n)
+ {
+ super(curve, g, n, 1);
+
+ this.name = name;
+ }
+
+ public ECNamedCurveSpec(
+ String name,
+ ECCurve curve,
+ com.android.internal.org.bouncycastle.math.ec.ECPoint g,
+ BigInteger n,
+ BigInteger h)
+ {
+ super(convertCurve(curve, null), EC5Util.convertPoint(g), n, h.intValue());
+
+ this.name = name;
+ }
+
+ public ECNamedCurveSpec(
+ String name,
+ EllipticCurve curve,
+ ECPoint g,
+ BigInteger n,
+ BigInteger h)
+ {
+ super(curve, g, n, h.intValue());
+
+ this.name = name;
+ }
+
+ public ECNamedCurveSpec(
+ String name,
+ ECCurve curve,
+ com.android.internal.org.bouncycastle.math.ec.ECPoint g,
+ BigInteger n,
+ BigInteger h,
+ byte[] seed)
+ {
+ super(convertCurve(curve, seed), EC5Util.convertPoint(g), n, h.intValue());
+
+ this.name = name;
+ }
+
+ /**
+ * return the name of the curve the EC domain parameters belong to.
+ */
+ public String getName()
+ {
+ return name;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECParameterSpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECParameterSpec.java
new file mode 100644
index 00000000..35c927fb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECParameterSpec.java
@@ -0,0 +1,123 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.spec;
+
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+
+import java.math.BigInteger;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * basic domain parameters for an Elliptic Curve public or private key.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECParameterSpec
+ implements AlgorithmParameterSpec
+{
+ private ECCurve curve;
+ private byte[] seed;
+ private ECPoint G;
+ private BigInteger n;
+ private BigInteger h;
+
+ public ECParameterSpec(
+ ECCurve curve,
+ ECPoint G,
+ BigInteger n)
+ {
+ this.curve = curve;
+ this.G = G.normalize();
+ this.n = n;
+ this.h = BigInteger.valueOf(1);
+ this.seed = null;
+ }
+
+ public ECParameterSpec(
+ ECCurve curve,
+ ECPoint G,
+ BigInteger n,
+ BigInteger h)
+ {
+ this.curve = curve;
+ this.G = G.normalize();
+ this.n = n;
+ this.h = h;
+ this.seed = null;
+ }
+
+ public ECParameterSpec(
+ ECCurve curve,
+ ECPoint G,
+ BigInteger n,
+ BigInteger h,
+ byte[] seed)
+ {
+ this.curve = curve;
+ this.G = G.normalize();
+ this.n = n;
+ this.h = h;
+ this.seed = seed;
+ }
+
+ /**
+ * return the curve along which the base point lies.
+ * @return the curve
+ */
+ public ECCurve getCurve()
+ {
+ return curve;
+ }
+
+ /**
+ * return the base point we are using for these domain parameters.
+ * @return the base point.
+ */
+ public ECPoint getG()
+ {
+ return G;
+ }
+
+ /**
+ * return the order N of G
+ * @return the order
+ */
+ public BigInteger getN()
+ {
+ return n;
+ }
+
+ /**
+ * return the cofactor H to the order of G.
+ * @return the cofactor
+ */
+ public BigInteger getH()
+ {
+ return h;
+ }
+
+ /**
+ * return the seed used to generate this curve (if available).
+ * @return the random seed
+ */
+ public byte[] getSeed()
+ {
+ return seed;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof ECParameterSpec))
+ {
+ return false;
+ }
+
+ ECParameterSpec other = (ECParameterSpec)o;
+
+ return this.getCurve().equals(other.getCurve()) && this.getG().equals(other.getG());
+ }
+
+ public int hashCode()
+ {
+ return this.getCurve().hashCode() ^ this.getG().hashCode();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECPrivateKeySpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECPrivateKeySpec.java
new file mode 100644
index 00000000..b5920451
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECPrivateKeySpec.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.spec;
+
+import java.math.BigInteger;
+
+/**
+ * Elliptic Curve private key specification.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECPrivateKeySpec
+ extends ECKeySpec
+{
+ private BigInteger d;
+
+ /**
+ * base constructor
+ *
+ * @param d the private number for the key.
+ * @param spec the domain parameters for the curve being used.
+ */
+ public ECPrivateKeySpec(
+ BigInteger d,
+ ECParameterSpec spec)
+ {
+ super(spec);
+
+ this.d = d;
+ }
+
+ /**
+ * return the private number D
+ */
+ public BigInteger getD()
+ {
+ return d;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECPublicKeySpec.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECPublicKeySpec.java
new file mode 100644
index 00000000..0078f47f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/spec/ECPublicKeySpec.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.jce.spec;
+
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+
+/**
+ * Elliptic Curve public key specification
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECPublicKeySpec
+ extends ECKeySpec
+{
+ private ECPoint q;
+
+ /**
+ * base constructor
+ *
+ * @param q the public point on the curve.
+ * @param spec the domain parameters for the curve.
+ */
+ public ECPublicKeySpec(
+ ECPoint q,
+ ECParameterSpec spec)
+ {
+ super(spec);
+
+ if (q.getCurve() != null)
+ {
+ this.q = q.normalize();
+ }
+ else
+ {
+ this.q = q;
+ }
+ }
+
+ /**
+ * return the public point q
+ */
+ public ECPoint getQ()
+ {
+ return q;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/Primes.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/Primes.java
new file mode 100644
index 00000000..dd83736e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/Primes.java
@@ -0,0 +1,678 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+
+/**
+ * Utility methods for generating primes and testing for primality.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class Primes
+{
+ public static final int SMALL_FACTOR_LIMIT = 211;
+
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+ private static final BigInteger THREE = BigInteger.valueOf(3);
+
+ /**
+ * Used to return the output from the
+ * {@linkplain Primes#enhancedMRProbablePrimeTest(BigInteger, SecureRandom, int) Enhanced
+ * Miller-Rabin Probabilistic Primality Test}
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class MROutput
+ {
+ private static MROutput probablyPrime()
+ {
+ return new MROutput(false, null);
+ }
+
+ private static MROutput provablyCompositeWithFactor(BigInteger factor)
+ {
+ return new MROutput(true, factor);
+ }
+
+ private static MROutput provablyCompositeNotPrimePower()
+ {
+ return new MROutput(true, null);
+ }
+
+ private boolean provablyComposite;
+ private BigInteger factor;
+
+ private MROutput(boolean provablyComposite, BigInteger factor)
+ {
+ this.provablyComposite = provablyComposite;
+ this.factor = factor;
+ }
+
+ public BigInteger getFactor()
+ {
+ return factor;
+ }
+
+ public boolean isProvablyComposite()
+ {
+ return provablyComposite;
+ }
+
+ public boolean isNotPrimePower()
+ {
+ return provablyComposite && factor == null;
+ }
+ }
+
+ /**
+ * Used to return the output from the
+ * {@linkplain Primes#generateSTRandomPrime(Digest, int, byte[]) Shawe-Taylor Random_Prime
+ * Routine}
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class STOutput
+ {
+ private BigInteger prime;
+ private byte[] primeSeed;
+ private int primeGenCounter;
+
+ private STOutput(BigInteger prime, byte[] primeSeed, int primeGenCounter)
+ {
+ this.prime = prime;
+ this.primeSeed = primeSeed;
+ this.primeGenCounter = primeGenCounter;
+ }
+
+ public BigInteger getPrime()
+ {
+ return prime;
+ }
+
+ public byte[] getPrimeSeed()
+ {
+ return primeSeed;
+ }
+
+ public int getPrimeGenCounter()
+ {
+ return primeGenCounter;
+ }
+ }
+
+ /**
+ * FIPS 186-4 C.6 Shawe-Taylor Random_Prime Routine
+ *
+ * Construct a provable prime number using a hash function.
+ *
+ * @param hash
+ * the {@link Digest} instance to use (as "Hash()"). Cannot be null.
+ * @param length
+ * the length (in bits) of the prime to be generated. Must be at least 2.
+ * @param inputSeed
+ * the seed to be used for the generation of the requested prime. Cannot be null or
+ * empty.
+ * @return an {@link STOutput} instance containing the requested prime.
+ */
+ public static STOutput generateSTRandomPrime(Digest hash, int length, byte[] inputSeed)
+ {
+ if (hash == null)
+ {
+ throw new IllegalArgumentException("'hash' cannot be null");
+ }
+ if (length < 2)
+ {
+ throw new IllegalArgumentException("'length' must be >= 2");
+ }
+ if (inputSeed == null || inputSeed.length == 0)
+ {
+ throw new IllegalArgumentException("'inputSeed' cannot be null or empty");
+ }
+
+ return implSTRandomPrime(hash, length, Arrays.clone(inputSeed));
+ }
+
+ /**
+ * FIPS 186-4 C.3.2 Enhanced Miller-Rabin Probabilistic Primality Test
+ *
+ * Run several iterations of the Miller-Rabin algorithm with randomly-chosen bases. This is an
+ * alternative to {@link #isMRProbablePrime(BigInteger, SecureRandom, int)} that provides more
+ * information about a composite candidate, which may be useful when generating or validating
+ * RSA moduli.
+ *
+ * @param candidate
+ * the {@link BigInteger} instance to test for primality.
+ * @param random
+ * the source of randomness to use to choose bases.
+ * @param iterations
+ * the number of randomly-chosen bases to perform the test for.
+ * @return an {@link MROutput} instance that can be further queried for details.
+ */
+ public static MROutput enhancedMRProbablePrimeTest(BigInteger candidate, SecureRandom random, int iterations)
+ {
+ checkCandidate(candidate, "candidate");
+
+ if (random == null)
+ {
+ throw new IllegalArgumentException("'random' cannot be null");
+ }
+ if (iterations < 1)
+ {
+ throw new IllegalArgumentException("'iterations' must be > 0");
+ }
+
+ if (candidate.bitLength() == 2)
+ {
+ return MROutput.probablyPrime();
+ }
+ if (!candidate.testBit(0))
+ {
+ return MROutput.provablyCompositeWithFactor(TWO);
+ }
+
+ BigInteger w = candidate;
+ BigInteger wSubOne = candidate.subtract(ONE);
+ BigInteger wSubTwo = candidate.subtract(TWO);
+
+ int a = wSubOne.getLowestSetBit();
+ BigInteger m = wSubOne.shiftRight(a);
+
+ for (int i = 0; i < iterations; ++i)
+ {
+ BigInteger b = BigIntegers.createRandomInRange(TWO, wSubTwo, random);
+ BigInteger g = b.gcd(w);
+
+ if (g.compareTo(ONE) > 0)
+ {
+ return MROutput.provablyCompositeWithFactor(g);
+ }
+
+ BigInteger z = b.modPow(m, w);
+
+ if (z.equals(ONE) || z.equals(wSubOne))
+ {
+ continue;
+ }
+
+ boolean primeToBase = false;
+
+ BigInteger x = z;
+ for (int j = 1; j < a; ++j)
+ {
+ z = z.modPow(TWO, w);
+
+ if (z.equals(wSubOne))
+ {
+ primeToBase = true;
+ break;
+ }
+
+ if (z.equals(ONE))
+ {
+ break;
+ }
+
+ x = z;
+ }
+
+ if (!primeToBase)
+ {
+ if (!z.equals(ONE))
+ {
+ x = z;
+ z = z.modPow(TWO, w);
+
+ if (!z.equals(ONE))
+ {
+ x = z;
+ }
+ }
+
+ g = x.subtract(ONE).gcd(w);
+
+ if (g.compareTo(ONE) > 0)
+ {
+ return MROutput.provablyCompositeWithFactor(g);
+ }
+
+ return MROutput.provablyCompositeNotPrimePower();
+ }
+ }
+
+ return MROutput.probablyPrime();
+ }
+
+ /**
+ * A fast check for small divisors, up to some implementation-specific limit.
+ *
+ * @param candidate
+ * the {@link BigInteger} instance to test for division by small factors.
+ *
+ * @return <code>true</code> if the candidate is found to have any small factors,
+ * <code>false</code> otherwise.
+ */
+ public static boolean hasAnySmallFactors(BigInteger candidate)
+ {
+ checkCandidate(candidate, "candidate");
+
+ return implHasAnySmallFactors(candidate);
+ }
+
+ /**
+ * FIPS 186-4 C.3.1 Miller-Rabin Probabilistic Primality Test
+ *
+ * Run several iterations of the Miller-Rabin algorithm with randomly-chosen bases.
+ *
+ * @param candidate
+ * the {@link BigInteger} instance to test for primality.
+ * @param random
+ * the source of randomness to use to choose bases.
+ * @param iterations
+ * the number of randomly-chosen bases to perform the test for.
+ * @return <code>false</code> if any witness to compositeness is found amongst the chosen bases
+ * (so <code>candidate</code> is definitely NOT prime), or else <code>true</code>
+ * (indicating primality with some probability dependent on the number of iterations
+ * that were performed).
+ */
+ public static boolean isMRProbablePrime(BigInteger candidate, SecureRandom random, int iterations)
+ {
+ checkCandidate(candidate, "candidate");
+
+ if (random == null)
+ {
+ throw new IllegalArgumentException("'random' cannot be null");
+ }
+ if (iterations < 1)
+ {
+ throw new IllegalArgumentException("'iterations' must be > 0");
+ }
+
+ if (candidate.bitLength() == 2)
+ {
+ return true;
+ }
+ if (!candidate.testBit(0))
+ {
+ return false;
+ }
+
+ BigInteger w = candidate;
+ BigInteger wSubOne = candidate.subtract(ONE);
+ BigInteger wSubTwo = candidate.subtract(TWO);
+
+ int a = wSubOne.getLowestSetBit();
+ BigInteger m = wSubOne.shiftRight(a);
+
+ for (int i = 0; i < iterations; ++i)
+ {
+ BigInteger b = BigIntegers.createRandomInRange(TWO, wSubTwo, random);
+
+ if (!implMRProbablePrimeToBase(w, wSubOne, m, a, b))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * FIPS 186-4 C.3.1 Miller-Rabin Probabilistic Primality Test (to a fixed base).
+ *
+ * Run a single iteration of the Miller-Rabin algorithm against the specified base.
+ *
+ * @param candidate
+ * the {@link BigInteger} instance to test for primality.
+ * @param base
+ * the base value to use for this iteration.
+ * @return <code>false</code> if the specified base is a witness to compositeness (so
+ * <code>candidate</code> is definitely NOT prime), or else <code>true</code>.
+ */
+ public static boolean isMRProbablePrimeToBase(BigInteger candidate, BigInteger base)
+ {
+ checkCandidate(candidate, "candidate");
+ checkCandidate(base, "base");
+
+ if (base.compareTo(candidate.subtract(ONE)) >= 0)
+ {
+ throw new IllegalArgumentException("'base' must be < ('candidate' - 1)");
+ }
+
+ if (candidate.bitLength() == 2)
+ {
+ return true;
+ }
+
+ BigInteger w = candidate;
+ BigInteger wSubOne = candidate.subtract(ONE);
+
+ int a = wSubOne.getLowestSetBit();
+ BigInteger m = wSubOne.shiftRight(a);
+
+ return implMRProbablePrimeToBase(w, wSubOne, m, a, base);
+ }
+
+ private static void checkCandidate(BigInteger n, String name)
+ {
+ if (n == null || n.signum() < 1 || n.bitLength() < 2)
+ {
+ throw new IllegalArgumentException("'" + name + "' must be non-null and >= 2");
+ }
+ }
+
+ private static boolean implHasAnySmallFactors(BigInteger x)
+ {
+ /*
+ * Bundle trial divisors into ~32-bit moduli then use fast tests on the ~32-bit remainders.
+ */
+ int m = 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23;
+ int r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 2) == 0 || (r % 3) == 0 || (r % 5) == 0 || (r % 7) == 0 || (r % 11) == 0 || (r % 13) == 0
+ || (r % 17) == 0 || (r % 19) == 0 || (r % 23) == 0)
+ {
+ return true;
+ }
+
+ m = 29 * 31 * 37 * 41 * 43;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 29) == 0 || (r % 31) == 0 || (r % 37) == 0 || (r % 41) == 0 || (r % 43) == 0)
+ {
+ return true;
+ }
+
+ m = 47 * 53 * 59 * 61 * 67;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 47) == 0 || (r % 53) == 0 || (r % 59) == 0 || (r % 61) == 0 || (r % 67) == 0)
+ {
+ return true;
+ }
+
+ m = 71 * 73 * 79 * 83;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 71) == 0 || (r % 73) == 0 || (r % 79) == 0 || (r % 83) == 0)
+ {
+ return true;
+ }
+
+ m = 89 * 97 * 101 * 103;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 89) == 0 || (r % 97) == 0 || (r % 101) == 0 || (r % 103) == 0)
+ {
+ return true;
+ }
+
+ m = 107 * 109 * 113 * 127;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 107) == 0 || (r % 109) == 0 || (r % 113) == 0 || (r % 127) == 0)
+ {
+ return true;
+ }
+
+ m = 131 * 137 * 139 * 149;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 131) == 0 || (r % 137) == 0 || (r % 139) == 0 || (r % 149) == 0)
+ {
+ return true;
+ }
+
+ m = 151 * 157 * 163 * 167;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 151) == 0 || (r % 157) == 0 || (r % 163) == 0 || (r % 167) == 0)
+ {
+ return true;
+ }
+
+ m = 173 * 179 * 181 * 191;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 173) == 0 || (r % 179) == 0 || (r % 181) == 0 || (r % 191) == 0)
+ {
+ return true;
+ }
+
+ m = 193 * 197 * 199 * 211;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 193) == 0 || (r % 197) == 0 || (r % 199) == 0 || (r % 211) == 0)
+ {
+ return true;
+ }
+
+ /*
+ * NOTE: Unit tests depend on SMALL_FACTOR_LIMIT matching the
+ * highest small factor tested here.
+ */
+ return false;
+ }
+
+ private static boolean implMRProbablePrimeToBase(BigInteger w, BigInteger wSubOne, BigInteger m, int a, BigInteger b)
+ {
+ BigInteger z = b.modPow(m, w);
+
+ if (z.equals(ONE) || z.equals(wSubOne))
+ {
+ return true;
+ }
+
+ boolean result = false;
+
+ for (int j = 1; j < a; ++j)
+ {
+ z = z.modPow(TWO, w);
+
+ if (z.equals(wSubOne))
+ {
+ result = true;
+ break;
+ }
+
+ if (z.equals(ONE))
+ {
+ return false;
+ }
+ }
+
+ return result;
+ }
+
+ private static STOutput implSTRandomPrime(Digest d, int length, byte[] primeSeed)
+ {
+ int dLen = d.getDigestSize();
+
+ if (length < 33)
+ {
+ int primeGenCounter = 0;
+
+ byte[] c0 = new byte[dLen];
+ byte[] c1 = new byte[dLen];
+
+ for (;;)
+ {
+ hash(d, primeSeed, c0, 0);
+ inc(primeSeed, 1);
+
+ hash(d, primeSeed, c1, 0);
+ inc(primeSeed, 1);
+
+ int c = extract32(c0) ^ extract32(c1);
+ c &= (-1 >>> (32 - length));
+ c |= (1 << (length - 1)) | 1;
+
+ ++primeGenCounter;
+
+ long c64 = c & 0xFFFFFFFFL;
+ if (isPrime32(c64))
+ {
+ return new STOutput(BigInteger.valueOf(c64), primeSeed, primeGenCounter);
+ }
+
+ if (primeGenCounter > (4 * length))
+ {
+ throw new IllegalStateException("Too many iterations in Shawe-Taylor Random_Prime Routine");
+ }
+ }
+ }
+
+ STOutput rec = implSTRandomPrime(d, (length + 3) / 2, primeSeed);
+
+ BigInteger c0 = rec.getPrime();
+ primeSeed = rec.getPrimeSeed();
+ int primeGenCounter = rec.getPrimeGenCounter();
+
+ int outlen = 8 * dLen;
+ int iterations = (length - 1) / outlen;
+
+ int oldCounter = primeGenCounter;
+
+ BigInteger x = hashGen(d, primeSeed, iterations + 1);
+ x = x.mod(ONE.shiftLeft(length - 1)).setBit(length - 1);
+
+ BigInteger c0x2 = c0.shiftLeft(1);
+ BigInteger tx2 = x.subtract(ONE).divide(c0x2).add(ONE).shiftLeft(1);
+ int dt = 0;
+
+ BigInteger c = tx2.multiply(c0).add(ONE);
+
+ /*
+ * TODO Since the candidate primes are generated by constant steps ('c0x2'), sieving could
+ * be used here in place of the 'hasAnySmallFactors' approach.
+ */
+ for (;;)
+ {
+ if (c.bitLength() > length)
+ {
+ tx2 = ONE.shiftLeft(length - 1).subtract(ONE).divide(c0x2).add(ONE).shiftLeft(1);
+ c = tx2.multiply(c0).add(ONE);
+ }
+
+ ++primeGenCounter;
+
+ /*
+ * This is an optimization of the original algorithm, using trial division to screen out
+ * many non-primes quickly.
+ *
+ * NOTE: 'primeSeed' is still incremented as if we performed the full check!
+ */
+ if (!implHasAnySmallFactors(c))
+ {
+ BigInteger a = hashGen(d, primeSeed, iterations + 1);
+ a = a.mod(c.subtract(THREE)).add(TWO);
+
+ tx2 = tx2.add(BigInteger.valueOf(dt));
+ dt = 0;
+
+ BigInteger z = a.modPow(tx2, c);
+
+ if (c.gcd(z.subtract(ONE)).equals(ONE) && z.modPow(c0, c).equals(ONE))
+ {
+ return new STOutput(c, primeSeed, primeGenCounter);
+ }
+ }
+ else
+ {
+ inc(primeSeed, iterations + 1);
+ }
+
+ if (primeGenCounter >= ((4 * length) + oldCounter))
+ {
+ throw new IllegalStateException("Too many iterations in Shawe-Taylor Random_Prime Routine");
+ }
+
+ dt += 2;
+ c = c.add(c0x2);
+ }
+ }
+
+ private static int extract32(byte[] bs)
+ {
+ int result = 0;
+
+ int count = Math.min(4, bs.length);
+ for (int i = 0; i < count; ++i)
+ {
+ int b = bs[bs.length - (i + 1)] & 0xFF;
+ result |= (b << (8 * i));
+ }
+
+ return result;
+ }
+
+ private static void hash(Digest d, byte[] input, byte[] output, int outPos)
+ {
+ d.update(input, 0, input.length);
+ d.doFinal(output, outPos);
+ }
+
+ private static BigInteger hashGen(Digest d, byte[] seed, int count)
+ {
+ int dLen = d.getDigestSize();
+ int pos = count * dLen;
+ byte[] buf = new byte[pos];
+ for (int i = 0; i < count; ++i)
+ {
+ pos -= dLen;
+ hash(d, seed, buf, pos);
+ inc(seed, 1);
+ }
+ return new BigInteger(1, buf);
+ }
+
+ private static void inc(byte[] seed, int c)
+ {
+ int pos = seed.length;
+ while (c > 0 && --pos >= 0)
+ {
+ c += (seed[pos] & 0xFF);
+ seed[pos] = (byte)c;
+ c >>>= 8;
+ }
+ }
+
+ private static boolean isPrime32(long x)
+ {
+ if (x >>> 32 != 0L)
+ {
+ throw new IllegalArgumentException("Size limit exceeded");
+ }
+
+ /*
+ * Use wheel factorization with 2, 3, 5 to select trial divisors.
+ */
+
+ if (x <= 5L)
+ {
+ return x == 2L || x == 3L || x == 5L;
+ }
+
+ if ((x & 1L) == 0L || (x % 3L) == 0L || (x % 5L) == 0L)
+ {
+ return false;
+ }
+
+ long[] ds = new long[]{ 1L, 7L, 11L, 13L, 17L, 19L, 23L, 29L };
+ long base = 0L;
+ for (int pos = 1;; pos = 0)
+ {
+ /*
+ * Trial division by wheel-selected divisors
+ */
+ while (pos < ds.length)
+ {
+ long d = base + ds[pos];
+ if (x % d == 0L)
+ {
+ return x < 30L;
+ }
+ ++pos;
+ }
+
+ base += 30L;
+
+ if (base * base >= x)
+ {
+ return true;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/AbstractECLookupTable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/AbstractECLookupTable.java
new file mode 100644
index 00000000..bba84f98
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/AbstractECLookupTable.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class AbstractECLookupTable
+ implements ECLookupTable
+{
+ public ECPoint lookupVar(int index)
+ {
+ return lookup(index);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/AbstractECMultiplier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/AbstractECMultiplier.java
new file mode 100644
index 00000000..3fbd92c8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/AbstractECMultiplier.java
@@ -0,0 +1,35 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class AbstractECMultiplier implements ECMultiplier
+{
+ public ECPoint multiply(ECPoint p, BigInteger k)
+ {
+ int sign = k.signum();
+ if (sign == 0 || p.isInfinity())
+ {
+ return p.getCurve().getInfinity();
+ }
+
+ ECPoint positive = multiplyPositive(p, k.abs());
+ ECPoint result = sign > 0 ? positive : positive.negate();
+
+ /*
+ * Although the various multipliers ought not to produce invalid output under normal
+ * circumstances, a final check here is advised to guard against fault attacks.
+ */
+ return checkResult(result);
+ }
+
+ protected abstract ECPoint multiplyPositive(ECPoint p, BigInteger k);
+
+ protected ECPoint checkResult(ECPoint p)
+ {
+ return ECAlgorithms.implCheckResult(p);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECAlgorithms.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECAlgorithms.java
new file mode 100644
index 00000000..c5bb0dd6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECAlgorithms.java
@@ -0,0 +1,620 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.endo.ECEndomorphism;
+import com.android.internal.org.bouncycastle.math.ec.endo.EndoUtil;
+import com.android.internal.org.bouncycastle.math.ec.endo.GLVEndomorphism;
+import com.android.internal.org.bouncycastle.math.field.FiniteField;
+import com.android.internal.org.bouncycastle.math.field.PolynomialExtensionField;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ECAlgorithms
+{
+ public static boolean isF2mCurve(ECCurve c)
+ {
+ return isF2mField(c.getField());
+ }
+
+ public static boolean isF2mField(FiniteField field)
+ {
+ return field.getDimension() > 1 && field.getCharacteristic().equals(ECConstants.TWO)
+ && field instanceof PolynomialExtensionField;
+ }
+
+ public static boolean isFpCurve(ECCurve c)
+ {
+ return isFpField(c.getField());
+ }
+
+ public static boolean isFpField(FiniteField field)
+ {
+ return field.getDimension() == 1;
+ }
+
+ public static ECPoint sumOfMultiplies(ECPoint[] ps, BigInteger[] ks)
+ {
+ if (ps == null || ks == null || ps.length != ks.length || ps.length < 1)
+ {
+ throw new IllegalArgumentException("point and scalar arrays should be non-null, and of equal, non-zero, length");
+ }
+
+ int count = ps.length;
+ switch (count)
+ {
+ case 1:
+ return ps[0].multiply(ks[0]);
+ case 2:
+ return sumOfTwoMultiplies(ps[0], ks[0], ps[1], ks[1]);
+ default:
+ break;
+ }
+
+ ECPoint p = ps[0];
+ ECCurve c = p.getCurve();
+
+ ECPoint[] imported = new ECPoint[count];
+ imported[0] = p;
+ for (int i = 1; i < count; ++i)
+ {
+ imported[i] = importPoint(c, ps[i]);
+ }
+
+ ECEndomorphism endomorphism = c.getEndomorphism();
+ if (endomorphism instanceof GLVEndomorphism)
+ {
+ return implCheckResult(implSumOfMultipliesGLV(imported, ks, (GLVEndomorphism)endomorphism));
+ }
+
+ return implCheckResult(implSumOfMultiplies(imported, ks));
+ }
+
+ public static ECPoint sumOfTwoMultiplies(ECPoint P, BigInteger a,
+ ECPoint Q, BigInteger b)
+ {
+ ECCurve cp = P.getCurve();
+ Q = importPoint(cp, Q);
+
+ // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick
+ if (cp instanceof ECCurve.AbstractF2m)
+ {
+ ECCurve.AbstractF2m f2mCurve = (ECCurve.AbstractF2m)cp;
+ if (f2mCurve.isKoblitz())
+ {
+ return implCheckResult(P.multiply(a).add(Q.multiply(b)));
+ }
+ }
+
+ ECEndomorphism endomorphism = cp.getEndomorphism();
+ if (endomorphism instanceof GLVEndomorphism)
+ {
+ return implCheckResult(
+ implSumOfMultipliesGLV(new ECPoint[]{ P, Q }, new BigInteger[]{ a, b }, (GLVEndomorphism)endomorphism));
+ }
+
+ return implCheckResult(implShamirsTrickWNaf(P, a, Q, b));
+ }
+
+ /*
+ * "Shamir's Trick", originally due to E. G. Straus
+ * (Addition chains of vectors. American Mathematical Monthly,
+ * 71(7):806-808, Aug./Sept. 1964)
+ * <pre>
+ * Input: The points P, Q, scalar k = (km?, ... , k1, k0)
+ * and scalar l = (lm?, ... , l1, l0).
+ * Output: R = k * P + l * Q.
+ * 1: Z <- P + Q
+ * 2: R <- O
+ * 3: for i from m-1 down to 0 do
+ * 4: R <- R + R {point doubling}
+ * 5: if (ki = 1) and (li = 0) then R <- R + P end if
+ * 6: if (ki = 0) and (li = 1) then R <- R + Q end if
+ * 7: if (ki = 1) and (li = 1) then R <- R + Z end if
+ * 8: end for
+ * 9: return R
+ * </pre>
+ */
+ public static ECPoint shamirsTrick(ECPoint P, BigInteger k,
+ ECPoint Q, BigInteger l)
+ {
+ ECCurve cp = P.getCurve();
+ Q = importPoint(cp, Q);
+
+ return implCheckResult(implShamirsTrickJsf(P, k, Q, l));
+ }
+
+ public static ECPoint importPoint(ECCurve c, ECPoint p)
+ {
+ ECCurve cp = p.getCurve();
+ if (!c.equals(cp))
+ {
+ throw new IllegalArgumentException("Point must be on the same curve");
+ }
+ return c.importPoint(p);
+ }
+
+ public static void montgomeryTrick(ECFieldElement[] zs, int off, int len)
+ {
+ montgomeryTrick(zs, off, len, null);
+ }
+
+ public static void montgomeryTrick(ECFieldElement[] zs, int off, int len, ECFieldElement scale)
+ {
+ /*
+ * Uses the "Montgomery Trick" to invert many field elements, with only a single actual
+ * field inversion. See e.g. the paper:
+ * "Fast Multi-scalar Multiplication Methods on Elliptic Curves with Precomputation Strategy Using Montgomery Trick"
+ * by Katsuyuki Okeya, Kouichi Sakurai.
+ */
+
+ ECFieldElement[] c = new ECFieldElement[len];
+ c[0] = zs[off];
+
+ int i = 0;
+ while (++i < len)
+ {
+ c[i] = c[i - 1].multiply(zs[off + i]);
+ }
+
+ --i;
+
+ if (scale != null)
+ {
+ c[i] = c[i].multiply(scale);
+ }
+
+ ECFieldElement u = c[i].invert();
+
+ while (i > 0)
+ {
+ int j = off + i--;
+ ECFieldElement tmp = zs[j];
+ zs[j] = c[i].multiply(u);
+ u = u.multiply(tmp);
+ }
+
+ zs[off] = u;
+ }
+
+ /**
+ * Simple shift-and-add multiplication. Serves as reference implementation to verify (possibly
+ * faster) implementations, and for very small scalars. CAUTION: This implementation is NOT
+ * constant-time in any way. It is only intended to be used for diagnostics.
+ *
+ * @param p
+ * The point to multiply.
+ * @param k
+ * The multiplier.
+ * @return The result of the point multiplication <code>kP</code>.
+ */
+ public static ECPoint referenceMultiply(ECPoint p, BigInteger k)
+ {
+ BigInteger x = k.abs();
+ ECPoint q = p.getCurve().getInfinity();
+ int t = x.bitLength();
+ if (t > 0)
+ {
+ if (x.testBit(0))
+ {
+ q = p;
+ }
+ for (int i = 1; i < t; i++)
+ {
+ p = p.twice();
+ if (x.testBit(i))
+ {
+ q = q.add(p);
+ }
+ }
+ }
+ return k.signum() < 0 ? q.negate() : q;
+ }
+
+ public static ECPoint validatePoint(ECPoint p)
+ {
+ if (!p.isValid())
+ {
+ throw new IllegalStateException("Invalid point");
+ }
+
+ return p;
+ }
+
+ public static ECPoint cleanPoint(ECCurve c, ECPoint p)
+ {
+ ECCurve cp = p.getCurve();
+ if (!c.equals(cp))
+ {
+ throw new IllegalArgumentException("Point must be on the same curve");
+ }
+
+ return c.decodePoint(p.getEncoded(false));
+ }
+
+ static ECPoint implCheckResult(ECPoint p)
+ {
+ if (!p.isValidPartial())
+ {
+ throw new IllegalStateException("Invalid result");
+ }
+
+ return p;
+ }
+
+ static ECPoint implShamirsTrickJsf(ECPoint P, BigInteger k,
+ ECPoint Q, BigInteger l)
+ {
+ ECCurve curve = P.getCurve();
+ ECPoint infinity = curve.getInfinity();
+
+ // TODO conjugate co-Z addition (ZADDC) can return both of these
+ ECPoint PaddQ = P.add(Q);
+ ECPoint PsubQ = P.subtract(Q);
+
+ ECPoint[] points = new ECPoint[]{ Q, PsubQ, P, PaddQ };
+ curve.normalizeAll(points);
+
+ ECPoint[] table = new ECPoint[] {
+ points[3].negate(), points[2].negate(), points[1].negate(),
+ points[0].negate(), infinity, points[0],
+ points[1], points[2], points[3] };
+
+ byte[] jsf = WNafUtil.generateJSF(k, l);
+
+ ECPoint R = infinity;
+
+ int i = jsf.length;
+ while (--i >= 0)
+ {
+ int jsfi = jsf[i];
+
+ // NOTE: The shifting ensures the sign is extended correctly
+ int kDigit = ((jsfi << 24) >> 28), lDigit = ((jsfi << 28) >> 28);
+
+ int index = 4 + (kDigit * 3) + lDigit;
+ R = R.twicePlus(table[index]);
+ }
+
+ return R;
+ }
+
+ static ECPoint implShamirsTrickWNaf(ECPoint P, BigInteger k,
+ ECPoint Q, BigInteger l)
+ {
+ boolean negK = k.signum() < 0, negL = l.signum() < 0;
+
+ BigInteger kAbs = k.abs(), lAbs = l.abs();
+
+ int minWidthP = WNafUtil.getWindowSize(kAbs.bitLength(), 8);
+ int minWidthQ = WNafUtil.getWindowSize(lAbs.bitLength(), 8);
+
+ WNafPreCompInfo infoP = WNafUtil.precompute(P, minWidthP, true);
+ WNafPreCompInfo infoQ = WNafUtil.precompute(Q, minWidthQ, true);
+
+ // When P, Q are 'promoted' (i.e. reused several times), switch to fixed-point algorithm
+ {
+ ECCurve c = P.getCurve();
+ int combSize = FixedPointUtil.getCombSize(c);
+ if (!negK && !negL
+ && k.bitLength() <= combSize && l.bitLength() <= combSize
+ && infoP.isPromoted() && infoQ.isPromoted())
+ {
+ return implShamirsTrickFixedPoint(P, k, Q, l);
+ }
+ }
+
+ int widthP = Math.min(8, infoP.getWidth());
+ int widthQ = Math.min(8, infoQ.getWidth());
+
+ ECPoint[] preCompP = negK ? infoP.getPreCompNeg() : infoP.getPreComp();
+ ECPoint[] preCompQ = negL ? infoQ.getPreCompNeg() : infoQ.getPreComp();
+ ECPoint[] preCompNegP = negK ? infoP.getPreComp() : infoP.getPreCompNeg();
+ ECPoint[] preCompNegQ = negL ? infoQ.getPreComp() : infoQ.getPreCompNeg();
+
+ byte[] wnafP = WNafUtil.generateWindowNaf(widthP, kAbs);
+ byte[] wnafQ = WNafUtil.generateWindowNaf(widthQ, lAbs);
+
+ return implShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ);
+ }
+
+ static ECPoint implShamirsTrickWNaf(ECEndomorphism endomorphism, ECPoint P, BigInteger k, BigInteger l)
+ {
+ boolean negK = k.signum() < 0, negL = l.signum() < 0;
+
+ k = k.abs();
+ l = l.abs();
+
+ int minWidth = WNafUtil.getWindowSize(Math.max(k.bitLength(), l.bitLength()), 8);
+
+ WNafPreCompInfo infoP = WNafUtil.precompute(P, minWidth, true);
+ ECPoint Q = EndoUtil.mapPoint(endomorphism, P);
+ WNafPreCompInfo infoQ = WNafUtil.precomputeWithPointMap(Q, endomorphism.getPointMap(), infoP, true);
+
+ int widthP = Math.min(8, infoP.getWidth());
+ int widthQ = Math.min(8, infoQ.getWidth());
+
+ ECPoint[] preCompP = negK ? infoP.getPreCompNeg() : infoP.getPreComp();
+ ECPoint[] preCompQ = negL ? infoQ.getPreCompNeg() : infoQ.getPreComp();
+ ECPoint[] preCompNegP = negK ? infoP.getPreComp() : infoP.getPreCompNeg();
+ ECPoint[] preCompNegQ = negL ? infoQ.getPreComp() : infoQ.getPreCompNeg();
+
+ byte[] wnafP = WNafUtil.generateWindowNaf(widthP, k);
+ byte[] wnafQ = WNafUtil.generateWindowNaf(widthQ, l);
+
+ return implShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ);
+ }
+
+ private static ECPoint implShamirsTrickWNaf(ECPoint[] preCompP, ECPoint[] preCompNegP, byte[] wnafP,
+ ECPoint[] preCompQ, ECPoint[] preCompNegQ, byte[] wnafQ)
+ {
+ int len = Math.max(wnafP.length, wnafQ.length);
+
+ ECCurve curve = preCompP[0].getCurve();
+ ECPoint infinity = curve.getInfinity();
+
+ ECPoint R = infinity;
+ int zeroes = 0;
+
+ for (int i = len - 1; i >= 0; --i)
+ {
+ int wiP = i < wnafP.length ? wnafP[i] : 0;
+ int wiQ = i < wnafQ.length ? wnafQ[i] : 0;
+
+ if ((wiP | wiQ) == 0)
+ {
+ ++zeroes;
+ continue;
+ }
+
+ ECPoint r = infinity;
+ if (wiP != 0)
+ {
+ int nP = Math.abs(wiP);
+ ECPoint[] tableP = wiP < 0 ? preCompNegP : preCompP;
+ r = r.add(tableP[nP >>> 1]);
+ }
+ if (wiQ != 0)
+ {
+ int nQ = Math.abs(wiQ);
+ ECPoint[] tableQ = wiQ < 0 ? preCompNegQ : preCompQ;
+ r = r.add(tableQ[nQ >>> 1]);
+ }
+
+ if (zeroes > 0)
+ {
+ R = R.timesPow2(zeroes);
+ zeroes = 0;
+ }
+
+ R = R.twicePlus(r);
+ }
+
+ if (zeroes > 0)
+ {
+ R = R.timesPow2(zeroes);
+ }
+
+ return R;
+ }
+
+ static ECPoint implSumOfMultiplies(ECPoint[] ps, BigInteger[] ks)
+ {
+ int count = ps.length;
+ boolean[] negs = new boolean[count];
+ WNafPreCompInfo[] infos = new WNafPreCompInfo[count];
+ byte[][] wnafs = new byte[count][];
+
+ for (int i = 0; i < count; ++i)
+ {
+ BigInteger ki = ks[i]; negs[i] = ki.signum() < 0; ki = ki.abs();
+
+ int minWidth = WNafUtil.getWindowSize(ki.bitLength(), 8);
+ WNafPreCompInfo info = WNafUtil.precompute(ps[i], minWidth, true);
+
+ int width = Math.min(8, info.getWidth());
+
+ infos[i] = info;
+ wnafs[i] = WNafUtil.generateWindowNaf(width, ki);
+ }
+
+ return implSumOfMultiplies(negs, infos, wnafs);
+ }
+
+ static ECPoint implSumOfMultipliesGLV(ECPoint[] ps, BigInteger[] ks, GLVEndomorphism glvEndomorphism)
+ {
+ BigInteger n = ps[0].getCurve().getOrder();
+
+ int len = ps.length;
+
+ BigInteger[] abs = new BigInteger[len << 1];
+ for (int i = 0, j = 0; i < len; ++i)
+ {
+ BigInteger[] ab = glvEndomorphism.decomposeScalar(ks[i].mod(n));
+ abs[j++] = ab[0];
+ abs[j++] = ab[1];
+ }
+
+ if (glvEndomorphism.hasEfficientPointMap())
+ {
+ return implSumOfMultiplies(glvEndomorphism, ps, abs);
+ }
+
+ ECPoint[] pqs = new ECPoint[len << 1];
+ for (int i = 0, j = 0; i < len; ++i)
+ {
+ ECPoint p = ps[i];
+ ECPoint q = EndoUtil.mapPoint(glvEndomorphism, p);
+ pqs[j++] = p;
+ pqs[j++] = q;
+ }
+
+ return implSumOfMultiplies(pqs, abs);
+ }
+
+ static ECPoint implSumOfMultiplies(ECEndomorphism endomorphism, ECPoint[] ps, BigInteger[] ks)
+ {
+ int halfCount = ps.length, fullCount = halfCount << 1;
+
+ boolean[] negs = new boolean[fullCount];
+ WNafPreCompInfo[] infos = new WNafPreCompInfo[fullCount];
+ byte[][] wnafs = new byte[fullCount][];
+
+ ECPointMap pointMap = endomorphism.getPointMap();
+
+ for (int i = 0; i < halfCount; ++i)
+ {
+ int j0 = i << 1, j1 = j0 + 1;
+
+ BigInteger kj0 = ks[j0]; negs[j0] = kj0.signum() < 0; kj0 = kj0.abs();
+ BigInteger kj1 = ks[j1]; negs[j1] = kj1.signum() < 0; kj1 = kj1.abs();
+
+ int minWidth = WNafUtil.getWindowSize(Math.max(kj0.bitLength(), kj1.bitLength()), 8);
+
+ ECPoint P = ps[i];
+ WNafPreCompInfo infoP = WNafUtil.precompute(P, minWidth, true);
+ ECPoint Q = EndoUtil.mapPoint(endomorphism, P);
+ WNafPreCompInfo infoQ = WNafUtil.precomputeWithPointMap(Q, pointMap, infoP, true);
+
+ int widthP = Math.min(8, infoP.getWidth());
+ int widthQ = Math.min(8, infoQ.getWidth());
+
+ infos[j0] = infoP;
+ infos[j1] = infoQ;
+ wnafs[j0] = WNafUtil.generateWindowNaf(widthP, kj0);
+ wnafs[j1] = WNafUtil.generateWindowNaf(widthQ, kj1);
+ }
+
+ return implSumOfMultiplies(negs, infos, wnafs);
+ }
+
+ private static ECPoint implSumOfMultiplies(boolean[] negs, WNafPreCompInfo[] infos, byte[][] wnafs)
+ {
+ int len = 0, count = wnafs.length;
+ for (int i = 0; i < count; ++i)
+ {
+ len = Math.max(len, wnafs[i].length);
+ }
+
+ ECCurve curve = infos[0].getPreComp()[0].getCurve();
+ ECPoint infinity = curve.getInfinity();
+
+ ECPoint R = infinity;
+ int zeroes = 0;
+
+ for (int i = len - 1; i >= 0; --i)
+ {
+ ECPoint r = infinity;
+
+ for (int j = 0; j < count; ++j)
+ {
+ byte[] wnaf = wnafs[j];
+ int wi = i < wnaf.length ? wnaf[i] : 0;
+ if (wi != 0)
+ {
+ int n = Math.abs(wi);
+ WNafPreCompInfo info = infos[j];
+ ECPoint[] table = (wi < 0 == negs[j]) ? info.getPreComp() : info.getPreCompNeg();
+ r = r.add(table[n >>> 1]);
+ }
+ }
+
+ if (r == infinity)
+ {
+ ++zeroes;
+ continue;
+ }
+
+ if (zeroes > 0)
+ {
+ R = R.timesPow2(zeroes);
+ zeroes = 0;
+ }
+
+ R = R.twicePlus(r);
+ }
+
+ if (zeroes > 0)
+ {
+ R = R.timesPow2(zeroes);
+ }
+
+ return R;
+ }
+
+ private static ECPoint implShamirsTrickFixedPoint(ECPoint p, BigInteger k, ECPoint q, BigInteger l)
+ {
+ ECCurve c = p.getCurve();
+ int combSize = FixedPointUtil.getCombSize(c);
+
+ if (k.bitLength() > combSize || l.bitLength() > combSize)
+ {
+ /*
+ * TODO The comb works best when the scalars are less than the (possibly unknown) order.
+ * Still, if we want to handle larger scalars, we could allow customization of the comb
+ * size, or alternatively we could deal with the 'extra' bits either by running the comb
+ * multiple times as necessary, or by using an alternative multiplier as prelude.
+ */
+ throw new IllegalStateException("fixed-point comb doesn't support scalars larger than the curve order");
+ }
+
+ FixedPointPreCompInfo infoP = FixedPointUtil.precompute(p);
+ FixedPointPreCompInfo infoQ = FixedPointUtil.precompute(q);
+
+ ECLookupTable lookupTableP = infoP.getLookupTable();
+ ECLookupTable lookupTableQ = infoQ.getLookupTable();
+
+ int widthP = infoP.getWidth();
+ int widthQ = infoQ.getWidth();
+
+ // TODO This shouldn't normally happen, but a better "solution" is desirable anyway
+ if (widthP != widthQ)
+ {
+ FixedPointCombMultiplier m = new FixedPointCombMultiplier();
+ ECPoint r1 = m.multiply(p, k);
+ ECPoint r2 = m.multiply(q, l);
+ return r1.add(r2);
+ }
+
+ int width = widthP;
+
+ int d = (combSize + width - 1) / width;
+
+ ECPoint R = c.getInfinity();
+
+ int fullComb = d * width;
+ int[] K = Nat.fromBigInteger(fullComb, k);
+ int[] L = Nat.fromBigInteger(fullComb, l);
+
+ int top = fullComb - 1;
+ for (int i = 0; i < d; ++i)
+ {
+ int secretIndexK = 0, secretIndexL = 0;
+
+ for (int j = top - i; j >= 0; j -= d)
+ {
+ int secretBitK = K[j >>> 5] >>> (j & 0x1F);
+ secretIndexK ^= secretBitK >>> 1;
+ secretIndexK <<= 1;
+ secretIndexK ^= secretBitK;
+
+ int secretBitL = L[j >>> 5] >>> (j & 0x1F);
+ secretIndexL ^= secretBitL >>> 1;
+ secretIndexL <<= 1;
+ secretIndexL ^= secretBitL;
+ }
+
+ ECPoint addP = lookupTableP.lookupVar(secretIndexK);
+ ECPoint addQ = lookupTableQ.lookupVar(secretIndexL);
+
+ ECPoint T = addP.add(addQ);
+
+ R = R.twicePlus(T);
+ }
+
+ return R.add(infoP.getOffset()).add(infoQ.getOffset());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECConstants.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECConstants.java
new file mode 100644
index 00000000..cd401574
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECConstants.java
@@ -0,0 +1,17 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ECConstants
+{
+ public static final BigInteger ZERO = BigInteger.valueOf(0);
+ public static final BigInteger ONE = BigInteger.valueOf(1);
+ public static final BigInteger TWO = BigInteger.valueOf(2);
+ public static final BigInteger THREE = BigInteger.valueOf(3);
+ public static final BigInteger FOUR = BigInteger.valueOf(4);
+ public static final BigInteger EIGHT = BigInteger.valueOf(8);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECCurve.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECCurve.java
new file mode 100644
index 00000000..d936d107
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECCurve.java
@@ -0,0 +1,1406 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+import java.util.Hashtable;
+import java.util.Random;
+
+import com.android.internal.org.bouncycastle.math.ec.endo.ECEndomorphism;
+import com.android.internal.org.bouncycastle.math.ec.endo.GLVEndomorphism;
+import com.android.internal.org.bouncycastle.math.field.FiniteField;
+import com.android.internal.org.bouncycastle.math.field.FiniteFields;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+import com.android.internal.org.bouncycastle.util.Integers;
+
+/**
+ * base class for an elliptic curve
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ECCurve
+{
+ public static final int COORD_AFFINE = 0;
+ public static final int COORD_HOMOGENEOUS = 1;
+ public static final int COORD_JACOBIAN = 2;
+ public static final int COORD_JACOBIAN_CHUDNOVSKY = 3;
+ public static final int COORD_JACOBIAN_MODIFIED = 4;
+ public static final int COORD_LAMBDA_AFFINE = 5;
+ public static final int COORD_LAMBDA_PROJECTIVE = 6;
+ public static final int COORD_SKEWED = 7;
+
+ public static int[] getAllCoordinateSystems()
+ {
+ return new int[]{ COORD_AFFINE, COORD_HOMOGENEOUS, COORD_JACOBIAN, COORD_JACOBIAN_CHUDNOVSKY,
+ COORD_JACOBIAN_MODIFIED, COORD_LAMBDA_AFFINE, COORD_LAMBDA_PROJECTIVE, COORD_SKEWED };
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public class Config
+ {
+ protected int coord;
+ protected ECEndomorphism endomorphism;
+ protected ECMultiplier multiplier;
+
+ Config(int coord, ECEndomorphism endomorphism, ECMultiplier multiplier)
+ {
+ this.coord = coord;
+ this.endomorphism = endomorphism;
+ this.multiplier = multiplier;
+ }
+
+ public Config setCoordinateSystem(int coord)
+ {
+ this.coord = coord;
+ return this;
+ }
+
+ public Config setEndomorphism(ECEndomorphism endomorphism)
+ {
+ this.endomorphism = endomorphism;
+ return this;
+ }
+
+ public Config setMultiplier(ECMultiplier multiplier)
+ {
+ this.multiplier = multiplier;
+ return this;
+ }
+
+ public ECCurve create()
+ {
+ if (!supportsCoordinateSystem(coord))
+ {
+ throw new IllegalStateException("unsupported coordinate system");
+ }
+
+ ECCurve c = cloneCurve();
+ if (c == ECCurve.this)
+ {
+ throw new IllegalStateException("implementation returned current curve");
+ }
+
+ // NOTE: Synchronization added to keep FindBugsâ„¢ happy
+ synchronized (c)
+ {
+ c.coord = coord;
+ c.endomorphism = endomorphism;
+ c.multiplier = multiplier;
+ }
+
+ return c;
+ }
+ }
+
+ protected FiniteField field;
+ protected ECFieldElement a, b;
+ protected BigInteger order, cofactor;
+
+ protected int coord = COORD_AFFINE;
+ protected ECEndomorphism endomorphism = null;
+ protected ECMultiplier multiplier = null;
+
+ protected ECCurve(FiniteField field)
+ {
+ this.field = field;
+ }
+
+ public abstract int getFieldSize();
+
+ public abstract ECFieldElement fromBigInteger(BigInteger x);
+
+ public abstract boolean isValidFieldElement(BigInteger x);
+
+ public abstract ECFieldElement randomFieldElement(SecureRandom r);
+
+ public abstract ECFieldElement randomFieldElementMult(SecureRandom r);
+
+ public synchronized Config configure()
+ {
+ return new Config(this.coord, this.endomorphism, this.multiplier);
+ }
+
+ public ECPoint validatePoint(BigInteger x, BigInteger y)
+ {
+ ECPoint p = createPoint(x, y);
+ if (!p.isValid())
+ {
+ throw new IllegalArgumentException("Invalid point coordinates");
+ }
+ return p;
+ }
+
+ public ECPoint createPoint(BigInteger x, BigInteger y)
+ {
+ return createRawPoint(fromBigInteger(x), fromBigInteger(y));
+ }
+
+ protected abstract ECCurve cloneCurve();
+
+ protected abstract ECPoint createRawPoint(ECFieldElement x, ECFieldElement y);
+
+ protected abstract ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs);
+
+ protected ECMultiplier createDefaultMultiplier()
+ {
+ if (endomorphism instanceof GLVEndomorphism)
+ {
+ return new GLVMultiplier(this, (GLVEndomorphism)endomorphism);
+ }
+
+ return new WNafL2RMultiplier();
+ }
+
+ public boolean supportsCoordinateSystem(int coord)
+ {
+ return coord == COORD_AFFINE;
+ }
+
+ public PreCompInfo getPreCompInfo(ECPoint point, String name)
+ {
+ checkPoint(point);
+
+ Hashtable table;
+ synchronized (point)
+ {
+ table = point.preCompTable;
+ }
+
+ if (null == table)
+ {
+ return null;
+ }
+
+ synchronized (table)
+ {
+ return (PreCompInfo)table.get(name);
+ }
+ }
+
+ /**
+ * Compute a <code>PreCompInfo</code> for a point on this curve, under a given name. Used by
+ * <code>ECMultiplier</code>s to save the precomputation for this <code>ECPoint</code> for use
+ * by subsequent multiplication.
+ *
+ * @param point
+ * The <code>ECPoint</code> to store precomputations for.
+ * @param name
+ * A <code>String</code> used to index precomputations of different types.
+ * @param callback
+ * Called to calculate the <code>PreCompInfo</code>.
+ */
+ public PreCompInfo precompute(ECPoint point, String name, PreCompCallback callback)
+ {
+ checkPoint(point);
+
+ Hashtable table;
+ synchronized (point)
+ {
+ table = point.preCompTable;
+ if (null == table)
+ {
+ point.preCompTable = table = new Hashtable(4);
+ }
+ }
+
+ synchronized (table)
+ {
+ PreCompInfo existing = (PreCompInfo)table.get(name);
+ PreCompInfo result = callback.precompute(existing);
+
+ if (result != existing)
+ {
+ table.put(name, result);
+ }
+
+ return result;
+ }
+ }
+
+ public ECPoint importPoint(ECPoint p)
+ {
+ if (this == p.getCurve())
+ {
+ return p;
+ }
+ if (p.isInfinity())
+ {
+ return getInfinity();
+ }
+
+ // TODO Default behaviour could be improved if the two curves have the same coordinate system by copying any Z coordinates.
+ p = p.normalize();
+
+ return createPoint(p.getXCoord().toBigInteger(), p.getYCoord().toBigInteger());
+ }
+
+ /**
+ * Normalization ensures that any projective coordinate is 1, and therefore that the x, y
+ * coordinates reflect those of the equivalent point in an affine coordinate system. Where more
+ * than one point is to be normalized, this method will generally be more efficient than
+ * normalizing each point separately.
+ *
+ * @param points
+ * An array of points that will be updated in place with their normalized versions,
+ * where necessary
+ */
+ public void normalizeAll(ECPoint[] points)
+ {
+ normalizeAll(points, 0, points.length, null);
+ }
+
+ /**
+ * Normalization ensures that any projective coordinate is 1, and therefore that the x, y
+ * coordinates reflect those of the equivalent point in an affine coordinate system. Where more
+ * than one point is to be normalized, this method will generally be more efficient than
+ * normalizing each point separately. An (optional) z-scaling factor can be applied; effectively
+ * each z coordinate is scaled by this value prior to normalization (but only one
+ * actual multiplication is needed).
+ *
+ * @param points
+ * An array of points that will be updated in place with their normalized versions,
+ * where necessary
+ * @param off
+ * The start of the range of points to normalize
+ * @param len
+ * The length of the range of points to normalize
+ * @param iso
+ * The (optional) z-scaling factor - can be null
+ */
+ public void normalizeAll(ECPoint[] points, int off, int len, ECFieldElement iso)
+ {
+ checkPoints(points, off, len);
+
+ switch (this.getCoordinateSystem())
+ {
+ case ECCurve.COORD_AFFINE:
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ {
+ if (iso != null)
+ {
+ throw new IllegalArgumentException("'iso' not valid for affine coordinates");
+ }
+ return;
+ }
+ }
+
+ /*
+ * Figure out which of the points actually need to be normalized
+ */
+ ECFieldElement[] zs = new ECFieldElement[len];
+ int[] indices = new int[len];
+ int count = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ ECPoint p = points[off + i];
+ if (null != p && (iso != null || !p.isNormalized()))
+ {
+ zs[count] = p.getZCoord(0);
+ indices[count++] = off + i;
+ }
+ }
+
+ if (count == 0)
+ {
+ return;
+ }
+
+ ECAlgorithms.montgomeryTrick(zs, 0, count, iso);
+
+ for (int j = 0; j < count; ++j)
+ {
+ int index = indices[j];
+ points[index] = points[index].normalize(zs[j]);
+ }
+ }
+
+ public abstract ECPoint getInfinity();
+
+ public FiniteField getField()
+ {
+ return field;
+ }
+
+ public ECFieldElement getA()
+ {
+ return a;
+ }
+
+ public ECFieldElement getB()
+ {
+ return b;
+ }
+
+ public BigInteger getOrder()
+ {
+ return order;
+ }
+
+ public BigInteger getCofactor()
+ {
+ return cofactor;
+ }
+
+ public int getCoordinateSystem()
+ {
+ return coord;
+ }
+
+ protected abstract ECPoint decompressPoint(int yTilde, BigInteger X1);
+
+ public ECEndomorphism getEndomorphism()
+ {
+ return endomorphism;
+ }
+
+ /**
+ * Sets the default <code>ECMultiplier</code>, unless already set.
+ *
+ * We avoid synchronizing for performance reasons, so there is no uniqueness guarantee.
+ */
+ public ECMultiplier getMultiplier()
+ {
+ if (this.multiplier == null)
+ {
+ this.multiplier = createDefaultMultiplier();
+ }
+ return this.multiplier;
+ }
+
+ /**
+ * Decode a point on this curve from its ASN.1 encoding. The different
+ * encodings are taken account of, including point compression for
+ * <code>F<sub>p</sub></code> (X9.62 s 4.2.1 pg 17).
+ * @return The decoded point.
+ */
+ public ECPoint decodePoint(byte[] encoded)
+ {
+ ECPoint p = null;
+ int expectedLength = (getFieldSize() + 7) / 8;
+
+ byte type = encoded[0];
+ switch (type)
+ {
+ case 0x00: // infinity
+ {
+ if (encoded.length != 1)
+ {
+ throw new IllegalArgumentException("Incorrect length for infinity encoding");
+ }
+
+ p = getInfinity();
+ break;
+ }
+ case 0x02: // compressed
+ case 0x03: // compressed
+ {
+ if (encoded.length != (expectedLength + 1))
+ {
+ throw new IllegalArgumentException("Incorrect length for compressed encoding");
+ }
+
+ int yTilde = type & 1;
+ BigInteger X = BigIntegers.fromUnsignedByteArray(encoded, 1, expectedLength);
+
+ p = decompressPoint(yTilde, X);
+ if (!p.implIsValid(true, true))
+ {
+ throw new IllegalArgumentException("Invalid point");
+ }
+
+ break;
+ }
+ case 0x04: // uncompressed
+ {
+ if (encoded.length != (2 * expectedLength + 1))
+ {
+ throw new IllegalArgumentException("Incorrect length for uncompressed encoding");
+ }
+
+ BigInteger X = BigIntegers.fromUnsignedByteArray(encoded, 1, expectedLength);
+ BigInteger Y = BigIntegers.fromUnsignedByteArray(encoded, 1 + expectedLength, expectedLength);
+
+ p = validatePoint(X, Y);
+ break;
+ }
+ case 0x06: // hybrid
+ case 0x07: // hybrid
+ {
+ if (encoded.length != (2 * expectedLength + 1))
+ {
+ throw new IllegalArgumentException("Incorrect length for hybrid encoding");
+ }
+
+ BigInteger X = BigIntegers.fromUnsignedByteArray(encoded, 1, expectedLength);
+ BigInteger Y = BigIntegers.fromUnsignedByteArray(encoded, 1 + expectedLength, expectedLength);
+
+ if (Y.testBit(0) != (type == 0x07))
+ {
+ throw new IllegalArgumentException("Inconsistent Y coordinate in hybrid encoding");
+ }
+
+ p = validatePoint(X, Y);
+ break;
+ }
+ default:
+ throw new IllegalArgumentException("Invalid point encoding 0x" + Integer.toString(type, 16));
+ }
+
+ if (type != 0x00 && p.isInfinity())
+ {
+ throw new IllegalArgumentException("Invalid infinity encoding");
+ }
+
+ return p;
+ }
+
+ /**
+ * Create a cache-safe lookup table for the specified sequence of points. All the points MUST
+ * belong to this {@link ECCurve} instance, and MUST already be normalized.
+ */
+ public ECLookupTable createCacheSafeLookupTable(final ECPoint[] points, int off, final int len)
+ {
+ final int FE_BYTES = (getFieldSize() + 7) >>> 3;
+
+ final byte[] table = new byte[len * FE_BYTES * 2];
+ {
+ int pos = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ ECPoint p = points[off + i];
+ byte[] px = p.getRawXCoord().toBigInteger().toByteArray();
+ byte[] py = p.getRawYCoord().toBigInteger().toByteArray();
+
+ int pxStart = px.length > FE_BYTES ? 1 : 0, pxLen = px.length - pxStart;
+ int pyStart = py.length > FE_BYTES ? 1 : 0, pyLen = py.length - pyStart;
+
+ System.arraycopy(px, pxStart, table, pos + FE_BYTES - pxLen, pxLen); pos += FE_BYTES;
+ System.arraycopy(py, pyStart, table, pos + FE_BYTES - pyLen, pyLen); pos += FE_BYTES;
+ }
+ }
+
+ return new AbstractECLookupTable()
+ {
+ public int getSize()
+ {
+ return len;
+ }
+
+ public ECPoint lookup(int index)
+ {
+ byte[] x = new byte[FE_BYTES], y = new byte[FE_BYTES];
+ int pos = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ int MASK = ((i ^ index) - 1) >> 31;
+
+ for (int j = 0; j < FE_BYTES; ++j)
+ {
+ x[j] ^= table[pos + j] & MASK;
+ y[j] ^= table[pos + FE_BYTES + j] & MASK;
+ }
+
+ pos += (FE_BYTES * 2);
+ }
+
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ byte[] x = new byte[FE_BYTES], y = new byte[FE_BYTES];
+ int pos = index * FE_BYTES * 2;
+
+ for (int j = 0; j < FE_BYTES; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_BYTES + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(byte[] x, byte[] y)
+ {
+ return createRawPoint(fromBigInteger(new BigInteger(1, x)), fromBigInteger(new BigInteger(1, y)));
+ }
+ };
+ }
+
+ protected void checkPoint(ECPoint point)
+ {
+ if (null == point || (this != point.getCurve()))
+ {
+ throw new IllegalArgumentException("'point' must be non-null and on this curve");
+ }
+ }
+
+ protected void checkPoints(ECPoint[] points)
+ {
+ checkPoints(points, 0, points.length);
+ }
+
+ protected void checkPoints(ECPoint[] points, int off, int len)
+ {
+ if (points == null)
+ {
+ throw new IllegalArgumentException("'points' cannot be null");
+ }
+ if (off < 0 || len < 0 || (off > (points.length - len)))
+ {
+ throw new IllegalArgumentException("invalid range specified for 'points'");
+ }
+
+ for (int i = 0; i < len; ++i)
+ {
+ ECPoint point = points[off + i];
+ if (null != point && this != point.getCurve())
+ {
+ throw new IllegalArgumentException("'points' entries must be null or on this curve");
+ }
+ }
+ }
+
+ public boolean equals(ECCurve other)
+ {
+ return this == other
+ || (null != other
+ && getField().equals(other.getField())
+ && getA().toBigInteger().equals(other.getA().toBigInteger())
+ && getB().toBigInteger().equals(other.getB().toBigInteger()));
+ }
+
+ public boolean equals(Object obj)
+ {
+ return this == obj || (obj instanceof ECCurve && equals((ECCurve)obj));
+ }
+
+ public int hashCode()
+ {
+ return getField().hashCode()
+ ^ Integers.rotateLeft(getA().toBigInteger().hashCode(), 8)
+ ^ Integers.rotateLeft(getB().toBigInteger().hashCode(), 16);
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static abstract class AbstractFp extends ECCurve
+ {
+ protected AbstractFp(BigInteger q)
+ {
+ super(FiniteFields.getPrimeField(q));
+ }
+
+ public boolean isValidFieldElement(BigInteger x)
+ {
+ return x != null && x.signum() >= 0 && x.compareTo(this.getField().getCharacteristic()) < 0;
+ }
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ BigInteger p = getField().getCharacteristic();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElement(r, p));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElement(r, p));
+ return fe1.multiply(fe2);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ BigInteger p = getField().getCharacteristic();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElementMult(r, p));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElementMult(r, p));
+ return fe1.multiply(fe2);
+ }
+
+ protected ECPoint decompressPoint(int yTilde, BigInteger X1)
+ {
+ ECFieldElement x = this.fromBigInteger(X1);
+ ECFieldElement rhs = x.square().add(this.a).multiply(x).add(this.b);
+ ECFieldElement y = rhs.sqrt();
+
+ /*
+ * If y is not a square, then we haven't got a point on the curve
+ */
+ if (y == null)
+ {
+ throw new IllegalArgumentException("Invalid point compression");
+ }
+
+ if (y.testBitZero() != (yTilde == 1))
+ {
+ // Use the other root
+ y = y.negate();
+ }
+
+ return this.createRawPoint(x, y);
+ }
+
+ private static BigInteger implRandomFieldElement(SecureRandom r, BigInteger p)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(p.bitLength(), r);
+ }
+ while (x.compareTo(p) >= 0);
+ return x;
+ }
+
+ private static BigInteger implRandomFieldElementMult(SecureRandom r, BigInteger p)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(p.bitLength(), r);
+ }
+ while (x.signum() <= 0 || x.compareTo(p) >= 0);
+ return x;
+ }
+ }
+
+ /**
+ * Elliptic curve over Fp
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Fp extends AbstractFp
+ {
+ private static final int FP_DEFAULT_COORDS = ECCurve.COORD_JACOBIAN_MODIFIED;
+
+ BigInteger q, r;
+ ECPoint.Fp infinity;
+
+ /**
+ * @deprecated use constructor taking order/cofactor
+ */
+ public Fp(BigInteger q, BigInteger a, BigInteger b)
+ {
+ this(q, a, b, null, null);
+ }
+
+ public Fp(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor)
+ {
+ super(q);
+
+ this.q = q;
+ this.r = ECFieldElement.Fp.calculateResidue(q);
+ this.infinity = new ECPoint.Fp(this, null, null);
+
+ this.a = fromBigInteger(a);
+ this.b = fromBigInteger(b);
+ this.order = order;
+ this.cofactor = cofactor;
+ this.coord = FP_DEFAULT_COORDS;
+ }
+
+ protected Fp(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor)
+ {
+ super(q);
+
+ this.q = q;
+ this.r = r;
+ this.infinity = new ECPoint.Fp(this, null, null);
+
+ this.a = a;
+ this.b = b;
+ this.order = order;
+ this.cofactor = cofactor;
+ this.coord = FP_DEFAULT_COORDS;
+ }
+
+ protected ECCurve cloneCurve()
+ {
+ return new Fp(this.q, this.r, this.a, this.b, this.order, this.cofactor);
+ }
+
+ public boolean supportsCoordinateSystem(int coord)
+ {
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ case ECCurve.COORD_HOMOGENEOUS:
+ case ECCurve.COORD_JACOBIAN:
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public int getFieldSize()
+ {
+ return q.bitLength();
+ }
+
+ public ECFieldElement fromBigInteger(BigInteger x)
+ {
+ return new ECFieldElement.Fp(this.q, this.r, x);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
+ {
+ return new ECPoint.Fp(this, x, y);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ return new ECPoint.Fp(this, x, y, zs);
+ }
+
+ public ECPoint importPoint(ECPoint p)
+ {
+ if (this != p.getCurve() && this.getCoordinateSystem() == ECCurve.COORD_JACOBIAN && !p.isInfinity())
+ {
+ switch (p.getCurve().getCoordinateSystem())
+ {
+ case ECCurve.COORD_JACOBIAN:
+ case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ return new ECPoint.Fp(this,
+ fromBigInteger(p.x.toBigInteger()),
+ fromBigInteger(p.y.toBigInteger()),
+ new ECFieldElement[]{ fromBigInteger(p.zs[0].toBigInteger()) });
+ default:
+ break;
+ }
+ }
+
+ return super.importPoint(p);
+ }
+
+ public ECPoint getInfinity()
+ {
+ return infinity;
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static abstract class AbstractF2m extends ECCurve
+ {
+ public static BigInteger inverse(int m, int[] ks, BigInteger x)
+ {
+ return new LongArray(x).modInverse(m, ks).toBigInteger();
+ }
+
+ /**
+ * The auxiliary values <code>s<sub>0</sub></code> and
+ * <code>s<sub>1</sub></code> used for partial modular reduction for
+ * Koblitz curves.
+ */
+ private BigInteger[] si = null;
+
+ private static FiniteField buildField(int m, int k1, int k2, int k3)
+ {
+ if (k1 == 0)
+ {
+ throw new IllegalArgumentException("k1 must be > 0");
+ }
+
+ if (k2 == 0)
+ {
+ if (k3 != 0)
+ {
+ throw new IllegalArgumentException("k3 must be 0 if k2 == 0");
+ }
+
+ return FiniteFields.getBinaryExtensionField(new int[]{ 0, k1, m });
+ }
+
+ if (k2 <= k1)
+ {
+ throw new IllegalArgumentException("k2 must be > k1");
+ }
+
+ if (k3 <= k2)
+ {
+ throw new IllegalArgumentException("k3 must be > k2");
+ }
+
+ return FiniteFields.getBinaryExtensionField(new int[]{ 0, k1, k2, k3, m });
+ }
+
+ protected AbstractF2m(int m, int k1, int k2, int k3)
+ {
+ super(buildField(m, k1, k2, k3));
+ }
+
+ public ECPoint createPoint(BigInteger x, BigInteger y)
+ {
+ ECFieldElement X = this.fromBigInteger(x), Y = this.fromBigInteger(y);
+
+ int coord = this.getCoordinateSystem();
+
+ switch (coord)
+ {
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ if (X.isZero())
+ {
+ if (!Y.square().equals(this.getB()))
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+ /*
+ * NOTE: A division could be avoided using a projective result, except at present
+ * callers will expect that the result is already normalized.
+ */
+// else if (coord == COORD_LAMBDA_PROJECTIVE)
+// {
+// ECFieldElement Z = X;
+// X = X.square();
+// Y = Y.add(X);
+// return createRawPoint(X, Y, new ECFieldElement[]{ Z });
+// }
+ else
+ {
+ // Y becomes Lambda (X + Y/X) here
+ Y = Y.divide(X).add(X);
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ return this.createRawPoint(X, Y);
+ }
+
+ public boolean isValidFieldElement(BigInteger x)
+ {
+ return x != null && x.signum() >= 0 && x.bitLength() <= this.getFieldSize();
+ }
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int m = getFieldSize();
+ return fromBigInteger(BigIntegers.createRandomBigInteger(m, r));
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ int m = getFieldSize();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElementMult(r, m));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElementMult(r, m));
+ return fe1.multiply(fe2);
+ }
+
+ /**
+ * Decompresses a compressed point P = (xp, yp) (X9.62 s 4.2.2).
+ *
+ * @param yTilde
+ * ~yp, an indication bit for the decompression of yp.
+ * @param X1
+ * The field element xp.
+ * @return the decompressed point.
+ */
+ protected ECPoint decompressPoint(int yTilde, BigInteger X1)
+ {
+ ECFieldElement x = this.fromBigInteger(X1), y = null;
+ if (x.isZero())
+ {
+ y = this.getB().sqrt();
+ }
+ else
+ {
+ ECFieldElement beta = x.square().invert().multiply(this.getB()).add(this.getA()).add(x);
+ ECFieldElement z = solveQuadraticEquation(beta);
+ if (z != null)
+ {
+ if (z.testBitZero() != (yTilde == 1))
+ {
+ z = z.addOne();
+ }
+
+ switch (this.getCoordinateSystem())
+ {
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ y = z.add(x);
+ break;
+ }
+ default:
+ {
+ y = z.multiply(x);
+ break;
+ }
+ }
+ }
+ }
+
+ if (y == null)
+ {
+ throw new IllegalArgumentException("Invalid point compression");
+ }
+
+ return this.createRawPoint(x, y);
+ }
+
+ /**
+ * Solves a quadratic equation <code>z<sup>2</sup> + z = beta</code>(X9.62
+ * D.1.6) The other solution is <code>z + 1</code>.
+ *
+ * @param beta
+ * The value to solve the quadratic equation for.
+ * @return the solution for <code>z<sup>2</sup> + z = beta</code> or
+ * <code>null</code> if no solution exists.
+ */
+ protected ECFieldElement solveQuadraticEquation(ECFieldElement beta)
+ {
+ ECFieldElement.AbstractF2m betaF2m = (ECFieldElement.AbstractF2m)beta;
+
+ boolean fastTrace = betaF2m.hasFastTrace();
+ if (fastTrace && 0 != betaF2m.trace())
+ {
+ return null;
+ }
+
+ int m = this.getFieldSize();
+
+ // For odd m, use the half-trace
+ if (0 != (m & 1))
+ {
+ ECFieldElement r = betaF2m.halfTrace();
+ if (fastTrace || r.square().add(r).add(beta).isZero())
+ {
+ return r;
+ }
+ return null;
+ }
+
+ if (beta.isZero())
+ {
+ return beta;
+ }
+
+ ECFieldElement gamma, z, zeroElement = this.fromBigInteger(ECConstants.ZERO);
+
+ Random rand = new Random();
+ do
+ {
+ ECFieldElement t = this.fromBigInteger(new BigInteger(m, rand));
+ z = zeroElement;
+ ECFieldElement w = beta;
+ for (int i = 1; i < m; i++)
+ {
+ ECFieldElement w2 = w.square();
+ z = z.square().add(w2.multiply(t));
+ w = w2.add(beta);
+ }
+ if (!w.isZero())
+ {
+ return null;
+ }
+ gamma = z.square().add(z);
+ }
+ while (gamma.isZero());
+
+ return z;
+ }
+
+ /**
+ * @return the auxiliary values <code>s<sub>0</sub></code> and
+ * <code>s<sub>1</sub></code> used for partial modular reduction for
+ * Koblitz curves.
+ */
+ synchronized BigInteger[] getSi()
+ {
+ if (si == null)
+ {
+ si = Tnaf.getSi(this);
+ }
+ return si;
+ }
+
+ /**
+ * Returns true if this is a Koblitz curve (ABC curve).
+ * @return true if this is a Koblitz curve (ABC curve), false otherwise
+ */
+ public boolean isKoblitz()
+ {
+ return this.order != null && this.cofactor != null && this.b.isOne() && (this.a.isZero() || this.a.isOne());
+ }
+
+ private static BigInteger implRandomFieldElementMult(SecureRandom r, int m)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(m, r);
+ }
+ while (x.signum() <= 0);
+ return x;
+ }
+ }
+
+ /**
+ * Elliptic curves over F2m. The Weierstrass equation is given by
+ * <code>y<sup>2</sup> + xy = x<sup>3</sup> + ax<sup>2</sup> + b</code>.
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class F2m extends AbstractF2m
+ {
+ private static final int F2M_DEFAULT_COORDS = ECCurve.COORD_LAMBDA_PROJECTIVE;
+
+ /**
+ * The exponent <code>m</code> of <code>F<sub>2<sup>m</sup></sub></code>.
+ */
+ private int m; // can't be final - JDK 1.1
+
+ /**
+ * TPB: The integer <code>k</code> where <code>x<sup>m</sup> +
+ * x<sup>k</sup> + 1</code> represents the reduction polynomial
+ * <code>f(z)</code>.<br>
+ * PPB: The integer <code>k1</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.<br>
+ */
+ private int k1; // can't be final - JDK 1.1
+
+ /**
+ * TPB: Always set to <code>0</code><br>
+ * PPB: The integer <code>k2</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.<br>
+ */
+ private int k2; // can't be final - JDK 1.1
+
+ /**
+ * TPB: Always set to <code>0</code><br>
+ * PPB: The integer <code>k3</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.<br>
+ */
+ private int k3; // can't be final - JDK 1.1
+
+ /**
+ * The point at infinity on this curve.
+ */
+ private ECPoint.F2m infinity; // can't be final - JDK 1.1
+
+ /**
+ * Constructor for Trinomial Polynomial Basis (TPB).
+ * @param m The exponent <code>m</code> of
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param k The integer <code>k</code> where <code>x<sup>m</sup> +
+ * x<sup>k</sup> + 1</code> represents the reduction
+ * polynomial <code>f(z)</code>.
+ * @param a The coefficient <code>a</code> in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param b The coefficient <code>b</code> in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @deprecated use constructor taking order/cofactor
+ */
+ public F2m(
+ int m,
+ int k,
+ BigInteger a,
+ BigInteger b)
+ {
+ this(m, k, 0, 0, a, b, null, null);
+ }
+
+ /**
+ * Constructor for Trinomial Polynomial Basis (TPB).
+ * @param m The exponent <code>m</code> of
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param k The integer <code>k</code> where <code>x<sup>m</sup> +
+ * x<sup>k</sup> + 1</code> represents the reduction
+ * polynomial <code>f(z)</code>.
+ * @param a The coefficient <code>a</code> in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param b The coefficient <code>b</code> in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param order The order of the main subgroup of the elliptic curve.
+ * @param cofactor The cofactor of the elliptic curve, i.e.
+ * <code>#E<sub>a</sub>(F<sub>2<sup>m</sup></sub>) = h * n</code>.
+ */
+ public F2m(
+ int m,
+ int k,
+ BigInteger a,
+ BigInteger b,
+ BigInteger order,
+ BigInteger cofactor)
+ {
+ this(m, k, 0, 0, a, b, order, cofactor);
+ }
+
+ /**
+ * Constructor for Pentanomial Polynomial Basis (PPB).
+ * @param m The exponent <code>m</code> of
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param k1 The integer <code>k1</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.
+ * @param k2 The integer <code>k2</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.
+ * @param k3 The integer <code>k3</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.
+ * @param a The coefficient <code>a</code> in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param b The coefficient <code>b</code> in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @deprecated use constructor taking order/cofactor
+ */
+ public F2m(
+ int m,
+ int k1,
+ int k2,
+ int k3,
+ BigInteger a,
+ BigInteger b)
+ {
+ this(m, k1, k2, k3, a, b, null, null);
+ }
+
+ /**
+ * Constructor for Pentanomial Polynomial Basis (PPB).
+ * @param m The exponent <code>m</code> of
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param k1 The integer <code>k1</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.
+ * @param k2 The integer <code>k2</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.
+ * @param k3 The integer <code>k3</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.
+ * @param a The coefficient <code>a</code> in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param b The coefficient <code>b</code> in the Weierstrass equation
+ * for non-supersingular elliptic curves over
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param order The order of the main subgroup of the elliptic curve.
+ * @param cofactor The cofactor of the elliptic curve, i.e.
+ * <code>#E<sub>a</sub>(F<sub>2<sup>m</sup></sub>) = h * n</code>.
+ */
+ public F2m(
+ int m,
+ int k1,
+ int k2,
+ int k3,
+ BigInteger a,
+ BigInteger b,
+ BigInteger order,
+ BigInteger cofactor)
+ {
+ super(m, k1, k2, k3);
+
+ this.m = m;
+ this.k1 = k1;
+ this.k2 = k2;
+ this.k3 = k3;
+ this.order = order;
+ this.cofactor = cofactor;
+
+ this.infinity = new ECPoint.F2m(this, null, null);
+ this.a = fromBigInteger(a);
+ this.b = fromBigInteger(b);
+ this.coord = F2M_DEFAULT_COORDS;
+ }
+
+ protected F2m(int m, int k1, int k2, int k3, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor)
+ {
+ super(m, k1, k2, k3);
+
+ this.m = m;
+ this.k1 = k1;
+ this.k2 = k2;
+ this.k3 = k3;
+ this.order = order;
+ this.cofactor = cofactor;
+
+ this.infinity = new ECPoint.F2m(this, null, null);
+ this.a = a;
+ this.b = b;
+ this.coord = F2M_DEFAULT_COORDS;
+ }
+
+ protected ECCurve cloneCurve()
+ {
+ return new F2m(this.m, this.k1, this.k2, this.k3, this.a, this.b, this.order, this.cofactor);
+ }
+
+ public boolean supportsCoordinateSystem(int coord)
+ {
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ case ECCurve.COORD_HOMOGENEOUS:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ protected ECMultiplier createDefaultMultiplier()
+ {
+ if (isKoblitz())
+ {
+ return new WTauNafMultiplier();
+ }
+
+ return super.createDefaultMultiplier();
+ }
+
+ public int getFieldSize()
+ {
+ return m;
+ }
+
+ public ECFieldElement fromBigInteger(BigInteger x)
+ {
+ return new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, x);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
+ {
+ return new ECPoint.F2m(this, x, y);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ return new ECPoint.F2m(this, x, y, zs);
+ }
+
+ public ECPoint getInfinity()
+ {
+ return infinity;
+ }
+
+ public int getM()
+ {
+ return m;
+ }
+
+ /**
+ * Return true if curve uses a Trinomial basis.
+ *
+ * @return true if curve Trinomial, false otherwise.
+ */
+ public boolean isTrinomial()
+ {
+ return k2 == 0 && k3 == 0;
+ }
+
+ public int getK1()
+ {
+ return k1;
+ }
+
+ public int getK2()
+ {
+ return k2;
+ }
+
+ public int getK3()
+ {
+ return k3;
+ }
+
+ public ECLookupTable createCacheSafeLookupTable(ECPoint[] points, int off, final int len)
+ {
+ final int FE_LONGS = (m + 63) >>> 6;
+ final int[] ks = isTrinomial() ? new int[]{ k1 } : new int[]{ k1, k2, k3 };
+
+ final long[] table = new long[len * FE_LONGS * 2];
+ {
+ int pos = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ ECPoint p = points[off + i];
+ ((ECFieldElement.F2m)p.getRawXCoord()).x.copyTo(table, pos); pos += FE_LONGS;
+ ((ECFieldElement.F2m)p.getRawYCoord()).x.copyTo(table, pos); pos += FE_LONGS;
+ }
+ }
+
+ return new AbstractECLookupTable()
+ {
+ public int getSize()
+ {
+ return len;
+ }
+
+ public ECPoint lookup(int index)
+ {
+ long[] x = Nat.create64(FE_LONGS), y = Nat.create64(FE_LONGS);
+ int pos = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ long MASK = ((i ^ index) - 1) >> 31;
+
+ for (int j = 0; j < FE_LONGS; ++j)
+ {
+ x[j] ^= table[pos + j] & MASK;
+ y[j] ^= table[pos + FE_LONGS + j] & MASK;
+ }
+
+ pos += (FE_LONGS * 2);
+ }
+
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ long[] x = Nat.create64(FE_LONGS), y = Nat.create64(FE_LONGS);
+ int pos = index * FE_LONGS * 2;
+
+ for (int j = 0; j < FE_LONGS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_LONGS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(long[] x, long[] y)
+ {
+ ECFieldElement.F2m X = new ECFieldElement.F2m(m, ks, new LongArray(x));
+ ECFieldElement.F2m Y = new ECFieldElement.F2m(m, ks, new LongArray(y));
+ return createRawPoint(X, Y);
+ }
+ };
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECFieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECFieldElement.java
new file mode 100644
index 00000000..7e612ec0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECFieldElement.java
@@ -0,0 +1,920 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+import java.util.Random;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.BigIntegers;
+import com.android.internal.org.bouncycastle.util.Integers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ECFieldElement
+ implements ECConstants
+{
+ public abstract BigInteger toBigInteger();
+ public abstract String getFieldName();
+ public abstract int getFieldSize();
+ public abstract ECFieldElement add(ECFieldElement b);
+ public abstract ECFieldElement addOne();
+ public abstract ECFieldElement subtract(ECFieldElement b);
+ public abstract ECFieldElement multiply(ECFieldElement b);
+ public abstract ECFieldElement divide(ECFieldElement b);
+ public abstract ECFieldElement negate();
+ public abstract ECFieldElement square();
+ public abstract ECFieldElement invert();
+ public abstract ECFieldElement sqrt();
+
+ public ECFieldElement()
+ {
+
+ }
+
+ public int bitLength()
+ {
+ return toBigInteger().bitLength();
+ }
+
+ public boolean isOne()
+ {
+ return bitLength() == 1;
+ }
+
+ public boolean isZero()
+ {
+ return 0 == toBigInteger().signum();
+ }
+
+ public ECFieldElement multiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
+ {
+ return multiply(b).subtract(x.multiply(y));
+ }
+
+ public ECFieldElement multiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
+ {
+ return multiply(b).add(x.multiply(y));
+ }
+
+ public ECFieldElement squareMinusProduct(ECFieldElement x, ECFieldElement y)
+ {
+ return square().subtract(x.multiply(y));
+ }
+
+ public ECFieldElement squarePlusProduct(ECFieldElement x, ECFieldElement y)
+ {
+ return square().add(x.multiply(y));
+ }
+
+ public ECFieldElement squarePow(int pow)
+ {
+ ECFieldElement r = this;
+ for (int i = 0; i < pow; ++i)
+ {
+ r = r.square();
+ }
+ return r;
+ }
+
+ public boolean testBitZero()
+ {
+ return toBigInteger().testBit(0);
+ }
+
+ public String toString()
+ {
+ return this.toBigInteger().toString(16);
+ }
+
+ public byte[] getEncoded()
+ {
+ return BigIntegers.asUnsignedByteArray((getFieldSize() + 7) / 8, toBigInteger());
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static abstract class AbstractFp extends ECFieldElement
+ {
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Fp extends AbstractFp
+ {
+ BigInteger q, r, x;
+
+ static BigInteger calculateResidue(BigInteger p)
+ {
+ int bitLength = p.bitLength();
+ if (bitLength >= 96)
+ {
+ BigInteger firstWord = p.shiftRight(bitLength - 64);
+ if (firstWord.longValue() == -1L)
+ {
+ return ONE.shiftLeft(bitLength).subtract(p);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @deprecated Use ECCurve.fromBigInteger to construct field elements
+ */
+ public Fp(BigInteger q, BigInteger x)
+ {
+ this(q, calculateResidue(q), x);
+ }
+
+ Fp(BigInteger q, BigInteger r, BigInteger x)
+ {
+ if (x == null || x.signum() < 0 || x.compareTo(q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid in Fp field element");
+ }
+
+ this.q = q;
+ this.r = r;
+ this.x = x;
+ }
+
+ public BigInteger toBigInteger()
+ {
+ return x;
+ }
+
+ /**
+ * return the field name for this field.
+ *
+ * @return the string "Fp".
+ */
+ public String getFieldName()
+ {
+ return "Fp";
+ }
+
+ public int getFieldSize()
+ {
+ return q.bitLength();
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public ECFieldElement add(ECFieldElement b)
+ {
+ return new Fp(q, r, modAdd(x, b.toBigInteger()));
+ }
+
+ public ECFieldElement addOne()
+ {
+ BigInteger x2 = x.add(ECConstants.ONE);
+ if (x2.compareTo(q) == 0)
+ {
+ x2 = ECConstants.ZERO;
+ }
+ return new Fp(q, r, x2);
+ }
+
+ public ECFieldElement subtract(ECFieldElement b)
+ {
+ return new Fp(q, r, modSubtract(x, b.toBigInteger()));
+ }
+
+ public ECFieldElement multiply(ECFieldElement b)
+ {
+ return new Fp(q, r, modMult(x, b.toBigInteger()));
+ }
+
+ public ECFieldElement multiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
+ {
+ BigInteger ax = this.x, bx = b.toBigInteger(), xx = x.toBigInteger(), yx = y.toBigInteger();
+ BigInteger ab = ax.multiply(bx);
+ BigInteger xy = xx.multiply(yx);
+ return new Fp(q, r, modReduce(ab.subtract(xy)));
+ }
+
+ public ECFieldElement multiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
+ {
+ BigInteger ax = this.x, bx = b.toBigInteger(), xx = x.toBigInteger(), yx = y.toBigInteger();
+ BigInteger ab = ax.multiply(bx);
+ BigInteger xy = xx.multiply(yx);
+ return new Fp(q, r, modReduce(ab.add(xy)));
+ }
+
+ public ECFieldElement divide(ECFieldElement b)
+ {
+ return new Fp(q, r, modMult(x, modInverse(b.toBigInteger())));
+ }
+
+ public ECFieldElement negate()
+ {
+ return x.signum() == 0 ? this : new Fp(q, r, q.subtract(x));
+ }
+
+ public ECFieldElement square()
+ {
+ return new Fp(q, r, modMult(x, x));
+ }
+
+ public ECFieldElement squareMinusProduct(ECFieldElement x, ECFieldElement y)
+ {
+ BigInteger ax = this.x, xx = x.toBigInteger(), yx = y.toBigInteger();
+ BigInteger aa = ax.multiply(ax);
+ BigInteger xy = xx.multiply(yx);
+ return new Fp(q, r, modReduce(aa.subtract(xy)));
+ }
+
+ public ECFieldElement squarePlusProduct(ECFieldElement x, ECFieldElement y)
+ {
+ BigInteger ax = this.x, xx = x.toBigInteger(), yx = y.toBigInteger();
+ BigInteger aa = ax.multiply(ax);
+ BigInteger xy = xx.multiply(yx);
+ return new Fp(q, r, modReduce(aa.add(xy)));
+ }
+
+ public ECFieldElement invert()
+ {
+ // TODO Modular inversion can be faster for a (Generalized) Mersenne Prime.
+ return new Fp(q, r, modInverse(x));
+ }
+
+ // D.1.4 91
+ /**
+ * return a sqrt root - the routine verifies that the calculation
+ * returns the right value - if none exists it returns null.
+ */
+ public ECFieldElement sqrt()
+ {
+ if (this.isZero() || this.isOne()) // earlier JDK compatibility
+ {
+ return this;
+ }
+
+ if (!q.testBit(0))
+ {
+ throw new RuntimeException("not done yet");
+ }
+
+ // note: even though this class implements ECConstants don't be tempted to
+ // remove the explicit declaration, some J2ME environments don't cope.
+
+ if (q.testBit(1)) // q == 4m + 3
+ {
+ BigInteger e = q.shiftRight(2).add(ECConstants.ONE);
+ return checkSqrt(new Fp(q, r, x.modPow(e, q)));
+ }
+
+ if (q.testBit(2)) // q == 8m + 5
+ {
+ BigInteger t1 = x.modPow(q.shiftRight(3), q);
+ BigInteger t2 = modMult(t1, x);
+ BigInteger t3 = modMult(t2, t1);
+
+ if (t3.equals(ECConstants.ONE))
+ {
+ return checkSqrt(new Fp(q, r, t2));
+ }
+
+ // TODO This is constant and could be precomputed
+ BigInteger t4 = ECConstants.TWO.modPow(q.shiftRight(2), q);
+
+ BigInteger y = modMult(t2, t4);
+
+ return checkSqrt(new Fp(q, r, y));
+ }
+
+ // q == 8m + 1
+
+ BigInteger legendreExponent = q.shiftRight(1);
+ if (!(x.modPow(legendreExponent, q).equals(ECConstants.ONE)))
+ {
+ return null;
+ }
+
+ BigInteger X = this.x;
+ BigInteger fourX = modDouble(modDouble(X));
+
+ BigInteger k = legendreExponent.add(ECConstants.ONE), qMinusOne = q.subtract(ECConstants.ONE);
+
+ BigInteger U, V;
+ Random rand = new Random();
+ do
+ {
+ BigInteger P;
+ do
+ {
+ P = new BigInteger(q.bitLength(), rand);
+ }
+ while (P.compareTo(q) >= 0
+ || !modReduce(P.multiply(P).subtract(fourX)).modPow(legendreExponent, q).equals(qMinusOne));
+
+ BigInteger[] result = lucasSequence(P, X, k);
+ U = result[0];
+ V = result[1];
+
+ if (modMult(V, V).equals(fourX))
+ {
+ return new ECFieldElement.Fp(q, r, modHalfAbs(V));
+ }
+ }
+ while (U.equals(ECConstants.ONE) || U.equals(qMinusOne));
+
+ return null;
+ }
+
+ private ECFieldElement checkSqrt(ECFieldElement z)
+ {
+ return z.square().equals(this) ? z : null;
+ }
+
+ private BigInteger[] lucasSequence(
+ BigInteger P,
+ BigInteger Q,
+ BigInteger k)
+ {
+ // TODO Research and apply "common-multiplicand multiplication here"
+
+ int n = k.bitLength();
+ int s = k.getLowestSetBit();
+
+ // assert k.testBit(s);
+
+ BigInteger Uh = ECConstants.ONE;
+ BigInteger Vl = ECConstants.TWO;
+ BigInteger Vh = P;
+ BigInteger Ql = ECConstants.ONE;
+ BigInteger Qh = ECConstants.ONE;
+
+ for (int j = n - 1; j >= s + 1; --j)
+ {
+ Ql = modMult(Ql, Qh);
+
+ if (k.testBit(j))
+ {
+ Qh = modMult(Ql, Q);
+ Uh = modMult(Uh, Vh);
+ Vl = modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql)));
+ Vh = modReduce(Vh.multiply(Vh).subtract(Qh.shiftLeft(1)));
+ }
+ else
+ {
+ Qh = Ql;
+ Uh = modReduce(Uh.multiply(Vl).subtract(Ql));
+ Vh = modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql)));
+ Vl = modReduce(Vl.multiply(Vl).subtract(Ql.shiftLeft(1)));
+ }
+ }
+
+ Ql = modMult(Ql, Qh);
+ Qh = modMult(Ql, Q);
+ Uh = modReduce(Uh.multiply(Vl).subtract(Ql));
+ Vl = modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql)));
+ Ql = modMult(Ql, Qh);
+
+ for (int j = 1; j <= s; ++j)
+ {
+ Uh = modMult(Uh, Vl);
+ Vl = modReduce(Vl.multiply(Vl).subtract(Ql.shiftLeft(1)));
+ Ql = modMult(Ql, Ql);
+ }
+
+ return new BigInteger[]{ Uh, Vl };
+ }
+
+ protected BigInteger modAdd(BigInteger x1, BigInteger x2)
+ {
+ BigInteger x3 = x1.add(x2);
+ if (x3.compareTo(q) >= 0)
+ {
+ x3 = x3.subtract(q);
+ }
+ return x3;
+ }
+
+ protected BigInteger modDouble(BigInteger x)
+ {
+ BigInteger _2x = x.shiftLeft(1);
+ if (_2x.compareTo(q) >= 0)
+ {
+ _2x = _2x.subtract(q);
+ }
+ return _2x;
+ }
+
+ protected BigInteger modHalf(BigInteger x)
+ {
+ if (x.testBit(0))
+ {
+ x = q.add(x);
+ }
+ return x.shiftRight(1);
+ }
+
+ protected BigInteger modHalfAbs(BigInteger x)
+ {
+ if (x.testBit(0))
+ {
+ x = q.subtract(x);
+ }
+ return x.shiftRight(1);
+ }
+
+ protected BigInteger modInverse(BigInteger x)
+ {
+ return BigIntegers.modOddInverse(q, x);
+ }
+
+ protected BigInteger modMult(BigInteger x1, BigInteger x2)
+ {
+ return modReduce(x1.multiply(x2));
+ }
+
+ protected BigInteger modReduce(BigInteger x)
+ {
+ if (r != null)
+ {
+ boolean negative = x.signum() < 0;
+ if (negative)
+ {
+ x = x.abs();
+ }
+ int qLen = q.bitLength();
+ boolean rIsOne = r.equals(ECConstants.ONE);
+ while (x.bitLength() > (qLen + 1))
+ {
+ BigInteger u = x.shiftRight(qLen);
+ BigInteger v = x.subtract(u.shiftLeft(qLen));
+ if (!rIsOne)
+ {
+ u = u.multiply(r);
+ }
+ x = u.add(v);
+ }
+ while (x.compareTo(q) >= 0)
+ {
+ x = x.subtract(q);
+ }
+ if (negative && x.signum() != 0)
+ {
+ x = q.subtract(x);
+ }
+ }
+ else
+ {
+ x = x.mod(q);
+ }
+ return x;
+ }
+
+ protected BigInteger modSubtract(BigInteger x1, BigInteger x2)
+ {
+ BigInteger x3 = x1.subtract(x2);
+ if (x3.signum() < 0)
+ {
+ x3 = x3.add(q);
+ }
+ return x3;
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof ECFieldElement.Fp))
+ {
+ return false;
+ }
+
+ ECFieldElement.Fp o = (ECFieldElement.Fp)other;
+ return q.equals(o.q) && x.equals(o.x);
+ }
+
+ public int hashCode()
+ {
+ return q.hashCode() ^ x.hashCode();
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static abstract class AbstractF2m extends ECFieldElement
+ {
+ public ECFieldElement halfTrace()
+ {
+ int m = this.getFieldSize();
+ if ((m & 1) == 0)
+ {
+ throw new IllegalStateException("Half-trace only defined for odd m");
+ }
+
+// ECFieldElement ht = this;
+// for (int i = 1; i < m; i += 2)
+// {
+// ht = ht.squarePow(2).add(this);
+// }
+
+ int n = (m + 1) >>> 1;
+ int k = 31 - Integers.numberOfLeadingZeros(n);
+ int nk = 1;
+
+ ECFieldElement ht = this;
+ while (k > 0)
+ {
+ ht = ht.squarePow(nk << 1).add(ht);
+ nk = n >>> --k;
+ if (0 != (nk & 1))
+ {
+ ht = ht.squarePow(2).add(this);
+ }
+ }
+
+ return ht;
+ }
+
+ public boolean hasFastTrace()
+ {
+ return false;
+ }
+
+ public int trace()
+ {
+ int m = this.getFieldSize();
+
+// ECFieldElement tr = this;
+// for (int i = 1; i < m; ++i)
+// {
+// tr = tr.square().add(this);
+// }
+
+ int k = 31 - Integers.numberOfLeadingZeros(m);
+ int mk = 1;
+
+ ECFieldElement tr = this;
+ while (k > 0)
+ {
+ tr = tr.squarePow(mk).add(tr);
+ mk = m >>> --k;
+ if (0 != (mk & 1))
+ {
+ tr = tr.square().add(this);
+ }
+ }
+
+ if (tr.isZero())
+ {
+ return 0;
+ }
+ if (tr.isOne())
+ {
+ return 1;
+ }
+ throw new IllegalStateException("Internal error in trace calculation");
+ }
+ }
+
+ /**
+ * Class representing the Elements of the finite field
+ * <code>F<sub>2<sup>m</sup></sub></code> in polynomial basis (PB)
+ * representation. Both trinomial (TPB) and pentanomial (PPB) polynomial
+ * basis representations are supported. Gaussian normal basis (GNB)
+ * representation is not supported.
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class F2m extends AbstractF2m
+ {
+ /**
+ * Indicates gaussian normal basis representation (GNB). Number chosen
+ * according to X9.62. GNB is not implemented at present.
+ */
+ public static final int GNB = 1;
+
+ /**
+ * Indicates trinomial basis representation (TPB). Number chosen
+ * according to X9.62.
+ */
+ public static final int TPB = 2;
+
+ /**
+ * Indicates pentanomial basis representation (PPB). Number chosen
+ * according to X9.62.
+ */
+ public static final int PPB = 3;
+
+ /**
+ * TPB or PPB.
+ */
+ private int representation;
+
+ /**
+ * The exponent <code>m</code> of <code>F<sub>2<sup>m</sup></sub></code>.
+ */
+ private int m;
+
+ private int[] ks;
+
+ /**
+ * The <code>LongArray</code> holding the bits.
+ */
+ LongArray x;
+
+ /**
+ * Constructor for PPB.
+ * @param m The exponent <code>m</code> of
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param k1 The integer <code>k1</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.
+ * @param k2 The integer <code>k2</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.
+ * @param k3 The integer <code>k3</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.
+ * @param x The BigInteger representing the value of the field element.
+ * @deprecated Use ECCurve.fromBigInteger to construct field elements
+ */
+ public F2m(
+ int m,
+ int k1,
+ int k2,
+ int k3,
+ BigInteger x)
+ {
+ if (x == null || x.signum() < 0 || x.bitLength() > m)
+ {
+ throw new IllegalArgumentException("x value invalid in F2m field element");
+ }
+
+ if ((k2 == 0) && (k3 == 0))
+ {
+ this.representation = TPB;
+ this.ks = new int[]{ k1 };
+ }
+ else
+ {
+ if (k2 >= k3)
+ {
+ throw new IllegalArgumentException(
+ "k2 must be smaller than k3");
+ }
+ if (k2 <= 0)
+ {
+ throw new IllegalArgumentException(
+ "k2 must be larger than 0");
+ }
+ this.representation = PPB;
+ this.ks = new int[]{ k1, k2, k3 };
+ }
+
+ this.m = m;
+ this.x = new LongArray(x);
+ }
+
+ F2m(int m, int[] ks, LongArray x)
+ {
+ this.m = m;
+ this.representation = (ks.length == 1) ? TPB : PPB;
+ this.ks = ks;
+ this.x = x;
+ }
+
+ public int bitLength()
+ {
+ return x.degree();
+ }
+
+ public boolean isOne()
+ {
+ return x.isOne();
+ }
+
+ public boolean isZero()
+ {
+ return x.isZero();
+ }
+
+ public boolean testBitZero()
+ {
+ return x.testBitZero();
+ }
+
+ public BigInteger toBigInteger()
+ {
+ return x.toBigInteger();
+ }
+
+ public String getFieldName()
+ {
+ return "F2m";
+ }
+
+ public int getFieldSize()
+ {
+ return m;
+ }
+
+ public ECFieldElement add(final ECFieldElement b)
+ {
+ // No check performed here for performance reasons. Instead the
+ // elements involved are checked in ECPoint.F2m
+ // checkFieldElements(this, b);
+ LongArray iarrClone = (LongArray)this.x.clone();
+ F2m bF2m = (F2m)b;
+ iarrClone.addShiftedByWords(bF2m.x, 0);
+ return new F2m(m, ks, iarrClone);
+ }
+
+ public ECFieldElement addOne()
+ {
+ return new F2m(m, ks, x.addOne());
+ }
+
+ public ECFieldElement subtract(final ECFieldElement b)
+ {
+ // Addition and subtraction are the same in F2m
+ return add(b);
+ }
+
+ public ECFieldElement multiply(final ECFieldElement b)
+ {
+ // Right-to-left comb multiplication in the LongArray
+ // Input: Binary polynomials a(z) and b(z) of degree at most m-1
+ // Output: c(z) = a(z) * b(z) mod f(z)
+
+ // No check performed here for performance reasons. Instead the
+ // elements involved are checked in ECPoint.F2m
+ // checkFieldElements(this, b);
+ return new F2m(m, ks, x.modMultiply(((F2m)b).x, m, ks));
+ }
+
+ public ECFieldElement multiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
+ {
+ return multiplyPlusProduct(b, x, y);
+ }
+
+ public ECFieldElement multiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
+ {
+ LongArray ax = this.x, bx = ((F2m)b).x, xx = ((F2m)x).x, yx = ((F2m)y).x;
+
+ LongArray ab = ax.multiply(bx, m, ks);
+ LongArray xy = xx.multiply(yx, m, ks);
+
+ if (ab == ax || ab == bx)
+ {
+ ab = (LongArray)ab.clone();
+ }
+
+ ab.addShiftedByWords(xy, 0);
+ ab.reduce(m, ks);
+
+ return new F2m(m, ks, ab);
+ }
+
+ public ECFieldElement divide(final ECFieldElement b)
+ {
+ // There may be more efficient implementations
+ ECFieldElement bInv = b.invert();
+ return multiply(bInv);
+ }
+
+ public ECFieldElement negate()
+ {
+ // -x == x holds for all x in F2m
+ return this;
+ }
+
+ public ECFieldElement square()
+ {
+ return new F2m(m, ks, x.modSquare(m, ks));
+ }
+
+ public ECFieldElement squareMinusProduct(ECFieldElement x, ECFieldElement y)
+ {
+ return squarePlusProduct(x, y);
+ }
+
+ public ECFieldElement squarePlusProduct(ECFieldElement x, ECFieldElement y)
+ {
+ LongArray ax = this.x, xx = ((F2m)x).x, yx = ((F2m)y).x;
+
+ LongArray aa = ax.square(m, ks);
+ LongArray xy = xx.multiply(yx, m, ks);
+
+ if (aa == ax)
+ {
+ aa = (LongArray)aa.clone();
+ }
+
+ aa.addShiftedByWords(xy, 0);
+ aa.reduce(m, ks);
+
+ return new F2m(m, ks, aa);
+ }
+
+ public ECFieldElement squarePow(int pow)
+ {
+ return pow < 1 ? this : new F2m(m, ks, x.modSquareN(pow, m, ks));
+ }
+
+ public ECFieldElement invert()
+ {
+ return new ECFieldElement.F2m(this.m, this.ks, this.x.modInverse(m, ks));
+ }
+
+ public ECFieldElement sqrt()
+ {
+ return (x.isZero() || x.isOne()) ? this : squarePow(m - 1);
+ }
+
+ /**
+ * @return the representation of the field
+ * <code>F<sub>2<sup>m</sup></sub></code>, either of
+ * TPB (trinomial
+ * basis representation) or
+ * PPB (pentanomial
+ * basis representation).
+ */
+ public int getRepresentation()
+ {
+ return this.representation;
+ }
+
+ /**
+ * @return the degree <code>m</code> of the reduction polynomial
+ * <code>f(z)</code>.
+ */
+ public int getM()
+ {
+ return this.m;
+ }
+
+ /**
+ * @return TPB: The integer <code>k</code> where <code>x<sup>m</sup> +
+ * x<sup>k</sup> + 1</code> represents the reduction polynomial
+ * <code>f(z)</code>.<br>
+ * PPB: The integer <code>k1</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.<br>
+ */
+ public int getK1()
+ {
+ return this.ks[0];
+ }
+
+ /**
+ * @return TPB: Always returns <code>0</code><br>
+ * PPB: The integer <code>k2</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.<br>
+ */
+ public int getK2()
+ {
+ return this.ks.length >= 2 ? this.ks[1] : 0;
+ }
+
+ /**
+ * @return TPB: Always set to <code>0</code><br>
+ * PPB: The integer <code>k3</code> where <code>x<sup>m</sup> +
+ * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
+ * represents the reduction polynomial <code>f(z)</code>.<br>
+ */
+ public int getK3()
+ {
+ return this.ks.length >= 3 ? this.ks[2] : 0;
+ }
+
+ public boolean equals(Object anObject)
+ {
+ if (anObject == this)
+ {
+ return true;
+ }
+
+ if (!(anObject instanceof ECFieldElement.F2m))
+ {
+ return false;
+ }
+
+ ECFieldElement.F2m b = (ECFieldElement.F2m)anObject;
+
+ return ((this.m == b.m)
+ && (this.representation == b.representation)
+ && Arrays.areEqual(this.ks, b.ks)
+ && (this.x.equals(b.x)));
+ }
+
+ public int hashCode()
+ {
+ return x.hashCode() ^ m ^ Arrays.hashCode(ks);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECLookupTable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECLookupTable.java
new file mode 100644
index 00000000..6323b0b8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECLookupTable.java
@@ -0,0 +1,12 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ECLookupTable
+{
+ int getSize();
+ ECPoint lookup(int index);
+ ECPoint lookupVar(int index);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECMultiplier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECMultiplier.java
new file mode 100644
index 00000000..7ee82e9f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECMultiplier.java
@@ -0,0 +1,21 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+
+/**
+ * Interface for classes encapsulating a point multiplication algorithm
+ * for <code>ECPoint</code>s.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ECMultiplier
+{
+ /**
+ * Multiplies the <code>ECPoint p</code> by <code>k</code>, i.e.
+ * <code>p</code> is added <code>k</code> times to itself.
+ * @param p The <code>ECPoint</code> to be multiplied.
+ * @param k The factor by which <code>p</code> is multiplied.
+ * @return <code>p</code> multiplied by <code>k</code>.
+ */
+ ECPoint multiply(ECPoint p, BigInteger k);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECPoint.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECPoint.java
new file mode 100644
index 00000000..90eefc78
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECPoint.java
@@ -0,0 +1,2133 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+import java.util.Hashtable;
+
+import com.android.internal.org.bouncycastle.crypto.CryptoServicesRegistrar;
+
+/**
+ * base class for points on elliptic curves.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ECPoint
+{
+ protected final static ECFieldElement[] EMPTY_ZS = new ECFieldElement[0];
+
+ protected static ECFieldElement[] getInitialZCoords(ECCurve curve)
+ {
+ // Cope with null curve, most commonly used by implicitlyCa
+ int coord = null == curve ? ECCurve.COORD_AFFINE : curve.getCoordinateSystem();
+
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ return EMPTY_ZS;
+ default:
+ break;
+ }
+
+ ECFieldElement one = curve.fromBigInteger(ECConstants.ONE);
+
+ switch (coord)
+ {
+ case ECCurve.COORD_HOMOGENEOUS:
+ case ECCurve.COORD_JACOBIAN:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ return new ECFieldElement[]{ one };
+ case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
+ return new ECFieldElement[]{ one, one, one };
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ return new ECFieldElement[]{ one, curve.getA() };
+ default:
+ throw new IllegalArgumentException("unknown coordinate system");
+ }
+ }
+
+ protected ECCurve curve;
+ protected ECFieldElement x;
+ protected ECFieldElement y;
+ protected ECFieldElement[] zs;
+
+ // Hashtable is (String -> PreCompInfo)
+ protected Hashtable preCompTable = null;
+
+ protected ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ this(curve, x, y, getInitialZCoords(curve));
+ }
+
+ protected ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ this.curve = curve;
+ this.x = x;
+ this.y = y;
+ this.zs = zs;
+ }
+
+ protected abstract boolean satisfiesCurveEquation();
+
+ protected boolean satisfiesOrder()
+ {
+ if (ECConstants.ONE.equals(curve.getCofactor()))
+ {
+ return true;
+ }
+
+ BigInteger n = curve.getOrder();
+
+ // TODO Require order to be available for all curves
+
+ return n == null || ECAlgorithms.referenceMultiply(this, n).isInfinity();
+ }
+
+ public final ECPoint getDetachedPoint()
+ {
+ return normalize().detach();
+ }
+
+ public ECCurve getCurve()
+ {
+ return curve;
+ }
+
+ protected abstract ECPoint detach();
+
+ protected int getCurveCoordinateSystem()
+ {
+ // Cope with null curve, most commonly used by implicitlyCa
+ return null == curve ? ECCurve.COORD_AFFINE : curve.getCoordinateSystem();
+ }
+
+ /**
+ * Returns the affine x-coordinate after checking that this point is normalized.
+ *
+ * @return The affine x-coordinate of this point
+ * @throws IllegalStateException if the point is not normalized
+ */
+ public ECFieldElement getAffineXCoord()
+ {
+ checkNormalized();
+ return getXCoord();
+ }
+
+ /**
+ * Returns the affine y-coordinate after checking that this point is normalized
+ *
+ * @return The affine y-coordinate of this point
+ * @throws IllegalStateException if the point is not normalized
+ */
+ public ECFieldElement getAffineYCoord()
+ {
+ checkNormalized();
+ return getYCoord();
+ }
+
+ /**
+ * Returns the x-coordinate.
+ *
+ * Caution: depending on the curve's coordinate system, this may not be the same value as in an
+ * affine coordinate system; use normalize() to get a point where the coordinates have their
+ * affine values, or use getAffineXCoord() if you expect the point to already have been
+ * normalized.
+ *
+ * @return the x-coordinate of this point
+ */
+ public ECFieldElement getXCoord()
+ {
+ return x;
+ }
+
+ /**
+ * Returns the y-coordinate.
+ *
+ * Caution: depending on the curve's coordinate system, this may not be the same value as in an
+ * affine coordinate system; use normalize() to get a point where the coordinates have their
+ * affine values, or use getAffineYCoord() if you expect the point to already have been
+ * normalized.
+ *
+ * @return the y-coordinate of this point
+ */
+ public ECFieldElement getYCoord()
+ {
+ return y;
+ }
+
+ public ECFieldElement getZCoord(int index)
+ {
+ return (index < 0 || index >= zs.length) ? null : zs[index];
+ }
+
+ public ECFieldElement[] getZCoords()
+ {
+ int zsLen = zs.length;
+ if (zsLen == 0)
+ {
+ return EMPTY_ZS;
+ }
+ ECFieldElement[] copy = new ECFieldElement[zsLen];
+ System.arraycopy(zs, 0, copy, 0, zsLen);
+ return copy;
+ }
+
+ public final ECFieldElement getRawXCoord()
+ {
+ return x;
+ }
+
+ public final ECFieldElement getRawYCoord()
+ {
+ return y;
+ }
+
+ protected final ECFieldElement[] getRawZCoords()
+ {
+ return zs;
+ }
+
+ protected void checkNormalized()
+ {
+ if (!isNormalized())
+ {
+ throw new IllegalStateException("point not in normal form");
+ }
+ }
+
+ public boolean isNormalized()
+ {
+ int coord = this.getCurveCoordinateSystem();
+
+ return coord == ECCurve.COORD_AFFINE
+ || coord == ECCurve.COORD_LAMBDA_AFFINE
+ || isInfinity()
+ || zs[0].isOne();
+ }
+
+ /**
+ * Normalization ensures that any projective coordinate is 1, and therefore that the x, y
+ * coordinates reflect those of the equivalent point in an affine coordinate system.
+ *
+ * @return a new ECPoint instance representing the same point, but with normalized coordinates
+ */
+ public ECPoint normalize()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ switch (this.getCurveCoordinateSystem())
+ {
+ case ECCurve.COORD_AFFINE:
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ {
+ return this;
+ }
+ default:
+ {
+ ECFieldElement z = getZCoord(0);
+ if (z.isOne())
+ {
+ return this;
+ }
+
+ if (null == curve)
+ {
+ throw new IllegalStateException("Detached points must be in affine coordinates");
+ }
+
+ /*
+ * Use blinding to avoid the side-channel leak identified and analyzed in the paper
+ * "Yet another GCD based inversion side-channel affecting ECC implementations" by Nir
+ * Drucker and Shay Gueron.
+ *
+ * To blind the calculation of z^-1, choose a multiplicative (i.e. non-zero) field
+ * element 'b' uniformly at random, then calculate the result instead as (z * b)^-1 * b.
+ * Any side-channel in the implementation of 'inverse' now only leaks information about
+ * the value (z * b), and no longer reveals information about 'z' itself.
+ */
+ SecureRandom r = CryptoServicesRegistrar.getSecureRandom();
+ ECFieldElement b = curve.randomFieldElementMult(r);
+ ECFieldElement zInv = z.multiply(b).invert().multiply(b);
+ return normalize(zInv);
+ }
+ }
+ }
+
+ ECPoint normalize(ECFieldElement zInv)
+ {
+ switch (this.getCurveCoordinateSystem())
+ {
+ case ECCurve.COORD_HOMOGENEOUS:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ return createScaledPoint(zInv, zInv);
+ }
+ case ECCurve.COORD_JACOBIAN:
+ case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ {
+ ECFieldElement zInv2 = zInv.square(), zInv3 = zInv2.multiply(zInv);
+ return createScaledPoint(zInv2, zInv3);
+ }
+ default:
+ {
+ throw new IllegalStateException("not a projective coordinate system");
+ }
+ }
+ }
+
+ protected ECPoint createScaledPoint(ECFieldElement sx, ECFieldElement sy)
+ {
+ return this.getCurve().createRawPoint(getRawXCoord().multiply(sx), getRawYCoord().multiply(sy));
+ }
+
+ public boolean isInfinity()
+ {
+ return x == null || y == null || (zs.length > 0 && zs[0].isZero());
+ }
+
+ public boolean isValid()
+ {
+ return implIsValid(false, true);
+ }
+
+ boolean isValidPartial()
+ {
+ return implIsValid(false, false);
+ }
+
+ boolean implIsValid(final boolean decompressed, final boolean checkOrder)
+ {
+ if (isInfinity())
+ {
+ return true;
+ }
+
+ ValidityPrecompInfo validity = (ValidityPrecompInfo)getCurve().precompute(this, ValidityPrecompInfo.PRECOMP_NAME, new PreCompCallback()
+ {
+ public PreCompInfo precompute(PreCompInfo existing)
+ {
+ ValidityPrecompInfo info = (existing instanceof ValidityPrecompInfo) ? (ValidityPrecompInfo)existing : null;
+ if (info == null)
+ {
+ info = new ValidityPrecompInfo();
+ }
+
+ if (info.hasFailed())
+ {
+ return info;
+ }
+ if (!info.hasCurveEquationPassed())
+ {
+ if (!decompressed && !satisfiesCurveEquation())
+ {
+ info.reportFailed();
+ return info;
+ }
+ info.reportCurveEquationPassed();
+ }
+ if (checkOrder && !info.hasOrderPassed())
+ {
+ if (!satisfiesOrder())
+ {
+ info.reportFailed();
+ return info;
+ }
+ info.reportOrderPassed();
+ }
+ return info;
+ }
+ });
+
+ return !validity.hasFailed();
+ }
+
+ public ECPoint scaleX(ECFieldElement scale)
+ {
+ return isInfinity()
+ ? this
+ : getCurve().createRawPoint(getRawXCoord().multiply(scale), getRawYCoord(), getRawZCoords());
+ }
+
+ public ECPoint scaleXNegateY(ECFieldElement scale)
+ {
+ return isInfinity()
+ ? this
+ : getCurve().createRawPoint(getRawXCoord().multiply(scale), getRawYCoord().negate(), getRawZCoords());
+ }
+
+ public ECPoint scaleY(ECFieldElement scale)
+ {
+ return isInfinity()
+ ? this
+ : getCurve().createRawPoint(getRawXCoord(), getRawYCoord().multiply(scale), getRawZCoords());
+ }
+
+ public ECPoint scaleYNegateX(ECFieldElement scale)
+ {
+ return isInfinity()
+ ? this
+ : getCurve().createRawPoint(getRawXCoord().negate(), getRawYCoord().multiply(scale), getRawZCoords());
+ }
+
+ public boolean equals(ECPoint other)
+ {
+ if (null == other)
+ {
+ return false;
+ }
+
+ ECCurve c1 = this.getCurve(), c2 = other.getCurve();
+ boolean n1 = (null == c1), n2 = (null == c2);
+ boolean i1 = isInfinity(), i2 = other.isInfinity();
+
+ if (i1 || i2)
+ {
+ return (i1 && i2) && (n1 || n2 || c1.equals(c2));
+ }
+
+ ECPoint p1 = this, p2 = other;
+ if (n1 && n2)
+ {
+ // Points with null curve are in affine form, so already normalized
+ }
+ else if (n1)
+ {
+ p2 = p2.normalize();
+ }
+ else if (n2)
+ {
+ p1 = p1.normalize();
+ }
+ else if (!c1.equals(c2))
+ {
+ return false;
+ }
+ else
+ {
+ // TODO Consider just requiring already normalized, to avoid silent performance degradation
+
+ ECPoint[] points = new ECPoint[]{ this, c1.importPoint(p2) };
+
+ // TODO This is a little strong, really only requires coZNormalizeAll to get Zs equal
+ c1.normalizeAll(points);
+
+ p1 = points[0];
+ p2 = points[1];
+ }
+
+ return p1.getXCoord().equals(p2.getXCoord()) && p1.getYCoord().equals(p2.getYCoord());
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof ECPoint))
+ {
+ return false;
+ }
+
+ return equals((ECPoint)other);
+ }
+
+ public int hashCode()
+ {
+ ECCurve c = this.getCurve();
+ int hc = (null == c) ? 0 : ~c.hashCode();
+
+ if (!this.isInfinity())
+ {
+ // TODO Consider just requiring already normalized, to avoid silent performance degradation
+
+ ECPoint p = normalize();
+
+ hc ^= p.getXCoord().hashCode() * 17;
+ hc ^= p.getYCoord().hashCode() * 257;
+ }
+
+ return hc;
+ }
+
+ public String toString()
+ {
+ if (this.isInfinity())
+ {
+ return "INF";
+ }
+
+ StringBuffer sb = new StringBuffer();
+ sb.append('(');
+ sb.append(getRawXCoord());
+ sb.append(',');
+ sb.append(getRawYCoord());
+ for (int i = 0; i < zs.length; ++i)
+ {
+ sb.append(',');
+ sb.append(zs[i]);
+ }
+ sb.append(')');
+ return sb.toString();
+ }
+
+ /**
+ * Get an encoding of the point value, optionally in compressed format.
+ *
+ * @param compressed whether to generate a compressed point encoding.
+ * @return the point encoding
+ */
+ public byte[] getEncoded(boolean compressed)
+ {
+ if (this.isInfinity())
+ {
+ return new byte[1];
+ }
+
+ ECPoint normed = normalize();
+
+ byte[] X = normed.getXCoord().getEncoded();
+
+ if (compressed)
+ {
+ byte[] PO = new byte[X.length + 1];
+ PO[0] = (byte)(normed.getCompressionYTilde() ? 0x03 : 0x02);
+ System.arraycopy(X, 0, PO, 1, X.length);
+ return PO;
+ }
+
+ byte[] Y = normed.getYCoord().getEncoded();
+
+ byte[] PO = new byte[X.length + Y.length + 1];
+ PO[0] = 0x04;
+ System.arraycopy(X, 0, PO, 1, X.length);
+ System.arraycopy(Y, 0, PO, X.length + 1, Y.length);
+ return PO;
+ }
+
+ protected abstract boolean getCompressionYTilde();
+
+ public abstract ECPoint add(ECPoint b);
+
+ public abstract ECPoint negate();
+
+ public abstract ECPoint subtract(ECPoint b);
+
+ public ECPoint timesPow2(int e)
+ {
+ if (e < 0)
+ {
+ throw new IllegalArgumentException("'e' cannot be negative");
+ }
+
+ ECPoint p = this;
+ while (--e >= 0)
+ {
+ p = p.twice();
+ }
+ return p;
+ }
+
+ public abstract ECPoint twice();
+
+ public ECPoint twicePlus(ECPoint b)
+ {
+ return twice().add(b);
+ }
+
+ public ECPoint threeTimes()
+ {
+ return twicePlus(this);
+ }
+
+ /**
+ * Multiplies this <code>ECPoint</code> by the given number.
+ * @param k The multiplicator.
+ * @return <code>k * this</code>.
+ */
+ public ECPoint multiply(BigInteger k)
+ {
+ return this.getCurve().getMultiplier().multiply(this, k);
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static abstract class AbstractFp extends ECPoint
+ {
+ protected AbstractFp(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ super(curve, x, y);
+ }
+
+ protected AbstractFp(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ super(curve, x, y, zs);
+ }
+
+ protected boolean getCompressionYTilde()
+ {
+ return this.getAffineYCoord().testBitZero();
+ }
+
+ protected boolean satisfiesCurveEquation()
+ {
+ ECFieldElement X = this.x, Y = this.y, A = curve.getA(), B = curve.getB();
+ ECFieldElement lhs = Y.square();
+
+ switch (this.getCurveCoordinateSystem())
+ {
+ case ECCurve.COORD_AFFINE:
+ break;
+ case ECCurve.COORD_HOMOGENEOUS:
+ {
+ ECFieldElement Z = this.zs[0];
+ if (!Z.isOne())
+ {
+ ECFieldElement Z2 = Z.square(), Z3 = Z.multiply(Z2);
+ lhs = lhs.multiply(Z);
+ A = A.multiply(Z2);
+ B = B.multiply(Z3);
+ }
+ break;
+ }
+ case ECCurve.COORD_JACOBIAN:
+ case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ {
+ ECFieldElement Z = this.zs[0];
+ if (!Z.isOne())
+ {
+ ECFieldElement Z2 = Z.square(), Z4 = Z2.square(), Z6 = Z2.multiply(Z4);
+ A = A.multiply(Z4);
+ B = B.multiply(Z6);
+ }
+ break;
+ }
+ default:
+ throw new IllegalStateException("unsupported coordinate system");
+ }
+
+ ECFieldElement rhs = X.square().add(A).multiply(X).add(B);
+ return lhs.equals(rhs);
+ }
+
+ public ECPoint subtract(ECPoint b)
+ {
+ if (b.isInfinity())
+ {
+ return this;
+ }
+
+ // Add -b
+ return this.add(b.negate());
+ }
+ }
+
+ /**
+ * Elliptic curve points over Fp
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Fp extends AbstractFp
+ {
+ Fp(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ super(curve, x, y);
+ }
+
+ Fp(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ super(curve, x, y, zs);
+ }
+
+ protected ECPoint detach()
+ {
+ return new ECPoint.Fp(null, this.getAffineXCoord(), this.getAffineYCoord());
+ }
+
+ public ECFieldElement getZCoord(int index)
+ {
+ if (index == 1 && ECCurve.COORD_JACOBIAN_MODIFIED == this.getCurveCoordinateSystem())
+ {
+ return getJacobianModifiedW();
+ }
+
+ return super.getZCoord(index);
+ }
+
+ // B.3 pg 62
+ public ECPoint add(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return this;
+ }
+ if (this == b)
+ {
+ return twice();
+ }
+
+ ECCurve curve = this.getCurve();
+ int coord = curve.getCoordinateSystem();
+
+ ECFieldElement X1 = this.x, Y1 = this.y;
+ ECFieldElement X2 = b.x, Y2 = b.y;
+
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ {
+ ECFieldElement dx = X2.subtract(X1), dy = Y2.subtract(Y1);
+
+ if (dx.isZero())
+ {
+ if (dy.isZero())
+ {
+ // this == b, i.e. this must be doubled
+ return twice();
+ }
+
+ // this == -b, i.e. the result is the point at infinity
+ return curve.getInfinity();
+ }
+
+ ECFieldElement gamma = dy.divide(dx);
+ ECFieldElement X3 = gamma.square().subtract(X1).subtract(X2);
+ ECFieldElement Y3 = gamma.multiply(X1.subtract(X3)).subtract(Y1);
+
+ return new ECPoint.Fp(curve, X3, Y3);
+ }
+
+ case ECCurve.COORD_HOMOGENEOUS:
+ {
+ ECFieldElement Z1 = this.zs[0];
+ ECFieldElement Z2 = b.zs[0];
+
+ boolean Z1IsOne = Z1.isOne();
+ boolean Z2IsOne = Z2.isOne();
+
+ ECFieldElement u1 = Z1IsOne ? Y2 : Y2.multiply(Z1);
+ ECFieldElement u2 = Z2IsOne ? Y1 : Y1.multiply(Z2);
+ ECFieldElement u = u1.subtract(u2);
+ ECFieldElement v1 = Z1IsOne ? X2 : X2.multiply(Z1);
+ ECFieldElement v2 = Z2IsOne ? X1 : X1.multiply(Z2);
+ ECFieldElement v = v1.subtract(v2);
+
+ // Check if b == this or b == -this
+ if (v.isZero())
+ {
+ if (u.isZero())
+ {
+ // this == b, i.e. this must be doubled
+ return this.twice();
+ }
+
+ // this == -b, i.e. the result is the point at infinity
+ return curve.getInfinity();
+ }
+
+ // TODO Optimize for when w == 1
+ ECFieldElement w = Z1IsOne ? Z2 : Z2IsOne ? Z1 : Z1.multiply(Z2);
+ ECFieldElement vSquared = v.square();
+ ECFieldElement vCubed = vSquared.multiply(v);
+ ECFieldElement vSquaredV2 = vSquared.multiply(v2);
+ ECFieldElement A = u.square().multiply(w).subtract(vCubed).subtract(two(vSquaredV2));
+
+ ECFieldElement X3 = v.multiply(A);
+ ECFieldElement Y3 = vSquaredV2.subtract(A).multiplyMinusProduct(u, u2, vCubed);
+ ECFieldElement Z3 = vCubed.multiply(w);
+
+ return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 });
+ }
+
+ case ECCurve.COORD_JACOBIAN:
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ {
+ ECFieldElement Z1 = this.zs[0];
+ ECFieldElement Z2 = b.zs[0];
+
+ boolean Z1IsOne = Z1.isOne();
+
+ ECFieldElement X3, Y3, Z3, Z3Squared = null;
+
+ if (!Z1IsOne && Z1.equals(Z2))
+ {
+ // TODO Make this available as public method coZAdd?
+
+ ECFieldElement dx = X1.subtract(X2), dy = Y1.subtract(Y2);
+ if (dx.isZero())
+ {
+ if (dy.isZero())
+ {
+ return twice();
+ }
+ return curve.getInfinity();
+ }
+
+ ECFieldElement C = dx.square();
+ ECFieldElement W1 = X1.multiply(C), W2 = X2.multiply(C);
+ ECFieldElement A1 = W1.subtract(W2).multiply(Y1);
+
+ X3 = dy.square().subtract(W1).subtract(W2);
+ Y3 = W1.subtract(X3).multiply(dy).subtract(A1);
+ Z3 = dx;
+
+ Z3 = Z3.multiply(Z1);
+ }
+ else
+ {
+ ECFieldElement Z1Squared, U2, S2;
+ if (Z1IsOne)
+ {
+ Z1Squared = Z1; U2 = X2; S2 = Y2;
+ }
+ else
+ {
+ Z1Squared = Z1.square();
+ U2 = Z1Squared.multiply(X2);
+ ECFieldElement Z1Cubed = Z1Squared.multiply(Z1);
+ S2 = Z1Cubed.multiply(Y2);
+ }
+
+ boolean Z2IsOne = Z2.isOne();
+ ECFieldElement Z2Squared, U1, S1;
+ if (Z2IsOne)
+ {
+ Z2Squared = Z2; U1 = X1; S1 = Y1;
+ }
+ else
+ {
+ Z2Squared = Z2.square();
+ U1 = Z2Squared.multiply(X1);
+ ECFieldElement Z2Cubed = Z2Squared.multiply(Z2);
+ S1 = Z2Cubed.multiply(Y1);
+ }
+
+ ECFieldElement H = U1.subtract(U2);
+ ECFieldElement R = S1.subtract(S2);
+
+ // Check if b == this or b == -this
+ if (H.isZero())
+ {
+ if (R.isZero())
+ {
+ // this == b, i.e. this must be doubled
+ return this.twice();
+ }
+
+ // this == -b, i.e. the result is the point at infinity
+ return curve.getInfinity();
+ }
+
+ ECFieldElement HSquared = H.square();
+ ECFieldElement G = HSquared.multiply(H);
+ ECFieldElement V = HSquared.multiply(U1);
+
+ X3 = R.square().add(G).subtract(two(V));
+ Y3 = V.subtract(X3).multiplyMinusProduct(R, G, S1);
+
+ Z3 = H;
+ if (!Z1IsOne)
+ {
+ Z3 = Z3.multiply(Z1);
+ }
+ if (!Z2IsOne)
+ {
+ Z3 = Z3.multiply(Z2);
+ }
+
+ // Alternative calculation of Z3 using fast square
+ // X3 = four(X3);
+ // Y3 = eight(Y3);
+ // Z3 = doubleProductFromSquares(Z1, Z2, Z1Squared, Z2Squared).multiply(H);
+
+ if (Z3 == H)
+ {
+ Z3Squared = HSquared;
+ }
+ }
+
+ ECFieldElement[] zs;
+ if (coord == ECCurve.COORD_JACOBIAN_MODIFIED)
+ {
+ // TODO If the result will only be used in a subsequent addition, we don't need W3
+ ECFieldElement W3 = calculateJacobianModifiedW(Z3, Z3Squared);
+
+ zs = new ECFieldElement[]{ Z3, W3 };
+ }
+ else
+ {
+ zs = new ECFieldElement[]{ Z3 };
+ }
+
+ return new ECPoint.Fp(curve, X3, Y3, zs);
+ }
+
+ default:
+ {
+ throw new IllegalStateException("unsupported coordinate system");
+ }
+ }
+ }
+
+ // B.3 pg 62
+ public ECPoint twice()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ int coord = curve.getCoordinateSystem();
+
+ ECFieldElement X1 = this.x;
+
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ {
+ ECFieldElement X1Squared = X1.square();
+ ECFieldElement gamma = three(X1Squared).add(this.getCurve().getA()).divide(two(Y1));
+ ECFieldElement X3 = gamma.square().subtract(two(X1));
+ ECFieldElement Y3 = gamma.multiply(X1.subtract(X3)).subtract(Y1);
+
+ return new ECPoint.Fp(curve, X3, Y3);
+ }
+
+ case ECCurve.COORD_HOMOGENEOUS:
+ {
+ ECFieldElement Z1 = this.zs[0];
+
+ boolean Z1IsOne = Z1.isOne();
+
+ // TODO Optimize for small negative a4 and -3
+ ECFieldElement w = curve.getA();
+ if (!w.isZero() && !Z1IsOne)
+ {
+ w = w.multiply(Z1.square());
+ }
+ w = w.add(three(X1.square()));
+
+ ECFieldElement s = Z1IsOne ? Y1 : Y1.multiply(Z1);
+ ECFieldElement t = Z1IsOne ? Y1.square() : s.multiply(Y1);
+ ECFieldElement B = X1.multiply(t);
+ ECFieldElement _4B = four(B);
+ ECFieldElement h = w.square().subtract(two(_4B));
+
+ ECFieldElement _2s = two(s);
+ ECFieldElement X3 = h.multiply(_2s);
+ ECFieldElement _2t = two(t);
+ ECFieldElement Y3 = _4B.subtract(h).multiply(w).subtract(two(_2t.square()));
+ ECFieldElement _4sSquared = Z1IsOne ? two(_2t) : _2s.square();
+ ECFieldElement Z3 = two(_4sSquared).multiply(s);
+
+ return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 });
+ }
+
+ case ECCurve.COORD_JACOBIAN:
+ {
+ ECFieldElement Z1 = this.zs[0];
+
+ boolean Z1IsOne = Z1.isOne();
+
+ ECFieldElement Y1Squared = Y1.square();
+ ECFieldElement T = Y1Squared.square();
+
+ ECFieldElement a4 = curve.getA();
+ ECFieldElement a4Neg = a4.negate();
+
+ ECFieldElement M, S;
+ if (a4Neg.toBigInteger().equals(BigInteger.valueOf(3)))
+ {
+ ECFieldElement Z1Squared = Z1IsOne ? Z1 : Z1.square();
+ M = three(X1.add(Z1Squared).multiply(X1.subtract(Z1Squared)));
+ S = four(Y1Squared.multiply(X1));
+ }
+ else
+ {
+ ECFieldElement X1Squared = X1.square();
+ M = three(X1Squared);
+ if (Z1IsOne)
+ {
+ M = M.add(a4);
+ }
+ else if (!a4.isZero())
+ {
+ ECFieldElement Z1Squared = Z1.square();
+ ECFieldElement Z1Pow4 = Z1Squared.square();
+ if (a4Neg.bitLength() < a4.bitLength())
+ {
+ M = M.subtract(Z1Pow4.multiply(a4Neg));
+ }
+ else
+ {
+ M = M.add(Z1Pow4.multiply(a4));
+ }
+ }
+// S = two(doubleProductFromSquares(X1, Y1Squared, X1Squared, T));
+ S = four(X1.multiply(Y1Squared));
+ }
+
+ ECFieldElement X3 = M.square().subtract(two(S));
+ ECFieldElement Y3 = S.subtract(X3).multiply(M).subtract(eight(T));
+
+ ECFieldElement Z3 = two(Y1);
+ if (!Z1IsOne)
+ {
+ Z3 = Z3.multiply(Z1);
+ }
+
+ // Alternative calculation of Z3 using fast square
+// ECFieldElement Z3 = doubleProductFromSquares(Y1, Z1, Y1Squared, Z1Squared);
+
+ return new ECPoint.Fp(curve, X3, Y3, new ECFieldElement[]{ Z3 });
+ }
+
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ {
+ return twiceJacobianModified(true);
+ }
+
+ default:
+ {
+ throw new IllegalStateException("unsupported coordinate system");
+ }
+ }
+ }
+
+ public ECPoint twicePlus(ECPoint b)
+ {
+ if (this == b)
+ {
+ return threeTimes();
+ }
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return twice();
+ }
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return b;
+ }
+
+ ECCurve curve = this.getCurve();
+ int coord = curve.getCoordinateSystem();
+
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ {
+ ECFieldElement X1 = this.x;
+ ECFieldElement X2 = b.x, Y2 = b.y;
+
+ ECFieldElement dx = X2.subtract(X1), dy = Y2.subtract(Y1);
+
+ if (dx.isZero())
+ {
+ if (dy.isZero())
+ {
+ // this == b i.e. the result is 3P
+ return threeTimes();
+ }
+
+ // this == -b, i.e. the result is P
+ return this;
+ }
+
+ /*
+ * Optimized calculation of 2P + Q, as described in "Trading Inversions for
+ * Multiplications in Elliptic Curve Cryptography", by Ciet, Joye, Lauter, Montgomery.
+ */
+
+ ECFieldElement X = dx.square(), Y = dy.square();
+ ECFieldElement d = X.multiply(two(X1).add(X2)).subtract(Y);
+ if (d.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ ECFieldElement D = d.multiply(dx);
+ ECFieldElement I = D.invert();
+ ECFieldElement L1 = d.multiply(I).multiply(dy);
+ ECFieldElement L2 = two(Y1).multiply(X).multiply(dx).multiply(I).subtract(L1);
+ ECFieldElement X4 = (L2.subtract(L1)).multiply(L1.add(L2)).add(X2);
+ ECFieldElement Y4 = (X1.subtract(X4)).multiply(L2).subtract(Y1);
+
+ return new ECPoint.Fp(curve, X4, Y4);
+ }
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ {
+ return twiceJacobianModified(false).add(b);
+ }
+ default:
+ {
+ return twice().add(b);
+ }
+ }
+ }
+
+ public ECPoint threeTimes()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+ int coord = curve.getCoordinateSystem();
+
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ {
+ ECFieldElement X1 = this.x;
+
+ ECFieldElement _2Y1 = two(Y1);
+ ECFieldElement X = _2Y1.square();
+ ECFieldElement Z = three(X1.square()).add(this.getCurve().getA());
+ ECFieldElement Y = Z.square();
+
+ ECFieldElement d = three(X1).multiply(X).subtract(Y);
+ if (d.isZero())
+ {
+ return this.getCurve().getInfinity();
+ }
+
+ ECFieldElement D = d.multiply(_2Y1);
+ ECFieldElement I = D.invert();
+ ECFieldElement L1 = d.multiply(I).multiply(Z);
+ ECFieldElement L2 = X.square().multiply(I).subtract(L1);
+
+ ECFieldElement X4 = (L2.subtract(L1)).multiply(L1.add(L2)).add(X1);
+ ECFieldElement Y4 = (X1.subtract(X4)).multiply(L2).subtract(Y1);
+ return new ECPoint.Fp(curve, X4, Y4);
+ }
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ {
+ return twiceJacobianModified(false).add(this);
+ }
+ default:
+ {
+ // NOTE: Be careful about recursions between twicePlus and threeTimes
+ return twice().add(this);
+ }
+ }
+ }
+
+ public ECPoint timesPow2(int e)
+ {
+ if (e < 0)
+ {
+ throw new IllegalArgumentException("'e' cannot be negative");
+ }
+ if (e == 0 || this.isInfinity())
+ {
+ return this;
+ }
+ if (e == 1)
+ {
+ return twice();
+ }
+
+ ECCurve curve = this.getCurve();
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ int coord = curve.getCoordinateSystem();
+
+ ECFieldElement W1 = curve.getA();
+ ECFieldElement X1 = this.x;
+ ECFieldElement Z1 = this.zs.length < 1 ? curve.fromBigInteger(ECConstants.ONE) : this.zs[0];
+
+ if (!Z1.isOne())
+ {
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ break;
+ case ECCurve.COORD_HOMOGENEOUS:
+ ECFieldElement Z1Sq = Z1.square();
+ X1 = X1.multiply(Z1);
+ Y1 = Y1.multiply(Z1Sq);
+ W1 = calculateJacobianModifiedW(Z1, Z1Sq);
+ break;
+ case ECCurve.COORD_JACOBIAN:
+ W1 = calculateJacobianModifiedW(Z1, null);
+ break;
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ W1 = getJacobianModifiedW();
+ break;
+ default:
+ throw new IllegalStateException("unsupported coordinate system");
+ }
+ }
+
+ for (int i = 0; i < e; ++i)
+ {
+ if (Y1.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ ECFieldElement X1Squared = X1.square();
+ ECFieldElement M = three(X1Squared);
+ ECFieldElement _2Y1 = two(Y1);
+ ECFieldElement _2Y1Squared = _2Y1.multiply(Y1);
+ ECFieldElement S = two(X1.multiply(_2Y1Squared));
+ ECFieldElement _4T = _2Y1Squared.square();
+ ECFieldElement _8T = two(_4T);
+
+ if (!W1.isZero())
+ {
+ M = M.add(W1);
+ W1 = two(_8T.multiply(W1));
+ }
+
+ X1 = M.square().subtract(two(S));
+ Y1 = M.multiply(S.subtract(X1)).subtract(_8T);
+ Z1 = Z1.isOne() ? _2Y1 : _2Y1.multiply(Z1);
+ }
+
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ ECFieldElement zInv = Z1.invert(), zInv2 = zInv.square(), zInv3 = zInv2.multiply(zInv);
+ return new Fp(curve, X1.multiply(zInv2), Y1.multiply(zInv3));
+ case ECCurve.COORD_HOMOGENEOUS:
+ X1 = X1.multiply(Z1);
+ Z1 = Z1.multiply(Z1.square());
+ return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1 });
+ case ECCurve.COORD_JACOBIAN:
+ return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1 });
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ return new Fp(curve, X1, Y1, new ECFieldElement[]{ Z1, W1 });
+ default:
+ throw new IllegalStateException("unsupported coordinate system");
+ }
+ }
+
+ protected ECFieldElement two(ECFieldElement x)
+ {
+ return x.add(x);
+ }
+
+ protected ECFieldElement three(ECFieldElement x)
+ {
+ return two(x).add(x);
+ }
+
+ protected ECFieldElement four(ECFieldElement x)
+ {
+ return two(two(x));
+ }
+
+ protected ECFieldElement eight(ECFieldElement x)
+ {
+ return four(two(x));
+ }
+
+ protected ECFieldElement doubleProductFromSquares(ECFieldElement a, ECFieldElement b,
+ ECFieldElement aSquared, ECFieldElement bSquared)
+ {
+ /*
+ * NOTE: If squaring in the field is faster than multiplication, then this is a quicker
+ * way to calculate 2.A.B, if A^2 and B^2 are already known.
+ */
+ return a.add(b).square().subtract(aSquared).subtract(bSquared);
+ }
+
+ public ECPoint negate()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+ int coord = curve.getCoordinateSystem();
+
+ if (ECCurve.COORD_AFFINE != coord)
+ {
+ return new ECPoint.Fp(curve, this.x, this.y.negate(), this.zs);
+ }
+
+ return new ECPoint.Fp(curve, this.x, this.y.negate());
+ }
+
+ protected ECFieldElement calculateJacobianModifiedW(ECFieldElement Z, ECFieldElement ZSquared)
+ {
+ ECFieldElement a4 = this.getCurve().getA();
+ if (a4.isZero() || Z.isOne())
+ {
+ return a4;
+ }
+
+ if (ZSquared == null)
+ {
+ ZSquared = Z.square();
+ }
+
+ ECFieldElement W = ZSquared.square();
+ ECFieldElement a4Neg = a4.negate();
+ if (a4Neg.bitLength() < a4.bitLength())
+ {
+ W = W.multiply(a4Neg).negate();
+ }
+ else
+ {
+ W = W.multiply(a4);
+ }
+ return W;
+ }
+
+ protected ECFieldElement getJacobianModifiedW()
+ {
+ ECFieldElement W = this.zs[1];
+ if (W == null)
+ {
+ // NOTE: Rarely, twicePlus will result in the need for a lazy W1 calculation here
+ this.zs[1] = W = calculateJacobianModifiedW(this.zs[0], null);
+ }
+ return W;
+ }
+
+ protected ECPoint.Fp twiceJacobianModified(boolean calculateW)
+ {
+ ECFieldElement X1 = this.x, Y1 = this.y, Z1 = this.zs[0], W1 = getJacobianModifiedW();
+
+ ECFieldElement X1Squared = X1.square();
+ ECFieldElement M = three(X1Squared).add(W1);
+ ECFieldElement _2Y1 = two(Y1);
+ ECFieldElement _2Y1Squared = _2Y1.multiply(Y1);
+ ECFieldElement S = two(X1.multiply(_2Y1Squared));
+ ECFieldElement X3 = M.square().subtract(two(S));
+ ECFieldElement _4T = _2Y1Squared.square();
+ ECFieldElement _8T = two(_4T);
+ ECFieldElement Y3 = M.multiply(S.subtract(X3)).subtract(_8T);
+ ECFieldElement W3 = calculateW ? two(_8T.multiply(W1)) : null;
+ ECFieldElement Z3 = Z1.isOne() ? _2Y1 : _2Y1.multiply(Z1);
+
+ return new ECPoint.Fp(this.getCurve(), X3, Y3, new ECFieldElement[]{ Z3, W3 });
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static abstract class AbstractF2m extends ECPoint
+ {
+ protected AbstractF2m(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ super(curve, x, y);
+ }
+
+ protected AbstractF2m(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ super(curve, x, y, zs);
+ }
+
+ protected boolean satisfiesCurveEquation()
+ {
+ ECCurve curve = this.getCurve();
+ ECFieldElement X = this.x, A = curve.getA(), B = curve.getB();
+
+ int coord = curve.getCoordinateSystem();
+ if (coord == ECCurve.COORD_LAMBDA_PROJECTIVE)
+ {
+ ECFieldElement Z = this.zs[0];
+ boolean ZIsOne = Z.isOne();
+
+ if (X.isZero())
+ {
+ // NOTE: For x == 0, we expect the affine-y instead of the lambda-y
+ ECFieldElement Y = this.y;
+ ECFieldElement lhs = Y.square(), rhs = B;
+ if (!ZIsOne)
+ {
+ rhs = rhs.multiply(Z.square());
+ }
+ return lhs.equals(rhs);
+ }
+
+ ECFieldElement L = this.y, X2 = X.square();
+ ECFieldElement lhs, rhs;
+ if (ZIsOne)
+ {
+ lhs = L.square().add(L).add(A);
+ rhs = X2.square().add(B);
+ }
+ else
+ {
+ ECFieldElement Z2 = Z.square(), Z4 = Z2.square();
+ lhs = L.add(Z).multiplyPlusProduct(L, A, Z2);
+ // TODO If sqrt(b) is precomputed this can be simplified to a single square
+ rhs = X2.squarePlusProduct(B, Z4);
+ }
+ lhs = lhs.multiply(X2);
+ return lhs.equals(rhs);
+ }
+
+ ECFieldElement Y = this.y;
+ ECFieldElement lhs = Y.add(X).multiply(Y);
+
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ break;
+ case ECCurve.COORD_HOMOGENEOUS:
+ {
+ ECFieldElement Z = this.zs[0];
+ if (!Z.isOne())
+ {
+ ECFieldElement Z2 = Z.square(), Z3 = Z.multiply(Z2);
+ lhs = lhs.multiply(Z);
+ A = A.multiply(Z);
+ B = B.multiply(Z3);
+ }
+ break;
+ }
+ default:
+ throw new IllegalStateException("unsupported coordinate system");
+ }
+
+ ECFieldElement rhs = X.add(A).multiply(X.square()).add(B);
+ return lhs.equals(rhs);
+ }
+
+ protected boolean satisfiesOrder()
+ {
+ BigInteger cofactor = curve.getCofactor();
+ if (ECConstants.TWO.equals(cofactor))
+ {
+ /*
+ * Check that 0 == Tr(X + A); then there exists a solution to L^2 + L = X + A, and
+ * so a halving is possible, so this point is the double of another.
+ *
+ * Note: Tr(A) == 1 for cofactor 2 curves.
+ */
+ ECPoint N = this.normalize();
+ ECFieldElement X = N.getAffineXCoord();
+ return 0 != ((ECFieldElement.AbstractF2m)X).trace();
+ }
+ if (ECConstants.FOUR.equals(cofactor))
+ {
+ /*
+ * Solve L^2 + L = X + A to find the half of this point, if it exists (fail if not).
+ *
+ * Note: Tr(A) == 0 for cofactor 4 curves.
+ */
+ ECPoint N = this.normalize();
+ ECFieldElement X = N.getAffineXCoord();
+ ECFieldElement L = ((ECCurve.AbstractF2m)curve).solveQuadraticEquation(X.add(curve.getA()));
+ if (null == L)
+ {
+ return false;
+ }
+
+ /*
+ * A solution exists, therefore 0 == Tr(X + A) == Tr(X).
+ */
+ ECFieldElement Y = N.getAffineYCoord();
+ ECFieldElement T = X.multiply(L).add(Y);
+
+ /*
+ * Either T or (T + X) is the square of a half-point's x coordinate (hx). In either
+ * case, the half-point can be halved again when 0 == Tr(hx + A).
+ *
+ * Note: Tr(hx + A) == Tr(hx) == Tr(hx^2) == Tr(T) == Tr(T + X)
+ *
+ * Check that 0 == Tr(T); then there exists a solution to L^2 + L = hx + A, and so a
+ * second halving is possible and this point is four times some other.
+ */
+ return 0 == ((ECFieldElement.AbstractF2m)T).trace();
+ }
+
+ return super.satisfiesOrder();
+ }
+
+ public ECPoint scaleX(ECFieldElement scale)
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ int coord = this.getCurveCoordinateSystem();
+
+ switch (coord)
+ {
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ {
+ // Y is actually Lambda (X + Y/X) here
+ ECFieldElement X = this.getRawXCoord(), L = this.getRawYCoord(); // earlier JDK
+
+ ECFieldElement X2 = X.multiply(scale);
+ ECFieldElement L2 = L.add(X).divide(scale).add(X2);
+
+ return this.getCurve().createRawPoint(X, L2, this.getRawZCoords()); // earlier JDK
+ }
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ // Y is actually Lambda (X + Y/X) here
+ ECFieldElement X = this.getRawXCoord(), L = this.getRawYCoord(), Z = this.getRawZCoords()[0]; // earlier JDK
+
+ // We scale the Z coordinate also, to avoid an inversion
+ ECFieldElement X2 = X.multiply(scale.square());
+ ECFieldElement L2 = L.add(X).add(X2);
+ ECFieldElement Z2 = Z.multiply(scale);
+
+ return this.getCurve().createRawPoint(X2, L2, new ECFieldElement[]{ Z2 }); // earlier JDK
+ }
+ default:
+ {
+ return super.scaleX(scale);
+ }
+ }
+ }
+
+ public ECPoint scaleXNegateY(ECFieldElement scale)
+ {
+ return scaleX(scale);
+ }
+
+ public ECPoint scaleY(ECFieldElement scale)
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ int coord = this.getCurveCoordinateSystem();
+
+ switch (coord)
+ {
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ ECFieldElement X = this.getRawXCoord(), L = this.getRawYCoord(); // earlier JDK
+
+ // Y is actually Lambda (X + Y/X) here
+ ECFieldElement L2 = L.add(X).multiply(scale).add(X);
+
+ return this.getCurve().createRawPoint(X, L2, this.getRawZCoords()); // earlier JDK
+ }
+ default:
+ {
+ return super.scaleY(scale);
+ }
+ }
+ }
+
+ public ECPoint scaleYNegateX(ECFieldElement scale)
+ {
+ return scaleY(scale);
+ }
+
+ public ECPoint subtract(ECPoint b)
+ {
+ if (b.isInfinity())
+ {
+ return this;
+ }
+
+ // Add -b
+ return this.add(b.negate());
+ }
+
+ public ECPoint.AbstractF2m tau()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+ int coord = curve.getCoordinateSystem();
+
+ ECFieldElement X1 = this.x;
+
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ {
+ ECFieldElement Y1 = this.y;
+ return (ECPoint.AbstractF2m)curve.createRawPoint(X1.square(), Y1.square());
+ }
+ case ECCurve.COORD_HOMOGENEOUS:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ ECFieldElement Y1 = this.y, Z1 = this.zs[0];
+ return (ECPoint.AbstractF2m)curve.createRawPoint(X1.square(), Y1.square(),
+ new ECFieldElement[]{ Z1.square() });
+ }
+ default:
+ {
+ throw new IllegalStateException("unsupported coordinate system");
+ }
+ }
+ }
+
+ public ECPoint.AbstractF2m tauPow(int pow)
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+ int coord = curve.getCoordinateSystem();
+
+ ECFieldElement X1 = this.x;
+
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ {
+ ECFieldElement Y1 = this.y;
+ return (ECPoint.AbstractF2m)curve.createRawPoint(X1.squarePow(pow), Y1.squarePow(pow));
+ }
+ case ECCurve.COORD_HOMOGENEOUS:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ ECFieldElement Y1 = this.y, Z1 = this.zs[0];
+ return (ECPoint.AbstractF2m)curve.createRawPoint(X1.squarePow(pow), Y1.squarePow(pow),
+ new ECFieldElement[]{ Z1.squarePow(pow) });
+ }
+ default:
+ {
+ throw new IllegalStateException("unsupported coordinate system");
+ }
+ }
+ }
+ }
+
+ /**
+ * Elliptic curve points over F2m
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class F2m extends AbstractF2m
+ {
+ F2m(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ super(curve, x, y);
+
+// checkCurveEquation();
+ }
+
+ F2m(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ super(curve, x, y, zs);
+
+// checkCurveEquation();
+ }
+
+ protected ECPoint detach()
+ {
+ return new ECPoint.F2m(null, this.getAffineXCoord(), this.getAffineYCoord()); // earlier JDK
+ }
+
+ public ECFieldElement getYCoord()
+ {
+ int coord = this.getCurveCoordinateSystem();
+
+ switch (coord)
+ {
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ ECFieldElement X = x, L = y;
+
+ if (this.isInfinity() || X.isZero())
+ {
+ return L;
+ }
+
+ // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly
+ ECFieldElement Y = L.add(X).multiply(X);
+ if (ECCurve.COORD_LAMBDA_PROJECTIVE == coord)
+ {
+ ECFieldElement Z = zs[0];
+ if (!Z.isOne())
+ {
+ Y = Y.divide(Z);
+ }
+ }
+ return Y;
+ }
+ default:
+ {
+ return y;
+ }
+ }
+ }
+
+ protected boolean getCompressionYTilde()
+ {
+ ECFieldElement X = this.getRawXCoord();
+ if (X.isZero())
+ {
+ return false;
+ }
+
+ ECFieldElement Y = this.getRawYCoord();
+
+ switch (this.getCurveCoordinateSystem())
+ {
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ // Y is actually Lambda (X + Y/X) here
+ return Y.testBitZero() != X.testBitZero();
+ }
+ default:
+ {
+ return Y.divide(X).testBitZero();
+ }
+ }
+ }
+
+ public ECPoint add(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+ int coord = curve.getCoordinateSystem();
+
+ ECFieldElement X1 = this.x;
+ ECFieldElement X2 = b.x;
+
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ {
+ ECFieldElement Y1 = this.y;
+ ECFieldElement Y2 = b.y;
+
+ ECFieldElement dx = X1.add(X2), dy = Y1.add(Y2);
+ if (dx.isZero())
+ {
+ if (dy.isZero())
+ {
+ return twice();
+ }
+
+ return curve.getInfinity();
+ }
+
+ ECFieldElement L = dy.divide(dx);
+
+ ECFieldElement X3 = L.square().add(L).add(dx).add(curve.getA());
+ ECFieldElement Y3 = L.multiply(X1.add(X3)).add(X3).add(Y1);
+
+ return new ECPoint.F2m(curve, X3, Y3);
+ }
+ case ECCurve.COORD_HOMOGENEOUS:
+ {
+ ECFieldElement Y1 = this.y, Z1 = this.zs[0];
+ ECFieldElement Y2 = b.y, Z2 = b.zs[0];
+
+ boolean Z2IsOne = Z2.isOne();
+
+ ECFieldElement U1 = Z1.multiply(Y2);
+ ECFieldElement U2 = Z2IsOne ? Y1 : Y1.multiply(Z2);
+ ECFieldElement U = U1.add(U2);
+ ECFieldElement V1 = Z1.multiply(X2);
+ ECFieldElement V2 = Z2IsOne ? X1 : X1.multiply(Z2);
+ ECFieldElement V = V1.add(V2);
+
+ if (V.isZero())
+ {
+ if (U.isZero())
+ {
+ return twice();
+ }
+
+ return curve.getInfinity();
+ }
+
+ ECFieldElement VSq = V.square();
+ ECFieldElement VCu = VSq.multiply(V);
+ ECFieldElement W = Z2IsOne ? Z1 : Z1.multiply(Z2);
+ ECFieldElement uv = U.add(V);
+ ECFieldElement A = uv.multiplyPlusProduct(U, VSq, curve.getA()).multiply(W).add(VCu);
+
+ ECFieldElement X3 = V.multiply(A);
+ ECFieldElement VSqZ2 = Z2IsOne ? VSq : VSq.multiply(Z2);
+ ECFieldElement Y3 = U.multiplyPlusProduct(X1, V, Y1).multiplyPlusProduct(VSqZ2, uv, A);
+ ECFieldElement Z3 = VCu.multiply(W);
+
+ return new ECPoint.F2m(curve, X3, Y3, new ECFieldElement[]{ Z3 });
+ }
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ if (X1.isZero())
+ {
+ if (X2.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ return b.add(this);
+ }
+
+ ECFieldElement L1 = this.y, Z1 = this.zs[0];
+ ECFieldElement L2 = b.y, Z2 = b.zs[0];
+
+ boolean Z1IsOne = Z1.isOne();
+ ECFieldElement U2 = X2, S2 = L2;
+ if (!Z1IsOne)
+ {
+ U2 = U2.multiply(Z1);
+ S2 = S2.multiply(Z1);
+ }
+
+ boolean Z2IsOne = Z2.isOne();
+ ECFieldElement U1 = X1, S1 = L1;
+ if (!Z2IsOne)
+ {
+ U1 = U1.multiply(Z2);
+ S1 = S1.multiply(Z2);
+ }
+
+ ECFieldElement A = S1.add(S2);
+ ECFieldElement B = U1.add(U2);
+
+ if (B.isZero())
+ {
+ if (A.isZero())
+ {
+ return twice();
+ }
+
+ return curve.getInfinity();
+ }
+
+ ECFieldElement X3, L3, Z3;
+ if (X2.isZero())
+ {
+ // TODO This can probably be optimized quite a bit
+ ECPoint p = this.normalize();
+ X1 = p.getXCoord();
+ ECFieldElement Y1 = p.getYCoord();
+
+ ECFieldElement Y2 = L2;
+ ECFieldElement L = Y1.add(Y2).divide(X1);
+
+ X3 = L.square().add(L).add(X1).add(curve.getA());
+ if (X3.isZero())
+ {
+ return new ECPoint.F2m(curve, X3, curve.getB().sqrt());
+ }
+
+ ECFieldElement Y3 = L.multiply(X1.add(X3)).add(X3).add(Y1);
+ L3 = Y3.divide(X3).add(X3);
+ Z3 = curve.fromBigInteger(ECConstants.ONE);
+ }
+ else
+ {
+ B = B.square();
+
+ ECFieldElement AU1 = A.multiply(U1);
+ ECFieldElement AU2 = A.multiply(U2);
+
+ X3 = AU1.multiply(AU2);
+ if (X3.isZero())
+ {
+ return new ECPoint.F2m(curve, X3, curve.getB().sqrt());
+ }
+
+ ECFieldElement ABZ2 = A.multiply(B);
+ if (!Z2IsOne)
+ {
+ ABZ2 = ABZ2.multiply(Z2);
+ }
+
+ L3 = AU2.add(B).squarePlusProduct(ABZ2, L1.add(Z1));
+
+ Z3 = ABZ2;
+ if (!Z1IsOne)
+ {
+ Z3 = Z3.multiply(Z1);
+ }
+ }
+
+ return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 });
+ }
+ default:
+ {
+ throw new IllegalStateException("unsupported coordinate system");
+ }
+ }
+ }
+
+ public ECPoint twice()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+
+ ECFieldElement X1 = this.x;
+ if (X1.isZero())
+ {
+ // A point with X == 0 is its own additive inverse
+ return curve.getInfinity();
+ }
+
+ int coord = curve.getCoordinateSystem();
+
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ {
+ ECFieldElement Y1 = this.y;
+
+ ECFieldElement L1 = Y1.divide(X1).add(X1);
+
+ ECFieldElement X3 = L1.square().add(L1).add(curve.getA());
+ ECFieldElement Y3 = X1.squarePlusProduct(X3, L1.addOne());
+
+ return new ECPoint.F2m(curve, X3, Y3);
+ }
+ case ECCurve.COORD_HOMOGENEOUS:
+ {
+ ECFieldElement Y1 = this.y, Z1 = this.zs[0];
+
+ boolean Z1IsOne = Z1.isOne();
+ ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.multiply(Z1);
+ ECFieldElement Y1Z1 = Z1IsOne ? Y1 : Y1.multiply(Z1);
+
+ ECFieldElement X1Sq = X1.square();
+ ECFieldElement S = X1Sq.add(Y1Z1);
+ ECFieldElement V = X1Z1;
+ ECFieldElement vSquared = V.square();
+ ECFieldElement sv = S.add(V);
+ ECFieldElement h = sv.multiplyPlusProduct(S, vSquared, curve.getA());
+
+ ECFieldElement X3 = V.multiply(h);
+ ECFieldElement Y3 = X1Sq.square().multiplyPlusProduct(V, h, sv);
+ ECFieldElement Z3 = V.multiply(vSquared);
+
+ return new ECPoint.F2m(curve, X3, Y3, new ECFieldElement[]{ Z3 });
+ }
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ ECFieldElement L1 = this.y, Z1 = this.zs[0];
+
+ boolean Z1IsOne = Z1.isOne();
+ ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.multiply(Z1);
+ ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.square();
+ ECFieldElement a = curve.getA();
+ ECFieldElement aZ1Sq = Z1IsOne ? a : a.multiply(Z1Sq);
+ ECFieldElement T = L1.square().add(L1Z1).add(aZ1Sq);
+ if (T.isZero())
+ {
+ return new ECPoint.F2m(curve, T, curve.getB().sqrt());
+ }
+
+ ECFieldElement X3 = T.square();
+ ECFieldElement Z3 = Z1IsOne ? T : T.multiply(Z1Sq);
+
+ ECFieldElement b = curve.getB();
+ ECFieldElement L3;
+ if (b.bitLength() < (curve.getFieldSize() >> 1))
+ {
+ ECFieldElement t1 = L1.add(X1).square();
+ ECFieldElement t2;
+ if (b.isOne())
+ {
+ t2 = aZ1Sq.add(Z1Sq).square();
+ }
+ else
+ {
+ // TODO Can be calculated with one square if we pre-compute sqrt(b)
+ t2 = aZ1Sq.squarePlusProduct(b, Z1Sq.square());
+ }
+ L3 = t1.add(T).add(Z1Sq).multiply(t1).add(t2).add(X3);
+ if (a.isZero())
+ {
+ L3 = L3.add(Z3);
+ }
+ else if (!a.isOne())
+ {
+ L3 = L3.add(a.addOne().multiply(Z3));
+ }
+ }
+ else
+ {
+ ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.multiply(Z1);
+ L3 = X1Z1.squarePlusProduct(T, L1Z1).add(X3).add(Z3);
+ }
+
+ return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 });
+ }
+ default:
+ {
+ throw new IllegalStateException("unsupported coordinate system");
+ }
+ }
+ }
+
+ public ECPoint twicePlus(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return twice();
+ }
+
+ ECCurve curve = this.getCurve();
+
+ ECFieldElement X1 = this.x;
+ if (X1.isZero())
+ {
+ // A point with X == 0 is its own additive inverse
+ return b;
+ }
+
+ int coord = curve.getCoordinateSystem();
+
+ switch (coord)
+ {
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ // NOTE: twicePlus() only optimized for lambda-affine argument
+ ECFieldElement X2 = b.x, Z2 = b.zs[0];
+ if (X2.isZero() || !Z2.isOne())
+ {
+ return twice().add(b);
+ }
+
+ ECFieldElement L1 = this.y, Z1 = this.zs[0];
+ ECFieldElement L2 = b.y;
+
+ ECFieldElement X1Sq = X1.square();
+ ECFieldElement L1Sq = L1.square();
+ ECFieldElement Z1Sq = Z1.square();
+ ECFieldElement L1Z1 = L1.multiply(Z1);
+
+ ECFieldElement T = curve.getA().multiply(Z1Sq).add(L1Sq).add(L1Z1);
+ ECFieldElement L2plus1 = L2.addOne();
+ ECFieldElement A = curve.getA().add(L2plus1).multiply(Z1Sq).add(L1Sq).multiplyPlusProduct(T, X1Sq, Z1Sq);
+ ECFieldElement X2Z1Sq = X2.multiply(Z1Sq);
+ ECFieldElement B = X2Z1Sq.add(T).square();
+
+ if (B.isZero())
+ {
+ if (A.isZero())
+ {
+ return b.twice();
+ }
+
+ return curve.getInfinity();
+ }
+
+ if (A.isZero())
+ {
+ return new ECPoint.F2m(curve, A, curve.getB().sqrt());
+ }
+
+ ECFieldElement X3 = A.square().multiply(X2Z1Sq);
+ ECFieldElement Z3 = A.multiply(B).multiply(Z1Sq);
+ ECFieldElement L3 = A.add(B).square().multiplyPlusProduct(T, L2plus1, Z3);
+
+ return new ECPoint.F2m(curve, X3, L3, new ECFieldElement[]{ Z3 });
+ }
+ default:
+ {
+ return twice().add(b);
+ }
+ }
+ }
+
+ public ECPoint negate()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECFieldElement X = this.x;
+ if (X.isZero())
+ {
+ return this;
+ }
+
+ switch (this.getCurveCoordinateSystem())
+ {
+ case ECCurve.COORD_AFFINE:
+ {
+ ECFieldElement Y = this.y;
+ return new ECPoint.F2m(curve, X, Y.add(X));
+ }
+ case ECCurve.COORD_HOMOGENEOUS:
+ {
+ ECFieldElement Y = this.y, Z = this.zs[0];
+ return new ECPoint.F2m(curve, X, Y.add(X), new ECFieldElement[]{ Z });
+ }
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ {
+ ECFieldElement L = this.y;
+ return new ECPoint.F2m(curve, X, L.addOne());
+ }
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ // L is actually Lambda (X + Y/X) here
+ ECFieldElement L = this.y, Z = this.zs[0];
+ return new ECPoint.F2m(curve, X, L.add(Z), new ECFieldElement[]{ Z });
+ }
+ default:
+ {
+ throw new IllegalStateException("unsupported coordinate system");
+ }
+ }
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECPointMap.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECPointMap.java
new file mode 100644
index 00000000..7ca86bcd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECPointMap.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ECPointMap
+{
+ ECPoint map(ECPoint p);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/FixedPointCombMultiplier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/FixedPointCombMultiplier.java
new file mode 100644
index 00000000..fdea98b8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/FixedPointCombMultiplier.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class FixedPointCombMultiplier extends AbstractECMultiplier
+{
+ protected ECPoint multiplyPositive(ECPoint p, BigInteger k)
+ {
+ ECCurve c = p.getCurve();
+ int size = FixedPointUtil.getCombSize(c);
+
+ if (k.bitLength() > size)
+ {
+ /*
+ * TODO The comb works best when the scalars are less than the (possibly unknown) order.
+ * Still, if we want to handle larger scalars, we could allow customization of the comb
+ * size, or alternatively we could deal with the 'extra' bits either by running the comb
+ * multiple times as necessary, or by using an alternative multiplier as prelude.
+ */
+ throw new IllegalStateException("fixed-point comb doesn't support scalars larger than the curve order");
+ }
+
+ FixedPointPreCompInfo info = FixedPointUtil.precompute(p);
+ ECLookupTable lookupTable = info.getLookupTable();
+ int width = info.getWidth();
+
+ int d = (size + width - 1) / width;
+
+ ECPoint R = c.getInfinity();
+
+ int fullComb = d * width;
+ int[] K = Nat.fromBigInteger(fullComb, k);
+
+ int top = fullComb - 1;
+ for (int i = 0; i < d; ++i)
+ {
+ int secretIndex = 0;
+
+ for (int j = top - i; j >= 0; j -= d)
+ {
+ int secretBit = K[j >>> 5] >>> (j & 0x1F);
+ secretIndex ^= secretBit >>> 1;
+ secretIndex <<= 1;
+ secretIndex ^= secretBit;
+ }
+
+ ECPoint add = lookupTable.lookup(secretIndex);
+
+ R = R.twicePlus(add);
+ }
+
+ return R.add(info.getOffset());
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/FixedPointPreCompInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/FixedPointPreCompInfo.java
new file mode 100644
index 00000000..9df7d80d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/FixedPointPreCompInfo.java
@@ -0,0 +1,53 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+/**
+ * Class holding precomputation data for fixed-point multiplications.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class FixedPointPreCompInfo implements PreCompInfo
+{
+ protected ECPoint offset = null;
+
+ /**
+ * Lookup table for the precomputed {@link ECPoint}s used for a fixed point multiplication.
+ */
+ protected ECLookupTable lookupTable = null;
+
+ /**
+ * The width used for the precomputation. If a larger width precomputation
+ * is already available this may be larger than was requested, so calling
+ * code should refer to the actual width.
+ */
+ protected int width = -1;
+
+ public ECLookupTable getLookupTable()
+ {
+ return lookupTable;
+ }
+
+ public void setLookupTable(ECLookupTable lookupTable)
+ {
+ this.lookupTable = lookupTable;
+ }
+
+ public ECPoint getOffset()
+ {
+ return offset;
+ }
+
+ public void setOffset(ECPoint offset)
+ {
+ this.offset = offset;
+ }
+
+ public int getWidth()
+ {
+ return width;
+ }
+
+ public void setWidth(int width)
+ {
+ this.width = width;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/FixedPointUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/FixedPointUtil.java
new file mode 100644
index 00000000..44290cba
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/FixedPointUtil.java
@@ -0,0 +1,91 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class FixedPointUtil
+{
+ public static final String PRECOMP_NAME = "bc_fixed_point";
+
+ public static int getCombSize(ECCurve c)
+ {
+ BigInteger order = c.getOrder();
+ return order == null ? c.getFieldSize() + 1 : order.bitLength();
+ }
+
+ public static FixedPointPreCompInfo getFixedPointPreCompInfo(PreCompInfo preCompInfo)
+ {
+ return (preCompInfo instanceof FixedPointPreCompInfo) ? (FixedPointPreCompInfo)preCompInfo : null;
+ }
+
+ public static FixedPointPreCompInfo precompute(final ECPoint p)
+ {
+ final ECCurve c = p.getCurve();
+
+ return (FixedPointPreCompInfo)c.precompute(p, PRECOMP_NAME, new PreCompCallback()
+ {
+ public PreCompInfo precompute(PreCompInfo existing)
+ {
+ FixedPointPreCompInfo existingFP = (existing instanceof FixedPointPreCompInfo) ? (FixedPointPreCompInfo)existing : null;
+
+ int bits = getCombSize(c);
+ int minWidth = bits > 250 ? 6 : 5;
+ int n = 1 << minWidth;
+
+ if (checkExisting(existingFP, n))
+ {
+ return existingFP;
+ }
+
+ int d = (bits + minWidth - 1) / minWidth;
+
+ ECPoint[] pow2Table = new ECPoint[minWidth + 1];
+ pow2Table[0] = p;
+ for (int i = 1; i < minWidth; ++i)
+ {
+ pow2Table[i] = pow2Table[i - 1].timesPow2(d);
+ }
+
+ // This will be the 'offset' value
+ pow2Table[minWidth] = pow2Table[0].subtract(pow2Table[1]);
+
+ c.normalizeAll(pow2Table);
+
+ ECPoint[] lookupTable = new ECPoint[n];
+ lookupTable[0] = pow2Table[0];
+
+ for (int bit = minWidth - 1; bit >= 0; --bit)
+ {
+ ECPoint pow2 = pow2Table[bit];
+
+ int step = 1 << bit;
+ for (int i = step; i < n; i += (step << 1))
+ {
+ lookupTable[i] = lookupTable[i - step].add(pow2);
+ }
+ }
+
+ c.normalizeAll(lookupTable);
+
+ FixedPointPreCompInfo result = new FixedPointPreCompInfo();
+ result.setLookupTable(c.createCacheSafeLookupTable(lookupTable, 0, lookupTable.length));
+ result.setOffset(pow2Table[minWidth]);
+ result.setWidth(minWidth);
+ return result;
+ }
+
+ private boolean checkExisting(FixedPointPreCompInfo existingFP, int n)
+ {
+ return existingFP != null && checkTable(existingFP.getLookupTable(), n);
+ }
+
+ private boolean checkTable(ECLookupTable table, int n)
+ {
+ return table != null && table.getSize() >= n;
+ }
+ });
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/GLVMultiplier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/GLVMultiplier.java
new file mode 100644
index 00000000..19ffeca7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/GLVMultiplier.java
@@ -0,0 +1,48 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.endo.EndoUtil;
+import com.android.internal.org.bouncycastle.math.ec.endo.GLVEndomorphism;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GLVMultiplier extends AbstractECMultiplier
+{
+ protected final ECCurve curve;
+ protected final GLVEndomorphism glvEndomorphism;
+
+ public GLVMultiplier(ECCurve curve, GLVEndomorphism glvEndomorphism)
+ {
+ if (curve == null || curve.getOrder() == null)
+ {
+ throw new IllegalArgumentException("Need curve with known group order");
+ }
+
+ this.curve = curve;
+ this.glvEndomorphism = glvEndomorphism;
+ }
+
+ protected ECPoint multiplyPositive(ECPoint p, BigInteger k)
+ {
+ if (!curve.equals(p.getCurve()))
+ {
+ throw new IllegalStateException();
+ }
+
+ BigInteger n = p.getCurve().getOrder();
+ BigInteger[] ab = glvEndomorphism.decomposeScalar(k.mod(n));
+ BigInteger a = ab[0], b = ab[1];
+
+ if (glvEndomorphism.hasEfficientPointMap())
+ {
+ return ECAlgorithms.implShamirsTrickWNaf(glvEndomorphism, p, a, b);
+ }
+
+ ECPoint q = EndoUtil.mapPoint(glvEndomorphism, p);
+
+ return ECAlgorithms.implShamirsTrickWNaf(p, a, q, b);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/LongArray.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/LongArray.java
new file mode 100644
index 00000000..504542ab
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/LongArray.java
@@ -0,0 +1,2203 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+import java.math.BigInteger;
+
+class LongArray implements Cloneable
+{
+// private static long DEINTERLEAVE_MASK = 0x5555555555555555L;
+
+ /*
+ * This expands 8 bit indices into 16 bit contents (high bit 14), by inserting 0s between bits.
+ * In a binary field, this operation is the same as squaring an 8 bit number.
+ *
+ * NOTE: All entries are positive so sign-extension is not an issue.
+ */
+ private static final short[] INTERLEAVE2_TABLE = new short[]
+ {
+ 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015,
+ 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055,
+ 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115,
+ 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155,
+ 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415,
+ 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455,
+ 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515,
+ 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555,
+ 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015,
+ 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055,
+ 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115,
+ 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155,
+ 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415,
+ 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455,
+ 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515,
+ 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555,
+ 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015,
+ 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055,
+ 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115,
+ 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155,
+ 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415,
+ 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455,
+ 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515,
+ 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555,
+ 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015,
+ 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055,
+ 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115,
+ 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155,
+ 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415,
+ 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455,
+ 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515,
+ 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555
+ };
+
+ /*
+ * This expands 7 bit indices into 21 bit contents (high bit 18), by inserting 0s between bits.
+ */
+ private static final int[] INTERLEAVE3_TABLE = new int[]
+ {
+ 0x00000, 0x00001, 0x00008, 0x00009, 0x00040, 0x00041, 0x00048, 0x00049,
+ 0x00200, 0x00201, 0x00208, 0x00209, 0x00240, 0x00241, 0x00248, 0x00249,
+ 0x01000, 0x01001, 0x01008, 0x01009, 0x01040, 0x01041, 0x01048, 0x01049,
+ 0x01200, 0x01201, 0x01208, 0x01209, 0x01240, 0x01241, 0x01248, 0x01249,
+ 0x08000, 0x08001, 0x08008, 0x08009, 0x08040, 0x08041, 0x08048, 0x08049,
+ 0x08200, 0x08201, 0x08208, 0x08209, 0x08240, 0x08241, 0x08248, 0x08249,
+ 0x09000, 0x09001, 0x09008, 0x09009, 0x09040, 0x09041, 0x09048, 0x09049,
+ 0x09200, 0x09201, 0x09208, 0x09209, 0x09240, 0x09241, 0x09248, 0x09249,
+ 0x40000, 0x40001, 0x40008, 0x40009, 0x40040, 0x40041, 0x40048, 0x40049,
+ 0x40200, 0x40201, 0x40208, 0x40209, 0x40240, 0x40241, 0x40248, 0x40249,
+ 0x41000, 0x41001, 0x41008, 0x41009, 0x41040, 0x41041, 0x41048, 0x41049,
+ 0x41200, 0x41201, 0x41208, 0x41209, 0x41240, 0x41241, 0x41248, 0x41249,
+ 0x48000, 0x48001, 0x48008, 0x48009, 0x48040, 0x48041, 0x48048, 0x48049,
+ 0x48200, 0x48201, 0x48208, 0x48209, 0x48240, 0x48241, 0x48248, 0x48249,
+ 0x49000, 0x49001, 0x49008, 0x49009, 0x49040, 0x49041, 0x49048, 0x49049,
+ 0x49200, 0x49201, 0x49208, 0x49209, 0x49240, 0x49241, 0x49248, 0x49249
+ };
+
+ /*
+ * This expands 8 bit indices into 32 bit contents (high bit 28), by inserting 0s between bits.
+ */
+ private static final int[] INTERLEAVE4_TABLE = new int[]
+ {
+ 0x00000000, 0x00000001, 0x00000010, 0x00000011, 0x00000100, 0x00000101, 0x00000110, 0x00000111,
+ 0x00001000, 0x00001001, 0x00001010, 0x00001011, 0x00001100, 0x00001101, 0x00001110, 0x00001111,
+ 0x00010000, 0x00010001, 0x00010010, 0x00010011, 0x00010100, 0x00010101, 0x00010110, 0x00010111,
+ 0x00011000, 0x00011001, 0x00011010, 0x00011011, 0x00011100, 0x00011101, 0x00011110, 0x00011111,
+ 0x00100000, 0x00100001, 0x00100010, 0x00100011, 0x00100100, 0x00100101, 0x00100110, 0x00100111,
+ 0x00101000, 0x00101001, 0x00101010, 0x00101011, 0x00101100, 0x00101101, 0x00101110, 0x00101111,
+ 0x00110000, 0x00110001, 0x00110010, 0x00110011, 0x00110100, 0x00110101, 0x00110110, 0x00110111,
+ 0x00111000, 0x00111001, 0x00111010, 0x00111011, 0x00111100, 0x00111101, 0x00111110, 0x00111111,
+ 0x01000000, 0x01000001, 0x01000010, 0x01000011, 0x01000100, 0x01000101, 0x01000110, 0x01000111,
+ 0x01001000, 0x01001001, 0x01001010, 0x01001011, 0x01001100, 0x01001101, 0x01001110, 0x01001111,
+ 0x01010000, 0x01010001, 0x01010010, 0x01010011, 0x01010100, 0x01010101, 0x01010110, 0x01010111,
+ 0x01011000, 0x01011001, 0x01011010, 0x01011011, 0x01011100, 0x01011101, 0x01011110, 0x01011111,
+ 0x01100000, 0x01100001, 0x01100010, 0x01100011, 0x01100100, 0x01100101, 0x01100110, 0x01100111,
+ 0x01101000, 0x01101001, 0x01101010, 0x01101011, 0x01101100, 0x01101101, 0x01101110, 0x01101111,
+ 0x01110000, 0x01110001, 0x01110010, 0x01110011, 0x01110100, 0x01110101, 0x01110110, 0x01110111,
+ 0x01111000, 0x01111001, 0x01111010, 0x01111011, 0x01111100, 0x01111101, 0x01111110, 0x01111111,
+ 0x10000000, 0x10000001, 0x10000010, 0x10000011, 0x10000100, 0x10000101, 0x10000110, 0x10000111,
+ 0x10001000, 0x10001001, 0x10001010, 0x10001011, 0x10001100, 0x10001101, 0x10001110, 0x10001111,
+ 0x10010000, 0x10010001, 0x10010010, 0x10010011, 0x10010100, 0x10010101, 0x10010110, 0x10010111,
+ 0x10011000, 0x10011001, 0x10011010, 0x10011011, 0x10011100, 0x10011101, 0x10011110, 0x10011111,
+ 0x10100000, 0x10100001, 0x10100010, 0x10100011, 0x10100100, 0x10100101, 0x10100110, 0x10100111,
+ 0x10101000, 0x10101001, 0x10101010, 0x10101011, 0x10101100, 0x10101101, 0x10101110, 0x10101111,
+ 0x10110000, 0x10110001, 0x10110010, 0x10110011, 0x10110100, 0x10110101, 0x10110110, 0x10110111,
+ 0x10111000, 0x10111001, 0x10111010, 0x10111011, 0x10111100, 0x10111101, 0x10111110, 0x10111111,
+ 0x11000000, 0x11000001, 0x11000010, 0x11000011, 0x11000100, 0x11000101, 0x11000110, 0x11000111,
+ 0x11001000, 0x11001001, 0x11001010, 0x11001011, 0x11001100, 0x11001101, 0x11001110, 0x11001111,
+ 0x11010000, 0x11010001, 0x11010010, 0x11010011, 0x11010100, 0x11010101, 0x11010110, 0x11010111,
+ 0x11011000, 0x11011001, 0x11011010, 0x11011011, 0x11011100, 0x11011101, 0x11011110, 0x11011111,
+ 0x11100000, 0x11100001, 0x11100010, 0x11100011, 0x11100100, 0x11100101, 0x11100110, 0x11100111,
+ 0x11101000, 0x11101001, 0x11101010, 0x11101011, 0x11101100, 0x11101101, 0x11101110, 0x11101111,
+ 0x11110000, 0x11110001, 0x11110010, 0x11110011, 0x11110100, 0x11110101, 0x11110110, 0x11110111,
+ 0x11111000, 0x11111001, 0x11111010, 0x11111011, 0x11111100, 0x11111101, 0x11111110, 0x11111111
+ };
+
+ /*
+ * This expands 7 bit indices into 35 bit contents (high bit 30), by inserting 0s between bits.
+ */
+ private static final int[] INTERLEAVE5_TABLE = new int[] {
+ 0x00000000, 0x00000001, 0x00000020, 0x00000021, 0x00000400, 0x00000401, 0x00000420, 0x00000421,
+ 0x00008000, 0x00008001, 0x00008020, 0x00008021, 0x00008400, 0x00008401, 0x00008420, 0x00008421,
+ 0x00100000, 0x00100001, 0x00100020, 0x00100021, 0x00100400, 0x00100401, 0x00100420, 0x00100421,
+ 0x00108000, 0x00108001, 0x00108020, 0x00108021, 0x00108400, 0x00108401, 0x00108420, 0x00108421,
+ 0x02000000, 0x02000001, 0x02000020, 0x02000021, 0x02000400, 0x02000401, 0x02000420, 0x02000421,
+ 0x02008000, 0x02008001, 0x02008020, 0x02008021, 0x02008400, 0x02008401, 0x02008420, 0x02008421,
+ 0x02100000, 0x02100001, 0x02100020, 0x02100021, 0x02100400, 0x02100401, 0x02100420, 0x02100421,
+ 0x02108000, 0x02108001, 0x02108020, 0x02108021, 0x02108400, 0x02108401, 0x02108420, 0x02108421,
+ 0x40000000, 0x40000001, 0x40000020, 0x40000021, 0x40000400, 0x40000401, 0x40000420, 0x40000421,
+ 0x40008000, 0x40008001, 0x40008020, 0x40008021, 0x40008400, 0x40008401, 0x40008420, 0x40008421,
+ 0x40100000, 0x40100001, 0x40100020, 0x40100021, 0x40100400, 0x40100401, 0x40100420, 0x40100421,
+ 0x40108000, 0x40108001, 0x40108020, 0x40108021, 0x40108400, 0x40108401, 0x40108420, 0x40108421,
+ 0x42000000, 0x42000001, 0x42000020, 0x42000021, 0x42000400, 0x42000401, 0x42000420, 0x42000421,
+ 0x42008000, 0x42008001, 0x42008020, 0x42008021, 0x42008400, 0x42008401, 0x42008420, 0x42008421,
+ 0x42100000, 0x42100001, 0x42100020, 0x42100021, 0x42100400, 0x42100401, 0x42100420, 0x42100421,
+ 0x42108000, 0x42108001, 0x42108020, 0x42108021, 0x42108400, 0x42108401, 0x42108420, 0x42108421
+ };
+
+ /*
+ * This expands 9 bit indices into 63 bit (long) contents (high bit 56), by inserting 0s between bits.
+ */
+ private static final long[] INTERLEAVE7_TABLE = new long[]
+ {
+ 0x0000000000000000L, 0x0000000000000001L, 0x0000000000000080L, 0x0000000000000081L,
+ 0x0000000000004000L, 0x0000000000004001L, 0x0000000000004080L, 0x0000000000004081L,
+ 0x0000000000200000L, 0x0000000000200001L, 0x0000000000200080L, 0x0000000000200081L,
+ 0x0000000000204000L, 0x0000000000204001L, 0x0000000000204080L, 0x0000000000204081L,
+ 0x0000000010000000L, 0x0000000010000001L, 0x0000000010000080L, 0x0000000010000081L,
+ 0x0000000010004000L, 0x0000000010004001L, 0x0000000010004080L, 0x0000000010004081L,
+ 0x0000000010200000L, 0x0000000010200001L, 0x0000000010200080L, 0x0000000010200081L,
+ 0x0000000010204000L, 0x0000000010204001L, 0x0000000010204080L, 0x0000000010204081L,
+ 0x0000000800000000L, 0x0000000800000001L, 0x0000000800000080L, 0x0000000800000081L,
+ 0x0000000800004000L, 0x0000000800004001L, 0x0000000800004080L, 0x0000000800004081L,
+ 0x0000000800200000L, 0x0000000800200001L, 0x0000000800200080L, 0x0000000800200081L,
+ 0x0000000800204000L, 0x0000000800204001L, 0x0000000800204080L, 0x0000000800204081L,
+ 0x0000000810000000L, 0x0000000810000001L, 0x0000000810000080L, 0x0000000810000081L,
+ 0x0000000810004000L, 0x0000000810004001L, 0x0000000810004080L, 0x0000000810004081L,
+ 0x0000000810200000L, 0x0000000810200001L, 0x0000000810200080L, 0x0000000810200081L,
+ 0x0000000810204000L, 0x0000000810204001L, 0x0000000810204080L, 0x0000000810204081L,
+ 0x0000040000000000L, 0x0000040000000001L, 0x0000040000000080L, 0x0000040000000081L,
+ 0x0000040000004000L, 0x0000040000004001L, 0x0000040000004080L, 0x0000040000004081L,
+ 0x0000040000200000L, 0x0000040000200001L, 0x0000040000200080L, 0x0000040000200081L,
+ 0x0000040000204000L, 0x0000040000204001L, 0x0000040000204080L, 0x0000040000204081L,
+ 0x0000040010000000L, 0x0000040010000001L, 0x0000040010000080L, 0x0000040010000081L,
+ 0x0000040010004000L, 0x0000040010004001L, 0x0000040010004080L, 0x0000040010004081L,
+ 0x0000040010200000L, 0x0000040010200001L, 0x0000040010200080L, 0x0000040010200081L,
+ 0x0000040010204000L, 0x0000040010204001L, 0x0000040010204080L, 0x0000040010204081L,
+ 0x0000040800000000L, 0x0000040800000001L, 0x0000040800000080L, 0x0000040800000081L,
+ 0x0000040800004000L, 0x0000040800004001L, 0x0000040800004080L, 0x0000040800004081L,
+ 0x0000040800200000L, 0x0000040800200001L, 0x0000040800200080L, 0x0000040800200081L,
+ 0x0000040800204000L, 0x0000040800204001L, 0x0000040800204080L, 0x0000040800204081L,
+ 0x0000040810000000L, 0x0000040810000001L, 0x0000040810000080L, 0x0000040810000081L,
+ 0x0000040810004000L, 0x0000040810004001L, 0x0000040810004080L, 0x0000040810004081L,
+ 0x0000040810200000L, 0x0000040810200001L, 0x0000040810200080L, 0x0000040810200081L,
+ 0x0000040810204000L, 0x0000040810204001L, 0x0000040810204080L, 0x0000040810204081L,
+ 0x0002000000000000L, 0x0002000000000001L, 0x0002000000000080L, 0x0002000000000081L,
+ 0x0002000000004000L, 0x0002000000004001L, 0x0002000000004080L, 0x0002000000004081L,
+ 0x0002000000200000L, 0x0002000000200001L, 0x0002000000200080L, 0x0002000000200081L,
+ 0x0002000000204000L, 0x0002000000204001L, 0x0002000000204080L, 0x0002000000204081L,
+ 0x0002000010000000L, 0x0002000010000001L, 0x0002000010000080L, 0x0002000010000081L,
+ 0x0002000010004000L, 0x0002000010004001L, 0x0002000010004080L, 0x0002000010004081L,
+ 0x0002000010200000L, 0x0002000010200001L, 0x0002000010200080L, 0x0002000010200081L,
+ 0x0002000010204000L, 0x0002000010204001L, 0x0002000010204080L, 0x0002000010204081L,
+ 0x0002000800000000L, 0x0002000800000001L, 0x0002000800000080L, 0x0002000800000081L,
+ 0x0002000800004000L, 0x0002000800004001L, 0x0002000800004080L, 0x0002000800004081L,
+ 0x0002000800200000L, 0x0002000800200001L, 0x0002000800200080L, 0x0002000800200081L,
+ 0x0002000800204000L, 0x0002000800204001L, 0x0002000800204080L, 0x0002000800204081L,
+ 0x0002000810000000L, 0x0002000810000001L, 0x0002000810000080L, 0x0002000810000081L,
+ 0x0002000810004000L, 0x0002000810004001L, 0x0002000810004080L, 0x0002000810004081L,
+ 0x0002000810200000L, 0x0002000810200001L, 0x0002000810200080L, 0x0002000810200081L,
+ 0x0002000810204000L, 0x0002000810204001L, 0x0002000810204080L, 0x0002000810204081L,
+ 0x0002040000000000L, 0x0002040000000001L, 0x0002040000000080L, 0x0002040000000081L,
+ 0x0002040000004000L, 0x0002040000004001L, 0x0002040000004080L, 0x0002040000004081L,
+ 0x0002040000200000L, 0x0002040000200001L, 0x0002040000200080L, 0x0002040000200081L,
+ 0x0002040000204000L, 0x0002040000204001L, 0x0002040000204080L, 0x0002040000204081L,
+ 0x0002040010000000L, 0x0002040010000001L, 0x0002040010000080L, 0x0002040010000081L,
+ 0x0002040010004000L, 0x0002040010004001L, 0x0002040010004080L, 0x0002040010004081L,
+ 0x0002040010200000L, 0x0002040010200001L, 0x0002040010200080L, 0x0002040010200081L,
+ 0x0002040010204000L, 0x0002040010204001L, 0x0002040010204080L, 0x0002040010204081L,
+ 0x0002040800000000L, 0x0002040800000001L, 0x0002040800000080L, 0x0002040800000081L,
+ 0x0002040800004000L, 0x0002040800004001L, 0x0002040800004080L, 0x0002040800004081L,
+ 0x0002040800200000L, 0x0002040800200001L, 0x0002040800200080L, 0x0002040800200081L,
+ 0x0002040800204000L, 0x0002040800204001L, 0x0002040800204080L, 0x0002040800204081L,
+ 0x0002040810000000L, 0x0002040810000001L, 0x0002040810000080L, 0x0002040810000081L,
+ 0x0002040810004000L, 0x0002040810004001L, 0x0002040810004080L, 0x0002040810004081L,
+ 0x0002040810200000L, 0x0002040810200001L, 0x0002040810200080L, 0x0002040810200081L,
+ 0x0002040810204000L, 0x0002040810204001L, 0x0002040810204080L, 0x0002040810204081L,
+ 0x0100000000000000L, 0x0100000000000001L, 0x0100000000000080L, 0x0100000000000081L,
+ 0x0100000000004000L, 0x0100000000004001L, 0x0100000000004080L, 0x0100000000004081L,
+ 0x0100000000200000L, 0x0100000000200001L, 0x0100000000200080L, 0x0100000000200081L,
+ 0x0100000000204000L, 0x0100000000204001L, 0x0100000000204080L, 0x0100000000204081L,
+ 0x0100000010000000L, 0x0100000010000001L, 0x0100000010000080L, 0x0100000010000081L,
+ 0x0100000010004000L, 0x0100000010004001L, 0x0100000010004080L, 0x0100000010004081L,
+ 0x0100000010200000L, 0x0100000010200001L, 0x0100000010200080L, 0x0100000010200081L,
+ 0x0100000010204000L, 0x0100000010204001L, 0x0100000010204080L, 0x0100000010204081L,
+ 0x0100000800000000L, 0x0100000800000001L, 0x0100000800000080L, 0x0100000800000081L,
+ 0x0100000800004000L, 0x0100000800004001L, 0x0100000800004080L, 0x0100000800004081L,
+ 0x0100000800200000L, 0x0100000800200001L, 0x0100000800200080L, 0x0100000800200081L,
+ 0x0100000800204000L, 0x0100000800204001L, 0x0100000800204080L, 0x0100000800204081L,
+ 0x0100000810000000L, 0x0100000810000001L, 0x0100000810000080L, 0x0100000810000081L,
+ 0x0100000810004000L, 0x0100000810004001L, 0x0100000810004080L, 0x0100000810004081L,
+ 0x0100000810200000L, 0x0100000810200001L, 0x0100000810200080L, 0x0100000810200081L,
+ 0x0100000810204000L, 0x0100000810204001L, 0x0100000810204080L, 0x0100000810204081L,
+ 0x0100040000000000L, 0x0100040000000001L, 0x0100040000000080L, 0x0100040000000081L,
+ 0x0100040000004000L, 0x0100040000004001L, 0x0100040000004080L, 0x0100040000004081L,
+ 0x0100040000200000L, 0x0100040000200001L, 0x0100040000200080L, 0x0100040000200081L,
+ 0x0100040000204000L, 0x0100040000204001L, 0x0100040000204080L, 0x0100040000204081L,
+ 0x0100040010000000L, 0x0100040010000001L, 0x0100040010000080L, 0x0100040010000081L,
+ 0x0100040010004000L, 0x0100040010004001L, 0x0100040010004080L, 0x0100040010004081L,
+ 0x0100040010200000L, 0x0100040010200001L, 0x0100040010200080L, 0x0100040010200081L,
+ 0x0100040010204000L, 0x0100040010204001L, 0x0100040010204080L, 0x0100040010204081L,
+ 0x0100040800000000L, 0x0100040800000001L, 0x0100040800000080L, 0x0100040800000081L,
+ 0x0100040800004000L, 0x0100040800004001L, 0x0100040800004080L, 0x0100040800004081L,
+ 0x0100040800200000L, 0x0100040800200001L, 0x0100040800200080L, 0x0100040800200081L,
+ 0x0100040800204000L, 0x0100040800204001L, 0x0100040800204080L, 0x0100040800204081L,
+ 0x0100040810000000L, 0x0100040810000001L, 0x0100040810000080L, 0x0100040810000081L,
+ 0x0100040810004000L, 0x0100040810004001L, 0x0100040810004080L, 0x0100040810004081L,
+ 0x0100040810200000L, 0x0100040810200001L, 0x0100040810200080L, 0x0100040810200081L,
+ 0x0100040810204000L, 0x0100040810204001L, 0x0100040810204080L, 0x0100040810204081L,
+ 0x0102000000000000L, 0x0102000000000001L, 0x0102000000000080L, 0x0102000000000081L,
+ 0x0102000000004000L, 0x0102000000004001L, 0x0102000000004080L, 0x0102000000004081L,
+ 0x0102000000200000L, 0x0102000000200001L, 0x0102000000200080L, 0x0102000000200081L,
+ 0x0102000000204000L, 0x0102000000204001L, 0x0102000000204080L, 0x0102000000204081L,
+ 0x0102000010000000L, 0x0102000010000001L, 0x0102000010000080L, 0x0102000010000081L,
+ 0x0102000010004000L, 0x0102000010004001L, 0x0102000010004080L, 0x0102000010004081L,
+ 0x0102000010200000L, 0x0102000010200001L, 0x0102000010200080L, 0x0102000010200081L,
+ 0x0102000010204000L, 0x0102000010204001L, 0x0102000010204080L, 0x0102000010204081L,
+ 0x0102000800000000L, 0x0102000800000001L, 0x0102000800000080L, 0x0102000800000081L,
+ 0x0102000800004000L, 0x0102000800004001L, 0x0102000800004080L, 0x0102000800004081L,
+ 0x0102000800200000L, 0x0102000800200001L, 0x0102000800200080L, 0x0102000800200081L,
+ 0x0102000800204000L, 0x0102000800204001L, 0x0102000800204080L, 0x0102000800204081L,
+ 0x0102000810000000L, 0x0102000810000001L, 0x0102000810000080L, 0x0102000810000081L,
+ 0x0102000810004000L, 0x0102000810004001L, 0x0102000810004080L, 0x0102000810004081L,
+ 0x0102000810200000L, 0x0102000810200001L, 0x0102000810200080L, 0x0102000810200081L,
+ 0x0102000810204000L, 0x0102000810204001L, 0x0102000810204080L, 0x0102000810204081L,
+ 0x0102040000000000L, 0x0102040000000001L, 0x0102040000000080L, 0x0102040000000081L,
+ 0x0102040000004000L, 0x0102040000004001L, 0x0102040000004080L, 0x0102040000004081L,
+ 0x0102040000200000L, 0x0102040000200001L, 0x0102040000200080L, 0x0102040000200081L,
+ 0x0102040000204000L, 0x0102040000204001L, 0x0102040000204080L, 0x0102040000204081L,
+ 0x0102040010000000L, 0x0102040010000001L, 0x0102040010000080L, 0x0102040010000081L,
+ 0x0102040010004000L, 0x0102040010004001L, 0x0102040010004080L, 0x0102040010004081L,
+ 0x0102040010200000L, 0x0102040010200001L, 0x0102040010200080L, 0x0102040010200081L,
+ 0x0102040010204000L, 0x0102040010204001L, 0x0102040010204080L, 0x0102040010204081L,
+ 0x0102040800000000L, 0x0102040800000001L, 0x0102040800000080L, 0x0102040800000081L,
+ 0x0102040800004000L, 0x0102040800004001L, 0x0102040800004080L, 0x0102040800004081L,
+ 0x0102040800200000L, 0x0102040800200001L, 0x0102040800200080L, 0x0102040800200081L,
+ 0x0102040800204000L, 0x0102040800204001L, 0x0102040800204080L, 0x0102040800204081L,
+ 0x0102040810000000L, 0x0102040810000001L, 0x0102040810000080L, 0x0102040810000081L,
+ 0x0102040810004000L, 0x0102040810004001L, 0x0102040810004080L, 0x0102040810004081L,
+ 0x0102040810200000L, 0x0102040810200001L, 0x0102040810200080L, 0x0102040810200081L,
+ 0x0102040810204000L, 0x0102040810204001L, 0x0102040810204080L, 0x0102040810204081L
+ };
+
+ // For toString(); must have length 64
+ private static final String ZEROES = "0000000000000000000000000000000000000000000000000000000000000000";
+
+ final static byte[] bitLengths =
+ {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
+ };
+
+ // TODO make m fixed for the LongArray, and hence compute T once and for all
+
+ private long[] m_ints;
+
+ public LongArray(int intLen)
+ {
+ m_ints = new long[intLen];
+ }
+
+ public LongArray(long[] ints)
+ {
+ m_ints = ints;
+ }
+
+ public LongArray(long[] ints, int off, int len)
+ {
+ if (off == 0 && len == ints.length)
+ {
+ m_ints = ints;
+ }
+ else
+ {
+ m_ints = new long[len];
+ System.arraycopy(ints, off, m_ints, 0, len);
+ }
+ }
+
+ public LongArray(BigInteger bigInt)
+ {
+ if (bigInt == null || bigInt.signum() < 0)
+ {
+ throw new IllegalArgumentException("invalid F2m field value");
+ }
+
+ if (bigInt.signum() == 0)
+ {
+ m_ints = new long[] { 0L };
+ return;
+ }
+
+ byte[] barr = bigInt.toByteArray();
+ int barrLen = barr.length;
+ int barrStart = 0;
+ if (barr[0] == 0)
+ {
+ // First byte is 0 to enforce highest (=sign) bit is zero.
+ // In this case ignore barr[0].
+ barrLen--;
+ barrStart = 1;
+ }
+ int intLen = (barrLen + 7) / 8;
+ m_ints = new long[intLen];
+
+ int iarrJ = intLen - 1;
+ int rem = barrLen % 8 + barrStart;
+ long temp = 0;
+ int barrI = barrStart;
+ if (barrStart < rem)
+ {
+ for (; barrI < rem; barrI++)
+ {
+ temp <<= 8;
+ int barrBarrI = barr[barrI] & 0xFF;
+ temp |= barrBarrI;
+ }
+ m_ints[iarrJ--] = temp;
+ }
+
+ for (; iarrJ >= 0; iarrJ--)
+ {
+ temp = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ temp <<= 8;
+ int barrBarrI = barr[barrI++] & 0xFF;
+ temp |= barrBarrI;
+ }
+ m_ints[iarrJ] = temp;
+ }
+ }
+
+ void copyTo(long[] z, int zOff)
+ {
+ System.arraycopy(m_ints, 0, z, zOff, m_ints.length);
+ }
+
+ public boolean isOne()
+ {
+ long[] a = m_ints;
+ if (a[0] != 1L)
+ {
+ return false;
+ }
+ for (int i = 1; i < a.length; ++i)
+ {
+ if (a[i] != 0L)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean isZero()
+ {
+ long[] a = m_ints;
+ for (int i = 0; i < a.length; ++i)
+ {
+ if (a[i] != 0L)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public int getUsedLength()
+ {
+ return getUsedLengthFrom(m_ints.length);
+ }
+
+ public int getUsedLengthFrom(int from)
+ {
+ long[] a = m_ints;
+ from = Math.min(from, a.length);
+
+ if (from < 1)
+ {
+ return 0;
+ }
+
+ // Check if first element will act as sentinel
+ if (a[0] != 0)
+ {
+ while (a[--from] == 0)
+ {
+ }
+ return from + 1;
+ }
+
+ do
+ {
+ if (a[--from] != 0)
+ {
+ return from + 1;
+ }
+ }
+ while (from > 0);
+
+ return 0;
+ }
+
+ public int degree()
+ {
+ int i = m_ints.length;
+ long w;
+ do
+ {
+ if (i == 0)
+ {
+ return 0;
+ }
+ w = m_ints[--i];
+ }
+ while (w == 0);
+
+ return (i << 6) + bitLength(w);
+ }
+
+ private int degreeFrom(int limit)
+ {
+ int i = (limit + 62) >>> 6;
+ long w;
+ do
+ {
+ if (i == 0)
+ {
+ return 0;
+ }
+ w = m_ints[--i];
+ }
+ while (w == 0);
+
+ return (i << 6) + bitLength(w);
+ }
+
+// private int lowestCoefficient()
+// {
+// for (int i = 0; i < m_ints.length; ++i)
+// {
+// long mi = m_ints[i];
+// if (mi != 0)
+// {
+// int j = 0;
+// while ((mi & 0xFFL) == 0)
+// {
+// j += 8;
+// mi >>>= 8;
+// }
+// while ((mi & 1L) == 0)
+// {
+// ++j;
+// mi >>>= 1;
+// }
+// return (i << 6) + j;
+// }
+// }
+// return -1;
+// }
+
+ private static int bitLength(long w)
+ {
+ int u = (int)(w >>> 32), b;
+ if (u == 0)
+ {
+ u = (int)w;
+ b = 0;
+ }
+ else
+ {
+ b = 32;
+ }
+
+ int t = u >>> 16, k;
+ if (t == 0)
+ {
+ t = u >>> 8;
+ k = (t == 0) ? bitLengths[u] : 8 + bitLengths[t];
+ }
+ else
+ {
+ int v = t >>> 8;
+ k = (v == 0) ? 16 + bitLengths[t] : 24 + bitLengths[v];
+ }
+
+ return b + k;
+ }
+
+ private long[] resizedInts(int newLen)
+ {
+ long[] newInts = new long[newLen];
+ System.arraycopy(m_ints, 0, newInts, 0, Math.min(m_ints.length, newLen));
+ return newInts;
+ }
+
+ public BigInteger toBigInteger()
+ {
+ int usedLen = getUsedLength();
+ if (usedLen == 0)
+ {
+ return ECConstants.ZERO;
+ }
+
+ long highestInt = m_ints[usedLen - 1];
+ byte[] temp = new byte[8];
+ int barrI = 0;
+ boolean trailingZeroBytesDone = false;
+ for (int j = 7; j >= 0; j--)
+ {
+ byte thisByte = (byte)(highestInt >>> (8 * j));
+ if (trailingZeroBytesDone || (thisByte != 0))
+ {
+ trailingZeroBytesDone = true;
+ temp[barrI++] = thisByte;
+ }
+ }
+
+ int barrLen = 8 * (usedLen - 1) + barrI;
+ byte[] barr = new byte[barrLen];
+ for (int j = 0; j < barrI; j++)
+ {
+ barr[j] = temp[j];
+ }
+ // Highest value int is done now
+
+ for (int iarrJ = usedLen - 2; iarrJ >= 0; iarrJ--)
+ {
+ long mi = m_ints[iarrJ];
+ for (int j = 7; j >= 0; j--)
+ {
+ barr[barrI++] = (byte)(mi >>> (8 * j));
+ }
+ }
+ return new BigInteger(1, barr);
+ }
+
+// private static long shiftUp(long[] x, int xOff, int count)
+// {
+// long prev = 0;
+// for (int i = 0; i < count; ++i)
+// {
+// long next = x[xOff + i];
+// x[xOff + i] = (next << 1) | prev;
+// prev = next >>> 63;
+// }
+// return prev;
+// }
+
+ private static long shiftUp(long[] x, int xOff, int count, int shift)
+ {
+ int shiftInv = 64 - shift;
+ long prev = 0;
+ for (int i = 0; i < count; ++i)
+ {
+ long next = x[xOff + i];
+ x[xOff + i] = (next << shift) | prev;
+ prev = next >>> shiftInv;
+ }
+ return prev;
+ }
+
+ private static long shiftUp(long[] x, int xOff, long[] z, int zOff, int count, int shift)
+ {
+ int shiftInv = 64 - shift;
+ long prev = 0;
+ for (int i = 0; i < count; ++i)
+ {
+ long next = x[xOff + i];
+ z[zOff + i] = (next << shift) | prev;
+ prev = next >>> shiftInv;
+ }
+ return prev;
+ }
+
+ public LongArray addOne()
+ {
+ if (m_ints.length == 0)
+ {
+ return new LongArray(new long[]{ 1L });
+ }
+
+ int resultLen = Math.max(1, getUsedLength());
+ long[] ints = resizedInts(resultLen);
+ ints[0] ^= 1L;
+ return new LongArray(ints);
+ }
+
+// private void addShiftedByBits(LongArray other, int bits)
+// {
+// int words = bits >>> 6;
+// int shift = bits & 0x3F;
+//
+// if (shift == 0)
+// {
+// addShiftedByWords(other, words);
+// return;
+// }
+//
+// int otherUsedLen = other.getUsedLength();
+// if (otherUsedLen == 0)
+// {
+// return;
+// }
+//
+// int minLen = otherUsedLen + words + 1;
+// if (minLen > m_ints.length)
+// {
+// m_ints = resizedInts(minLen);
+// }
+//
+// long carry = addShiftedByBits(m_ints, words, other.m_ints, 0, otherUsedLen, shift);
+// m_ints[otherUsedLen + words] ^= carry;
+// }
+
+ private void addShiftedByBitsSafe(LongArray other, int otherDegree, int bits)
+ {
+ int otherLen = (otherDegree + 63) >>> 6;
+
+ int words = bits >>> 6;
+ int shift = bits & 0x3F;
+
+ if (shift == 0)
+ {
+ add(m_ints, words, other.m_ints, 0, otherLen);
+ return;
+ }
+
+ long carry = addShiftedUp(m_ints, words, other.m_ints, 0, otherLen, shift);
+ if (carry != 0L)
+ {
+ m_ints[otherLen + words] ^= carry;
+ }
+ }
+
+ private static long addShiftedUp(long[] x, int xOff, long[] y, int yOff, int count, int shift)
+ {
+ int shiftInv = 64 - shift;
+ long prev = 0;
+ for (int i = 0; i < count; ++i)
+ {
+ long next = y[yOff + i];
+ x[xOff + i] ^= (next << shift) | prev;
+ prev = next >>> shiftInv;
+ }
+ return prev;
+ }
+
+ private static long addShiftedDown(long[] x, int xOff, long[] y, int yOff, int count, int shift)
+ {
+ int shiftInv = 64 - shift;
+ long prev = 0;
+ int i = count;
+ while (--i >= 0)
+ {
+ long next = y[yOff + i];
+ x[xOff + i] ^= (next >>> shift) | prev;
+ prev = next << shiftInv;
+ }
+ return prev;
+ }
+
+ public void addShiftedByWords(LongArray other, int words)
+ {
+ int otherUsedLen = other.getUsedLength();
+ if (otherUsedLen == 0)
+ {
+ return;
+ }
+
+ int minLen = otherUsedLen + words;
+ if (minLen > m_ints.length)
+ {
+ m_ints = resizedInts(minLen);
+ }
+
+ add(m_ints, words, other.m_ints, 0, otherUsedLen);
+ }
+
+ private static void add(long[] x, int xOff, long[] y, int yOff, int count)
+ {
+ for (int i = 0; i < count; ++i)
+ {
+ x[xOff + i] ^= y[yOff + i];
+ }
+ }
+
+ private static void add(long[] x, int xOff, long[] y, int yOff, long[] z, int zOff, int count)
+ {
+ for (int i = 0; i < count; ++i)
+ {
+ z[zOff + i] = x[xOff + i] ^ y[yOff + i];
+ }
+ }
+
+ private static void addBoth(long[] x, int xOff, long[] y1, int y1Off, long[] y2, int y2Off, int count)
+ {
+ for (int i = 0; i < count; ++i)
+ {
+ x[xOff + i] ^= y1[y1Off + i] ^ y2[y2Off + i];
+ }
+ }
+
+ private static void distribute(long[] x, int src, int dst1, int dst2, int count)
+ {
+ for (int i = 0; i < count; ++i)
+ {
+ long v = x[src + i];
+ x[dst1 + i] ^= v;
+ x[dst2 + i] ^= v;
+ }
+ }
+
+ public int getLength()
+ {
+ return m_ints.length;
+ }
+
+ private static void flipWord(long[] buf, int off, int bit, long word)
+ {
+ int n = off + (bit >>> 6);
+ int shift = bit & 0x3F;
+ if (shift == 0)
+ {
+ buf[n] ^= word;
+ }
+ else
+ {
+ buf[n] ^= word << shift;
+ word >>>= (64 - shift);
+ if (word != 0)
+ {
+ buf[++n] ^= word;
+ }
+ }
+ }
+
+// private static long getWord(long[] buf, int off, int len, int bit)
+// {
+// int n = off + (bit >>> 6);
+// int shift = bit & 0x3F;
+// if (shift == 0)
+// {
+// return buf[n];
+// }
+// long result = buf[n] >>> shift;
+// if (++n < len)
+// {
+// result |= buf[n] << (64 - shift);
+// }
+// return result;
+// }
+
+ public boolean testBitZero()
+ {
+ return m_ints.length > 0 && (m_ints[0] & 1L) != 0;
+ }
+
+ private static boolean testBit(long[] buf, int off, int n)
+ {
+ // theInt = n / 64
+ int theInt = n >>> 6;
+ // theBit = n % 64
+ int theBit = n & 0x3F;
+ long tester = 1L << theBit;
+ return (buf[off + theInt] & tester) != 0;
+ }
+
+ private static void flipBit(long[] buf, int off, int n)
+ {
+ // theInt = n / 64
+ int theInt = n >>> 6;
+ // theBit = n % 64
+ int theBit = n & 0x3F;
+ long flipper = 1L << theBit;
+ buf[off + theInt] ^= flipper;
+ }
+
+// private static void setBit(long[] buf, int off, int n)
+// {
+// // theInt = n / 64
+// int theInt = n >>> 6;
+// // theBit = n % 64
+// int theBit = n & 0x3F;
+// long setter = 1L << theBit;
+// buf[off + theInt] |= setter;
+// }
+//
+// private static void clearBit(long[] buf, int off, int n)
+// {
+// // theInt = n / 64
+// int theInt = n >>> 6;
+// // theBit = n % 64
+// int theBit = n & 0x3F;
+// long setter = 1L << theBit;
+// buf[off + theInt] &= ~setter;
+// }
+
+ private static void multiplyWord(long a, long[] b, int bLen, long[] c, int cOff)
+ {
+ if ((a & 1L) != 0L)
+ {
+ add(c, cOff, b, 0, bLen);
+ }
+ int k = 1;
+ while ((a >>>= 1) != 0L)
+ {
+ if ((a & 1L) != 0L)
+ {
+ long carry = addShiftedUp(c, cOff, b, 0, bLen, k);
+ if (carry != 0L)
+ {
+ c[cOff + bLen] ^= carry;
+ }
+ }
+ ++k;
+ }
+ }
+
+ public LongArray modMultiplyLD(LongArray other, int m, int[] ks)
+ {
+ /*
+ * Find out the degree of each argument and handle the zero cases
+ */
+ int aDeg = degree();
+ if (aDeg == 0)
+ {
+ return this;
+ }
+ int bDeg = other.degree();
+ if (bDeg == 0)
+ {
+ return other;
+ }
+
+ /*
+ * Swap if necessary so that A is the smaller argument
+ */
+ LongArray A = this, B = other;
+ if (aDeg > bDeg)
+ {
+ A = other; B = this;
+ int tmp = aDeg; aDeg = bDeg; bDeg = tmp;
+ }
+
+ /*
+ * Establish the word lengths of the arguments and result
+ */
+ int aLen = (aDeg + 63) >>> 6;
+ int bLen = (bDeg + 63) >>> 6;
+ int cLen = (aDeg + bDeg + 62) >>> 6;
+
+ if (aLen == 1)
+ {
+ long a0 = A.m_ints[0];
+ if (a0 == 1L)
+ {
+ return B;
+ }
+
+ /*
+ * Fast path for small A, with performance dependent only on the number of set bits
+ */
+ long[] c0 = new long[cLen];
+ multiplyWord(a0, B.m_ints, bLen, c0, 0);
+
+ /*
+ * Reduce the raw answer against the reduction coefficients
+ */
+ return reduceResult(c0, 0, cLen, m, ks);
+ }
+
+ /*
+ * Determine if B will get bigger during shifting
+ */
+ int bMax = (bDeg + 7 + 63) >>> 6;
+
+ /*
+ * Lookup table for the offset of each B in the tables
+ */
+ int[] ti = new int[16];
+
+ /*
+ * Precompute table of all 4-bit products of B
+ */
+ long[] T0 = new long[bMax << 4];
+ int tOff = bMax;
+ ti[1] = tOff;
+ System.arraycopy(B.m_ints, 0, T0, tOff, bLen);
+ for (int i = 2; i < 16; ++i)
+ {
+ ti[i] = (tOff += bMax);
+ if ((i & 1) == 0)
+ {
+ shiftUp(T0, tOff >>> 1, T0, tOff, bMax, 1);
+ }
+ else
+ {
+ add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax);
+ }
+ }
+
+ /*
+ * Second table with all 4-bit products of B shifted 4 bits
+ */
+ long[] T1 = new long[T0.length];
+ shiftUp(T0, 0, T1, 0, T0.length, 4);
+// shiftUp(T0, bMax, T1, bMax, tOff, 4);
+
+ long[] a = A.m_ints;
+ long[] c = new long[cLen];
+
+ int MASK = 0xF;
+
+ /*
+ * Lopez-Dahab algorithm
+ */
+
+ for (int k = 56; k >= 0; k -= 8)
+ {
+ for (int j = 1; j < aLen; j += 2)
+ {
+ int aVal = (int)(a[j] >>> k);
+ int u = aVal & MASK;
+ int v = (aVal >>> 4) & MASK;
+ addBoth(c, j - 1, T0, ti[u], T1, ti[v], bMax);
+ }
+ shiftUp(c, 0, cLen, 8);
+ }
+
+ for (int k = 56; k >= 0; k -= 8)
+ {
+ for (int j = 0; j < aLen; j += 2)
+ {
+ int aVal = (int)(a[j] >>> k);
+ int u = aVal & MASK;
+ int v = (aVal >>> 4) & MASK;
+ addBoth(c, j, T0, ti[u], T1, ti[v], bMax);
+ }
+ if (k > 0)
+ {
+ shiftUp(c, 0, cLen, 8);
+ }
+ }
+
+ /*
+ * Finally the raw answer is collected, reduce it against the reduction coefficients
+ */
+ return reduceResult(c, 0, cLen, m, ks);
+ }
+
+ public LongArray modMultiply(LongArray other, int m, int[] ks)
+ {
+ /*
+ * Find out the degree of each argument and handle the zero cases
+ */
+ int aDeg = degree();
+ if (aDeg == 0)
+ {
+ return this;
+ }
+ int bDeg = other.degree();
+ if (bDeg == 0)
+ {
+ return other;
+ }
+
+ /*
+ * Swap if necessary so that A is the smaller argument
+ */
+ LongArray A = this, B = other;
+ if (aDeg > bDeg)
+ {
+ A = other; B = this;
+ int tmp = aDeg; aDeg = bDeg; bDeg = tmp;
+ }
+
+ /*
+ * Establish the word lengths of the arguments and result
+ */
+ int aLen = (aDeg + 63) >>> 6;
+ int bLen = (bDeg + 63) >>> 6;
+ int cLen = (aDeg + bDeg + 62) >>> 6;
+
+ if (aLen == 1)
+ {
+ long a0 = A.m_ints[0];
+ if (a0 == 1L)
+ {
+ return B;
+ }
+
+ /*
+ * Fast path for small A, with performance dependent only on the number of set bits
+ */
+ long[] c0 = new long[cLen];
+ multiplyWord(a0, B.m_ints, bLen, c0, 0);
+
+ /*
+ * Reduce the raw answer against the reduction coefficients
+ */
+ return reduceResult(c0, 0, cLen, m, ks);
+ }
+
+ /*
+ * Determine if B will get bigger during shifting
+ */
+ int bMax = (bDeg + 7 + 63) >>> 6;
+
+ /*
+ * Lookup table for the offset of each B in the tables
+ */
+ int[] ti = new int[16];
+
+ /*
+ * Precompute table of all 4-bit products of B
+ */
+ long[] T0 = new long[bMax << 4];
+ int tOff = bMax;
+ ti[1] = tOff;
+ System.arraycopy(B.m_ints, 0, T0, tOff, bLen);
+ for (int i = 2; i < 16; ++i)
+ {
+ ti[i] = (tOff += bMax);
+ if ((i & 1) == 0)
+ {
+ shiftUp(T0, tOff >>> 1, T0, tOff, bMax, 1);
+ }
+ else
+ {
+ add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax);
+ }
+ }
+
+ /*
+ * Second table with all 4-bit products of B shifted 4 bits
+ */
+ long[] T1 = new long[T0.length];
+ shiftUp(T0, 0, T1, 0, T0.length, 4);
+// shiftUp(T0, bMax, T1, bMax, tOff, 4);
+
+ long[] a = A.m_ints;
+ long[] c = new long[cLen << 3];
+
+ int MASK = 0xF;
+
+ /*
+ * Lopez-Dahab (Modified) algorithm
+ */
+
+ for (int aPos = 0; aPos < aLen; ++aPos)
+ {
+ long aVal = a[aPos];
+ int cOff = aPos;
+ for (;;)
+ {
+ int u = (int)aVal & MASK;
+ aVal >>>= 4;
+ int v = (int)aVal & MASK;
+ addBoth(c, cOff, T0, ti[u], T1, ti[v], bMax);
+ aVal >>>= 4;
+ if (aVal == 0L)
+ {
+ break;
+ }
+ cOff += cLen;
+ }
+ }
+
+ {
+ int cOff = c.length;
+ while ((cOff -= cLen) != 0)
+ {
+ addShiftedUp(c, cOff - cLen, c, cOff, cLen, 8);
+ }
+ }
+
+ /*
+ * Finally the raw answer is collected, reduce it against the reduction coefficients
+ */
+ return reduceResult(c, 0, cLen, m, ks);
+ }
+
+ public LongArray modMultiplyAlt(LongArray other, int m, int[] ks)
+ {
+ /*
+ * Find out the degree of each argument and handle the zero cases
+ */
+ int aDeg = degree();
+ if (aDeg == 0)
+ {
+ return this;
+ }
+ int bDeg = other.degree();
+ if (bDeg == 0)
+ {
+ return other;
+ }
+
+ /*
+ * Swap if necessary so that A is the smaller argument
+ */
+ LongArray A = this, B = other;
+ if (aDeg > bDeg)
+ {
+ A = other; B = this;
+ int tmp = aDeg; aDeg = bDeg; bDeg = tmp;
+ }
+
+ /*
+ * Establish the word lengths of the arguments and result
+ */
+ int aLen = (aDeg + 63) >>> 6;
+ int bLen = (bDeg + 63) >>> 6;
+ int cLen = (aDeg + bDeg + 62) >>> 6;
+
+ if (aLen == 1)
+ {
+ long a0 = A.m_ints[0];
+ if (a0 == 1L)
+ {
+ return B;
+ }
+
+ /*
+ * Fast path for small A, with performance dependent only on the number of set bits
+ */
+ long[] c0 = new long[cLen];
+ multiplyWord(a0, B.m_ints, bLen, c0, 0);
+
+ /*
+ * Reduce the raw answer against the reduction coefficients
+ */
+ return reduceResult(c0, 0, cLen, m, ks);
+ }
+
+ // NOTE: This works, but is slower than width 4 processing
+// if (aLen == 2)
+// {
+// /*
+// * Use common-multiplicand optimization to save ~1/4 of the adds
+// */
+// long a1 = A.m_ints[0], a2 = A.m_ints[1];
+// long aa = a1 & a2; a1 ^= aa; a2 ^= aa;
+//
+// long[] b = B.m_ints;
+// long[] c = new long[cLen];
+// multiplyWord(aa, b, bLen, c, 1);
+// add(c, 0, c, 1, cLen - 1);
+// multiplyWord(a1, b, bLen, c, 0);
+// multiplyWord(a2, b, bLen, c, 1);
+//
+// /*
+// * Reduce the raw answer against the reduction coefficients
+// */
+// return reduceResult(c, 0, cLen, m, ks);
+// }
+
+ /*
+ * Determine the parameters of the interleaved window algorithm: the 'width' in bits to
+ * process together, the number of evaluation 'positions' implied by that width, and the
+ * 'top' position at which the regular window algorithm stops.
+ */
+ int width, positions, top, banks;
+
+ // NOTE: width 4 is the fastest over the entire range of sizes used in current crypto
+// width = 1; positions = 64; top = 64; banks = 4;
+// width = 2; positions = 32; top = 64; banks = 4;
+// width = 3; positions = 21; top = 63; banks = 3;
+ width = 4; positions = 16; top = 64; banks = 8;
+// width = 5; positions = 13; top = 65; banks = 7;
+// width = 7; positions = 9; top = 63; banks = 9;
+// width = 8; positions = 8; top = 64; banks = 8;
+
+ /*
+ * Determine if B will get bigger during shifting
+ */
+ int shifts = top < 64 ? positions : positions - 1;
+ int bMax = (bDeg + shifts + 63) >>> 6;
+
+ int bTotal = bMax * banks, stride = width * banks;
+
+ /*
+ * Create a single temporary buffer, with an offset table to find the positions of things in it
+ */
+ int[] ci = new int[1 << width];
+ int cTotal = aLen;
+ {
+ ci[0] = cTotal;
+ cTotal += bTotal;
+ ci[1] = cTotal;
+ for (int i = 2; i < ci.length; ++i)
+ {
+ cTotal += cLen;
+ ci[i] = cTotal;
+ }
+ cTotal += cLen;
+ }
+ // NOTE: Provide a safe dump for "high zeroes" since we are adding 'bMax' and not 'bLen'
+ ++cTotal;
+
+ long[] c = new long[cTotal];
+
+ // Prepare A in interleaved form, according to the chosen width
+ interleave(A.m_ints, 0, c, 0, aLen, width);
+
+ // Make a working copy of B, since we will be shifting it
+ {
+ int bOff = aLen;
+ System.arraycopy(B.m_ints, 0, c, bOff, bLen);
+ for (int bank = 1; bank < banks; ++bank)
+ {
+ shiftUp(c, aLen, c, bOff += bMax, bMax, bank);
+ }
+ }
+
+ /*
+ * The main loop analyzes the interleaved windows in A, and for each non-zero window
+ * a single word-array XOR is performed to a carefully selected slice of 'c'. The loop is
+ * breadth-first, checking the lowest window in each word, then looping again for the
+ * next higher window position.
+ */
+ int MASK = (1 << width) - 1;
+
+ int k = 0;
+ for (;;)
+ {
+ int aPos = 0;
+ do
+ {
+ long aVal = c[aPos] >>> k;
+ int bank = 0, bOff = aLen;
+ for (;;)
+ {
+ int index = (int)(aVal) & MASK;
+ if (index != 0)
+ {
+ /*
+ * Add to a 'c' buffer based on the bit-pattern of 'index'. Since A is in
+ * interleaved form, the bits represent the current B shifted by 0, 'positions',
+ * 'positions' * 2, ..., 'positions' * ('width' - 1)
+ */
+ add(c, aPos + ci[index], c, bOff, bMax);
+ }
+ if (++bank == banks)
+ {
+ break;
+ }
+ bOff += bMax;
+ aVal >>>= width;
+ }
+ }
+ while (++aPos < aLen);
+
+ if ((k += stride) >= top)
+ {
+ if (k >= 64)
+ {
+ break;
+ }
+
+ /*
+ * Adjustment for window setups with top == 63, the final bit (if any) is processed
+ * as the top-bit of a window
+ */
+ k = 64 - width;
+ MASK &= MASK << (top - k);
+ }
+
+ /*
+ * After each position has been checked for all words of A, B is shifted up 1 place
+ */
+ shiftUp(c, aLen, bTotal, banks);
+ }
+
+ int ciPos = ci.length;
+ while (--ciPos > 1)
+ {
+ if ((ciPos & 1L) == 0L)
+ {
+ /*
+ * For even numbers, shift contents and add to the half-position
+ */
+ addShiftedUp(c, ci[ciPos >>> 1], c, ci[ciPos], cLen, positions);
+ }
+ else
+ {
+ /*
+ * For odd numbers, 'distribute' contents to the result and the next-lowest position
+ */
+ distribute(c, ci[ciPos], ci[ciPos - 1], ci[1], cLen);
+ }
+ }
+
+ /*
+ * Finally the raw answer is collected, reduce it against the reduction coefficients
+ */
+ return reduceResult(c, ci[1], cLen, m, ks);
+ }
+
+ public LongArray modReduce(int m, int[] ks)
+ {
+ long[] buf = Arrays.clone(m_ints);
+ int rLen = reduceInPlace(buf, 0, buf.length, m, ks);
+ return new LongArray(buf, 0, rLen);
+ }
+
+ public LongArray multiply(LongArray other, int m, int[] ks)
+ {
+ /*
+ * Find out the degree of each argument and handle the zero cases
+ */
+ int aDeg = degree();
+ if (aDeg == 0)
+ {
+ return this;
+ }
+ int bDeg = other.degree();
+ if (bDeg == 0)
+ {
+ return other;
+ }
+
+ /*
+ * Swap if necessary so that A is the smaller argument
+ */
+ LongArray A = this, B = other;
+ if (aDeg > bDeg)
+ {
+ A = other; B = this;
+ int tmp = aDeg; aDeg = bDeg; bDeg = tmp;
+ }
+
+ /*
+ * Establish the word lengths of the arguments and result
+ */
+ int aLen = (aDeg + 63) >>> 6;
+ int bLen = (bDeg + 63) >>> 6;
+ int cLen = (aDeg + bDeg + 62) >>> 6;
+
+ if (aLen == 1)
+ {
+ long a0 = A.m_ints[0];
+ if (a0 == 1L)
+ {
+ return B;
+ }
+
+ /*
+ * Fast path for small A, with performance dependent only on the number of set bits
+ */
+ long[] c0 = new long[cLen];
+ multiplyWord(a0, B.m_ints, bLen, c0, 0);
+
+ /*
+ * Reduce the raw answer against the reduction coefficients
+ */
+// return reduceResult(c0, 0, cLen, m, ks);
+ return new LongArray(c0, 0, cLen);
+ }
+
+ /*
+ * Determine if B will get bigger during shifting
+ */
+ int bMax = (bDeg + 7 + 63) >>> 6;
+
+ /*
+ * Lookup table for the offset of each B in the tables
+ */
+ int[] ti = new int[16];
+
+ /*
+ * Precompute table of all 4-bit products of B
+ */
+ long[] T0 = new long[bMax << 4];
+ int tOff = bMax;
+ ti[1] = tOff;
+ System.arraycopy(B.m_ints, 0, T0, tOff, bLen);
+ for (int i = 2; i < 16; ++i)
+ {
+ ti[i] = (tOff += bMax);
+ if ((i & 1) == 0)
+ {
+ shiftUp(T0, tOff >>> 1, T0, tOff, bMax, 1);
+ }
+ else
+ {
+ add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax);
+ }
+ }
+
+ /*
+ * Second table with all 4-bit products of B shifted 4 bits
+ */
+ long[] T1 = new long[T0.length];
+ shiftUp(T0, 0, T1, 0, T0.length, 4);
+// shiftUp(T0, bMax, T1, bMax, tOff, 4);
+
+ long[] a = A.m_ints;
+ long[] c = new long[cLen << 3];
+
+ int MASK = 0xF;
+
+ /*
+ * Lopez-Dahab (Modified) algorithm
+ */
+
+ for (int aPos = 0; aPos < aLen; ++aPos)
+ {
+ long aVal = a[aPos];
+ int cOff = aPos;
+ for (;;)
+ {
+ int u = (int)aVal & MASK;
+ aVal >>>= 4;
+ int v = (int)aVal & MASK;
+ addBoth(c, cOff, T0, ti[u], T1, ti[v], bMax);
+ aVal >>>= 4;
+ if (aVal == 0L)
+ {
+ break;
+ }
+ cOff += cLen;
+ }
+ }
+
+ {
+ int cOff = c.length;
+ while ((cOff -= cLen) != 0)
+ {
+ addShiftedUp(c, cOff - cLen, c, cOff, cLen, 8);
+ }
+ }
+
+ /*
+ * Finally the raw answer is collected, reduce it against the reduction coefficients
+ */
+// return reduceResult(c, 0, cLen, m, ks);
+ return new LongArray(c, 0, cLen);
+ }
+
+ public void reduce(int m, int[] ks)
+ {
+ long[] buf = m_ints;
+ int rLen = reduceInPlace(buf, 0, buf.length, m, ks);
+ if (rLen < buf.length)
+ {
+ m_ints = new long[rLen];
+ System.arraycopy(buf, 0, m_ints, 0, rLen);
+ }
+ }
+
+ private static LongArray reduceResult(long[] buf, int off, int len, int m, int[] ks)
+ {
+ int rLen = reduceInPlace(buf, off, len, m, ks);
+ return new LongArray(buf, off, rLen);
+ }
+
+// private static void deInterleave(long[] x, int xOff, long[] z, int zOff, int count, int rounds)
+// {
+// for (int i = 0; i < count; ++i)
+// {
+// z[zOff + i] = deInterleave(x[zOff + i], rounds);
+// }
+// }
+//
+// private static long deInterleave(long x, int rounds)
+// {
+// while (--rounds >= 0)
+// {
+// x = deInterleave32(x & DEINTERLEAVE_MASK) | (deInterleave32((x >>> 1) & DEINTERLEAVE_MASK) << 32);
+// }
+// return x;
+// }
+//
+// private static long deInterleave32(long x)
+// {
+// x = (x | (x >>> 1)) & 0x3333333333333333L;
+// x = (x | (x >>> 2)) & 0x0F0F0F0F0F0F0F0FL;
+// x = (x | (x >>> 4)) & 0x00FF00FF00FF00FFL;
+// x = (x | (x >>> 8)) & 0x0000FFFF0000FFFFL;
+// x = (x | (x >>> 16)) & 0x00000000FFFFFFFFL;
+// return x;
+// }
+
+ private static int reduceInPlace(long[] buf, int off, int len, int m, int[] ks)
+ {
+ int mLen = (m + 63) >>> 6;
+ if (len < mLen)
+ {
+ return len;
+ }
+
+ int numBits = Math.min(len << 6, (m << 1) - 1); // TODO use actual degree?
+ int excessBits = (len << 6) - numBits;
+ while (excessBits >= 64)
+ {
+ --len;
+ excessBits -= 64;
+ }
+
+ int kLen = ks.length, kMax = ks[kLen - 1], kNext = kLen > 1 ? ks[kLen - 2] : 0;
+ int wordWiseLimit = Math.max(m, kMax + 64);
+ int vectorableWords = (excessBits + Math.min(numBits - wordWiseLimit, m - kNext)) >> 6;
+ if (vectorableWords > 1)
+ {
+ int vectorWiseWords = len - vectorableWords;
+ reduceVectorWise(buf, off, len, vectorWiseWords, m, ks);
+ while (len > vectorWiseWords)
+ {
+ buf[off + --len] = 0L;
+ }
+ numBits = vectorWiseWords << 6;
+ }
+
+ if (numBits > wordWiseLimit)
+ {
+ reduceWordWise(buf, off, len, wordWiseLimit, m, ks);
+ numBits = wordWiseLimit;
+ }
+
+ if (numBits > m)
+ {
+ reduceBitWise(buf, off, numBits, m, ks);
+ }
+
+ return mLen;
+ }
+
+ private static void reduceBitWise(long[] buf, int off, int bitlength, int m, int[] ks)
+ {
+ while (--bitlength >= m)
+ {
+ if (testBit(buf, off, bitlength))
+ {
+ reduceBit(buf, off, bitlength, m, ks);
+ }
+ }
+ }
+
+ private static void reduceBit(long[] buf, int off, int bit, int m, int[] ks)
+ {
+ flipBit(buf, off, bit);
+ int n = bit - m;
+ int j = ks.length;
+ while (--j >= 0)
+ {
+ flipBit(buf, off, ks[j] + n);
+ }
+ flipBit(buf, off, n);
+ }
+
+ private static void reduceWordWise(long[] buf, int off, int len, int toBit, int m, int[] ks)
+ {
+ int toPos = toBit >>> 6;
+
+ while (--len > toPos)
+ {
+ long word = buf[off + len];
+ if (word != 0)
+ {
+ buf[off + len] = 0;
+ reduceWord(buf, off, (len << 6), word, m, ks);
+ }
+ }
+
+ {
+ int partial = toBit & 0x3F;
+ long word = buf[off + toPos] >>> partial;
+ if (word != 0)
+ {
+ buf[off + toPos] ^= word << partial;
+ reduceWord(buf, off, toBit, word, m, ks);
+ }
+ }
+ }
+
+ private static void reduceWord(long[] buf, int off, int bit, long word, int m, int[] ks)
+ {
+ int offset = bit - m;
+ int j = ks.length;
+ while (--j >= 0)
+ {
+ flipWord(buf, off, offset + ks[j], word);
+ }
+ flipWord(buf, off, offset, word);
+ }
+
+ private static void reduceVectorWise(long[] buf, int off, int len, int words, int m, int[] ks)
+ {
+ /*
+ * NOTE: It's important we go from highest coefficient to lowest, because for the highest
+ * one (only) we allow the ranges to partially overlap, and therefore any changes must take
+ * effect for the subsequent lower coefficients.
+ */
+ int baseBit = (words << 6) - m;
+ int j = ks.length;
+ while (--j >= 0)
+ {
+ flipVector(buf, off, buf, off + words, len - words, baseBit + ks[j]);
+ }
+ flipVector(buf, off, buf, off + words, len - words, baseBit);
+ }
+
+ private static void flipVector(long[] x, int xOff, long[] y, int yOff, int yLen, int bits)
+ {
+ xOff += bits >>> 6;
+ bits &= 0x3F;
+
+ if (bits == 0)
+ {
+ add(x, xOff, y, yOff, yLen);
+ }
+ else
+ {
+ long carry = addShiftedDown(x, xOff + 1, y, yOff, yLen, 64 - bits);
+ x[xOff] ^= carry;
+ }
+ }
+
+ public LongArray modSquare(int m, int[] ks)
+ {
+ int len = getUsedLength();
+ if (len == 0)
+ {
+ return this;
+ }
+
+ int _2len = len << 1;
+ long[] r = new long[_2len];
+
+ int pos = 0;
+ while (pos < _2len)
+ {
+ long mi = m_ints[pos >>> 1];
+ r[pos++] = interleave2_32to64((int)mi);
+ r[pos++] = interleave2_32to64((int)(mi >>> 32));
+ }
+
+ return new LongArray(r, 0, reduceInPlace(r, 0, r.length, m, ks));
+ }
+
+ public LongArray modSquareN(int n, int m, int[] ks)
+ {
+ int len = getUsedLength();
+ if (len == 0)
+ {
+ return this;
+ }
+
+ int mLen = (m + 63) >>> 6;
+ long[] r = new long[mLen << 1];
+ System.arraycopy(m_ints, 0, r, 0, len);
+
+ while (--n >= 0)
+ {
+ squareInPlace(r, len, m, ks);
+ len = reduceInPlace(r, 0, r.length, m, ks);
+ }
+
+ return new LongArray(r, 0, len);
+ }
+
+ public LongArray square(int m, int[] ks)
+ {
+ int len = getUsedLength();
+ if (len == 0)
+ {
+ return this;
+ }
+
+ int _2len = len << 1;
+ long[] r = new long[_2len];
+
+ int pos = 0;
+ while (pos < _2len)
+ {
+ long mi = m_ints[pos >>> 1];
+ r[pos++] = interleave2_32to64((int)mi);
+ r[pos++] = interleave2_32to64((int)(mi >>> 32));
+ }
+
+ return new LongArray(r, 0, r.length);
+ }
+
+ private static void squareInPlace(long[] x, int xLen, int m, int[] ks)
+ {
+ int pos = xLen << 1;
+ while (--xLen >= 0)
+ {
+ long xVal = x[xLen];
+ x[--pos] = interleave2_32to64((int)(xVal >>> 32));
+ x[--pos] = interleave2_32to64((int)xVal);
+ }
+ }
+
+ private static void interleave(long[] x, int xOff, long[] z, int zOff, int count, int width)
+ {
+ switch (width)
+ {
+ case 3:
+ interleave3(x, xOff, z, zOff, count);
+ break;
+ case 5:
+ interleave5(x, xOff, z, zOff, count);
+ break;
+ case 7:
+ interleave7(x, xOff, z, zOff, count);
+ break;
+ default:
+ interleave2_n(x, xOff, z, zOff, count, bitLengths[width] - 1);
+ break;
+ }
+ }
+
+ private static void interleave3(long[] x, int xOff, long[] z, int zOff, int count)
+ {
+ for (int i = 0; i < count; ++i)
+ {
+ z[zOff + i] = interleave3(x[xOff + i]);
+ }
+ }
+
+ private static long interleave3(long x)
+ {
+ long z = x & (1L << 63);
+ return z
+ | interleave3_21to63((int)x & 0x1FFFFF)
+ | interleave3_21to63((int)(x >>> 21) & 0x1FFFFF) << 1
+ | interleave3_21to63((int)(x >>> 42) & 0x1FFFFF) << 2;
+
+// int zPos = 0, wPos = 0, xPos = 0;
+// for (;;)
+// {
+// z |= ((x >>> xPos) & 1L) << zPos;
+// if (++zPos == 63)
+// {
+// String sz2 = Long.toBinaryString(z);
+// return z;
+// }
+// if ((xPos += 21) >= 63)
+// {
+// xPos = ++wPos;
+// }
+// }
+ }
+
+ private static long interleave3_21to63(int x)
+ {
+ int r00 = INTERLEAVE3_TABLE[x & 0x7F];
+ int r21 = INTERLEAVE3_TABLE[(x >>> 7) & 0x7F];
+ int r42 = INTERLEAVE3_TABLE[x >>> 14];
+ return (r42 & 0xFFFFFFFFL) << 42 | (r21 & 0xFFFFFFFFL) << 21 | (r00 & 0xFFFFFFFFL);
+ }
+
+ private static void interleave5(long[] x, int xOff, long[] z, int zOff, int count)
+ {
+ for (int i = 0; i < count; ++i)
+ {
+ z[zOff + i] = interleave5(x[xOff + i]);
+ }
+ }
+
+ private static long interleave5(long x)
+ {
+ return interleave3_13to65((int)x & 0x1FFF)
+ | interleave3_13to65((int)(x >>> 13) & 0x1FFF) << 1
+ | interleave3_13to65((int)(x >>> 26) & 0x1FFF) << 2
+ | interleave3_13to65((int)(x >>> 39) & 0x1FFF) << 3
+ | interleave3_13to65((int)(x >>> 52) & 0x1FFF) << 4;
+
+// long z = 0;
+// int zPos = 0, wPos = 0, xPos = 0;
+// for (;;)
+// {
+// z |= ((x >>> xPos) & 1L) << zPos;
+// if (++zPos == 64)
+// {
+// return z;
+// }
+// if ((xPos += 13) >= 64)
+// {
+// xPos = ++wPos;
+// }
+// }
+ }
+
+ private static long interleave3_13to65(int x)
+ {
+ int r00 = INTERLEAVE5_TABLE[x & 0x7F];
+ int r35 = INTERLEAVE5_TABLE[x >>> 7];
+ return (r35 & 0xFFFFFFFFL) << 35 | (r00 & 0xFFFFFFFFL);
+ }
+
+ private static void interleave7(long[] x, int xOff, long[] z, int zOff, int count)
+ {
+ for (int i = 0; i < count; ++i)
+ {
+ z[zOff + i] = interleave7(x[xOff + i]);
+ }
+ }
+
+ private static long interleave7(long x)
+ {
+ long z = x & (1L << 63);
+ return z
+ | INTERLEAVE7_TABLE[(int)x & 0x1FF]
+ | INTERLEAVE7_TABLE[(int)(x >>> 9) & 0x1FF] << 1
+ | INTERLEAVE7_TABLE[(int)(x >>> 18) & 0x1FF] << 2
+ | INTERLEAVE7_TABLE[(int)(x >>> 27) & 0x1FF] << 3
+ | INTERLEAVE7_TABLE[(int)(x >>> 36) & 0x1FF] << 4
+ | INTERLEAVE7_TABLE[(int)(x >>> 45) & 0x1FF] << 5
+ | INTERLEAVE7_TABLE[(int)(x >>> 54) & 0x1FF] << 6;
+
+// int zPos = 0, wPos = 0, xPos = 0;
+// for (;;)
+// {
+// z |= ((x >>> xPos) & 1L) << zPos;
+// if (++zPos == 63)
+// {
+// return z;
+// }
+// if ((xPos += 9) >= 63)
+// {
+// xPos = ++wPos;
+// }
+// }
+ }
+
+ private static void interleave2_n(long[] x, int xOff, long[] z, int zOff, int count, int rounds)
+ {
+ for (int i = 0; i < count; ++i)
+ {
+ z[zOff + i] = interleave2_n(x[xOff + i], rounds);
+ }
+ }
+
+ private static long interleave2_n(long x, int rounds)
+ {
+ while (rounds > 1)
+ {
+ rounds -= 2;
+ x = interleave4_16to64((int)x & 0xFFFF)
+ | interleave4_16to64((int)(x >>> 16) & 0xFFFF) << 1
+ | interleave4_16to64((int)(x >>> 32) & 0xFFFF) << 2
+ | interleave4_16to64((int)(x >>> 48) & 0xFFFF) << 3;
+ }
+ if (rounds > 0)
+ {
+ x = interleave2_32to64((int)x) | interleave2_32to64((int)(x >>> 32)) << 1;
+ }
+ return x;
+ }
+
+ private static long interleave4_16to64(int x)
+ {
+ int r00 = INTERLEAVE4_TABLE[x & 0xFF];
+ int r32 = INTERLEAVE4_TABLE[x >>> 8];
+ return (r32 & 0xFFFFFFFFL) << 32 | (r00 & 0xFFFFFFFFL);
+ }
+
+ private static long interleave2_32to64(int x)
+ {
+ int r00 = INTERLEAVE2_TABLE[x & 0xFF] | INTERLEAVE2_TABLE[(x >>> 8) & 0xFF] << 16;
+ int r32 = INTERLEAVE2_TABLE[(x >>> 16) & 0xFF] | INTERLEAVE2_TABLE[x >>> 24] << 16;
+ return (r32 & 0xFFFFFFFFL) << 32 | (r00 & 0xFFFFFFFFL);
+ }
+
+// private static LongArray expItohTsujii2(LongArray B, int n, int m, int[] ks)
+// {
+// LongArray t1 = B, t3 = new LongArray(new long[]{ 1L });
+// int scale = 1;
+//
+// int numTerms = n;
+// while (numTerms > 1)
+// {
+// if ((numTerms & 1) != 0)
+// {
+// t3 = t3.modMultiply(t1, m, ks);
+// t1 = t1.modSquareN(scale, m, ks);
+// }
+//
+// LongArray t2 = t1.modSquareN(scale, m, ks);
+// t1 = t1.modMultiply(t2, m, ks);
+// numTerms >>>= 1; scale <<= 1;
+// }
+//
+// return t3.modMultiply(t1, m, ks);
+// }
+//
+// private static LongArray expItohTsujii23(LongArray B, int n, int m, int[] ks)
+// {
+// LongArray t1 = B, t3 = new LongArray(new long[]{ 1L });
+// int scale = 1;
+//
+// int numTerms = n;
+// while (numTerms > 1)
+// {
+// boolean m03 = numTerms % 3 == 0;
+// boolean m14 = !m03 && (numTerms & 1) != 0;
+//
+// if (m14)
+// {
+// t3 = t3.modMultiply(t1, m, ks);
+// t1 = t1.modSquareN(scale, m, ks);
+// }
+//
+// LongArray t2 = t1.modSquareN(scale, m, ks);
+// t1 = t1.modMultiply(t2, m, ks);
+//
+// if (m03)
+// {
+// t2 = t2.modSquareN(scale, m, ks);
+// t1 = t1.modMultiply(t2, m, ks);
+// numTerms /= 3; scale *= 3;
+// }
+// else
+// {
+// numTerms >>>= 1; scale <<= 1;
+// }
+// }
+//
+// return t3.modMultiply(t1, m, ks);
+// }
+//
+// private static LongArray expItohTsujii235(LongArray B, int n, int m, int[] ks)
+// {
+// LongArray t1 = B, t4 = new LongArray(new long[]{ 1L });
+// int scale = 1;
+//
+// int numTerms = n;
+// while (numTerms > 1)
+// {
+// if (numTerms % 5 == 0)
+// {
+//// t1 = expItohTsujii23(t1, 5, m, ks);
+//
+// LongArray t3 = t1;
+// t1 = t1.modSquareN(scale, m, ks);
+//
+// LongArray t2 = t1.modSquareN(scale, m, ks);
+// t1 = t1.modMultiply(t2, m, ks);
+// t2 = t1.modSquareN(scale << 1, m, ks);
+// t1 = t1.modMultiply(t2, m, ks);
+//
+// t1 = t1.modMultiply(t3, m, ks);
+//
+// numTerms /= 5; scale *= 5;
+// continue;
+// }
+//
+// boolean m03 = numTerms % 3 == 0;
+// boolean m14 = !m03 && (numTerms & 1) != 0;
+//
+// if (m14)
+// {
+// t4 = t4.modMultiply(t1, m, ks);
+// t1 = t1.modSquareN(scale, m, ks);
+// }
+//
+// LongArray t2 = t1.modSquareN(scale, m, ks);
+// t1 = t1.modMultiply(t2, m, ks);
+//
+// if (m03)
+// {
+// t2 = t2.modSquareN(scale, m, ks);
+// t1 = t1.modMultiply(t2, m, ks);
+// numTerms /= 3; scale *= 3;
+// }
+// else
+// {
+// numTerms >>>= 1; scale <<= 1;
+// }
+// }
+//
+// return t4.modMultiply(t1, m, ks);
+// }
+
+ public LongArray modInverse(int m, int[] ks)
+ {
+ /*
+ * Fermat's Little Theorem
+ */
+// LongArray A = this;
+// LongArray B = A.modSquare(m, ks);
+// LongArray R0 = B, R1 = B;
+// for (int i = 2; i < m; ++i)
+// {
+// R1 = R1.modSquare(m, ks);
+// R0 = R0.modMultiply(R1, m, ks);
+// }
+//
+// return R0;
+
+ /*
+ * Itoh-Tsujii
+ */
+// LongArray B = modSquare(m, ks);
+// switch (m)
+// {
+// case 409:
+// return expItohTsujii23(B, m - 1, m, ks);
+// case 571:
+// return expItohTsujii235(B, m - 1, m, ks);
+// case 163:
+// case 233:
+// case 283:
+// default:
+// return expItohTsujii2(B, m - 1, m, ks);
+// }
+
+ /*
+ * Inversion in F2m using the extended Euclidean algorithm
+ *
+ * Input: A nonzero polynomial a(z) of degree at most m-1
+ * Output: a(z)^(-1) mod f(z)
+ */
+ int uzDegree = degree();
+ if (uzDegree == 0)
+ {
+ throw new IllegalStateException();
+ }
+ if (uzDegree == 1)
+ {
+ return this;
+ }
+
+ // u(z) := a(z)
+ LongArray uz = (LongArray)clone();
+
+ int t = (m + 63) >>> 6;
+
+ // v(z) := f(z)
+ LongArray vz = new LongArray(t);
+ reduceBit(vz.m_ints, 0, m, m, ks);
+
+ // g1(z) := 1, g2(z) := 0
+ LongArray g1z = new LongArray(t);
+ g1z.m_ints[0] = 1L;
+ LongArray g2z = new LongArray(t);
+
+ int[] uvDeg = new int[]{ uzDegree, m + 1 };
+ LongArray[] uv = new LongArray[]{ uz, vz };
+
+ int[] ggDeg = new int[]{ 1, 0 };
+ LongArray[] gg = new LongArray[]{ g1z, g2z };
+
+ int b = 1;
+ int duv1 = uvDeg[b];
+ int dgg1 = ggDeg[b];
+ int j = duv1 - uvDeg[1 - b];
+
+ for (;;)
+ {
+ if (j < 0)
+ {
+ j = -j;
+ uvDeg[b] = duv1;
+ ggDeg[b] = dgg1;
+ b = 1 - b;
+ duv1 = uvDeg[b];
+ dgg1 = ggDeg[b];
+ }
+
+ uv[b].addShiftedByBitsSafe(uv[1 - b], uvDeg[1 - b], j);
+
+ int duv2 = uv[b].degreeFrom(duv1);
+ if (duv2 == 0)
+ {
+ return gg[1 - b];
+ }
+
+ {
+ int dgg2 = ggDeg[1 - b];
+ gg[b].addShiftedByBitsSafe(gg[1 - b], dgg2, j);
+ dgg2 += j;
+
+ if (dgg2 > dgg1)
+ {
+ dgg1 = dgg2;
+ }
+ else if (dgg2 == dgg1)
+ {
+ dgg1 = gg[b].degreeFrom(dgg1);
+ }
+ }
+
+ j += (duv2 - duv1);
+ duv1 = duv2;
+ }
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof LongArray))
+ {
+ return false;
+ }
+ LongArray other = (LongArray) o;
+ int usedLen = getUsedLength();
+ if (other.getUsedLength() != usedLen)
+ {
+ return false;
+ }
+ for (int i = 0; i < usedLen; i++)
+ {
+ if (m_ints[i] != other.m_ints[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int usedLen = getUsedLength();
+ int hash = 1;
+ for (int i = 0; i < usedLen; i++)
+ {
+ long mi = m_ints[i];
+ hash *= 31;
+ hash ^= (int)mi;
+ hash *= 31;
+ hash ^= (int)(mi >>> 32);
+ }
+ return hash;
+ }
+
+ public Object clone()
+ {
+ return new LongArray(Arrays.clone(m_ints));
+ }
+
+ public String toString()
+ {
+ int i = getUsedLength();
+ if (i == 0)
+ {
+ return "0";
+ }
+
+ StringBuffer sb = new StringBuffer(Long.toBinaryString(m_ints[--i]));
+ while (--i >= 0)
+ {
+ String s = Long.toBinaryString(m_ints[i]);
+
+ // Add leading zeroes, except for highest significant word
+ int len = s.length();
+ if (len < 64)
+ {
+ sb.append(ZEROES.substring(len));
+ }
+
+ sb.append(s);
+ }
+ return sb.toString();
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/PreCompCallback.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/PreCompCallback.java
new file mode 100644
index 00000000..4f4132e3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/PreCompCallback.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PreCompCallback
+{
+ PreCompInfo precompute(PreCompInfo existing);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/PreCompInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/PreCompInfo.java
new file mode 100644
index 00000000..0c440e58
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/PreCompInfo.java
@@ -0,0 +1,12 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+/**
+ * Interface for classes storing precomputation data for multiplication
+ * algorithms. Used as a Memento (see GOF patterns) by e.g.
+ * <code>WNafL2RMultiplier</code>.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PreCompInfo
+{
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ScaleXNegateYPointMap.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ScaleXNegateYPointMap.java
new file mode 100644
index 00000000..e2a2ee99
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ScaleXNegateYPointMap.java
@@ -0,0 +1,20 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ScaleXNegateYPointMap implements ECPointMap
+{
+ protected final ECFieldElement scale;
+
+ public ScaleXNegateYPointMap(ECFieldElement scale)
+ {
+ this.scale = scale;
+ }
+
+ public ECPoint map(ECPoint p)
+ {
+ return p.scaleXNegateY(scale);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ScaleXPointMap.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ScaleXPointMap.java
new file mode 100644
index 00000000..e67dc785
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ScaleXPointMap.java
@@ -0,0 +1,20 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ScaleXPointMap implements ECPointMap
+{
+ protected final ECFieldElement scale;
+
+ public ScaleXPointMap(ECFieldElement scale)
+ {
+ this.scale = scale;
+ }
+
+ public ECPoint map(ECPoint p)
+ {
+ return p.scaleX(scale);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ScaleYNegateXPointMap.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ScaleYNegateXPointMap.java
new file mode 100644
index 00000000..0dba4388
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ScaleYNegateXPointMap.java
@@ -0,0 +1,20 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ScaleYNegateXPointMap implements ECPointMap
+{
+ protected final ECFieldElement scale;
+
+ public ScaleYNegateXPointMap(ECFieldElement scale)
+ {
+ this.scale = scale;
+ }
+
+ public ECPoint map(ECPoint p)
+ {
+ return p.scaleYNegateX(scale);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/SimpleBigDecimal.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/SimpleBigDecimal.java
new file mode 100644
index 00000000..d9ceecd7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/SimpleBigDecimal.java
@@ -0,0 +1,248 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+
+/**
+ * Class representing a simple version of a big decimal. A
+ * <code>SimpleBigDecimal</code> is basically a
+ * {@link java.math.BigInteger BigInteger} with a few digits on the right of
+ * the decimal point. The number of (binary) digits on the right of the decimal
+ * point is called the <code>scale</code> of the <code>SimpleBigDecimal</code>.
+ * Unlike in {@link java.math.BigDecimal BigDecimal}, the scale is not adjusted
+ * automatically, but must be set manually. All <code>SimpleBigDecimal</code>s
+ * taking part in the same arithmetic operation must have equal scale. The
+ * result of a multiplication of two <code>SimpleBigDecimal</code>s returns a
+ * <code>SimpleBigDecimal</code> with double scale.
+ */
+class SimpleBigDecimal
+ //extends Number // not in J2ME - add compatibility class?
+{
+ private static final long serialVersionUID = 1L;
+
+ private final BigInteger bigInt;
+ private final int scale;
+
+ /**
+ * Returns a <code>SimpleBigDecimal</code> representing the same numerical
+ * value as <code>value</code>.
+ * @param value The value of the <code>SimpleBigDecimal</code> to be
+ * created.
+ * @param scale The scale of the <code>SimpleBigDecimal</code> to be
+ * created.
+ * @return The such created <code>SimpleBigDecimal</code>.
+ */
+ public static SimpleBigDecimal getInstance(BigInteger value, int scale)
+ {
+ return new SimpleBigDecimal(value.shiftLeft(scale), scale);
+ }
+
+ /**
+ * Constructor for <code>SimpleBigDecimal</code>. The value of the
+ * constructed <code>SimpleBigDecimal</code> equals <code>bigInt /
+ * 2<sup>scale</sup></code>.
+ * @param bigInt The <code>bigInt</code> value parameter.
+ * @param scale The scale of the constructed <code>SimpleBigDecimal</code>.
+ */
+ public SimpleBigDecimal(BigInteger bigInt, int scale)
+ {
+ if (scale < 0)
+ {
+ throw new IllegalArgumentException("scale may not be negative");
+ }
+
+ this.bigInt = bigInt;
+ this.scale = scale;
+ }
+
+ private void checkScale(SimpleBigDecimal b)
+ {
+ if (scale != b.scale)
+ {
+ throw new IllegalArgumentException("Only SimpleBigDecimal of " +
+ "same scale allowed in arithmetic operations");
+ }
+ }
+
+ public SimpleBigDecimal adjustScale(int newScale)
+ {
+ if (newScale < 0)
+ {
+ throw new IllegalArgumentException("scale may not be negative");
+ }
+
+ if (newScale == scale)
+ {
+ return this;
+ }
+
+ return new SimpleBigDecimal(bigInt.shiftLeft(newScale - scale),
+ newScale);
+ }
+
+ public SimpleBigDecimal add(SimpleBigDecimal b)
+ {
+ checkScale(b);
+ return new SimpleBigDecimal(bigInt.add(b.bigInt), scale);
+ }
+
+ public SimpleBigDecimal add(BigInteger b)
+ {
+ return new SimpleBigDecimal(bigInt.add(b.shiftLeft(scale)), scale);
+ }
+
+ public SimpleBigDecimal negate()
+ {
+ return new SimpleBigDecimal(bigInt.negate(), scale);
+ }
+
+ public SimpleBigDecimal subtract(SimpleBigDecimal b)
+ {
+ return add(b.negate());
+ }
+
+ public SimpleBigDecimal subtract(BigInteger b)
+ {
+ return new SimpleBigDecimal(bigInt.subtract(b.shiftLeft(scale)),
+ scale);
+ }
+
+ public SimpleBigDecimal multiply(SimpleBigDecimal b)
+ {
+ checkScale(b);
+ return new SimpleBigDecimal(bigInt.multiply(b.bigInt), scale + scale);
+ }
+
+ public SimpleBigDecimal multiply(BigInteger b)
+ {
+ return new SimpleBigDecimal(bigInt.multiply(b), scale);
+ }
+
+ public SimpleBigDecimal divide(SimpleBigDecimal b)
+ {
+ checkScale(b);
+ BigInteger dividend = bigInt.shiftLeft(scale);
+ return new SimpleBigDecimal(dividend.divide(b.bigInt), scale);
+ }
+
+ public SimpleBigDecimal divide(BigInteger b)
+ {
+ return new SimpleBigDecimal(bigInt.divide(b), scale);
+ }
+
+ public SimpleBigDecimal shiftLeft(int n)
+ {
+ return new SimpleBigDecimal(bigInt.shiftLeft(n), scale);
+ }
+
+ public int compareTo(SimpleBigDecimal val)
+ {
+ checkScale(val);
+ return bigInt.compareTo(val.bigInt);
+ }
+
+ public int compareTo(BigInteger val)
+ {
+ return bigInt.compareTo(val.shiftLeft(scale));
+ }
+
+ public BigInteger floor()
+ {
+ return bigInt.shiftRight(scale);
+ }
+
+ public BigInteger round()
+ {
+ SimpleBigDecimal oneHalf = new SimpleBigDecimal(ECConstants.ONE, 1);
+ return add(oneHalf.adjustScale(scale)).floor();
+ }
+
+ public int intValue()
+ {
+ return floor().intValue();
+ }
+
+ public long longValue()
+ {
+ return floor().longValue();
+ }
+ /* NON-J2ME compliant.
+ public double doubleValue()
+ {
+ return Double.valueOf(toString()).doubleValue();
+ }
+
+ public float floatValue()
+ {
+ return Float.valueOf(toString()).floatValue();
+ }
+ */
+ public int getScale()
+ {
+ return scale;
+ }
+
+ public String toString()
+ {
+ if (scale == 0)
+ {
+ return bigInt.toString();
+ }
+
+ BigInteger floorBigInt = floor();
+
+ BigInteger fract = bigInt.subtract(floorBigInt.shiftLeft(scale));
+ if (bigInt.signum() == -1)
+ {
+ fract = ECConstants.ONE.shiftLeft(scale).subtract(fract);
+ }
+
+ if ((floorBigInt.signum() == -1) && (!(fract.equals(ECConstants.ZERO))))
+ {
+ floorBigInt = floorBigInt.add(ECConstants.ONE);
+ }
+ String leftOfPoint = floorBigInt.toString();
+
+ char[] fractCharArr = new char[scale];
+ String fractStr = fract.toString(2);
+ int fractLen = fractStr.length();
+ int zeroes = scale - fractLen;
+ for (int i = 0; i < zeroes; i++)
+ {
+ fractCharArr[i] = '0';
+ }
+ for (int j = 0; j < fractLen; j++)
+ {
+ fractCharArr[zeroes + j] = fractStr.charAt(j);
+ }
+ String rightOfPoint = new String(fractCharArr);
+
+ StringBuffer sb = new StringBuffer(leftOfPoint);
+ sb.append(".");
+ sb.append(rightOfPoint);
+
+ return sb.toString();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+
+ if (!(o instanceof SimpleBigDecimal))
+ {
+ return false;
+ }
+
+ SimpleBigDecimal other = (SimpleBigDecimal)o;
+ return ((bigInt.equals(other.bigInt)) && (scale == other.scale));
+ }
+
+ public int hashCode()
+ {
+ return bigInt.hashCode() ^ scale;
+ }
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/Tnaf.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/Tnaf.java
new file mode 100644
index 00000000..f3266080
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/Tnaf.java
@@ -0,0 +1,850 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+
+/**
+ * Class holding methods for point multiplication based on the window
+ * &tau;-adic nonadjacent form (WTNAF). The algorithms are based on the
+ * paper "Improved Algorithms for Arithmetic on Anomalous Binary Curves"
+ * by Jerome A. Solinas. The paper first appeared in the Proceedings of
+ * Crypto 1997.
+ */
+class Tnaf
+{
+ private static final BigInteger MINUS_ONE = ECConstants.ONE.negate();
+ private static final BigInteger MINUS_TWO = ECConstants.TWO.negate();
+ private static final BigInteger MINUS_THREE = ECConstants.THREE.negate();
+
+ /**
+ * The window width of WTNAF. The standard value of 4 is slightly less
+ * than optimal for running time, but keeps space requirements for
+ * precomputation low. For typical curves, a value of 5 or 6 results in
+ * a better running time. When changing this value, the
+ * <code>&alpha;<sub>u</sub></code>'s must be computed differently, see
+ * e.g. "Guide to Elliptic Curve Cryptography", Darrel Hankerson,
+ * Alfred Menezes, Scott Vanstone, Springer-Verlag New York Inc., 2004,
+ * p. 121-122
+ */
+ public static final byte WIDTH = 4;
+
+ /**
+ * 2<sup>4</sup>
+ */
+ public static final byte POW_2_WIDTH = 16;
+
+ /**
+ * The <code>&alpha;<sub>u</sub></code>'s for <code>a=0</code> as an array
+ * of <code>ZTauElement</code>s.
+ */
+ public static final ZTauElement[] alpha0 = {
+ null,
+ new ZTauElement(ECConstants.ONE, ECConstants.ZERO), null,
+ new ZTauElement(MINUS_THREE, MINUS_ONE), null,
+ new ZTauElement(MINUS_ONE, MINUS_ONE), null,
+ new ZTauElement(ECConstants.ONE, MINUS_ONE), null
+ };
+
+ /**
+ * The <code>&alpha;<sub>u</sub></code>'s for <code>a=0</code> as an array
+ * of TNAFs.
+ */
+ public static final byte[][] alpha0Tnaf = {
+ null, {1}, null, {-1, 0, 1}, null, {1, 0, 1}, null, {-1, 0, 0, 1}
+ };
+
+ /**
+ * The <code>&alpha;<sub>u</sub></code>'s for <code>a=1</code> as an array
+ * of <code>ZTauElement</code>s.
+ */
+ public static final ZTauElement[] alpha1 = {null,
+ new ZTauElement(ECConstants.ONE, ECConstants.ZERO), null,
+ new ZTauElement(MINUS_THREE, ECConstants.ONE), null,
+ new ZTauElement(MINUS_ONE, ECConstants.ONE), null,
+ new ZTauElement(ECConstants.ONE, ECConstants.ONE), null
+ };
+
+ /**
+ * The <code>&alpha;<sub>u</sub></code>'s for <code>a=1</code> as an array
+ * of TNAFs.
+ */
+ public static final byte[][] alpha1Tnaf = {
+ null, {1}, null, {-1, 0, 1}, null, {1, 0, 1}, null, {-1, 0, 0, -1}
+ };
+
+ /**
+ * Computes the norm of an element <code>&lambda;</code> of
+ * <code><b>Z</b>[&tau;]</code>.
+ * @param mu The parameter <code>&mu;</code> of the elliptic curve.
+ * @param lambda The element <code>&lambda;</code> of
+ * <code><b>Z</b>[&tau;]</code>.
+ * @return The norm of <code>&lambda;</code>.
+ */
+ public static BigInteger norm(final byte mu, ZTauElement lambda)
+ {
+ BigInteger norm;
+
+ // s1 = u^2
+ BigInteger s1 = lambda.u.multiply(lambda.u);
+
+ // s2 = u * v
+ BigInteger s2 = lambda.u.multiply(lambda.v);
+
+ // s3 = 2 * v^2
+ BigInteger s3 = lambda.v.multiply(lambda.v).shiftLeft(1);
+
+ if (mu == 1)
+ {
+ norm = s1.add(s2).add(s3);
+ }
+ else if (mu == -1)
+ {
+ norm = s1.subtract(s2).add(s3);
+ }
+ else
+ {
+ throw new IllegalArgumentException("mu must be 1 or -1");
+ }
+
+ return norm;
+ }
+
+ /**
+ * Computes the norm of an element <code>&lambda;</code> of
+ * <code><b>R</b>[&tau;]</code>, where <code>&lambda; = u + v&tau;</code>
+ * and <code>u</code> and <code>u</code> are real numbers (elements of
+ * <code><b>R</b></code>).
+ * @param mu The parameter <code>&mu;</code> of the elliptic curve.
+ * @param u The real part of the element <code>&lambda;</code> of
+ * <code><b>R</b>[&tau;]</code>.
+ * @param v The <code>&tau;</code>-adic part of the element
+ * <code>&lambda;</code> of <code><b>R</b>[&tau;]</code>.
+ * @return The norm of <code>&lambda;</code>.
+ */
+ public static SimpleBigDecimal norm(final byte mu, SimpleBigDecimal u,
+ SimpleBigDecimal v)
+ {
+ SimpleBigDecimal norm;
+
+ // s1 = u^2
+ SimpleBigDecimal s1 = u.multiply(u);
+
+ // s2 = u * v
+ SimpleBigDecimal s2 = u.multiply(v);
+
+ // s3 = 2 * v^2
+ SimpleBigDecimal s3 = v.multiply(v).shiftLeft(1);
+
+ if (mu == 1)
+ {
+ norm = s1.add(s2).add(s3);
+ }
+ else if (mu == -1)
+ {
+ norm = s1.subtract(s2).add(s3);
+ }
+ else
+ {
+ throw new IllegalArgumentException("mu must be 1 or -1");
+ }
+
+ return norm;
+ }
+
+ /**
+ * Rounds an element <code>&lambda;</code> of <code><b>R</b>[&tau;]</code>
+ * to an element of <code><b>Z</b>[&tau;]</code>, such that their difference
+ * has minimal norm. <code>&lambda;</code> is given as
+ * <code>&lambda; = &lambda;<sub>0</sub> + &lambda;<sub>1</sub>&tau;</code>.
+ * @param lambda0 The component <code>&lambda;<sub>0</sub></code>.
+ * @param lambda1 The component <code>&lambda;<sub>1</sub></code>.
+ * @param mu The parameter <code>&mu;</code> of the elliptic curve. Must
+ * equal 1 or -1.
+ * @return The rounded element of <code><b>Z</b>[&tau;]</code>.
+ * @throws IllegalArgumentException if <code>lambda0</code> and
+ * <code>lambda1</code> do not have same scale.
+ */
+ public static ZTauElement round(SimpleBigDecimal lambda0,
+ SimpleBigDecimal lambda1, byte mu)
+ {
+ int scale = lambda0.getScale();
+ if (lambda1.getScale() != scale)
+ {
+ throw new IllegalArgumentException("lambda0 and lambda1 do not " +
+ "have same scale");
+ }
+
+ if (!((mu == 1) || (mu == -1)))
+ {
+ throw new IllegalArgumentException("mu must be 1 or -1");
+ }
+
+ BigInteger f0 = lambda0.round();
+ BigInteger f1 = lambda1.round();
+
+ SimpleBigDecimal eta0 = lambda0.subtract(f0);
+ SimpleBigDecimal eta1 = lambda1.subtract(f1);
+
+ // eta = 2*eta0 + mu*eta1
+ SimpleBigDecimal eta = eta0.add(eta0);
+ if (mu == 1)
+ {
+ eta = eta.add(eta1);
+ }
+ else
+ {
+ // mu == -1
+ eta = eta.subtract(eta1);
+ }
+
+ // check1 = eta0 - 3*mu*eta1
+ // check2 = eta0 + 4*mu*eta1
+ SimpleBigDecimal threeEta1 = eta1.add(eta1).add(eta1);
+ SimpleBigDecimal fourEta1 = threeEta1.add(eta1);
+ SimpleBigDecimal check1;
+ SimpleBigDecimal check2;
+ if (mu == 1)
+ {
+ check1 = eta0.subtract(threeEta1);
+ check2 = eta0.add(fourEta1);
+ }
+ else
+ {
+ // mu == -1
+ check1 = eta0.add(threeEta1);
+ check2 = eta0.subtract(fourEta1);
+ }
+
+ byte h0 = 0;
+ byte h1 = 0;
+
+ // if eta >= 1
+ if (eta.compareTo(ECConstants.ONE) >= 0)
+ {
+ if (check1.compareTo(MINUS_ONE) < 0)
+ {
+ h1 = mu;
+ }
+ else
+ {
+ h0 = 1;
+ }
+ }
+ else
+ {
+ // eta < 1
+ if (check2.compareTo(ECConstants.TWO) >= 0)
+ {
+ h1 = mu;
+ }
+ }
+
+ // if eta < -1
+ if (eta.compareTo(MINUS_ONE) < 0)
+ {
+ if (check1.compareTo(ECConstants.ONE) >= 0)
+ {
+ h1 = (byte)-mu;
+ }
+ else
+ {
+ h0 = -1;
+ }
+ }
+ else
+ {
+ // eta >= -1
+ if (check2.compareTo(MINUS_TWO) < 0)
+ {
+ h1 = (byte)-mu;
+ }
+ }
+
+ BigInteger q0 = f0.add(BigInteger.valueOf(h0));
+ BigInteger q1 = f1.add(BigInteger.valueOf(h1));
+ return new ZTauElement(q0, q1);
+ }
+
+ /**
+ * Approximate division by <code>n</code>. For an integer
+ * <code>k</code>, the value <code>&lambda; = s k / n</code> is
+ * computed to <code>c</code> bits of accuracy.
+ * @param k The parameter <code>k</code>.
+ * @param s The curve parameter <code>s<sub>0</sub></code> or
+ * <code>s<sub>1</sub></code>.
+ * @param vm The Lucas Sequence element <code>V<sub>m</sub></code>.
+ * @param a The parameter <code>a</code> of the elliptic curve.
+ * @param m The bit length of the finite field
+ * <code><b>F</b><sub>m</sub></code>.
+ * @param c The number of bits of accuracy, i.e. the scale of the returned
+ * <code>SimpleBigDecimal</code>.
+ * @return The value <code>&lambda; = s k / n</code> computed to
+ * <code>c</code> bits of accuracy.
+ */
+ public static SimpleBigDecimal approximateDivisionByN(BigInteger k,
+ BigInteger s, BigInteger vm, byte a, int m, int c)
+ {
+ int _k = (m + 5)/2 + c;
+ BigInteger ns = k.shiftRight(m - _k - 2 + a);
+
+ BigInteger gs = s.multiply(ns);
+
+ BigInteger hs = gs.shiftRight(m);
+
+ BigInteger js = vm.multiply(hs);
+
+ BigInteger gsPlusJs = gs.add(js);
+ BigInteger ls = gsPlusJs.shiftRight(_k-c);
+ if (gsPlusJs.testBit(_k-c-1))
+ {
+ // round up
+ ls = ls.add(ECConstants.ONE);
+ }
+
+ return new SimpleBigDecimal(ls, c);
+ }
+
+ /**
+ * Computes the <code>&tau;</code>-adic NAF (non-adjacent form) of an
+ * element <code>&lambda;</code> of <code><b>Z</b>[&tau;]</code>.
+ * @param mu The parameter <code>&mu;</code> of the elliptic curve.
+ * @param lambda The element <code>&lambda;</code> of
+ * <code><b>Z</b>[&tau;]</code>.
+ * @return The <code>&tau;</code>-adic NAF of <code>&lambda;</code>.
+ */
+ public static byte[] tauAdicNaf(byte mu, ZTauElement lambda)
+ {
+ if (!((mu == 1) || (mu == -1)))
+ {
+ throw new IllegalArgumentException("mu must be 1 or -1");
+ }
+
+ BigInteger norm = norm(mu, lambda);
+
+ // Ceiling of log2 of the norm
+ int log2Norm = norm.bitLength();
+
+ // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52
+ int maxLength = log2Norm > 30 ? log2Norm + 4 : 34;
+
+ // The array holding the TNAF
+ byte[] u = new byte[maxLength];
+ int i = 0;
+
+ // The actual length of the TNAF
+ int length = 0;
+
+ BigInteger r0 = lambda.u;
+ BigInteger r1 = lambda.v;
+
+ while(!((r0.equals(ECConstants.ZERO)) && (r1.equals(ECConstants.ZERO))))
+ {
+ // If r0 is odd
+ if (r0.testBit(0))
+ {
+ u[i] = (byte) ECConstants.TWO.subtract((r0.subtract(r1.shiftLeft(1))).mod(ECConstants.FOUR)).intValue();
+
+ // r0 = r0 - u[i]
+ if (u[i] == 1)
+ {
+ r0 = r0.clearBit(0);
+ }
+ else
+ {
+ // u[i] == -1
+ r0 = r0.add(ECConstants.ONE);
+ }
+ length = i;
+ }
+ else
+ {
+ u[i] = 0;
+ }
+
+ BigInteger t = r0;
+ BigInteger s = r0.shiftRight(1);
+ if (mu == 1)
+ {
+ r0 = r1.add(s);
+ }
+ else
+ {
+ // mu == -1
+ r0 = r1.subtract(s);
+ }
+
+ r1 = t.shiftRight(1).negate();
+ i++;
+ }
+
+ length++;
+
+ // Reduce the TNAF array to its actual length
+ byte[] tnaf = new byte[length];
+ System.arraycopy(u, 0, tnaf, 0, length);
+ return tnaf;
+ }
+
+ /**
+ * Applies the operation <code>&tau;()</code> to an
+ * <code>ECPoint.AbstractF2m</code>.
+ * @param p The ECPoint.AbstractF2m to which <code>&tau;()</code> is applied.
+ * @return <code>&tau;(p)</code>
+ */
+ public static ECPoint.AbstractF2m tau(ECPoint.AbstractF2m p)
+ {
+ return p.tau();
+ }
+
+ /**
+ * Returns the parameter <code>&mu;</code> of the elliptic curve.
+ * @param curve The elliptic curve from which to obtain <code>&mu;</code>.
+ * The curve must be a Koblitz curve, i.e. <code>a</code> equals
+ * <code>0</code> or <code>1</code> and <code>b</code> equals
+ * <code>1</code>.
+ * @return <code>&mu;</code> of the elliptic curve.
+ * @throws IllegalArgumentException if the given ECCurve is not a Koblitz
+ * curve.
+ */
+ public static byte getMu(ECCurve.AbstractF2m curve)
+ {
+ if (!curve.isKoblitz())
+ {
+ throw new IllegalArgumentException("No Koblitz curve (ABC), TNAF multiplication not possible");
+ }
+
+ if (curve.getA().isZero())
+ {
+ return -1;
+ }
+
+ return 1;
+ }
+
+ public static byte getMu(ECFieldElement curveA)
+ {
+ return (byte)(curveA.isZero() ? -1 : 1);
+ }
+
+ public static byte getMu(int curveA)
+ {
+ return (byte)(curveA == 0 ? -1 : 1);
+ }
+
+ /**
+ * Calculates the Lucas Sequence elements <code>U<sub>k-1</sub></code> and
+ * <code>U<sub>k</sub></code> or <code>V<sub>k-1</sub></code> and
+ * <code>V<sub>k</sub></code>.
+ * @param mu The parameter <code>&mu;</code> of the elliptic curve.
+ * @param k The index of the second element of the Lucas Sequence to be
+ * returned.
+ * @param doV If set to true, computes <code>V<sub>k-1</sub></code> and
+ * <code>V<sub>k</sub></code>, otherwise <code>U<sub>k-1</sub></code> and
+ * <code>U<sub>k</sub></code>.
+ * @return An array with 2 elements, containing <code>U<sub>k-1</sub></code>
+ * and <code>U<sub>k</sub></code> or <code>V<sub>k-1</sub></code>
+ * and <code>V<sub>k</sub></code>.
+ */
+ public static BigInteger[] getLucas(byte mu, int k, boolean doV)
+ {
+ if (!((mu == 1) || (mu == -1)))
+ {
+ throw new IllegalArgumentException("mu must be 1 or -1");
+ }
+
+ BigInteger u0;
+ BigInteger u1;
+ BigInteger u2;
+
+ if (doV)
+ {
+ u0 = ECConstants.TWO;
+ u1 = BigInteger.valueOf(mu);
+ }
+ else
+ {
+ u0 = ECConstants.ZERO;
+ u1 = ECConstants.ONE;
+ }
+
+ for (int i = 1; i < k; i++)
+ {
+ // u2 = mu*u1 - 2*u0;
+ BigInteger s = null;
+ if (mu == 1)
+ {
+ s = u1;
+ }
+ else
+ {
+ // mu == -1
+ s = u1.negate();
+ }
+
+ u2 = s.subtract(u0.shiftLeft(1));
+ u0 = u1;
+ u1 = u2;
+// System.out.println(i + ": " + u2);
+// System.out.println();
+ }
+
+ BigInteger[] retVal = {u0, u1};
+ return retVal;
+ }
+
+ /**
+ * Computes the auxiliary value <code>t<sub>w</sub></code>. If the width is
+ * 4, then for <code>mu = 1</code>, <code>t<sub>w</sub> = 6</code> and for
+ * <code>mu = -1</code>, <code>t<sub>w</sub> = 10</code>
+ * @param mu The parameter <code>&mu;</code> of the elliptic curve.
+ * @param w The window width of the WTNAF.
+ * @return the auxiliary value <code>t<sub>w</sub></code>
+ */
+ public static BigInteger getTw(byte mu, int w)
+ {
+ if (w == 4)
+ {
+ if (mu == 1)
+ {
+ return BigInteger.valueOf(6);
+ }
+ else
+ {
+ // mu == -1
+ return BigInteger.valueOf(10);
+ }
+ }
+ else
+ {
+ // For w <> 4, the values must be computed
+ BigInteger[] us = getLucas(mu, w, false);
+ BigInteger twoToW = ECConstants.ZERO.setBit(w);
+ BigInteger u1invert = us[1].modInverse(twoToW);
+ BigInteger tw;
+ tw = ECConstants.TWO.multiply(us[0]).multiply(u1invert).mod(twoToW);
+// System.out.println("mu = " + mu);
+// System.out.println("tw = " + tw);
+ return tw;
+ }
+ }
+
+ /**
+ * Computes the auxiliary values <code>s<sub>0</sub></code> and
+ * <code>s<sub>1</sub></code> used for partial modular reduction.
+ * @param curve The elliptic curve for which to compute
+ * <code>s<sub>0</sub></code> and <code>s<sub>1</sub></code>.
+ * @throws IllegalArgumentException if <code>curve</code> is not a
+ * Koblitz curve (Anomalous Binary Curve, ABC).
+ */
+ public static BigInteger[] getSi(ECCurve.AbstractF2m curve)
+ {
+ if (!curve.isKoblitz())
+ {
+ throw new IllegalArgumentException("si is defined for Koblitz curves only");
+ }
+
+ int m = curve.getFieldSize();
+ int a = curve.getA().toBigInteger().intValue();
+ byte mu = getMu(a);
+ int shifts = getShiftsForCofactor(curve.getCofactor());
+ int index = m + 3 - a;
+ BigInteger[] ui = getLucas(mu, index, false);
+ if (mu == 1)
+ {
+ ui[0] = ui[0].negate();
+ ui[1] = ui[1].negate();
+ }
+
+ BigInteger dividend0 = ECConstants.ONE.add(ui[1]).shiftRight(shifts);
+ BigInteger dividend1 = ECConstants.ONE.add(ui[0]).shiftRight(shifts).negate();
+
+ return new BigInteger[] { dividend0, dividend1 };
+ }
+
+ public static BigInteger[] getSi(int fieldSize, int curveA, BigInteger cofactor)
+ {
+ byte mu = getMu(curveA);
+ int shifts = getShiftsForCofactor(cofactor);
+ int index = fieldSize + 3 - curveA;
+ BigInteger[] ui = getLucas(mu, index, false);
+ if (mu == 1)
+ {
+ ui[0] = ui[0].negate();
+ ui[1] = ui[1].negate();
+ }
+
+ BigInteger dividend0 = ECConstants.ONE.add(ui[1]).shiftRight(shifts);
+ BigInteger dividend1 = ECConstants.ONE.add(ui[0]).shiftRight(shifts).negate();
+
+ return new BigInteger[] { dividend0, dividend1 };
+ }
+
+ protected static int getShiftsForCofactor(BigInteger h)
+ {
+ if (h != null)
+ {
+ if (h.equals(ECConstants.TWO))
+ {
+ return 1;
+ }
+ if (h.equals(ECConstants.FOUR))
+ {
+ return 2;
+ }
+ }
+
+ throw new IllegalArgumentException("h (Cofactor) must be 2 or 4");
+ }
+
+ /**
+ * Partial modular reduction modulo
+ * <code>(&tau;<sup>m</sup> - 1)/(&tau; - 1)</code>.
+ * @param k The integer to be reduced.
+ * @param m The bitlength of the underlying finite field.
+ * @param a The parameter <code>a</code> of the elliptic curve.
+ * @param s The auxiliary values <code>s<sub>0</sub></code> and
+ * <code>s<sub>1</sub></code>.
+ * @param mu The parameter &mu; of the elliptic curve.
+ * @param c The precision (number of bits of accuracy) of the partial
+ * modular reduction.
+ * @return <code>&rho; := k partmod (&tau;<sup>m</sup> - 1)/(&tau; - 1)</code>
+ */
+ public static ZTauElement partModReduction(BigInteger k, int m, byte a,
+ BigInteger[] s, byte mu, byte c)
+ {
+ // d0 = s[0] + mu*s[1]; mu is either 1 or -1
+ BigInteger d0;
+ if (mu == 1)
+ {
+ d0 = s[0].add(s[1]);
+ }
+ else
+ {
+ d0 = s[0].subtract(s[1]);
+ }
+
+ BigInteger[] v = getLucas(mu, m, true);
+ BigInteger vm = v[1];
+
+ SimpleBigDecimal lambda0 = approximateDivisionByN(
+ k, s[0], vm, a, m, c);
+
+ SimpleBigDecimal lambda1 = approximateDivisionByN(
+ k, s[1], vm, a, m, c);
+
+ ZTauElement q = round(lambda0, lambda1, mu);
+
+ // r0 = n - d0*q0 - 2*s1*q1
+ BigInteger r0 = k.subtract(d0.multiply(q.u)).subtract(
+ BigInteger.valueOf(2).multiply(s[1]).multiply(q.v));
+
+ // r1 = s1*q0 - s0*q1
+ BigInteger r1 = s[1].multiply(q.u).subtract(s[0].multiply(q.v));
+
+ return new ZTauElement(r0, r1);
+ }
+
+ /**
+ * Multiplies a {@link com.android.internal.org.bouncycastle.math.ec.ECPoint.AbstractF2m ECPoint.AbstractF2m}
+ * by a <code>BigInteger</code> using the reduced <code>&tau;</code>-adic
+ * NAF (RTNAF) method.
+ * @param p The ECPoint.AbstractF2m to multiply.
+ * @param k The <code>BigInteger</code> by which to multiply <code>p</code>.
+ * @return <code>k * p</code>
+ */
+ public static ECPoint.AbstractF2m multiplyRTnaf(ECPoint.AbstractF2m p, BigInteger k)
+ {
+ ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m) p.getCurve();
+ int m = curve.getFieldSize();
+ int a = curve.getA().toBigInteger().intValue();
+ byte mu = getMu(a);
+ BigInteger[] s = curve.getSi();
+ ZTauElement rho = partModReduction(k, m, (byte)a, s, mu, (byte)10);
+
+ return multiplyTnaf(p, rho);
+ }
+
+ /**
+ * Multiplies a {@link com.android.internal.org.bouncycastle.math.ec.ECPoint.AbstractF2m ECPoint.AbstractF2m}
+ * by an element <code>&lambda;</code> of <code><b>Z</b>[&tau;]</code>
+ * using the <code>&tau;</code>-adic NAF (TNAF) method.
+ * @param p The ECPoint.AbstractF2m to multiply.
+ * @param lambda The element <code>&lambda;</code> of
+ * <code><b>Z</b>[&tau;]</code>.
+ * @return <code>&lambda; * p</code>
+ */
+ public static ECPoint.AbstractF2m multiplyTnaf(ECPoint.AbstractF2m p, ZTauElement lambda)
+ {
+ ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m)p.getCurve();
+ byte mu = getMu(curve.getA());
+ byte[] u = tauAdicNaf(mu, lambda);
+
+ ECPoint.AbstractF2m q = multiplyFromTnaf(p, u);
+
+ return q;
+ }
+
+ /**
+ * Multiplies a {@link com.android.internal.org.bouncycastle.math.ec.ECPoint.AbstractF2m ECPoint.AbstractF2m}
+ * by an element <code>&lambda;</code> of <code><b>Z</b>[&tau;]</code>
+ * using the <code>&tau;</code>-adic NAF (TNAF) method, given the TNAF
+ * of <code>&lambda;</code>.
+ * @param p The ECPoint.AbstractF2m to multiply.
+ * @param u The the TNAF of <code>&lambda;</code>..
+ * @return <code>&lambda; * p</code>
+ */
+ public static ECPoint.AbstractF2m multiplyFromTnaf(ECPoint.AbstractF2m p, byte[] u)
+ {
+ ECCurve curve = p.getCurve();
+ ECPoint.AbstractF2m q = (ECPoint.AbstractF2m)curve.getInfinity();
+ ECPoint.AbstractF2m pNeg = (ECPoint.AbstractF2m)p.negate();
+ int tauCount = 0;
+ for (int i = u.length - 1; i >= 0; i--)
+ {
+ ++tauCount;
+ byte ui = u[i];
+ if (ui != 0)
+ {
+ q = q.tauPow(tauCount);
+ tauCount = 0;
+
+ ECPoint x = ui > 0 ? p : pNeg;
+ q = (ECPoint.AbstractF2m)q.add(x);
+ }
+ }
+ if (tauCount > 0)
+ {
+ q = q.tauPow(tauCount);
+ }
+ return q;
+ }
+
+ /**
+ * Computes the <code>[&tau;]</code>-adic window NAF of an element
+ * <code>&lambda;</code> of <code><b>Z</b>[&tau;]</code>.
+ * @param mu The parameter &mu; of the elliptic curve.
+ * @param lambda The element <code>&lambda;</code> of
+ * <code><b>Z</b>[&tau;]</code> of which to compute the
+ * <code>[&tau;]</code>-adic NAF.
+ * @param width The window width of the resulting WNAF.
+ * @param pow2w 2<sup>width</sup>.
+ * @param tw The auxiliary value <code>t<sub>w</sub></code>.
+ * @param alpha The <code>&alpha;<sub>u</sub></code>'s for the window width.
+ * @return The <code>[&tau;]</code>-adic window NAF of
+ * <code>&lambda;</code>.
+ */
+ public static byte[] tauAdicWNaf(byte mu, ZTauElement lambda,
+ byte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha)
+ {
+ if (!((mu == 1) || (mu == -1)))
+ {
+ throw new IllegalArgumentException("mu must be 1 or -1");
+ }
+
+ BigInteger norm = norm(mu, lambda);
+
+ // Ceiling of log2 of the norm
+ int log2Norm = norm.bitLength();
+
+ // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52
+ int maxLength = log2Norm > 30 ? log2Norm + 4 + width : 34 + width;
+
+ // The array holding the TNAF
+ byte[] u = new byte[maxLength];
+
+ // 2^(width - 1)
+ BigInteger pow2wMin1 = pow2w.shiftRight(1);
+
+ // Split lambda into two BigIntegers to simplify calculations
+ BigInteger r0 = lambda.u;
+ BigInteger r1 = lambda.v;
+ int i = 0;
+
+ // while lambda <> (0, 0)
+ while (!((r0.equals(ECConstants.ZERO))&&(r1.equals(ECConstants.ZERO))))
+ {
+ // if r0 is odd
+ if (r0.testBit(0))
+ {
+ // uUnMod = r0 + r1*tw mod 2^width
+ BigInteger uUnMod
+ = r0.add(r1.multiply(tw)).mod(pow2w);
+
+ byte uLocal;
+ // if uUnMod >= 2^(width - 1)
+ if (uUnMod.compareTo(pow2wMin1) >= 0)
+ {
+ uLocal = (byte) uUnMod.subtract(pow2w).intValue();
+ }
+ else
+ {
+ uLocal = (byte) uUnMod.intValue();
+ }
+ // uLocal is now in [-2^(width-1), 2^(width-1)-1]
+
+ u[i] = uLocal;
+ boolean s = true;
+ if (uLocal < 0)
+ {
+ s = false;
+ uLocal = (byte)-uLocal;
+ }
+ // uLocal is now >= 0
+
+ if (s)
+ {
+ r0 = r0.subtract(alpha[uLocal].u);
+ r1 = r1.subtract(alpha[uLocal].v);
+ }
+ else
+ {
+ r0 = r0.add(alpha[uLocal].u);
+ r1 = r1.add(alpha[uLocal].v);
+ }
+ }
+ else
+ {
+ u[i] = 0;
+ }
+
+ BigInteger t = r0;
+
+ if (mu == 1)
+ {
+ r0 = r1.add(r0.shiftRight(1));
+ }
+ else
+ {
+ // mu == -1
+ r0 = r1.subtract(r0.shiftRight(1));
+ }
+ r1 = t.shiftRight(1).negate();
+ i++;
+ }
+ return u;
+ }
+
+ /**
+ * Does the precomputation for WTNAF multiplication.
+ * @param p The <code>ECPoint</code> for which to do the precomputation.
+ * @param a The parameter <code>a</code> of the elliptic curve.
+ * @return The precomputation array for <code>p</code>.
+ */
+ public static ECPoint.AbstractF2m[] getPreComp(ECPoint.AbstractF2m p, byte a)
+ {
+ byte[][] alphaTnaf = (a == 0) ? Tnaf.alpha0Tnaf : Tnaf.alpha1Tnaf;
+
+ ECPoint.AbstractF2m[] pu = new ECPoint.AbstractF2m[(alphaTnaf.length + 1) >>> 1];
+ pu[0] = p;
+
+ int precompLen = alphaTnaf.length;
+ for (int i = 3; i < precompLen; i += 2)
+ {
+ pu[i >>> 1] = Tnaf.multiplyFromTnaf(p, alphaTnaf[i]);
+ }
+
+ p.getCurve().normalizeAll(pu);
+
+ return pu;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ValidityPrecompInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ValidityPrecompInfo.java
new file mode 100644
index 00000000..183c11a8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ValidityPrecompInfo.java
@@ -0,0 +1,41 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+class ValidityPrecompInfo implements PreCompInfo
+{
+ static final String PRECOMP_NAME = "bc_validity";
+
+ private boolean failed = false;
+ private boolean curveEquationPassed = false;
+ private boolean orderPassed = false;
+
+ boolean hasFailed()
+ {
+ return failed;
+ }
+
+ void reportFailed()
+ {
+ failed = true;
+ }
+
+ boolean hasCurveEquationPassed()
+ {
+ return curveEquationPassed;
+ }
+
+ void reportCurveEquationPassed()
+ {
+ curveEquationPassed = true;
+ }
+
+ boolean hasOrderPassed()
+ {
+ return orderPassed;
+ }
+
+ void reportOrderPassed()
+ {
+ orderPassed = true;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafL2RMultiplier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafL2RMultiplier.java
new file mode 100644
index 00000000..b6b44711
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafL2RMultiplier.java
@@ -0,0 +1,89 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.util.Integers;
+
+/**
+ * Class implementing the WNAF (Window Non-Adjacent Form) multiplication
+ * algorithm.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class WNafL2RMultiplier extends AbstractECMultiplier
+{
+ /**
+ * Multiplies <code>this</code> by an integer <code>k</code> using the
+ * Window NAF method.
+ * @param k The integer by which <code>this</code> is multiplied.
+ * @return A new <code>ECPoint</code> which equals <code>this</code>
+ * multiplied by <code>k</code>.
+ */
+ protected ECPoint multiplyPositive(ECPoint p, BigInteger k)
+ {
+ int minWidth = WNafUtil.getWindowSize(k.bitLength());
+
+ WNafPreCompInfo info = WNafUtil.precompute(p, minWidth, true);
+ ECPoint[] preComp = info.getPreComp();
+ ECPoint[] preCompNeg = info.getPreCompNeg();
+ int width = info.getWidth();
+
+ int[] wnaf = WNafUtil.generateCompactWindowNaf(width, k);
+
+ ECPoint R = p.getCurve().getInfinity();
+
+ int i = wnaf.length;
+
+ /*
+ * NOTE: We try to optimize the first window using the precomputed points to substitute an
+ * addition for 2 or more doublings.
+ */
+ if (i > 1)
+ {
+ int wi = wnaf[--i];
+ int digit = wi >> 16, zeroes = wi & 0xFFFF;
+
+ int n = Math.abs(digit);
+ ECPoint[] table = digit < 0 ? preCompNeg : preComp;
+
+ // Optimization can only be used for values in the lower half of the table
+ if ((n << 2) < (1 << width))
+ {
+ int highest = 32 - Integers.numberOfLeadingZeros(n);
+
+ // TODO Get addition/doubling cost ratio from curve and compare to 'scale' to see if worth substituting?
+ int scale = width - highest;
+ int lowBits = n ^ (1 << (highest - 1));
+
+ int i1 = ((1 << (width - 1)) - 1);
+ int i2 = (lowBits << scale) + 1;
+ R = table[i1 >>> 1].add(table[i2 >>> 1]);
+
+ zeroes -= scale;
+
+// System.out.println("Optimized: 2^" + scale + " * " + n + " = " + i1 + " + " + i2);
+ }
+ else
+ {
+ R = table[n >>> 1];
+ }
+
+ R = R.timesPow2(zeroes);
+ }
+
+ while (i > 0)
+ {
+ int wi = wnaf[--i];
+ int digit = wi >> 16, zeroes = wi & 0xFFFF;
+
+ int n = Math.abs(digit);
+ ECPoint[] table = digit < 0 ? preCompNeg : preComp;
+ ECPoint r = table[n >>> 1];
+
+ R = R.twicePlus(r);
+ R = R.timesPow2(zeroes);
+ }
+
+ return R;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafPreCompInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafPreCompInfo.java
new file mode 100644
index 00000000..0505a466
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafPreCompInfo.java
@@ -0,0 +1,109 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+/**
+ * Class holding precomputation data for the WNAF (Window Non-Adjacent Form)
+ * algorithm.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class WNafPreCompInfo implements PreCompInfo
+{
+ volatile int promotionCountdown = 4;
+
+ protected int confWidth = -1;
+
+ /**
+ * Array holding the precomputed <code>ECPoint</code>s used for a Window
+ * NAF multiplication.
+ */
+ protected ECPoint[] preComp = null;
+
+ /**
+ * Array holding the negations of the precomputed <code>ECPoint</code>s used
+ * for a Window NAF multiplication.
+ */
+ protected ECPoint[] preCompNeg = null;
+
+ /**
+ * Holds an <code>ECPoint</code> representing twice(this). Used for the
+ * Window NAF multiplication to create or extend the precomputed values.
+ */
+ protected ECPoint twice = null;
+
+ protected int width = -1;
+
+ int decrementPromotionCountdown()
+ {
+ int t = promotionCountdown;
+ if (t > 0)
+ {
+ promotionCountdown = --t;
+ }
+ return t;
+ }
+
+ int getPromotionCountdown()
+ {
+ return promotionCountdown;
+ }
+
+ void setPromotionCountdown(int promotionCountdown)
+ {
+ this.promotionCountdown = promotionCountdown;
+ }
+
+ public boolean isPromoted()
+ {
+ return promotionCountdown <= 0;
+ }
+
+ public int getConfWidth()
+ {
+ return confWidth;
+ }
+
+ public void setConfWidth(int confWidth)
+ {
+ this.confWidth = confWidth;
+ }
+
+ public ECPoint[] getPreComp()
+ {
+ return preComp;
+ }
+
+ public void setPreComp(ECPoint[] preComp)
+ {
+ this.preComp = preComp;
+ }
+
+ public ECPoint[] getPreCompNeg()
+ {
+ return preCompNeg;
+ }
+
+ public void setPreCompNeg(ECPoint[] preCompNeg)
+ {
+ this.preCompNeg = preCompNeg;
+ }
+
+ public ECPoint getTwice()
+ {
+ return twice;
+ }
+
+ public void setTwice(ECPoint twice)
+ {
+ this.twice = twice;
+ }
+
+ public int getWidth()
+ {
+ return width;
+ }
+
+ public void setWidth(int width)
+ {
+ this.width = width;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafUtil.java
new file mode 100644
index 00000000..e74c8fb5
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafUtil.java
@@ -0,0 +1,685 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class WNafUtil
+{
+ public static final String PRECOMP_NAME = "bc_wnaf";
+
+ private static final int[] DEFAULT_WINDOW_SIZE_CUTOFFS = new int[]{ 13, 41, 121, 337, 897, 2305 };
+ private static final int MAX_WIDTH = 16;
+
+ private static final byte[] EMPTY_BYTES = new byte[0];
+ private static final int[] EMPTY_INTS = new int[0];
+ private static final ECPoint[] EMPTY_POINTS = new ECPoint[0];
+
+ public static void configureBasepoint(ECPoint p)
+ {
+ final ECCurve c = p.getCurve();
+ if (null == c)
+ {
+ return;
+ }
+
+ BigInteger n = c.getOrder();
+ int bits = (null == n) ? c.getFieldSize() + 1 : n.bitLength();
+ final int confWidth = Math.min(MAX_WIDTH, getWindowSize(bits) + 3);
+
+ c.precompute(p, PRECOMP_NAME, new PreCompCallback()
+ {
+ public PreCompInfo precompute(PreCompInfo existing)
+ {
+ WNafPreCompInfo existingWNaf = (existing instanceof WNafPreCompInfo) ? (WNafPreCompInfo)existing : null;
+
+ if (null != existingWNaf && existingWNaf.getConfWidth() == confWidth)
+ {
+ existingWNaf.setPromotionCountdown(0);
+ return existingWNaf;
+ }
+
+ WNafPreCompInfo result = new WNafPreCompInfo();
+
+ result.setPromotionCountdown(0);
+ result.setConfWidth(confWidth);
+
+ if (null != existingWNaf)
+ {
+ result.setPreComp(existingWNaf.getPreComp());
+ result.setPreCompNeg(existingWNaf.getPreCompNeg());
+ result.setTwice(existingWNaf.getTwice());
+ result.setWidth(existingWNaf.getWidth());
+ }
+
+ return result;
+ }
+ });
+ }
+
+ public static int[] generateCompactNaf(BigInteger k)
+ {
+ if ((k.bitLength() >>> 16) != 0)
+ {
+ throw new IllegalArgumentException("'k' must have bitlength < 2^16");
+ }
+ if (k.signum() == 0)
+ {
+ return EMPTY_INTS;
+ }
+
+ BigInteger _3k = k.shiftLeft(1).add(k);
+
+ int bits = _3k.bitLength();
+ int[] naf = new int[bits >> 1];
+
+ BigInteger diff = _3k.xor(k);
+
+ int highBit = bits - 1, length = 0, zeroes = 0;
+ for (int i = 1; i < highBit; ++i)
+ {
+ if (!diff.testBit(i))
+ {
+ ++zeroes;
+ continue;
+ }
+
+ int digit = k.testBit(i) ? -1 : 1;
+ naf[length++] = (digit << 16) | zeroes;
+ zeroes = 1;
+ ++i;
+ }
+
+ naf[length++] = (1 << 16) | zeroes;
+
+ if (naf.length > length)
+ {
+ naf = trim(naf, length);
+ }
+
+ return naf;
+ }
+
+ public static int[] generateCompactWindowNaf(int width, BigInteger k)
+ {
+ if (width == 2)
+ {
+ return generateCompactNaf(k);
+ }
+
+ if (width < 2 || width > 16)
+ {
+ throw new IllegalArgumentException("'width' must be in the range [2, 16]");
+ }
+ if ((k.bitLength() >>> 16) != 0)
+ {
+ throw new IllegalArgumentException("'k' must have bitlength < 2^16");
+ }
+ if (k.signum() == 0)
+ {
+ return EMPTY_INTS;
+ }
+
+ int[] wnaf = new int[k.bitLength() / width + 1];
+
+ // 2^width and a mask and sign bit set accordingly
+ int pow2 = 1 << width;
+ int mask = pow2 - 1;
+ int sign = pow2 >>> 1;
+
+ boolean carry = false;
+ int length = 0, pos = 0;
+
+ while (pos <= k.bitLength())
+ {
+ if (k.testBit(pos) == carry)
+ {
+ ++pos;
+ continue;
+ }
+
+ k = k.shiftRight(pos);
+
+ int digit = k.intValue() & mask;
+ if (carry)
+ {
+ ++digit;
+ }
+
+ carry = (digit & sign) != 0;
+ if (carry)
+ {
+ digit -= pow2;
+ }
+
+ int zeroes = length > 0 ? pos - 1 : pos;
+ wnaf[length++] = (digit << 16) | zeroes;
+ pos = width;
+ }
+
+ // Reduce the WNAF array to its actual length
+ if (wnaf.length > length)
+ {
+ wnaf = trim(wnaf, length);
+ }
+
+ return wnaf;
+ }
+
+ public static byte[] generateJSF(BigInteger g, BigInteger h)
+ {
+ int digits = Math.max(g.bitLength(), h.bitLength()) + 1;
+ byte[] jsf = new byte[digits];
+
+ BigInteger k0 = g, k1 = h;
+ int j = 0, d0 = 0, d1 = 0;
+
+ int offset = 0;
+ while ((d0 | d1) != 0 || k0.bitLength() > offset || k1.bitLength() > offset)
+ {
+ int n0 = ((k0.intValue() >>> offset) + d0) & 7, n1 = ((k1.intValue() >>> offset) + d1) & 7;
+
+ int u0 = n0 & 1;
+ if (u0 != 0)
+ {
+ u0 -= (n0 & 2);
+ if ((n0 + u0) == 4 && (n1 & 3) == 2)
+ {
+ u0 = -u0;
+ }
+ }
+
+ int u1 = n1 & 1;
+ if (u1 != 0)
+ {
+ u1 -= (n1 & 2);
+ if ((n1 + u1) == 4 && (n0 & 3) == 2)
+ {
+ u1 = -u1;
+ }
+ }
+
+ if ((d0 << 1) == 1 + u0)
+ {
+ d0 ^= 1;
+ }
+ if ((d1 << 1) == 1 + u1)
+ {
+ d1 ^= 1;
+ }
+
+ if (++offset == 30)
+ {
+ offset = 0;
+ k0 = k0.shiftRight(30);
+ k1 = k1.shiftRight(30);
+ }
+
+ jsf[j++] = (byte)((u0 << 4) | (u1 & 0xF));
+ }
+
+ // Reduce the JSF array to its actual length
+ if (jsf.length > j)
+ {
+ jsf = trim(jsf, j);
+ }
+
+ return jsf;
+ }
+
+ public static byte[] generateNaf(BigInteger k)
+ {
+ if (k.signum() == 0)
+ {
+ return EMPTY_BYTES;
+ }
+
+ BigInteger _3k = k.shiftLeft(1).add(k);
+
+ int digits = _3k.bitLength() - 1;
+ byte[] naf = new byte[digits];
+
+ BigInteger diff = _3k.xor(k);
+
+ for (int i = 1; i < digits; ++i)
+ {
+ if (diff.testBit(i))
+ {
+ naf[i - 1] = (byte)(k.testBit(i) ? -1 : 1);
+ ++i;
+ }
+ }
+
+ naf[digits - 1] = 1;
+
+ return naf;
+ }
+
+ /**
+ * Computes the Window NAF (non-adjacent Form) of an integer.
+ * @param width The width <code>w</code> of the Window NAF. The width is
+ * defined as the minimal number <code>w</code>, such that for any
+ * <code>w</code> consecutive digits in the resulting representation, at
+ * most one is non-zero.
+ * @param k The integer of which the Window NAF is computed.
+ * @return The Window NAF of the given width, such that the following holds:
+ * <code>k = &sum;<sub>i=0</sub><sup>l-1</sup> k<sub>i</sub>2<sup>i</sup>
+ * </code>, where the <code>k<sub>i</sub></code> denote the elements of the
+ * returned <code>byte[]</code>.
+ */
+ public static byte[] generateWindowNaf(int width, BigInteger k)
+ {
+ if (width == 2)
+ {
+ return generateNaf(k);
+ }
+
+ if (width < 2 || width > 8)
+ {
+ throw new IllegalArgumentException("'width' must be in the range [2, 8]");
+ }
+ if (k.signum() == 0)
+ {
+ return EMPTY_BYTES;
+ }
+
+ byte[] wnaf = new byte[k.bitLength() + 1];
+
+ // 2^width and a mask and sign bit set accordingly
+ int pow2 = 1 << width;
+ int mask = pow2 - 1;
+ int sign = pow2 >>> 1;
+
+ boolean carry = false;
+ int length = 0, pos = 0;
+
+ while (pos <= k.bitLength())
+ {
+ if (k.testBit(pos) == carry)
+ {
+ ++pos;
+ continue;
+ }
+
+ k = k.shiftRight(pos);
+
+ int digit = k.intValue() & mask;
+ if (carry)
+ {
+ ++digit;
+ }
+
+ carry = (digit & sign) != 0;
+ if (carry)
+ {
+ digit -= pow2;
+ }
+
+ length += (length > 0) ? pos - 1 : pos;
+ wnaf[length++] = (byte)digit;
+ pos = width;
+ }
+
+ // Reduce the WNAF array to its actual length
+ if (wnaf.length > length)
+ {
+ wnaf = trim(wnaf, length);
+ }
+
+ return wnaf;
+ }
+
+ public static int getNafWeight(BigInteger k)
+ {
+ if (k.signum() == 0)
+ {
+ return 0;
+ }
+
+ BigInteger _3k = k.shiftLeft(1).add(k);
+ BigInteger diff = _3k.xor(k);
+
+ return diff.bitCount();
+ }
+
+ public static WNafPreCompInfo getWNafPreCompInfo(ECPoint p)
+ {
+ return getWNafPreCompInfo(p.getCurve().getPreCompInfo(p, PRECOMP_NAME));
+ }
+
+ public static WNafPreCompInfo getWNafPreCompInfo(PreCompInfo preCompInfo)
+ {
+ return (preCompInfo instanceof WNafPreCompInfo) ? (WNafPreCompInfo)preCompInfo : null;
+ }
+
+ /**
+ * Determine window width to use for a scalar multiplication of the given size.
+ *
+ * @param bits the bit-length of the scalar to multiply by
+ * @return the window size to use
+ */
+ public static int getWindowSize(int bits)
+ {
+ return getWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS, MAX_WIDTH);
+ }
+
+ /**
+ * Determine window width to use for a scalar multiplication of the given size.
+ *
+ * @param bits the bit-length of the scalar to multiply by
+ * @param maxWidth the maximum window width to return
+ * @return the window size to use
+ */
+ public static int getWindowSize(int bits, int maxWidth)
+ {
+ return getWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS, maxWidth);
+ }
+
+ /**
+ * Determine window width to use for a scalar multiplication of the given size.
+ *
+ * @param bits the bit-length of the scalar to multiply by
+ * @param windowSizeCutoffs a monotonically increasing list of bit sizes at which to increment the window width
+ * @return the window size to use
+ */
+ public static int getWindowSize(int bits, int[] windowSizeCutoffs)
+ {
+ return getWindowSize(bits, windowSizeCutoffs, MAX_WIDTH);
+ }
+
+ /**
+ * Determine window width to use for a scalar multiplication of the given size.
+ *
+ * @param bits the bit-length of the scalar to multiply by
+ * @param windowSizeCutoffs a monotonically increasing list of bit sizes at which to increment the window width
+ * @param maxWidth the maximum window width to return
+ * @return the window size to use
+ */
+ public static int getWindowSize(int bits, int[] windowSizeCutoffs, int maxWidth)
+ {
+ int w = 0;
+ for (; w < windowSizeCutoffs.length; ++w)
+ {
+ if (bits < windowSizeCutoffs[w])
+ {
+ break;
+ }
+ }
+
+ return Math.max(2, Math.min(maxWidth, w + 2));
+ }
+
+ public static WNafPreCompInfo precompute(final ECPoint p, final int minWidth, final boolean includeNegated)
+ {
+ final ECCurve c = p.getCurve();
+
+ return (WNafPreCompInfo)c.precompute(p, PRECOMP_NAME, new PreCompCallback()
+ {
+ public PreCompInfo precompute(PreCompInfo existing)
+ {
+ WNafPreCompInfo existingWNaf = (existing instanceof WNafPreCompInfo) ? (WNafPreCompInfo)existing : null;
+
+ int width = Math.max(2, Math.min(MAX_WIDTH, minWidth));
+ int reqPreCompLen = 1 << (width - 2);
+
+ if (checkExisting(existingWNaf, width, reqPreCompLen, includeNegated))
+ {
+ existingWNaf.decrementPromotionCountdown();
+ return existingWNaf;
+ }
+
+ WNafPreCompInfo result = new WNafPreCompInfo();
+
+ ECPoint[] preComp = null, preCompNeg = null;
+ ECPoint twiceP = null;
+
+ if (null != existingWNaf)
+ {
+ int promotionCountdown = existingWNaf.decrementPromotionCountdown();
+ result.setPromotionCountdown(promotionCountdown);
+
+ int confWidth = existingWNaf.getConfWidth();
+ result.setConfWidth(confWidth);
+
+ preComp = existingWNaf.getPreComp();
+ preCompNeg = existingWNaf.getPreCompNeg();
+ twiceP = existingWNaf.getTwice();
+ }
+
+ width = Math.min(MAX_WIDTH, Math.max(result.getConfWidth(), width));
+ reqPreCompLen = 1 << (width - 2);
+
+ int iniPreCompLen = 0;
+ if (null == preComp)
+ {
+ preComp = EMPTY_POINTS;
+ }
+ else
+ {
+ iniPreCompLen = preComp.length;
+ }
+
+ if (iniPreCompLen < reqPreCompLen)
+ {
+ preComp = resizeTable(preComp, reqPreCompLen);
+
+ if (reqPreCompLen == 1)
+ {
+ preComp[0] = p.normalize();
+ }
+ else
+ {
+ int curPreCompLen = iniPreCompLen;
+ if (curPreCompLen == 0)
+ {
+ preComp[0] = p;
+ curPreCompLen = 1;
+ }
+
+ ECFieldElement iso = null;
+
+ if (reqPreCompLen == 2)
+ {
+ preComp[1] = p.threeTimes();
+ }
+ else
+ {
+ ECPoint isoTwiceP = twiceP, last = preComp[curPreCompLen - 1];
+ if (null == isoTwiceP)
+ {
+ isoTwiceP = preComp[0].twice();
+ twiceP = isoTwiceP;
+
+ /*
+ * For Fp curves with Jacobian projective coordinates, use a (quasi-)isomorphism
+ * where 'twiceP' is "affine", so that the subsequent additions are cheaper. This
+ * also requires scaling the initial point's X, Y coordinates, and reversing the
+ * isomorphism as part of the subsequent normalization.
+ *
+ * NOTE: The correctness of this optimization depends on:
+ * 1) additions do not use the curve's A, B coefficients.
+ * 2) no special cases (i.e. Q +/- Q) when calculating 1P, 3P, 5P, ...
+ */
+ if (!twiceP.isInfinity() && ECAlgorithms.isFpCurve(c) && c.getFieldSize() >= 64)
+ {
+ switch (c.getCoordinateSystem())
+ {
+ case ECCurve.COORD_JACOBIAN:
+ case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ {
+ iso = twiceP.getZCoord(0);
+ isoTwiceP = c.createPoint(twiceP.getXCoord().toBigInteger(), twiceP.getYCoord()
+ .toBigInteger());
+
+ ECFieldElement iso2 = iso.square(), iso3 = iso2.multiply(iso);
+ last = last.scaleX(iso2).scaleY(iso3);
+
+ if (iniPreCompLen == 0)
+ {
+ preComp[0] = last;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ while (curPreCompLen < reqPreCompLen)
+ {
+ /*
+ * Compute the new ECPoints for the precomputation array. The values 1, 3,
+ * 5, ..., 2^(width-1)-1 times p are computed
+ */
+ preComp[curPreCompLen++] = last = last.add(isoTwiceP);
+ }
+ }
+
+ /*
+ * Having oft-used operands in affine form makes operations faster.
+ */
+ c.normalizeAll(preComp, iniPreCompLen, reqPreCompLen - iniPreCompLen, iso);
+ }
+ }
+
+ if (includeNegated)
+ {
+ int pos;
+ if (null == preCompNeg)
+ {
+ pos = 0;
+ preCompNeg = new ECPoint[reqPreCompLen];
+ }
+ else
+ {
+ pos = preCompNeg.length;
+ if (pos < reqPreCompLen)
+ {
+ preCompNeg = resizeTable(preCompNeg, reqPreCompLen);
+ }
+ }
+
+ while (pos < reqPreCompLen)
+ {
+ preCompNeg[pos] = preComp[pos].negate();
+ ++pos;
+ }
+ }
+
+ result.setPreComp(preComp);
+ result.setPreCompNeg(preCompNeg);
+ result.setTwice(twiceP);
+ result.setWidth(width);
+ return result;
+ }
+
+ private boolean checkExisting(WNafPreCompInfo existingWNaf, int width, int reqPreCompLen, boolean includeNegated)
+ {
+ return null != existingWNaf
+ && existingWNaf.getWidth() >= Math.max(existingWNaf.getConfWidth(), width)
+ && checkTable(existingWNaf.getPreComp(), reqPreCompLen)
+ && (!includeNegated || checkTable(existingWNaf.getPreCompNeg(), reqPreCompLen));
+ }
+
+ private boolean checkTable(ECPoint[] table, int reqLen)
+ {
+ return null != table && table.length >= reqLen;
+ }
+ });
+ }
+
+ public static WNafPreCompInfo precomputeWithPointMap(final ECPoint p, final ECPointMap pointMap, final WNafPreCompInfo fromWNaf,
+ final boolean includeNegated)
+ {
+ final ECCurve c = p.getCurve();
+
+ return (WNafPreCompInfo)c.precompute(p, PRECOMP_NAME, new PreCompCallback()
+ {
+ public PreCompInfo precompute(PreCompInfo existing)
+ {
+ WNafPreCompInfo existingWNaf = (existing instanceof WNafPreCompInfo) ? (WNafPreCompInfo)existing : null;
+
+ int width = fromWNaf.getWidth();
+ int reqPreCompLen = fromWNaf.getPreComp().length;
+
+ if (checkExisting(existingWNaf, width, reqPreCompLen, includeNegated))
+ {
+ existingWNaf.decrementPromotionCountdown();
+ return existingWNaf;
+ }
+
+ /*
+ * TODO Ideally this method would support incremental calculation, but given the
+ * existing use-cases it would be of little-to-no benefit.
+ */
+ WNafPreCompInfo result = new WNafPreCompInfo();
+
+ result.setPromotionCountdown(fromWNaf.getPromotionCountdown());
+
+ ECPoint twiceFrom = fromWNaf.getTwice();
+ if (null != twiceFrom)
+ {
+ ECPoint twice = pointMap.map(twiceFrom);
+ result.setTwice(twice);
+ }
+
+ ECPoint[] preCompFrom = fromWNaf.getPreComp();
+ ECPoint[] preComp = new ECPoint[preCompFrom.length];
+ for (int i = 0; i < preCompFrom.length; ++i)
+ {
+ preComp[i] = pointMap.map(preCompFrom[i]);
+ }
+ result.setPreComp(preComp);
+ result.setWidth(width);
+
+ if (includeNegated)
+ {
+ ECPoint[] preCompNeg = new ECPoint[preComp.length];
+ for (int i = 0; i < preCompNeg.length; ++i)
+ {
+ preCompNeg[i] = preComp[i].negate();
+ }
+ result.setPreCompNeg(preCompNeg);
+ }
+
+ return result;
+ }
+
+ private boolean checkExisting(WNafPreCompInfo existingWNaf, int width, int reqPreCompLen, boolean includeNegated)
+ {
+ return null != existingWNaf
+ && existingWNaf.getWidth() >= width
+ && checkTable(existingWNaf.getPreComp(), reqPreCompLen)
+ && (!includeNegated || checkTable(existingWNaf.getPreCompNeg(), reqPreCompLen));
+ }
+
+ private boolean checkTable(ECPoint[] table, int reqLen)
+ {
+ return null != table && table.length >= reqLen;
+ }
+ });
+ }
+
+ private static byte[] trim(byte[] a, int length)
+ {
+ byte[] result = new byte[length];
+ System.arraycopy(a, 0, result, 0, result.length);
+ return result;
+ }
+
+ private static int[] trim(int[] a, int length)
+ {
+ int[] result = new int[length];
+ System.arraycopy(a, 0, result, 0, result.length);
+ return result;
+ }
+
+ private static ECPoint[] resizeTable(ECPoint[] a, int length)
+ {
+ ECPoint[] result = new ECPoint[length];
+ System.arraycopy(a, 0, result, 0, a.length);
+ return result;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WTauNafMultiplier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WTauNafMultiplier.java
new file mode 100644
index 00000000..43308b12
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WTauNafMultiplier.java
@@ -0,0 +1,128 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+
+/**
+ * Class implementing the WTNAF (Window
+ * <code>&tau;</code>-adic Non-Adjacent Form) algorithm.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class WTauNafMultiplier extends AbstractECMultiplier
+{
+ // TODO Create WTauNafUtil class and move various functionality into it
+ static final String PRECOMP_NAME = "bc_wtnaf";
+
+ /**
+ * Multiplies a {@link com.android.internal.org.bouncycastle.math.ec.ECPoint.AbstractF2m ECPoint.AbstractF2m}
+ * by <code>k</code> using the reduced <code>&tau;</code>-adic NAF (RTNAF)
+ * method.
+ * @param point The ECPoint.AbstractF2m to multiply.
+ * @param k The integer by which to multiply <code>k</code>.
+ * @return <code>p</code> multiplied by <code>k</code>.
+ */
+ protected ECPoint multiplyPositive(ECPoint point, BigInteger k)
+ {
+ if (!(point instanceof ECPoint.AbstractF2m))
+ {
+ throw new IllegalArgumentException("Only ECPoint.AbstractF2m can be " +
+ "used in WTauNafMultiplier");
+ }
+
+ ECPoint.AbstractF2m p = (ECPoint.AbstractF2m)point;
+ ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m)p.getCurve();
+ int m = curve.getFieldSize();
+ byte a = curve.getA().toBigInteger().byteValue();
+ byte mu = Tnaf.getMu(a);
+ BigInteger[] s = curve.getSi();
+
+ ZTauElement rho = Tnaf.partModReduction(k, m, a, s, mu, (byte)10);
+
+ return multiplyWTnaf(p, rho, a, mu);
+ }
+
+ /**
+ * Multiplies a {@link com.android.internal.org.bouncycastle.math.ec.ECPoint.AbstractF2m ECPoint.AbstractF2m}
+ * by an element <code>&lambda;</code> of <code><b>Z</b>[&tau;]</code> using
+ * the <code>&tau;</code>-adic NAF (TNAF) method.
+ * @param p The ECPoint.AbstractF2m to multiply.
+ * @param lambda The element <code>&lambda;</code> of
+ * <code><b>Z</b>[&tau;]</code> of which to compute the
+ * <code>[&tau;]</code>-adic NAF.
+ * @return <code>p</code> multiplied by <code>&lambda;</code>.
+ */
+ private ECPoint.AbstractF2m multiplyWTnaf(ECPoint.AbstractF2m p, ZTauElement lambda, byte a, byte mu)
+ {
+ ZTauElement[] alpha = (a == 0) ? Tnaf.alpha0 : Tnaf.alpha1;
+
+ BigInteger tw = Tnaf.getTw(mu, Tnaf.WIDTH);
+
+ byte[]u = Tnaf.tauAdicWNaf(mu, lambda, Tnaf.WIDTH,
+ BigInteger.valueOf(Tnaf.POW_2_WIDTH), tw, alpha);
+
+ return multiplyFromWTnaf(p, u);
+ }
+
+ /**
+ * Multiplies a {@link com.android.internal.org.bouncycastle.math.ec.ECPoint.AbstractF2m ECPoint.AbstractF2m}
+ * by an element <code>&lambda;</code> of <code><b>Z</b>[&tau;]</code>
+ * using the window <code>&tau;</code>-adic NAF (TNAF) method, given the
+ * WTNAF of <code>&lambda;</code>.
+ * @param p The ECPoint.AbstractF2m to multiply.
+ * @param u The the WTNAF of <code>&lambda;</code>..
+ * @return <code>&lambda; * p</code>
+ */
+ private static ECPoint.AbstractF2m multiplyFromWTnaf(final ECPoint.AbstractF2m p, byte[] u)
+ {
+ ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m)p.getCurve();
+ final byte a = curve.getA().toBigInteger().byteValue();
+
+ WTauNafPreCompInfo preCompInfo = (WTauNafPreCompInfo)curve.precompute(p, PRECOMP_NAME, new PreCompCallback()
+ {
+ public PreCompInfo precompute(PreCompInfo existing)
+ {
+ if (existing instanceof WTauNafPreCompInfo)
+ {
+ return existing;
+ }
+
+ WTauNafPreCompInfo result = new WTauNafPreCompInfo();
+ result.setPreComp(Tnaf.getPreComp(p, a));
+ return result;
+ }
+ });
+
+ ECPoint.AbstractF2m[] pu = preCompInfo.getPreComp();
+
+ // TODO Include negations in precomp (optionally) and use from here
+ ECPoint.AbstractF2m[] puNeg = new ECPoint.AbstractF2m[pu.length];
+ for (int i = 0; i < pu.length; ++i)
+ {
+ puNeg[i] = (ECPoint.AbstractF2m)pu[i].negate();
+ }
+
+
+ // q = infinity
+ ECPoint.AbstractF2m q = (ECPoint.AbstractF2m) p.getCurve().getInfinity();
+
+ int tauCount = 0;
+ for (int i = u.length - 1; i >= 0; i--)
+ {
+ ++tauCount;
+ int ui = u[i];
+ if (ui != 0)
+ {
+ q = q.tauPow(tauCount);
+ tauCount = 0;
+
+ ECPoint x = ui > 0 ? pu[ui >>> 1] : puNeg[(-ui) >>> 1];
+ q = (ECPoint.AbstractF2m)q.add(x);
+ }
+ }
+ if (tauCount > 0)
+ {
+ q = q.tauPow(tauCount);
+ }
+ return q;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WTauNafPreCompInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WTauNafPreCompInfo.java
new file mode 100644
index 00000000..498a91bf
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WTauNafPreCompInfo.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+/**
+ * Class holding precomputation data for the WTNAF (Window
+ * <code>&tau;</code>-adic Non-Adjacent Form) algorithm.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class WTauNafPreCompInfo implements PreCompInfo
+{
+ /**
+ * Array holding the precomputed <code>ECPoint.AbstractF2m</code>s used for the
+ * WTNAF multiplication.
+ */
+ protected ECPoint.AbstractF2m[] preComp = null;
+
+ public ECPoint.AbstractF2m[] getPreComp()
+ {
+ return preComp;
+ }
+
+ public void setPreComp(ECPoint.AbstractF2m[] preComp)
+ {
+ this.preComp = preComp;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ZTauElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ZTauElement.java
new file mode 100644
index 00000000..cf2e8a46
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ZTauElement.java
@@ -0,0 +1,38 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+
+/**
+ * Class representing an element of <code><b>Z</b>[&tau;]</code>. Let
+ * <code>&lambda;</code> be an element of <code><b>Z</b>[&tau;]</code>. Then
+ * <code>&lambda;</code> is given as <code>&lambda; = u + v&tau;</code>. The
+ * components <code>u</code> and <code>v</code> may be used directly, there
+ * are no accessor methods.
+ * Immutable class.
+ */
+class ZTauElement
+{
+ /**
+ * The &quot;real&quot; part of <code>&lambda;</code>.
+ */
+ public final BigInteger u;
+
+ /**
+ * The &quot;<code>&tau;</code>-adic&quot; part of <code>&lambda;</code>.
+ */
+ public final BigInteger v;
+
+ /**
+ * Constructor for an element <code>&lambda;</code> of
+ * <code><b>Z</b>[&tau;]</code>.
+ * @param u The &quot;real&quot; part of <code>&lambda;</code>.
+ * @param v The &quot;<code>&tau;</code>-adic&quot; part of
+ * <code>&lambda;</code>.
+ */
+ public ZTauElement(BigInteger u, BigInteger v)
+ {
+ this.u = u;
+ this.v = v;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java
new file mode 100644
index 00000000..21c4ad56
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java
@@ -0,0 +1,165 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.ec.AbstractECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat192;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP192K1Curve extends ECCurve.AbstractFp
+{
+ public static final BigInteger q = SecP192K1FieldElement.Q;
+
+ private static final int SECP192K1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP192K1_AFFINE_ZS = new ECFieldElement[] { new SecP192K1FieldElement(ECConstants.ONE) };
+
+ protected SecP192K1Point infinity;
+
+ public SecP192K1Curve()
+ {
+ super(q);
+
+ this.infinity = new SecP192K1Point(this, null, null);
+
+ this.a = fromBigInteger(ECConstants.ZERO);
+ this.b = fromBigInteger(BigInteger.valueOf(3));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"));
+ this.cofactor = BigInteger.valueOf(1);
+
+ this.coord = SECP192K1_DEFAULT_COORDS;
+ }
+
+ protected ECCurve cloneCurve()
+ {
+ return new SecP192K1Curve();
+ }
+
+ public boolean supportsCoordinateSystem(int coord)
+ {
+ switch (coord)
+ {
+ case COORD_JACOBIAN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public int getFieldSize()
+ {
+ return q.bitLength();
+ }
+
+ public ECFieldElement fromBigInteger(BigInteger x)
+ {
+ return new SecP192K1FieldElement(x);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
+ {
+ return new SecP192K1Point(this, x, y);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ return new SecP192K1Point(this, x, y, zs);
+ }
+
+ public ECPoint getInfinity()
+ {
+ return infinity;
+ }
+
+ public ECLookupTable createCacheSafeLookupTable(ECPoint[] points, int off, final int len)
+ {
+ final int FE_INTS = 6;
+
+ final int[] table = new int[len * FE_INTS * 2];
+ {
+ int pos = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ ECPoint p = points[off + i];
+ Nat192.copy(((SecP192K1FieldElement)p.getRawXCoord()).x, 0, table, pos); pos += FE_INTS;
+ Nat192.copy(((SecP192K1FieldElement)p.getRawYCoord()).x, 0, table, pos); pos += FE_INTS;
+ }
+ }
+
+ return new AbstractECLookupTable()
+ {
+ public int getSize()
+ {
+ return len;
+ }
+
+ public ECPoint lookup(int index)
+ {
+ int[] x = Nat192.create(), y = Nat192.create();
+ int pos = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ int MASK = ((i ^ index) - 1) >> 31;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] ^= table[pos + j] & MASK;
+ y[j] ^= table[pos + FE_INTS + j] & MASK;
+ }
+
+ pos += (FE_INTS * 2);
+ }
+
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat192.create(), y = Nat192.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP192K1FieldElement(x), new SecP192K1FieldElement(y), SECP192K1_AFFINE_ZS);
+ }
+ };
+ }
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat192.create();
+ SecP192K1Field.random(r, x);
+ return new SecP192K1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat192.create();
+ SecP192K1Field.randomMult(r, x);
+ return new SecP192K1FieldElement(x);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java
new file mode 100644
index 00000000..6d8ba91e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java
@@ -0,0 +1,220 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.raw.Mod;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat192;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP192K1Field
+{
+ // 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1
+ static final int[] P = new int[]{ 0xFFFFEE37, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x013C4FD1, 0x00002392, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0xFFFFDC6E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExtInv = new int[]{ 0xFEC3B02F, 0xFFFFDC6D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0x00002391, 0x00000002 };
+ private static final int P5 = 0xFFFFFFFF;
+ private static final int PExt11 = 0xFFFFFFFF;
+ private static final int PInv33 = 0x11C9;
+
+ public static void add(int[] x, int[] y, int[] z)
+ {
+ int c = Nat192.add(x, y, z);
+ if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
+ {
+ Nat.add33To(6, PInv33, z);
+ }
+ }
+
+ public static void addExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.add(12, xx, yy, zz);
+ if (c != 0 || (zz[11] == PExt11 && Nat.gte(12, zz, PExt)))
+ {
+ if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.incAt(12, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void addOne(int[] x, int[] z)
+ {
+ int c = Nat.inc(6, x, z);
+ if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
+ {
+ Nat.add33To(6, PInv33, z);
+ }
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ int[] z = Nat192.fromBigInteger(x);
+ if (z[5] == P5 && Nat192.gte(z, P))
+ {
+ Nat192.subFrom(P, z);
+ }
+ return z;
+ }
+
+ public static void half(int[] x, int[] z)
+ {
+ if ((x[0] & 1) == 0)
+ {
+ Nat.shiftDownBit(6, x, 0, z);
+ }
+ else
+ {
+ int c = Nat192.add(x, P, z);
+ Nat.shiftDownBit(6, z, c);
+ }
+ }
+
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 6; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static void multiply(int[] x, int[] y, int[] z)
+ {
+ int[] tt = Nat192.createExt();
+ Nat192.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
+ public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
+ {
+ int c = Nat192.mulAddTo(x, y, zz);
+ if (c != 0 || (zz[11] == PExt11 && Nat.gte(12, zz, PExt)))
+ {
+ if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.incAt(12, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void negate(int[] x, int[] z)
+ {
+ if (0 != isZero(x))
+ {
+ Nat192.sub(P, P, z);
+ }
+ else
+ {
+ Nat192.sub(P, x, z);
+ }
+ }
+
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[6 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 6);
+ }
+ while (0 == Nat.lessThan(6, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
+ public static void reduce(int[] xx, int[] z)
+ {
+ long cc = Nat192.mul33Add(PInv33, xx, 6, xx, 0, z, 0);
+ int c = Nat192.mul33DWordAdd(PInv33, cc, z, 0);
+
+ // assert c == 0L || c == 1L;
+
+ if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
+ {
+ Nat.add33To(6, PInv33, z);
+ }
+ }
+
+ public static void reduce32(int x, int[] z)
+ {
+ if ((x != 0 && Nat192.mul33WordAdd(PInv33, x, z, 0) != 0)
+ || (z[5] == P5 && Nat192.gte(z, P)))
+ {
+ Nat.add33To(6, PInv33, z);
+ }
+ }
+
+ public static void square(int[] x, int[] z)
+ {
+ int[] tt = Nat192.createExt();
+ Nat192.square(x, tt);
+ reduce(tt, z);
+ }
+
+ public static void squareN(int[] x, int n, int[] z)
+ {
+// assert n > 0;
+
+ int[] tt = Nat192.createExt();
+ Nat192.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat192.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
+ public static void subtract(int[] x, int[] y, int[] z)
+ {
+ int c = Nat192.sub(x, y, z);
+ if (c != 0)
+ {
+ Nat.sub33From(6, PInv33, z);
+ }
+ }
+
+ public static void subtractExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.sub(12, xx, yy, zz);
+ if (c != 0)
+ {
+ if (Nat.subFrom(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.decAt(12, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void twice(int[] x, int[] z)
+ {
+ int c = Nat.shiftUpBit(6, x, 0, z);
+ if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
+ {
+ Nat.add33To(6, PInv33, z);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java
new file mode 100644
index 00000000..39d8ef08
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java
@@ -0,0 +1,218 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.raw.Nat192;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP192K1FieldElement extends ECFieldElement.AbstractFp
+{
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"));
+
+ protected int[] x;
+
+ public SecP192K1FieldElement(BigInteger x)
+ {
+ if (x == null || x.signum() < 0 || x.compareTo(Q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid for SecP192K1FieldElement");
+ }
+
+ this.x = SecP192K1Field.fromBigInteger(x);
+ }
+
+ public SecP192K1FieldElement()
+ {
+ this.x = Nat192.create();
+ }
+
+ protected SecP192K1FieldElement(int[] x)
+ {
+ this.x = x;
+ }
+
+ public boolean isZero()
+ {
+ return Nat192.isZero(x);
+ }
+
+ public boolean isOne()
+ {
+ return Nat192.isOne(x);
+ }
+
+ public boolean testBitZero()
+ {
+ return Nat192.getBit(x, 0) == 1;
+ }
+
+ public BigInteger toBigInteger()
+ {
+ return Nat192.toBigInteger(x);
+ }
+
+ public String getFieldName()
+ {
+ return "SecP192K1Field";
+ }
+
+ public int getFieldSize()
+ {
+ return Q.bitLength();
+ }
+
+ public ECFieldElement add(ECFieldElement b)
+ {
+ int[] z = Nat192.create();
+ SecP192K1Field.add(x, ((SecP192K1FieldElement)b).x, z);
+ return new SecP192K1FieldElement(z);
+ }
+
+ public ECFieldElement addOne()
+ {
+ int[] z = Nat192.create();
+ SecP192K1Field.addOne(x, z);
+ return new SecP192K1FieldElement(z);
+ }
+
+ public ECFieldElement subtract(ECFieldElement b)
+ {
+ int[] z = Nat192.create();
+ SecP192K1Field.subtract(x, ((SecP192K1FieldElement)b).x, z);
+ return new SecP192K1FieldElement(z);
+ }
+
+ public ECFieldElement multiply(ECFieldElement b)
+ {
+ int[] z = Nat192.create();
+ SecP192K1Field.multiply(x, ((SecP192K1FieldElement)b).x, z);
+ return new SecP192K1FieldElement(z);
+ }
+
+ public ECFieldElement divide(ECFieldElement b)
+ {
+// return multiply(b.invert());
+ int[] z = Nat192.create();
+ SecP192K1Field.inv(((SecP192K1FieldElement)b).x, z);
+ SecP192K1Field.multiply(z, x, z);
+ return new SecP192K1FieldElement(z);
+ }
+
+ public ECFieldElement negate()
+ {
+ int[] z = Nat192.create();
+ SecP192K1Field.negate(x, z);
+ return new SecP192K1FieldElement(z);
+ }
+
+ public ECFieldElement square()
+ {
+ int[] z = Nat192.create();
+ SecP192K1Field.square(x, z);
+ return new SecP192K1FieldElement(z);
+ }
+
+ public ECFieldElement invert()
+ {
+// return new SecP192K1FieldElement(toBigInteger().modInverse(Q));
+ int[] z = Nat192.create();
+ SecP192K1Field.inv(x, z);
+ return new SecP192K1FieldElement(z);
+ }
+
+ /**
+ * return a sqrt root - the routine verifies that the calculation returns the right value - if
+ * none exists it returns null.
+ */
+ public ECFieldElement sqrt()
+ {
+ /*
+ * Raise this element to the exponent 2^190 - 2^30 - 2^10 - 2^6 - 2^5 - 2^4 - 2^1
+ *
+ * Breaking up the exponent's binary representation into "repunits", we get:
+ * { 159 1s } { 1 0s } { 19 1s } { 1 0s } { 3 1s } { 3 0s } { 3 1s } { 1 0s }
+ *
+ * Therefore we need an addition chain containing 3, 19, 159 (the lengths of the repunits)
+ * We use: 1, 2, [3], 6, 8, 16, [19], 35, 70, 140, [159]
+ */
+
+ int[] x1 = this.x;
+ if (Nat192.isZero(x1) || Nat192.isOne(x1))
+ {
+ return this;
+ }
+
+ int[] x2 = Nat192.create();
+ SecP192K1Field.square(x1, x2);
+ SecP192K1Field.multiply(x2, x1, x2);
+ int[] x3 = Nat192.create();
+ SecP192K1Field.square(x2, x3);
+ SecP192K1Field.multiply(x3, x1, x3);
+ int[] x6 = Nat192.create();
+ SecP192K1Field.squareN(x3, 3, x6);
+ SecP192K1Field.multiply(x6, x3, x6);
+ int[] x8 = x6;
+ SecP192K1Field.squareN(x6, 2, x8);
+ SecP192K1Field.multiply(x8, x2, x8);
+ int[] x16 = x2;
+ SecP192K1Field.squareN(x8, 8, x16);
+ SecP192K1Field.multiply(x16, x8, x16);
+ int[] x19 = x8;
+ SecP192K1Field.squareN(x16, 3, x19);
+ SecP192K1Field.multiply(x19, x3, x19);
+ int[] x35 = Nat192.create();
+ SecP192K1Field.squareN(x19, 16, x35);
+ SecP192K1Field.multiply(x35, x16, x35);
+ int[] x70 = x16;
+ SecP192K1Field.squareN(x35, 35, x70);
+ SecP192K1Field.multiply(x70, x35, x70);
+ int[] x140 = x35;
+ SecP192K1Field.squareN(x70, 70, x140);
+ SecP192K1Field.multiply(x140, x70, x140);
+ int[] x159 = x70;
+ SecP192K1Field.squareN(x140, 19, x159);
+ SecP192K1Field.multiply(x159, x19, x159);
+
+ int[] t1 = x159;
+ SecP192K1Field.squareN(t1, 20, t1);
+ SecP192K1Field.multiply(t1, x19, t1);
+ SecP192K1Field.squareN(t1, 4, t1);
+ SecP192K1Field.multiply(t1, x3, t1);
+ SecP192K1Field.squareN(t1, 6, t1);
+ SecP192K1Field.multiply(t1, x3, t1);
+ SecP192K1Field.square(t1, t1);
+
+ int[] t2 = x3;
+ SecP192K1Field.square(t1, t2);
+
+ return Nat192.eq(x1, t2) ? new SecP192K1FieldElement(t1) : null;
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof SecP192K1FieldElement))
+ {
+ return false;
+ }
+
+ SecP192K1FieldElement o = (SecP192K1FieldElement)other;
+ return Nat192.eq(x, o.x);
+ }
+
+ public int hashCode()
+ {
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 6);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java
new file mode 100644
index 00000000..632f5710
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java
@@ -0,0 +1,260 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat192;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP192K1Point extends ECPoint.AbstractFp
+{
+ SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ super(curve, x, y);
+ }
+
+ SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ super(curve, x, y, zs);
+ }
+
+ protected ECPoint detach()
+ {
+ return new SecP192K1Point(null, getAffineXCoord(), getAffineYCoord());
+ }
+
+ // B.3 pg 62
+ public ECPoint add(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return this;
+ }
+ if (this == b)
+ {
+ return twice();
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP192K1FieldElement X1 = (SecP192K1FieldElement)this.x, Y1 = (SecP192K1FieldElement)this.y;
+ SecP192K1FieldElement X2 = (SecP192K1FieldElement)b.getXCoord(), Y2 = (SecP192K1FieldElement)b.getYCoord();
+
+ SecP192K1FieldElement Z1 = (SecP192K1FieldElement)this.zs[0];
+ SecP192K1FieldElement Z2 = (SecP192K1FieldElement)b.getZCoord(0);
+
+ int c;
+ int[] tt1 = Nat192.createExt();
+ int[] t2 = Nat192.create();
+ int[] t3 = Nat192.create();
+ int[] t4 = Nat192.create();
+
+ boolean Z1IsOne = Z1.isOne();
+ int[] U2, S2;
+ if (Z1IsOne)
+ {
+ U2 = X2.x;
+ S2 = Y2.x;
+ }
+ else
+ {
+ S2 = t3;
+ SecP192K1Field.square(Z1.x, S2);
+
+ U2 = t2;
+ SecP192K1Field.multiply(S2, X2.x, U2);
+
+ SecP192K1Field.multiply(S2, Z1.x, S2);
+ SecP192K1Field.multiply(S2, Y2.x, S2);
+ }
+
+ boolean Z2IsOne = Z2.isOne();
+ int[] U1, S1;
+ if (Z2IsOne)
+ {
+ U1 = X1.x;
+ S1 = Y1.x;
+ }
+ else
+ {
+ S1 = t4;
+ SecP192K1Field.square(Z2.x, S1);
+
+ U1 = tt1;
+ SecP192K1Field.multiply(S1, X1.x, U1);
+
+ SecP192K1Field.multiply(S1, Z2.x, S1);
+ SecP192K1Field.multiply(S1, Y1.x, S1);
+ }
+
+ int[] H = Nat192.create();
+ SecP192K1Field.subtract(U1, U2, H);
+
+ int[] R = t2;
+ SecP192K1Field.subtract(S1, S2, R);
+
+ // Check if b == this or b == -this
+ if (Nat192.isZero(H))
+ {
+ if (Nat192.isZero(R))
+ {
+ // this == b, i.e. this must be doubled
+ return this.twice();
+ }
+
+ // this == -b, i.e. the result is the point at infinity
+ return curve.getInfinity();
+ }
+
+ int[] HSquared = t3;
+ SecP192K1Field.square(H, HSquared);
+
+ int[] G = Nat192.create();
+ SecP192K1Field.multiply(HSquared, H, G);
+
+ int[] V = t3;
+ SecP192K1Field.multiply(HSquared, U1, V);
+
+ SecP192K1Field.negate(G, G);
+ Nat192.mul(S1, G, tt1);
+
+ c = Nat192.addBothTo(V, V, G);
+ SecP192K1Field.reduce32(c, G);
+
+ SecP192K1FieldElement X3 = new SecP192K1FieldElement(t4);
+ SecP192K1Field.square(R, X3.x);
+ SecP192K1Field.subtract(X3.x, G, X3.x);
+
+ SecP192K1FieldElement Y3 = new SecP192K1FieldElement(G);
+ SecP192K1Field.subtract(V, X3.x, Y3.x);
+ SecP192K1Field.multiplyAddToExt(Y3.x, R, tt1);
+ SecP192K1Field.reduce(tt1, Y3.x);
+
+ SecP192K1FieldElement Z3 = new SecP192K1FieldElement(H);
+ if (!Z1IsOne)
+ {
+ SecP192K1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+ if (!Z2IsOne)
+ {
+ SecP192K1Field.multiply(Z3.x, Z2.x, Z3.x);
+ }
+
+ ECFieldElement[] zs = new ECFieldElement[] { Z3 };
+
+ return new SecP192K1Point(curve, X3, Y3, zs);
+ }
+
+ // B.3 pg 62
+ public ECPoint twice()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP192K1FieldElement Y1 = (SecP192K1FieldElement)this.y;
+ if (Y1.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ SecP192K1FieldElement X1 = (SecP192K1FieldElement)this.x, Z1 = (SecP192K1FieldElement)this.zs[0];
+
+ int c;
+
+ int[] Y1Squared = Nat192.create();
+ SecP192K1Field.square(Y1.x, Y1Squared);
+
+ int[] T = Nat192.create();
+ SecP192K1Field.square(Y1Squared, T);
+
+ int[] M = Nat192.create();
+ SecP192K1Field.square(X1.x, M);
+ c = Nat192.addBothTo(M, M, M);
+ SecP192K1Field.reduce32(c, M);
+
+ int[] S = Y1Squared;
+ SecP192K1Field.multiply(Y1Squared, X1.x, S);
+ c = Nat.shiftUpBits(6, S, 2, 0);
+ SecP192K1Field.reduce32(c, S);
+
+ int[] t1 = Nat192.create();
+ c = Nat.shiftUpBits(6, T, 3, 0, t1);
+ SecP192K1Field.reduce32(c, t1);
+
+ SecP192K1FieldElement X3 = new SecP192K1FieldElement(T);
+ SecP192K1Field.square(M, X3.x);
+ SecP192K1Field.subtract(X3.x, S, X3.x);
+ SecP192K1Field.subtract(X3.x, S, X3.x);
+
+ SecP192K1FieldElement Y3 = new SecP192K1FieldElement(S);
+ SecP192K1Field.subtract(S, X3.x, Y3.x);
+ SecP192K1Field.multiply(Y3.x, M, Y3.x);
+ SecP192K1Field.subtract(Y3.x, t1, Y3.x);
+
+ SecP192K1FieldElement Z3 = new SecP192K1FieldElement(M);
+ SecP192K1Field.twice(Y1.x, Z3.x);
+ if (!Z1.isOne())
+ {
+ SecP192K1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+
+ return new SecP192K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
+ }
+
+ public ECPoint twicePlus(ECPoint b)
+ {
+ if (this == b)
+ {
+ return threeTimes();
+ }
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return twice();
+ }
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return b;
+ }
+
+ return twice().add(b);
+ }
+
+ public ECPoint threeTimes()
+ {
+ if (this.isInfinity() || this.y.isZero())
+ {
+ return this;
+ }
+
+ // NOTE: Be careful about recursions between twicePlus and threeTimes
+ return twice().add(this);
+ }
+
+ public ECPoint negate()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ return new SecP192K1Point(curve, this.x, this.y.negate(), this.zs);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java
new file mode 100644
index 00000000..c052ddec
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java
@@ -0,0 +1,167 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.ec.AbstractECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat192;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP192R1Curve extends ECCurve.AbstractFp
+{
+ public static final BigInteger q = SecP192R1FieldElement.Q;
+
+ private static final int SECP192R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP192R1_AFFINE_ZS = new ECFieldElement[] { new SecP192R1FieldElement(ECConstants.ONE) };
+
+ protected SecP192R1Point infinity;
+
+ public SecP192R1Curve()
+ {
+ super(q);
+
+ this.infinity = new SecP192R1Point(this, null, null);
+
+ this.a = fromBigInteger(new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")));
+ this.b = fromBigInteger(new BigInteger(1,
+ Hex.decodeStrict("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"));
+ this.cofactor = BigInteger.valueOf(1);
+
+ this.coord = SECP192R1_DEFAULT_COORDS;
+ }
+
+ protected ECCurve cloneCurve()
+ {
+ return new SecP192R1Curve();
+ }
+
+ public boolean supportsCoordinateSystem(int coord)
+ {
+ switch (coord)
+ {
+ case COORD_JACOBIAN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public int getFieldSize()
+ {
+ return q.bitLength();
+ }
+
+ public ECFieldElement fromBigInteger(BigInteger x)
+ {
+ return new SecP192R1FieldElement(x);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
+ {
+ return new SecP192R1Point(this, x, y);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ return new SecP192R1Point(this, x, y, zs);
+ }
+
+ public ECPoint getInfinity()
+ {
+ return infinity;
+ }
+
+ public ECLookupTable createCacheSafeLookupTable(ECPoint[] points, int off, final int len)
+ {
+ final int FE_INTS = 6;
+
+ final int[] table = new int[len * FE_INTS * 2];
+ {
+ int pos = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ ECPoint p = points[off + i];
+ Nat192.copy(((SecP192R1FieldElement)p.getRawXCoord()).x, 0, table, pos); pos += FE_INTS;
+ Nat192.copy(((SecP192R1FieldElement)p.getRawYCoord()).x, 0, table, pos); pos += FE_INTS;
+ }
+ }
+
+ return new AbstractECLookupTable()
+ {
+ public int getSize()
+ {
+ return len;
+ }
+
+ public ECPoint lookup(int index)
+ {
+ int[] x = Nat192.create(), y = Nat192.create();
+ int pos = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ int MASK = ((i ^ index) - 1) >> 31;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] ^= table[pos + j] & MASK;
+ y[j] ^= table[pos + FE_INTS + j] & MASK;
+ }
+
+ pos += (FE_INTS * 2);
+ }
+
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat192.create(), y = Nat192.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP192R1FieldElement(x), new SecP192R1FieldElement(y), SECP192R1_AFFINE_ZS);
+ }
+ };
+ }
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat192.create();
+ SecP192R1Field.random(r, x);
+ return new SecP192R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat192.create();
+ SecP192R1Field.randomMult(r, x);
+ return new SecP192R1FieldElement(x);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java
new file mode 100644
index 00000000..580aa328
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java
@@ -0,0 +1,329 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.raw.Mod;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat192;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP192R1Field
+{
+ private static final long M = 0xFFFFFFFFL;
+
+ // 2^192 - 2^64 - 1
+ static final int[] P = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000,
+ 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFE,
+ 0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000002 };
+ private static final int P5 = 0xFFFFFFFF;
+ private static final int PExt11 = 0xFFFFFFFF;
+
+ public static void add(int[] x, int[] y, int[] z)
+ {
+ int c = Nat192.add(x, y, z);
+ if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ public static void addExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.add(12, xx, yy, zz);
+ if (c != 0 || (zz[11] == PExt11 && Nat.gte(12, zz, PExt)))
+ {
+ if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.incAt(12, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void addOne(int[] x, int[] z)
+ {
+ int c = Nat.inc(6, x, z);
+ if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ int[] z = Nat192.fromBigInteger(x);
+ if (z[5] == P5 && Nat192.gte(z, P))
+ {
+ Nat192.subFrom(P, z);
+ }
+ return z;
+ }
+
+ public static void half(int[] x, int[] z)
+ {
+ if ((x[0] & 1) == 0)
+ {
+ Nat.shiftDownBit(6, x, 0, z);
+ }
+ else
+ {
+ int c = Nat192.add(x, P, z);
+ Nat.shiftDownBit(6, z, c);
+ }
+ }
+
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 6; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static void multiply(int[] x, int[] y, int[] z)
+ {
+ int[] tt = Nat192.createExt();
+ Nat192.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
+ public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
+ {
+ int c = Nat192.mulAddTo(x, y, zz);
+ if (c != 0 || (zz[11] == PExt11 && Nat.gte(12, zz, PExt)))
+ {
+ if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.incAt(12, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void negate(int[] x, int[] z)
+ {
+ if (0 != isZero(x))
+ {
+ Nat192.sub(P, P, z);
+ }
+ else
+ {
+ Nat192.sub(P, x, z);
+ }
+ }
+
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[6 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 6);
+ }
+ while (0 == Nat.lessThan(6, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
+ public static void reduce(int[] xx, int[] z)
+ {
+ long xx06 = xx[6] & M, xx07 = xx[7] & M, xx08 = xx[8] & M;
+ long xx09 = xx[9] & M, xx10 = xx[10] & M, xx11 = xx[11] & M;
+
+ long t0 = xx06 + xx10;
+ long t1 = xx07 + xx11;
+
+ long cc = 0;
+ cc += (xx[0] & M) + t0;
+ int z0 = (int)cc;
+ cc >>= 32;
+ cc += (xx[1] & M) + t1;
+ z[1] = (int)cc;
+ cc >>= 32;
+
+ t0 += xx08;
+ t1 += xx09;
+
+ cc += (xx[2] & M) + t0;
+ long z2 = cc & M;
+ cc >>= 32;
+ cc += (xx[3] & M) + t1;
+ z[3] = (int)cc;
+ cc >>= 32;
+
+ t0 -= xx06;
+ t1 -= xx07;
+
+ cc += (xx[4] & M) + t0;
+ z[4] = (int)cc;
+ cc >>= 32;
+ cc += (xx[5] & M) + t1;
+ z[5] = (int)cc;
+ cc >>= 32;
+
+ z2 += cc;
+
+ cc += (z0 & M);
+ z[0] = (int)cc;
+ cc >>= 32;
+ if (cc != 0)
+ {
+ cc += (z[1] & M);
+ z[1] = (int)cc;
+ z2 += cc >> 32;
+ }
+ z[2] = (int)z2;
+ cc = z2 >> 32;
+
+// assert cc == 0 || cc == 1;
+
+ if ((cc != 0 && Nat.incAt(6, z, 3) != 0)
+ || (z[5] == P5 && Nat192.gte(z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ public static void reduce32(int x, int[] z)
+ {
+ long cc = 0;
+
+ if (x != 0)
+ {
+ long xx06 = x & M;
+
+ cc += (z[0] & M) + xx06;
+ z[0] = (int)cc;
+ cc >>= 32;
+ if (cc != 0)
+ {
+ cc += (z[1] & M);
+ z[1] = (int)cc;
+ cc >>= 32;
+ }
+ cc += (z[2] & M) + xx06;
+ z[2] = (int)cc;
+ cc >>= 32;
+
+// assert cc == 0 || cc == 1;
+ }
+
+ if ((cc != 0 && Nat.incAt(6, z, 3) != 0)
+ || (z[5] == P5 && Nat192.gte(z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ public static void square(int[] x, int[] z)
+ {
+ int[] tt = Nat192.createExt();
+ Nat192.square(x, tt);
+ reduce(tt, z);
+ }
+
+ public static void squareN(int[] x, int n, int[] z)
+ {
+// assert n > 0;
+
+ int[] tt = Nat192.createExt();
+ Nat192.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat192.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
+ public static void subtract(int[] x, int[] y, int[] z)
+ {
+ int c = Nat192.sub(x, y, z);
+ if (c != 0)
+ {
+ subPInvFrom(z);
+ }
+ }
+
+ public static void subtractExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.sub(12, xx, yy, zz);
+ if (c != 0)
+ {
+ if (Nat.subFrom(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.decAt(12, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void twice(int[] x, int[] z)
+ {
+ int c = Nat.shiftUpBit(6, x, 0, z);
+ if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ private static void addPInvTo(int[] z)
+ {
+ long c = (z[0] & M) + 1;
+ z[0] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ c += (z[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ }
+ c += (z[2] & M) + 1;
+ z[2] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ Nat.incAt(6, z, 3);
+ }
+ }
+
+ private static void subPInvFrom(int[] z)
+ {
+ long c = (z[0] & M) - 1;
+ z[0] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ c += (z[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ }
+ c += (z[2] & M) - 1;
+ z[2] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ Nat.decAt(6, z, 3);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java
new file mode 100644
index 00000000..ac55d3b1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java
@@ -0,0 +1,195 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.raw.Nat192;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP192R1FieldElement extends ECFieldElement.AbstractFp
+{
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"));
+
+ protected int[] x;
+
+ public SecP192R1FieldElement(BigInteger x)
+ {
+ if (x == null || x.signum() < 0 || x.compareTo(Q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid for SecP192R1FieldElement");
+ }
+
+ this.x = SecP192R1Field.fromBigInteger(x);
+ }
+
+ public SecP192R1FieldElement()
+ {
+ this.x = Nat192.create();
+ }
+
+ protected SecP192R1FieldElement(int[] x)
+ {
+ this.x = x;
+ }
+
+ public boolean isZero()
+ {
+ return Nat192.isZero(x);
+ }
+
+ public boolean isOne()
+ {
+ return Nat192.isOne(x);
+ }
+
+ public boolean testBitZero()
+ {
+ return Nat192.getBit(x, 0) == 1;
+ }
+
+ public BigInteger toBigInteger()
+ {
+ return Nat192.toBigInteger(x);
+ }
+
+ public String getFieldName()
+ {
+ return "SecP192R1Field";
+ }
+
+ public int getFieldSize()
+ {
+ return Q.bitLength();
+ }
+
+ public ECFieldElement add(ECFieldElement b)
+ {
+ int[] z = Nat192.create();
+ SecP192R1Field.add(x, ((SecP192R1FieldElement)b).x, z);
+ return new SecP192R1FieldElement(z);
+ }
+
+ public ECFieldElement addOne()
+ {
+ int[] z = Nat192.create();
+ SecP192R1Field.addOne(x, z);
+ return new SecP192R1FieldElement(z);
+ }
+
+ public ECFieldElement subtract(ECFieldElement b)
+ {
+ int[] z = Nat192.create();
+ SecP192R1Field.subtract(x, ((SecP192R1FieldElement)b).x, z);
+ return new SecP192R1FieldElement(z);
+ }
+
+ public ECFieldElement multiply(ECFieldElement b)
+ {
+ int[] z = Nat192.create();
+ SecP192R1Field.multiply(x, ((SecP192R1FieldElement)b).x, z);
+ return new SecP192R1FieldElement(z);
+ }
+
+ public ECFieldElement divide(ECFieldElement b)
+ {
+// return multiply(b.invert());
+ int[] z = Nat192.create();
+ SecP192R1Field.inv(((SecP192R1FieldElement)b).x, z);
+ SecP192R1Field.multiply(z, x, z);
+ return new SecP192R1FieldElement(z);
+ }
+
+ public ECFieldElement negate()
+ {
+ int[] z = Nat192.create();
+ SecP192R1Field.negate(x, z);
+ return new SecP192R1FieldElement(z);
+ }
+
+ public ECFieldElement square()
+ {
+ int[] z = Nat192.create();
+ SecP192R1Field.square(x, z);
+ return new SecP192R1FieldElement(z);
+ }
+
+ public ECFieldElement invert()
+ {
+// return new SecP192R1FieldElement(toBigInteger().modInverse(Q));
+ int[] z = Nat192.create();
+ SecP192R1Field.inv(x, z);
+ return new SecP192R1FieldElement(z);
+ }
+
+ // D.1.4 91
+ /**
+ * return a sqrt root - the routine verifies that the calculation returns the right value - if
+ * none exists it returns null.
+ */
+ public ECFieldElement sqrt()
+ {
+ // Raise this element to the exponent 2^190 - 2^62
+
+ int[] x1 = this.x;
+ if (Nat192.isZero(x1) || Nat192.isOne(x1))
+ {
+ return this;
+ }
+
+ int[] t1 = Nat192.create();
+ int[] t2 = Nat192.create();
+
+ SecP192R1Field.square(x1, t1);
+ SecP192R1Field.multiply(t1, x1, t1);
+
+ SecP192R1Field.squareN(t1, 2, t2);
+ SecP192R1Field.multiply(t2, t1, t2);
+
+ SecP192R1Field.squareN(t2, 4, t1);
+ SecP192R1Field.multiply(t1, t2, t1);
+
+ SecP192R1Field.squareN(t1, 8, t2);
+ SecP192R1Field.multiply(t2, t1, t2);
+
+ SecP192R1Field.squareN(t2, 16, t1);
+ SecP192R1Field.multiply(t1, t2, t1);
+
+ SecP192R1Field.squareN(t1, 32, t2);
+ SecP192R1Field.multiply(t2, t1, t2);
+
+ SecP192R1Field.squareN(t2, 64, t1);
+ SecP192R1Field.multiply(t1, t2, t1);
+
+ SecP192R1Field.squareN(t1, 62, t1);
+ SecP192R1Field.square(t1, t2);
+
+ return Nat192.eq(x1, t2) ? new SecP192R1FieldElement(t1) : null;
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof SecP192R1FieldElement))
+ {
+ return false;
+ }
+
+ SecP192R1FieldElement o = (SecP192R1FieldElement)other;
+ return Nat192.eq(x, o.x);
+ }
+
+ public int hashCode()
+ {
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 6);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java
new file mode 100644
index 00000000..9f96a0eb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java
@@ -0,0 +1,273 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat192;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP192R1Point extends ECPoint.AbstractFp
+{
+ SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ super(curve, x, y);
+ }
+
+ SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ super(curve, x, y, zs);
+ }
+
+ protected ECPoint detach()
+ {
+ return new SecP192R1Point(null, getAffineXCoord(), getAffineYCoord());
+ }
+
+ // B.3 pg 62
+ public ECPoint add(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return this;
+ }
+ if (this == b)
+ {
+ return twice();
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP192R1FieldElement X1 = (SecP192R1FieldElement)this.x, Y1 = (SecP192R1FieldElement)this.y;
+ SecP192R1FieldElement X2 = (SecP192R1FieldElement)b.getXCoord(), Y2 = (SecP192R1FieldElement)b.getYCoord();
+
+ SecP192R1FieldElement Z1 = (SecP192R1FieldElement)this.zs[0];
+ SecP192R1FieldElement Z2 = (SecP192R1FieldElement)b.getZCoord(0);
+
+ int c;
+ int[] tt1 = Nat192.createExt();
+ int[] t2 = Nat192.create();
+ int[] t3 = Nat192.create();
+ int[] t4 = Nat192.create();
+
+ boolean Z1IsOne = Z1.isOne();
+ int[] U2, S2;
+ if (Z1IsOne)
+ {
+ U2 = X2.x;
+ S2 = Y2.x;
+ }
+ else
+ {
+ S2 = t3;
+ SecP192R1Field.square(Z1.x, S2);
+
+ U2 = t2;
+ SecP192R1Field.multiply(S2, X2.x, U2);
+
+ SecP192R1Field.multiply(S2, Z1.x, S2);
+ SecP192R1Field.multiply(S2, Y2.x, S2);
+ }
+
+ boolean Z2IsOne = Z2.isOne();
+ int[] U1, S1;
+ if (Z2IsOne)
+ {
+ U1 = X1.x;
+ S1 = Y1.x;
+ }
+ else
+ {
+ S1 = t4;
+ SecP192R1Field.square(Z2.x, S1);
+
+ U1 = tt1;
+ SecP192R1Field.multiply(S1, X1.x, U1);
+
+ SecP192R1Field.multiply(S1, Z2.x, S1);
+ SecP192R1Field.multiply(S1, Y1.x, S1);
+ }
+
+ int[] H = Nat192.create();
+ SecP192R1Field.subtract(U1, U2, H);
+
+ int[] R = t2;
+ SecP192R1Field.subtract(S1, S2, R);
+
+ // Check if b == this or b == -this
+ if (Nat192.isZero(H))
+ {
+ if (Nat192.isZero(R))
+ {
+ // this == b, i.e. this must be doubled
+ return this.twice();
+ }
+
+ // this == -b, i.e. the result is the point at infinity
+ return curve.getInfinity();
+ }
+
+ int[] HSquared = t3;
+ SecP192R1Field.square(H, HSquared);
+
+ int[] G = Nat192.create();
+ SecP192R1Field.multiply(HSquared, H, G);
+
+ int[] V = t3;
+ SecP192R1Field.multiply(HSquared, U1, V);
+
+ SecP192R1Field.negate(G, G);
+ Nat192.mul(S1, G, tt1);
+
+ c = Nat192.addBothTo(V, V, G);
+ SecP192R1Field.reduce32(c, G);
+
+ SecP192R1FieldElement X3 = new SecP192R1FieldElement(t4);
+ SecP192R1Field.square(R, X3.x);
+ SecP192R1Field.subtract(X3.x, G, X3.x);
+
+ SecP192R1FieldElement Y3 = new SecP192R1FieldElement(G);
+ SecP192R1Field.subtract(V, X3.x, Y3.x);
+ SecP192R1Field.multiplyAddToExt(Y3.x, R, tt1);
+ SecP192R1Field.reduce(tt1, Y3.x);
+
+ SecP192R1FieldElement Z3 = new SecP192R1FieldElement(H);
+ if (!Z1IsOne)
+ {
+ SecP192R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+ if (!Z2IsOne)
+ {
+ SecP192R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ }
+
+ ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
+
+ return new SecP192R1Point(curve, X3, Y3, zs);
+ }
+
+ // B.3 pg 62
+ public ECPoint twice()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP192R1FieldElement Y1 = (SecP192R1FieldElement)this.y;
+ if (Y1.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ SecP192R1FieldElement X1 = (SecP192R1FieldElement)this.x, Z1 = (SecP192R1FieldElement)this.zs[0];
+
+ int c;
+ int[] t1 = Nat192.create();
+ int[] t2 = Nat192.create();
+
+ int[] Y1Squared = Nat192.create();
+ SecP192R1Field.square(Y1.x, Y1Squared);
+
+ int[] T = Nat192.create();
+ SecP192R1Field.square(Y1Squared, T);
+
+ boolean Z1IsOne = Z1.isOne();
+
+ int[] Z1Squared = Z1.x;
+ if (!Z1IsOne)
+ {
+ Z1Squared = t2;
+ SecP192R1Field.square(Z1.x, Z1Squared);
+ }
+
+ SecP192R1Field.subtract(X1.x, Z1Squared, t1);
+
+ int[] M = t2;
+ SecP192R1Field.add(X1.x, Z1Squared, M);
+ SecP192R1Field.multiply(M, t1, M);
+ c = Nat192.addBothTo(M, M, M);
+ SecP192R1Field.reduce32(c, M);
+
+ int[] S = Y1Squared;
+ SecP192R1Field.multiply(Y1Squared, X1.x, S);
+ c = Nat.shiftUpBits(6, S, 2, 0);
+ SecP192R1Field.reduce32(c, S);
+
+ c = Nat.shiftUpBits(6, T, 3, 0, t1);
+ SecP192R1Field.reduce32(c, t1);
+
+ SecP192R1FieldElement X3 = new SecP192R1FieldElement(T);
+ SecP192R1Field.square(M, X3.x);
+ SecP192R1Field.subtract(X3.x, S, X3.x);
+ SecP192R1Field.subtract(X3.x, S, X3.x);
+
+ SecP192R1FieldElement Y3 = new SecP192R1FieldElement(S);
+ SecP192R1Field.subtract(S, X3.x, Y3.x);
+ SecP192R1Field.multiply(Y3.x, M, Y3.x);
+ SecP192R1Field.subtract(Y3.x, t1, Y3.x);
+
+ SecP192R1FieldElement Z3 = new SecP192R1FieldElement(M);
+ SecP192R1Field.twice(Y1.x, Z3.x);
+ if (!Z1IsOne)
+ {
+ SecP192R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+
+ return new SecP192R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
+ }
+
+ public ECPoint twicePlus(ECPoint b)
+ {
+ if (this == b)
+ {
+ return threeTimes();
+ }
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return twice();
+ }
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return b;
+ }
+
+ return twice().add(b);
+ }
+
+ public ECPoint threeTimes()
+ {
+ if (this.isInfinity() || this.y.isZero())
+ {
+ return this;
+ }
+
+ // NOTE: Be careful about recursions between twicePlus and threeTimes
+ return twice().add(this);
+ }
+
+ public ECPoint negate()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ return new SecP192R1Point(curve, this.x, this.y.negate(), this.zs);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java
new file mode 100644
index 00000000..b1fc91dc
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java
@@ -0,0 +1,171 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.ec.AbstractECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat224;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP224K1Curve extends ECCurve.AbstractFp
+{
+ public static final BigInteger q = SecP224K1FieldElement.Q;
+
+ private static final int SECP224K1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP224K1_AFFINE_ZS = new ECFieldElement[] { new SecP224K1FieldElement(ECConstants.ONE) };
+
+ protected SecP224K1Point infinity;
+
+ public SecP224K1Curve()
+ {
+ super(q);
+
+ this.infinity = new SecP224K1Point(this, null, null);
+
+ this.a = fromBigInteger(ECConstants.ZERO);
+ this.b = fromBigInteger(BigInteger.valueOf(5));
+ this.order = new BigInteger(1, Hex.decodeStrict("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7"));
+ this.cofactor = BigInteger.valueOf(1);
+ this.coord = SECP224K1_DEFAULT_COORDS;
+ }
+
+ protected ECCurve cloneCurve()
+ {
+ return new SecP224K1Curve();
+ }
+
+ public boolean supportsCoordinateSystem(int coord)
+ {
+ switch (coord)
+ {
+ case COORD_JACOBIAN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public int getFieldSize()
+ {
+ return q.bitLength();
+ }
+
+ public ECFieldElement fromBigInteger(BigInteger x)
+ {
+ return new SecP224K1FieldElement(x);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
+ {
+ return new SecP224K1Point(this, x, y);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ return new SecP224K1Point(this, x, y, zs);
+ }
+
+ public ECPoint getInfinity()
+ {
+ return infinity;
+ }
+
+ public ECLookupTable createCacheSafeLookupTable(ECPoint[] points, int off, final int len)
+ {
+ final int FE_INTS = 7;
+
+ final int[] table = new int[len * FE_INTS * 2];
+ {
+ int pos = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ ECPoint p = points[off + i];
+ Nat224.copy(((SecP224K1FieldElement)p.getRawXCoord()).x, 0, table, pos); pos += FE_INTS;
+ Nat224.copy(((SecP224K1FieldElement)p.getRawYCoord()).x, 0, table, pos); pos += FE_INTS;
+ }
+ }
+
+ return new AbstractECLookupTable()
+ {
+ public int getSize()
+ {
+ return len;
+ }
+
+ public ECPoint lookup(int index)
+ {
+ int[] x = Nat224.create(), y = Nat224.create();
+ int pos = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ int MASK = ((i ^ index) - 1) >> 31;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] ^= table[pos + j] & MASK;
+ y[j] ^= table[pos + FE_INTS + j] & MASK;
+ }
+
+ pos += (FE_INTS * 2);
+ }
+
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat224.create(), y = Nat224.create();
+ int pos = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ int MASK = ((i ^ index) - 1) >> 31;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] ^= table[pos + j] & MASK;
+ y[j] ^= table[pos + FE_INTS + j] & MASK;
+ }
+
+ pos += (FE_INTS * 2);
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP224K1FieldElement(x), new SecP224K1FieldElement(y), SECP224K1_AFFINE_ZS);
+ }
+ };
+ }
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat224.create();
+ SecP224K1Field.random(r, x);
+ return new SecP224K1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat224.create();
+ SecP224K1Field.randomMult(r, x);
+ return new SecP224K1FieldElement(x);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java
new file mode 100644
index 00000000..437e3bda
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java
@@ -0,0 +1,221 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.raw.Mod;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat224;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP224K1Field
+{
+ // 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1
+ static final int[] P = new int[]{ 0xFFFFE56D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x02C23069, 0x00003526, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xFFFFCADA, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExtInv = new int[]{ 0xFD3DCF97, 0xFFFFCAD9, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00003525, 0x00000002 };
+ private static final int P6 = 0xFFFFFFFF;
+ private static final int PExt13 = 0xFFFFFFFF;
+ private static final int PInv33 = 0x1A93;
+
+ public static void add(int[] x, int[] y, int[] z)
+ {
+ int c = Nat224.add(x, y, z);
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ Nat.add33To(7, PInv33, z);
+ }
+ }
+
+ public static void addExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.add(14, xx, yy, zz);
+ if (c != 0 || (zz[13] == PExt13 && Nat.gte(14, zz, PExt)))
+ {
+ if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.incAt(14, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void addOne(int[] x, int[] z)
+ {
+ int c = Nat.inc(7, x, z);
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ Nat.add33To(7, PInv33, z);
+ }
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ int[] z = Nat224.fromBigInteger(x);
+ if (z[6] == P6 && Nat224.gte(z, P))
+ {
+ Nat.add33To(7, PInv33, z);
+ }
+ return z;
+ }
+
+ public static void half(int[] x, int[] z)
+ {
+ if ((x[0] & 1) == 0)
+ {
+ Nat.shiftDownBit(7, x, 0, z);
+ }
+ else
+ {
+ int c = Nat224.add(x, P, z);
+ Nat.shiftDownBit(7, z, c);
+ }
+ }
+
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 7; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static void multiply(int[] x, int[] y, int[] z)
+ {
+ int[] tt = Nat224.createExt();
+ Nat224.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
+ public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
+ {
+ int c = Nat224.mulAddTo(x, y, zz);
+ if (c != 0 || (zz[13] == PExt13 && Nat.gte(14, zz, PExt)))
+ {
+ if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.incAt(14, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void negate(int[] x, int[] z)
+ {
+ if (0 != isZero(x))
+ {
+ Nat224.sub(P, P, z);
+ }
+ else
+ {
+ Nat224.sub(P, x, z);
+ }
+ }
+
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[7 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 7);
+ }
+ while (0 == Nat.lessThan(7, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
+ public static void reduce(int[] xx, int[] z)
+ {
+ long cc = Nat224.mul33Add(PInv33, xx, 7, xx, 0, z, 0);
+ int c = Nat224.mul33DWordAdd(PInv33, cc, z, 0);
+
+ // assert c == 0L || c == 1L;
+
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ Nat.add33To(7, PInv33, z);
+ }
+ }
+
+ public static void reduce32(int x, int[] z)
+ {
+ if ((x != 0 && Nat224.mul33WordAdd(PInv33, x, z, 0) != 0)
+ || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ Nat.add33To(7, PInv33, z);
+ }
+ }
+
+ public static void square(int[] x, int[] z)
+ {
+ int[] tt = Nat224.createExt();
+ Nat224.square(x, tt);
+ reduce(tt, z);
+ }
+
+ public static void squareN(int[] x, int n, int[] z)
+ {
+// assert n > 0;
+
+ int[] tt = Nat224.createExt();
+ Nat224.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat224.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
+ public static void subtract(int[] x, int[] y, int[] z)
+ {
+ int c = Nat224.sub(x, y, z);
+ if (c != 0)
+ {
+ Nat.sub33From(7, PInv33, z);
+ }
+ }
+
+ public static void subtractExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.sub(14, xx, yy, zz);
+ if (c != 0)
+ {
+ if (Nat.subFrom(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.decAt(14, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void twice(int[] x, int[] z)
+ {
+ int c = Nat.shiftUpBit(7, x, 0, z);
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ Nat.add33To(7, PInv33, z);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java
new file mode 100644
index 00000000..96fea43b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java
@@ -0,0 +1,248 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.raw.Nat224;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP224K1FieldElement extends ECFieldElement.AbstractFp
+{
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D"));
+
+ // Calculated as ECConstants.TWO.modPow(Q.shiftRight(2), Q)
+ private static final int[] PRECOMP_POW2 = new int[]{ 0x33bfd202, 0xdcfad133, 0x2287624a, 0xc3811ba8,
+ 0xa85558fc, 0x1eaef5d7, 0x8edf154c };
+
+ protected int[] x;
+
+ public SecP224K1FieldElement(BigInteger x)
+ {
+ if (x == null || x.signum() < 0 || x.compareTo(Q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid for SecP224K1FieldElement");
+ }
+
+ this.x = SecP224K1Field.fromBigInteger(x);
+ }
+
+ public SecP224K1FieldElement()
+ {
+ this.x = Nat224.create();
+ }
+
+ protected SecP224K1FieldElement(int[] x)
+ {
+ this.x = x;
+ }
+
+ public boolean isZero()
+ {
+ return Nat224.isZero(x);
+ }
+
+ public boolean isOne()
+ {
+ return Nat224.isOne(x);
+ }
+
+ public boolean testBitZero()
+ {
+ return Nat224.getBit(x, 0) == 1;
+ }
+
+ public BigInteger toBigInteger()
+ {
+ return Nat224.toBigInteger(x);
+ }
+
+ public String getFieldName()
+ {
+ return "SecP224K1Field";
+ }
+
+ public int getFieldSize()
+ {
+ return Q.bitLength();
+ }
+
+ public ECFieldElement add(ECFieldElement b)
+ {
+ int[] z = Nat224.create();
+ SecP224K1Field.add(x, ((SecP224K1FieldElement)b).x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ public ECFieldElement addOne()
+ {
+ int[] z = Nat224.create();
+ SecP224K1Field.addOne(x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ public ECFieldElement subtract(ECFieldElement b)
+ {
+ int[] z = Nat224.create();
+ SecP224K1Field.subtract(x, ((SecP224K1FieldElement)b).x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ public ECFieldElement multiply(ECFieldElement b)
+ {
+ int[] z = Nat224.create();
+ SecP224K1Field.multiply(x, ((SecP224K1FieldElement)b).x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ public ECFieldElement divide(ECFieldElement b)
+ {
+// return multiply(b.invert());
+ int[] z = Nat224.create();
+ SecP224K1Field.inv(((SecP224K1FieldElement)b).x, z);
+ SecP224K1Field.multiply(z, x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ public ECFieldElement negate()
+ {
+ int[] z = Nat224.create();
+ SecP224K1Field.negate(x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ public ECFieldElement square()
+ {
+ int[] z = Nat224.create();
+ SecP224K1Field.square(x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ public ECFieldElement invert()
+ {
+// return new SecP224K1FieldElement(toBigInteger().modInverse(Q));
+ int[] z = Nat224.create();
+ SecP224K1Field.inv(x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ // D.1.4 91
+ /**
+ * return a sqrt root - the routine verifies that the calculation returns the right value - if
+ * none exists it returns null.
+ */
+ public ECFieldElement sqrt()
+ {
+ /*
+ * Q == 8m + 5, so we use Pocklington's method for this case.
+ *
+ * First, raise this element to the exponent 2^221 - 2^29 - 2^9 - 2^8 - 2^6 - 2^4 - 2^1 (i.e. m + 1)
+ *
+ * Breaking up the exponent's binary representation into "repunits", we get:
+ * { 191 1s } { 1 0s } { 19 1s } { 2 0s } { 1 1s } { 1 0s } { 1 1s } { 1 0s } { 3 1s } { 1 0s }
+ *
+ * Therefore we need an addition chain containing 1, 3, 19, 191 (the lengths of the repunits)
+ * We use: [1], 2, [3], 4, 8, 11, [19], 23, 42, 84, 107, [191]
+ */
+
+ int[] x1 = this.x;
+ if (Nat224.isZero(x1) || Nat224.isOne(x1))
+ {
+ return this;
+ }
+
+ int[] x2 = Nat224.create();
+ SecP224K1Field.square(x1, x2);
+ SecP224K1Field.multiply(x2, x1, x2);
+ int[] x3 = x2;
+ SecP224K1Field.square(x2, x3);
+ SecP224K1Field.multiply(x3, x1, x3);
+ int[] x4 = Nat224.create();
+ SecP224K1Field.square(x3, x4);
+ SecP224K1Field.multiply(x4, x1, x4);
+ int[] x8 = Nat224.create();
+ SecP224K1Field.squareN(x4, 4, x8);
+ SecP224K1Field.multiply(x8, x4, x8);
+ int[] x11 = Nat224.create();
+ SecP224K1Field.squareN(x8, 3, x11);
+ SecP224K1Field.multiply(x11, x3, x11);
+ int[] x19 = x11;
+ SecP224K1Field.squareN(x11, 8, x19);
+ SecP224K1Field.multiply(x19, x8, x19);
+ int[] x23 = x8;
+ SecP224K1Field.squareN(x19, 4, x23);
+ SecP224K1Field.multiply(x23, x4, x23);
+ int[] x42 = x4;
+ SecP224K1Field.squareN(x23, 19, x42);
+ SecP224K1Field.multiply(x42, x19, x42);
+ int[] x84 = Nat224.create();
+ SecP224K1Field.squareN(x42, 42, x84);
+ SecP224K1Field.multiply(x84, x42, x84);
+ int[] x107 = x42;
+ SecP224K1Field.squareN(x84, 23, x107);
+ SecP224K1Field.multiply(x107, x23, x107);
+ int[] x191 = x23;
+ SecP224K1Field.squareN(x107, 84, x191);
+ SecP224K1Field.multiply(x191, x84, x191);
+
+ int[] t1 = x191;
+ SecP224K1Field.squareN(t1, 20, t1);
+ SecP224K1Field.multiply(t1, x19, t1);
+ SecP224K1Field.squareN(t1, 3, t1);
+ SecP224K1Field.multiply(t1, x1, t1);
+ SecP224K1Field.squareN(t1, 2, t1);
+ SecP224K1Field.multiply(t1, x1, t1);
+ SecP224K1Field.squareN(t1, 4, t1);
+ SecP224K1Field.multiply(t1, x3, t1);
+ SecP224K1Field.square(t1, t1);
+
+ int[] t2 = x84;
+ SecP224K1Field.square(t1, t2);
+
+ if (Nat224.eq(x1, t2))
+ {
+ return new SecP224K1FieldElement(t1);
+ }
+
+ /*
+ * If the first guess is incorrect, we multiply by a precomputed power of 2 to get the second guess,
+ * which is ((4x)^(m + 1))/2 mod Q
+ */
+ SecP224K1Field.multiply(t1, PRECOMP_POW2, t1);
+
+ SecP224K1Field.square(t1, t2);
+
+ if (Nat224.eq(x1, t2))
+ {
+ return new SecP224K1FieldElement(t1);
+ }
+
+ return null;
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof SecP224K1FieldElement))
+ {
+ return false;
+ }
+
+ SecP224K1FieldElement o = (SecP224K1FieldElement)other;
+ return Nat224.eq(x, o.x);
+ }
+
+ public int hashCode()
+ {
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 7);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java
new file mode 100644
index 00000000..2e1017cb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java
@@ -0,0 +1,260 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat224;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP224K1Point extends ECPoint.AbstractFp
+{
+ SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ super(curve, x, y);
+ }
+
+ SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ super(curve, x, y, zs);
+ }
+
+ protected ECPoint detach()
+ {
+ return new SecP224K1Point(null, getAffineXCoord(), getAffineYCoord());
+ }
+
+ // B.3 pg 62
+ public ECPoint add(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return this;
+ }
+ if (this == b)
+ {
+ return twice();
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP224K1FieldElement X1 = (SecP224K1FieldElement)this.x, Y1 = (SecP224K1FieldElement)this.y;
+ SecP224K1FieldElement X2 = (SecP224K1FieldElement)b.getXCoord(), Y2 = (SecP224K1FieldElement)b.getYCoord();
+
+ SecP224K1FieldElement Z1 = (SecP224K1FieldElement)this.zs[0];
+ SecP224K1FieldElement Z2 = (SecP224K1FieldElement)b.getZCoord(0);
+
+ int c;
+ int[] tt1 = Nat224.createExt();
+ int[] t2 = Nat224.create();
+ int[] t3 = Nat224.create();
+ int[] t4 = Nat224.create();
+
+ boolean Z1IsOne = Z1.isOne();
+ int[] U2, S2;
+ if (Z1IsOne)
+ {
+ U2 = X2.x;
+ S2 = Y2.x;
+ }
+ else
+ {
+ S2 = t3;
+ SecP224K1Field.square(Z1.x, S2);
+
+ U2 = t2;
+ SecP224K1Field.multiply(S2, X2.x, U2);
+
+ SecP224K1Field.multiply(S2, Z1.x, S2);
+ SecP224K1Field.multiply(S2, Y2.x, S2);
+ }
+
+ boolean Z2IsOne = Z2.isOne();
+ int[] U1, S1;
+ if (Z2IsOne)
+ {
+ U1 = X1.x;
+ S1 = Y1.x;
+ }
+ else
+ {
+ S1 = t4;
+ SecP224K1Field.square(Z2.x, S1);
+
+ U1 = tt1;
+ SecP224K1Field.multiply(S1, X1.x, U1);
+
+ SecP224K1Field.multiply(S1, Z2.x, S1);
+ SecP224K1Field.multiply(S1, Y1.x, S1);
+ }
+
+ int[] H = Nat224.create();
+ SecP224K1Field.subtract(U1, U2, H);
+
+ int[] R = t2;
+ SecP224K1Field.subtract(S1, S2, R);
+
+ // Check if b == this or b == -this
+ if (Nat224.isZero(H))
+ {
+ if (Nat224.isZero(R))
+ {
+ // this == b, i.e. this must be doubled
+ return this.twice();
+ }
+
+ // this == -b, i.e. the result is the point at infinity
+ return curve.getInfinity();
+ }
+
+ int[] HSquared = t3;
+ SecP224K1Field.square(H, HSquared);
+
+ int[] G = Nat224.create();
+ SecP224K1Field.multiply(HSquared, H, G);
+
+ int[] V = t3;
+ SecP224K1Field.multiply(HSquared, U1, V);
+
+ SecP224K1Field.negate(G, G);
+ Nat224.mul(S1, G, tt1);
+
+ c = Nat224.addBothTo(V, V, G);
+ SecP224K1Field.reduce32(c, G);
+
+ SecP224K1FieldElement X3 = new SecP224K1FieldElement(t4);
+ SecP224K1Field.square(R, X3.x);
+ SecP224K1Field.subtract(X3.x, G, X3.x);
+
+ SecP224K1FieldElement Y3 = new SecP224K1FieldElement(G);
+ SecP224K1Field.subtract(V, X3.x, Y3.x);
+ SecP224K1Field.multiplyAddToExt(Y3.x, R, tt1);
+ SecP224K1Field.reduce(tt1, Y3.x);
+
+ SecP224K1FieldElement Z3 = new SecP224K1FieldElement(H);
+ if (!Z1IsOne)
+ {
+ SecP224K1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+ if (!Z2IsOne)
+ {
+ SecP224K1Field.multiply(Z3.x, Z2.x, Z3.x);
+ }
+
+ ECFieldElement[] zs = new ECFieldElement[] { Z3 };
+
+ return new SecP224K1Point(curve, X3, Y3, zs);
+ }
+
+ // B.3 pg 62
+ public ECPoint twice()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP224K1FieldElement Y1 = (SecP224K1FieldElement)this.y;
+ if (Y1.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ SecP224K1FieldElement X1 = (SecP224K1FieldElement)this.x, Z1 = (SecP224K1FieldElement)this.zs[0];
+
+ int c;
+
+ int[] Y1Squared = Nat224.create();
+ SecP224K1Field.square(Y1.x, Y1Squared);
+
+ int[] T = Nat224.create();
+ SecP224K1Field.square(Y1Squared, T);
+
+ int[] M = Nat224.create();
+ SecP224K1Field.square(X1.x, M);
+ c = Nat224.addBothTo(M, M, M);
+ SecP224K1Field.reduce32(c, M);
+
+ int[] S = Y1Squared;
+ SecP224K1Field.multiply(Y1Squared, X1.x, S);
+ c = Nat.shiftUpBits(7, S, 2, 0);
+ SecP224K1Field.reduce32(c, S);
+
+ int[] t1 = Nat224.create();
+ c = Nat.shiftUpBits(7, T, 3, 0, t1);
+ SecP224K1Field.reduce32(c, t1);
+
+ SecP224K1FieldElement X3 = new SecP224K1FieldElement(T);
+ SecP224K1Field.square(M, X3.x);
+ SecP224K1Field.subtract(X3.x, S, X3.x);
+ SecP224K1Field.subtract(X3.x, S, X3.x);
+
+ SecP224K1FieldElement Y3 = new SecP224K1FieldElement(S);
+ SecP224K1Field.subtract(S, X3.x, Y3.x);
+ SecP224K1Field.multiply(Y3.x, M, Y3.x);
+ SecP224K1Field.subtract(Y3.x, t1, Y3.x);
+
+ SecP224K1FieldElement Z3 = new SecP224K1FieldElement(M);
+ SecP224K1Field.twice(Y1.x, Z3.x);
+ if (!Z1.isOne())
+ {
+ SecP224K1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+
+ return new SecP224K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
+ }
+
+ public ECPoint twicePlus(ECPoint b)
+ {
+ if (this == b)
+ {
+ return threeTimes();
+ }
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return twice();
+ }
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return b;
+ }
+
+ return twice().add(b);
+ }
+
+ public ECPoint threeTimes()
+ {
+ if (this.isInfinity() || this.y.isZero())
+ {
+ return this;
+ }
+
+ // NOTE: Be careful about recursions between twicePlus and threeTimes
+ return twice().add(this);
+ }
+
+ public ECPoint negate()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ return new SecP224K1Point(curve, this.x, this.y.negate(), this.zs);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java
new file mode 100644
index 00000000..52ebc74c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java
@@ -0,0 +1,167 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.ec.AbstractECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat224;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP224R1Curve extends ECCurve.AbstractFp
+{
+ public static final BigInteger q = SecP224R1FieldElement.Q;
+
+ private static final int SECP224R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP224R1_AFFINE_ZS = new ECFieldElement[] { new SecP224R1FieldElement(ECConstants.ONE) };
+
+ protected SecP224R1Point infinity;
+
+ public SecP224R1Curve()
+ {
+ super(q);
+
+ this.infinity = new SecP224R1Point(this, null, null);
+
+ this.a = fromBigInteger(new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")));
+ this.b = fromBigInteger(new BigInteger(1,
+ Hex.decodeStrict("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"));
+ this.cofactor = BigInteger.valueOf(1);
+
+ this.coord = SECP224R1_DEFAULT_COORDS;
+ }
+
+ protected ECCurve cloneCurve()
+ {
+ return new SecP224R1Curve();
+ }
+
+ public boolean supportsCoordinateSystem(int coord)
+ {
+ switch (coord)
+ {
+ case COORD_JACOBIAN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public int getFieldSize()
+ {
+ return q.bitLength();
+ }
+
+ public ECFieldElement fromBigInteger(BigInteger x)
+ {
+ return new SecP224R1FieldElement(x);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
+ {
+ return new SecP224R1Point(this, x, y);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ return new SecP224R1Point(this, x, y, zs);
+ }
+
+ public ECPoint getInfinity()
+ {
+ return infinity;
+ }
+
+ public ECLookupTable createCacheSafeLookupTable(ECPoint[] points, int off, final int len)
+ {
+ final int FE_INTS = 7;
+
+ final int[] table = new int[len * FE_INTS * 2];
+ {
+ int pos = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ ECPoint p = points[off + i];
+ Nat224.copy(((SecP224R1FieldElement)p.getRawXCoord()).x, 0, table, pos); pos += FE_INTS;
+ Nat224.copy(((SecP224R1FieldElement)p.getRawYCoord()).x, 0, table, pos); pos += FE_INTS;
+ }
+ }
+
+ return new AbstractECLookupTable()
+ {
+ public int getSize()
+ {
+ return len;
+ }
+
+ public ECPoint lookup(int index)
+ {
+ int[] x = Nat224.create(), y = Nat224.create();
+ int pos = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ int MASK = ((i ^ index) - 1) >> 31;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] ^= table[pos + j] & MASK;
+ y[j] ^= table[pos + FE_INTS + j] & MASK;
+ }
+
+ pos += (FE_INTS * 2);
+ }
+
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat224.create(), y = Nat224.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP224R1FieldElement(x), new SecP224R1FieldElement(y), SECP224R1_AFFINE_ZS);
+ }
+ };
+ }
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat224.create();
+ SecP224R1Field.random(r, x);
+ return new SecP224R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat224.create();
+ SecP224R1Field.randomMult(r, x);
+ return new SecP224R1FieldElement(x);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java
new file mode 100644
index 00000000..cf24a779
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java
@@ -0,0 +1,342 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.raw.Mod;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat224;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP224R1Field
+{
+ private static final long M = 0xFFFFFFFFL;
+
+ // 2^224 - 2^96 + 1
+ static final int[] P = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0x00000000,
+ 0x00000000, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001 };
+ private static final int P6 = 0xFFFFFFFF;
+ private static final int PExt13 = 0xFFFFFFFF;
+
+ public static void add(int[] x, int[] y, int[] z)
+ {
+ int c = Nat224.add(x, y, z);
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ public static void addExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.add(14, xx, yy, zz);
+ if (c != 0 || (zz[13] == PExt13 && Nat.gte(14, zz, PExt)))
+ {
+ if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.incAt(14, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void addOne(int[] x, int[] z)
+ {
+ int c = Nat.inc(7, x, z);
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ int[] z = Nat224.fromBigInteger(x);
+ if (z[6] == P6 && Nat224.gte(z, P))
+ {
+ Nat224.subFrom(P, z);
+ }
+ return z;
+ }
+
+ public static void half(int[] x, int[] z)
+ {
+ if ((x[0] & 1) == 0)
+ {
+ Nat.shiftDownBit(7, x, 0, z);
+ }
+ else
+ {
+ int c = Nat224.add(x, P, z);
+ Nat.shiftDownBit(7, z, c);
+ }
+ }
+
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 7; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static void multiply(int[] x, int[] y, int[] z)
+ {
+ int[] tt = Nat224.createExt();
+ Nat224.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
+ public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
+ {
+ int c = Nat224.mulAddTo(x, y, zz);
+ if (c != 0 || (zz[13] == PExt13 && Nat.gte(14, zz, PExt)))
+ {
+ if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.incAt(14, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void negate(int[] x, int[] z)
+ {
+ if (0 != isZero(x))
+ {
+ Nat224.sub(P, P, z);
+ }
+ else
+ {
+ Nat224.sub(P, x, z);
+ }
+ }
+
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[7 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 7);
+ }
+ while (0 == Nat.lessThan(7, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
+ public static void reduce(int[] xx, int[] z)
+ {
+ long xx10 = xx[10] & M, xx11 = xx[11] & M, xx12 = xx[12] & M, xx13 = xx[13] & M;
+
+ final long n = 1;
+
+ long t0 = (xx[7] & M) + xx11 - n;
+ long t1 = (xx[8] & M) + xx12;
+ long t2 = (xx[9] & M) + xx13;
+
+ long cc = 0;
+ cc += (xx[0] & M) - t0;
+ long z0 = cc & M;
+ cc >>= 32;
+ cc += (xx[1] & M) - t1;
+ z[1] = (int)cc;
+ cc >>= 32;
+ cc += (xx[2] & M) - t2;
+ z[2] = (int)cc;
+ cc >>= 32;
+ cc += (xx[3] & M) + t0 - xx10;
+ long z3 = cc & M;
+ cc >>= 32;
+ cc += (xx[4] & M) + t1 - xx11;
+ z[4] = (int)cc;
+ cc >>= 32;
+ cc += (xx[5] & M) + t2 - xx12;
+ z[5] = (int)cc;
+ cc >>= 32;
+ cc += (xx[6] & M) + xx10 - xx13;
+ z[6] = (int)cc;
+ cc >>= 32;
+ cc += n;
+
+// assert cc >= 0;
+
+ z3 += cc;
+
+ z0 -= cc;
+ z[0] = (int)z0;
+ cc = z0 >> 32;
+ if (cc != 0)
+ {
+ cc += (z[1] & M);
+ z[1] = (int)cc;
+ cc >>= 32;
+ cc += (z[2] & M);
+ z[2] = (int)cc;
+ z3 += cc >> 32;
+ }
+ z[3] = (int)z3;
+ cc = z3 >> 32;
+
+// assert cc == 0 || cc == 1;
+
+ if ((cc != 0 && Nat.incAt(7, z, 4) != 0)
+ || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ public static void reduce32(int x, int[] z)
+ {
+ long cc = 0;
+
+ if (x != 0)
+ {
+ long xx07 = x & M;
+
+ cc += (z[0] & M) - xx07;
+ z[0] = (int)cc;
+ cc >>= 32;
+ if (cc != 0)
+ {
+ cc += (z[1] & M);
+ z[1] = (int)cc;
+ cc >>= 32;
+ cc += (z[2] & M);
+ z[2] = (int)cc;
+ cc >>= 32;
+ }
+ cc += (z[3] & M) + xx07;
+ z[3] = (int)cc;
+ cc >>= 32;
+
+// assert cc == 0 || cc == 1;
+ }
+
+ if ((cc != 0 && Nat.incAt(7, z, 4) != 0)
+ || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ public static void square(int[] x, int[] z)
+ {
+ int[] tt = Nat224.createExt();
+ Nat224.square(x, tt);
+ reduce(tt, z);
+ }
+
+ public static void squareN(int[] x, int n, int[] z)
+ {
+// assert n > 0;
+
+ int[] tt = Nat224.createExt();
+ Nat224.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat224.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
+ public static void subtract(int[] x, int[] y, int[] z)
+ {
+ int c = Nat224.sub(x, y, z);
+ if (c != 0)
+ {
+ subPInvFrom(z);
+ }
+ }
+
+ public static void subtractExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.sub(14, xx, yy, zz);
+ if (c != 0)
+ {
+ if (Nat.subFrom(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.decAt(14, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void twice(int[] x, int[] z)
+ {
+ int c = Nat.shiftUpBit(7, x, 0, z);
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ private static void addPInvTo(int[] z)
+ {
+ long c = (z[0] & M) - 1;
+ z[0] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ c += (z[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (z[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ }
+ c += (z[3] & M) + 1;
+ z[3] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ Nat.incAt(7, z, 4);
+ }
+ }
+
+ private static void subPInvFrom(int[] z)
+ {
+ long c = (z[0] & M) + 1;
+ z[0] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ c += (z[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (z[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ }
+ c += (z[3] & M) - 1;
+ z[3] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ Nat.decAt(7, z, 4);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java
new file mode 100644
index 00000000..afe1a986
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java
@@ -0,0 +1,279 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.raw.Mod;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat224;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP224R1FieldElement extends ECFieldElement.AbstractFp
+{
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"));
+
+ protected int[] x;
+
+ public SecP224R1FieldElement(BigInteger x)
+ {
+ if (x == null || x.signum() < 0 || x.compareTo(Q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid for SecP224R1FieldElement");
+ }
+
+ this.x = SecP224R1Field.fromBigInteger(x);
+ }
+
+ public SecP224R1FieldElement()
+ {
+ this.x = Nat224.create();
+ }
+
+ protected SecP224R1FieldElement(int[] x)
+ {
+ this.x = x;
+ }
+
+ public boolean isZero()
+ {
+ return Nat224.isZero(x);
+ }
+
+ public boolean isOne()
+ {
+ return Nat224.isOne(x);
+ }
+
+ public boolean testBitZero()
+ {
+ return Nat224.getBit(x, 0) == 1;
+ }
+
+ public BigInteger toBigInteger()
+ {
+ return Nat224.toBigInteger(x);
+ }
+
+ public String getFieldName()
+ {
+ return "SecP224R1Field";
+ }
+
+ public int getFieldSize()
+ {
+ return Q.bitLength();
+ }
+
+ public ECFieldElement add(ECFieldElement b)
+ {
+ int[] z = Nat224.create();
+ SecP224R1Field.add(x, ((SecP224R1FieldElement)b).x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ public ECFieldElement addOne()
+ {
+ int[] z = Nat224.create();
+ SecP224R1Field.addOne(x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ public ECFieldElement subtract(ECFieldElement b)
+ {
+ int[] z = Nat224.create();
+ SecP224R1Field.subtract(x, ((SecP224R1FieldElement)b).x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ public ECFieldElement multiply(ECFieldElement b)
+ {
+ int[] z = Nat224.create();
+ SecP224R1Field.multiply(x, ((SecP224R1FieldElement)b).x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ public ECFieldElement divide(ECFieldElement b)
+ {
+// return multiply(b.invert());
+ int[] z = Nat224.create();
+ SecP224R1Field.inv(((SecP224R1FieldElement)b).x, z);
+ SecP224R1Field.multiply(z, x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ public ECFieldElement negate()
+ {
+ int[] z = Nat224.create();
+ SecP224R1Field.negate(x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ public ECFieldElement square()
+ {
+ int[] z = Nat224.create();
+ SecP224R1Field.square(x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ public ECFieldElement invert()
+ {
+// return new SecP224R1FieldElement(toBigInteger().modInverse(Q));
+ int[] z = Nat224.create();
+ SecP224R1Field.inv(x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ /**
+ * return a sqrt root - the routine verifies that the calculation returns the right value - if
+ * none exists it returns null.
+ */
+ public ECFieldElement sqrt()
+ {
+ int[] c = this.x;
+ if (Nat224.isZero(c) || Nat224.isOne(c))
+ {
+ return this;
+ }
+
+ int[] nc = Nat224.create();
+ SecP224R1Field.negate(c, nc);
+
+ int[] r = Mod.random(SecP224R1Field.P);
+ int[] t = Nat224.create();
+
+ if (!isSquare(c))
+ {
+ return null;
+ }
+
+ while (!trySqrt(nc, r, t))
+ {
+ SecP224R1Field.addOne(r, r);
+ }
+
+ SecP224R1Field.square(t, r);
+
+ return Nat224.eq(c, r) ? new SecP224R1FieldElement(t) : null;
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof SecP224R1FieldElement))
+ {
+ return false;
+ }
+
+ SecP224R1FieldElement o = (SecP224R1FieldElement)other;
+ return Nat224.eq(x, o.x);
+ }
+
+ public int hashCode()
+ {
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 7);
+ }
+
+ private static boolean isSquare(int[] x)
+ {
+ int[] t1 = Nat224.create();
+ int[] t2 = Nat224.create();
+ Nat224.copy(x, t1);
+
+ for (int i = 0; i < 7; ++i)
+ {
+ Nat224.copy(t1, t2);
+ SecP224R1Field.squareN(t1, 1 << i, t1);
+ SecP224R1Field.multiply(t1, t2, t1);
+ }
+
+ SecP224R1Field.squareN(t1, 95, t1);
+ return Nat224.isOne(t1);
+ }
+
+ private static void RM(int[] nc, int[] d0, int[] e0, int[] d1, int[] e1, int[] f1, int[] t)
+ {
+ SecP224R1Field.multiply(e1, e0, t);
+ SecP224R1Field.multiply(t, nc, t);
+ SecP224R1Field.multiply(d1, d0, f1);
+ SecP224R1Field.add(f1, t, f1);
+ SecP224R1Field.multiply(d1, e0, t);
+ Nat224.copy(f1, d1);
+ SecP224R1Field.multiply(e1, d0, e1);
+ SecP224R1Field.add(e1, t, e1);
+ SecP224R1Field.square(e1, f1);
+ SecP224R1Field.multiply(f1, nc, f1);
+ }
+
+ private static void RP(int[] nc, int[] d1, int[] e1, int[] f1, int[] t)
+ {
+ Nat224.copy(nc, f1);
+
+ int[] d0 = Nat224.create();
+ int[] e0 = Nat224.create();
+
+ for (int i = 0; i < 7; ++i)
+ {
+ Nat224.copy(d1, d0);
+ Nat224.copy(e1, e0);
+
+ int j = 1 << i;
+ while (--j >= 0)
+ {
+ RS(d1, e1, f1, t);
+ }
+
+ RM(nc, d0, e0, d1, e1, f1, t);
+ }
+ }
+
+ private static void RS(int[] d, int[] e, int[] f, int[] t)
+ {
+ SecP224R1Field.multiply(e, d, e);
+ SecP224R1Field.twice(e, e);
+ SecP224R1Field.square(d, t);
+ SecP224R1Field.add(f, t, d);
+ SecP224R1Field.multiply(f, t, f);
+ int c = Nat.shiftUpBits(7, f, 2, 0);
+ SecP224R1Field.reduce32(c, f);
+ }
+
+ private static boolean trySqrt(int[] nc, int[] r, int[] t)
+ {
+ int[] d1 = Nat224.create();
+ Nat224.copy(r, d1);
+ int[] e1 = Nat224.create();
+ e1[0] = 1;
+ int[] f1 = Nat224.create();
+ RP(nc, d1, e1, f1, t);
+
+ int[] d0 = Nat224.create();
+ int[] e0 = Nat224.create();
+
+ for (int k = 1; k < 96; ++k)
+ {
+ Nat224.copy(d1, d0);
+ Nat224.copy(e1, e0);
+
+ RS(d1, e1, f1, t);
+
+ if (Nat224.isZero(d1))
+ {
+ SecP224R1Field.inv(e0, t);
+ SecP224R1Field.multiply(t, d0, t);
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java
new file mode 100644
index 00000000..9b8ccf6c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java
@@ -0,0 +1,271 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat224;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP224R1Point extends ECPoint.AbstractFp
+{
+ SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ super(curve, x, y);
+ }
+
+ SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ super(curve, x, y, zs);
+ }
+
+ protected ECPoint detach()
+ {
+ return new SecP224R1Point(null, getAffineXCoord(), getAffineYCoord());
+ }
+
+ public ECPoint add(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return this;
+ }
+ if (this == b)
+ {
+ return twice();
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP224R1FieldElement X1 = (SecP224R1FieldElement)this.x, Y1 = (SecP224R1FieldElement)this.y;
+ SecP224R1FieldElement X2 = (SecP224R1FieldElement)b.getXCoord(), Y2 = (SecP224R1FieldElement)b.getYCoord();
+
+ SecP224R1FieldElement Z1 = (SecP224R1FieldElement)this.zs[0];
+ SecP224R1FieldElement Z2 = (SecP224R1FieldElement)b.getZCoord(0);
+
+ int c;
+ int[] tt1 = Nat224.createExt();
+ int[] t2 = Nat224.create();
+ int[] t3 = Nat224.create();
+ int[] t4 = Nat224.create();
+
+ boolean Z1IsOne = Z1.isOne();
+ int[] U2, S2;
+ if (Z1IsOne)
+ {
+ U2 = X2.x;
+ S2 = Y2.x;
+ }
+ else
+ {
+ S2 = t3;
+ SecP224R1Field.square(Z1.x, S2);
+
+ U2 = t2;
+ SecP224R1Field.multiply(S2, X2.x, U2);
+
+ SecP224R1Field.multiply(S2, Z1.x, S2);
+ SecP224R1Field.multiply(S2, Y2.x, S2);
+ }
+
+ boolean Z2IsOne = Z2.isOne();
+ int[] U1, S1;
+ if (Z2IsOne)
+ {
+ U1 = X1.x;
+ S1 = Y1.x;
+ }
+ else
+ {
+ S1 = t4;
+ SecP224R1Field.square(Z2.x, S1);
+
+ U1 = tt1;
+ SecP224R1Field.multiply(S1, X1.x, U1);
+
+ SecP224R1Field.multiply(S1, Z2.x, S1);
+ SecP224R1Field.multiply(S1, Y1.x, S1);
+ }
+
+ int[] H = Nat224.create();
+ SecP224R1Field.subtract(U1, U2, H);
+
+ int[] R = t2;
+ SecP224R1Field.subtract(S1, S2, R);
+
+ // Check if b == this or b == -this
+ if (Nat224.isZero(H))
+ {
+ if (Nat224.isZero(R))
+ {
+ // this == b, i.e. this must be doubled
+ return this.twice();
+ }
+
+ // this == -b, i.e. the result is the point at infinity
+ return curve.getInfinity();
+ }
+
+ int[] HSquared = t3;
+ SecP224R1Field.square(H, HSquared);
+
+ int[] G = Nat224.create();
+ SecP224R1Field.multiply(HSquared, H, G);
+
+ int[] V = t3;
+ SecP224R1Field.multiply(HSquared, U1, V);
+
+ SecP224R1Field.negate(G, G);
+ Nat224.mul(S1, G, tt1);
+
+ c = Nat224.addBothTo(V, V, G);
+ SecP224R1Field.reduce32(c, G);
+
+ SecP224R1FieldElement X3 = new SecP224R1FieldElement(t4);
+ SecP224R1Field.square(R, X3.x);
+ SecP224R1Field.subtract(X3.x, G, X3.x);
+
+ SecP224R1FieldElement Y3 = new SecP224R1FieldElement(G);
+ SecP224R1Field.subtract(V, X3.x, Y3.x);
+ SecP224R1Field.multiplyAddToExt(Y3.x, R, tt1);
+ SecP224R1Field.reduce(tt1, Y3.x);
+
+ SecP224R1FieldElement Z3 = new SecP224R1FieldElement(H);
+ if (!Z1IsOne)
+ {
+ SecP224R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+ if (!Z2IsOne)
+ {
+ SecP224R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ }
+
+ ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
+
+ return new SecP224R1Point(curve, X3, Y3, zs);
+ }
+
+ public ECPoint twice()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP224R1FieldElement Y1 = (SecP224R1FieldElement)this.y;
+ if (Y1.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ SecP224R1FieldElement X1 = (SecP224R1FieldElement)this.x, Z1 = (SecP224R1FieldElement)this.zs[0];
+
+ int c;
+ int[] t1 = Nat224.create();
+ int[] t2 = Nat224.create();
+
+ int[] Y1Squared = Nat224.create();
+ SecP224R1Field.square(Y1.x, Y1Squared);
+
+ int[] T = Nat224.create();
+ SecP224R1Field.square(Y1Squared, T);
+
+ boolean Z1IsOne = Z1.isOne();
+
+ int[] Z1Squared = Z1.x;
+ if (!Z1IsOne)
+ {
+ Z1Squared = t2;
+ SecP224R1Field.square(Z1.x, Z1Squared);
+ }
+
+ SecP224R1Field.subtract(X1.x, Z1Squared, t1);
+
+ int[] M = t2;
+ SecP224R1Field.add(X1.x, Z1Squared, M);
+ SecP224R1Field.multiply(M, t1, M);
+ c = Nat224.addBothTo(M, M, M);
+ SecP224R1Field.reduce32(c, M);
+
+ int[] S = Y1Squared;
+ SecP224R1Field.multiply(Y1Squared, X1.x, S);
+ c = Nat.shiftUpBits(7, S, 2, 0);
+ SecP224R1Field.reduce32(c, S);
+
+ c = Nat.shiftUpBits(7, T, 3, 0, t1);
+ SecP224R1Field.reduce32(c, t1);
+
+ SecP224R1FieldElement X3 = new SecP224R1FieldElement(T);
+ SecP224R1Field.square(M, X3.x);
+ SecP224R1Field.subtract(X3.x, S, X3.x);
+ SecP224R1Field.subtract(X3.x, S, X3.x);
+
+ SecP224R1FieldElement Y3 = new SecP224R1FieldElement(S);
+ SecP224R1Field.subtract(S, X3.x, Y3.x);
+ SecP224R1Field.multiply(Y3.x, M, Y3.x);
+ SecP224R1Field.subtract(Y3.x, t1, Y3.x);
+
+ SecP224R1FieldElement Z3 = new SecP224R1FieldElement(M);
+ SecP224R1Field.twice(Y1.x, Z3.x);
+ if (!Z1IsOne)
+ {
+ SecP224R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+
+ return new SecP224R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
+ }
+
+ public ECPoint twicePlus(ECPoint b)
+ {
+ if (this == b)
+ {
+ return threeTimes();
+ }
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return twice();
+ }
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return b;
+ }
+
+ return twice().add(b);
+ }
+
+ public ECPoint threeTimes()
+ {
+ if (this.isInfinity() || this.y.isZero())
+ {
+ return this;
+ }
+
+ // NOTE: Be careful about recursions between twicePlus and threeTimes
+ return twice().add(this);
+ }
+
+ public ECPoint negate()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ return new SecP224R1Point(curve, this.x, this.y.negate(), this.zs);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java
new file mode 100644
index 00000000..a39fc8a4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java
@@ -0,0 +1,164 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.ec.AbstractECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat256;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP256K1Curve extends ECCurve.AbstractFp
+{
+ public static final BigInteger q = SecP256K1FieldElement.Q;
+
+ private static final int SECP256K1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP256K1_AFFINE_ZS = new ECFieldElement[] { new SecP256K1FieldElement(ECConstants.ONE) };
+
+ protected SecP256K1Point infinity;
+
+ public SecP256K1Curve()
+ {
+ super(q);
+
+ this.infinity = new SecP256K1Point(this, null, null);
+
+ this.a = fromBigInteger(ECConstants.ZERO);
+ this.b = fromBigInteger(BigInteger.valueOf(7));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"));
+ this.cofactor = BigInteger.valueOf(1);
+ this.coord = SECP256K1_DEFAULT_COORDS;
+ }
+
+ protected ECCurve cloneCurve()
+ {
+ return new SecP256K1Curve();
+ }
+
+ public boolean supportsCoordinateSystem(int coord)
+ {
+ switch (coord)
+ {
+ case COORD_JACOBIAN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public int getFieldSize()
+ {
+ return q.bitLength();
+ }
+
+ public ECFieldElement fromBigInteger(BigInteger x)
+ {
+ return new SecP256K1FieldElement(x);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
+ {
+ return new SecP256K1Point(this, x, y);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ return new SecP256K1Point(this, x, y, zs);
+ }
+
+ public ECPoint getInfinity()
+ {
+ return infinity;
+ }
+
+ public ECLookupTable createCacheSafeLookupTable(ECPoint[] points, int off, final int len)
+ {
+ final int FE_INTS = 8;
+
+ final int[] table = new int[len * FE_INTS * 2];
+ {
+ int pos = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ ECPoint p = points[off + i];
+ Nat256.copy(((SecP256K1FieldElement)p.getRawXCoord()).x, 0, table, pos); pos += FE_INTS;
+ Nat256.copy(((SecP256K1FieldElement)p.getRawYCoord()).x, 0, table, pos); pos += FE_INTS;
+ }
+ }
+
+ return new AbstractECLookupTable()
+ {
+ public int getSize()
+ {
+ return len;
+ }
+
+ public ECPoint lookup(int index)
+ {
+ int[] x = Nat256.create(), y = Nat256.create();
+ int pos = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ int MASK = ((i ^ index) - 1) >> 31;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] ^= table[pos + j] & MASK;
+ y[j] ^= table[pos + FE_INTS + j] & MASK;
+ }
+
+ pos += (FE_INTS * 2);
+ }
+
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat256.create(), y = Nat256.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP256K1FieldElement(x), new SecP256K1FieldElement(y), SECP256K1_AFFINE_ZS);
+ }
+ };
+ }
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat256.create();
+ SecP256K1Field.random(r, x);
+ return new SecP256K1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat256.create();
+ SecP256K1Field.randomMult(r, x);
+ return new SecP256K1FieldElement(x);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
new file mode 100644
index 00000000..fd47d216
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
@@ -0,0 +1,222 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.raw.Mod;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat256;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP256K1Field
+{
+ // 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
+ static final int[] P = new int[]{ 0xFFFFFC2F, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x000E90A1, 0x000007A2, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xFFFFF85E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF };
+ private static final int[] PExtInv = new int[]{ 0xFFF16F5F, 0xFFFFF85D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000007A1, 0x00000002 };
+ private static final int P7 = 0xFFFFFFFF;
+ private static final int PExt15 = 0xFFFFFFFF;
+ private static final int PInv33 = 0x3D1;
+
+ public static void add(int[] x, int[] y, int[] z)
+ {
+ int c = Nat256.add(x, y, z);
+ if (c != 0 || (z[7] == P7 && Nat256.gte(z, P)))
+ {
+ Nat.add33To(8, PInv33, z);
+ }
+ }
+
+ public static void addExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.add(16, xx, yy, zz);
+ if (c != 0 || (zz[15] == PExt15 && Nat.gte(16, zz, PExt)))
+ {
+ if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.incAt(16, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void addOne(int[] x, int[] z)
+ {
+ int c = Nat.inc(8, x, z);
+ if (c != 0 || (z[7] == P7 && Nat256.gte(z, P)))
+ {
+ Nat.add33To(8, PInv33, z);
+ }
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ int[] z = Nat256.fromBigInteger(x);
+ if (z[7] == P7 && Nat256.gte(z, P))
+ {
+ Nat256.subFrom(P, z);
+ }
+ return z;
+ }
+
+ public static void half(int[] x, int[] z)
+ {
+ if ((x[0] & 1) == 0)
+ {
+ Nat.shiftDownBit(8, x, 0, z);
+ }
+ else
+ {
+ int c = Nat256.add(x, P, z);
+ Nat.shiftDownBit(8, z, c);
+ }
+ }
+
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 8; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static void multiply(int[] x, int[] y, int[] z)
+ {
+ int[] tt = Nat256.createExt();
+ Nat256.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
+ public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
+ {
+ int c = Nat256.mulAddTo(x, y, zz);
+ if (c != 0 || (zz[15] == PExt15 && Nat.gte(16, zz, PExt)))
+ {
+ if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.incAt(16, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void negate(int[] x, int[] z)
+ {
+ if (0 != isZero(x))
+ {
+ Nat256.sub(P, P, z);
+ }
+ else
+ {
+ Nat256.sub(P, x, z);
+ }
+ }
+
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[8 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 8);
+ }
+ while (0 == Nat.lessThan(8, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
+ public static void reduce(int[] xx, int[] z)
+ {
+ long cc = Nat256.mul33Add(PInv33, xx, 8, xx, 0, z, 0);
+ int c = Nat256.mul33DWordAdd(PInv33, cc, z, 0);
+
+ // assert c == 0L || c == 1L;
+
+ if (c != 0 || (z[7] == P7 && Nat256.gte(z, P)))
+ {
+ Nat.add33To(8, PInv33, z);
+ }
+ }
+
+ public static void reduce32(int x, int[] z)
+ {
+ if ((x != 0 && Nat256.mul33WordAdd(PInv33, x, z, 0) != 0)
+ || (z[7] == P7 && Nat256.gte(z, P)))
+ {
+ Nat.add33To(8, PInv33, z);
+ }
+ }
+
+ public static void square(int[] x, int[] z)
+ {
+ int[] tt = Nat256.createExt();
+ Nat256.square(x, tt);
+ reduce(tt, z);
+ }
+
+ public static void squareN(int[] x, int n, int[] z)
+ {
+// assert n > 0;
+
+ int[] tt = Nat256.createExt();
+ Nat256.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat256.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
+ public static void subtract(int[] x, int[] y, int[] z)
+ {
+ int c = Nat256.sub(x, y, z);
+ if (c != 0)
+ {
+ Nat.sub33From(8, PInv33, z);
+ }
+ }
+
+ public static void subtractExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.sub(16, xx, yy, zz);
+ if (c != 0)
+ {
+ if (Nat.subFrom(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.decAt(16, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void twice(int[] x, int[] z)
+ {
+ int c = Nat.shiftUpBit(8, x, 0, z);
+ if (c != 0 || (z[7] == P7 && Nat256.gte(z, P)))
+ {
+ Nat.add33To(8, PInv33, z);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
new file mode 100644
index 00000000..08218941
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
@@ -0,0 +1,220 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.raw.Nat256;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP256K1FieldElement extends ECFieldElement.AbstractFp
+{
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"));
+
+ protected int[] x;
+
+ public SecP256K1FieldElement(BigInteger x)
+ {
+ if (x == null || x.signum() < 0 || x.compareTo(Q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid for SecP256K1FieldElement");
+ }
+
+ this.x = SecP256K1Field.fromBigInteger(x);
+ }
+
+ public SecP256K1FieldElement()
+ {
+ this.x = Nat256.create();
+ }
+
+ protected SecP256K1FieldElement(int[] x)
+ {
+ this.x = x;
+ }
+
+ public boolean isZero()
+ {
+ return Nat256.isZero(x);
+ }
+
+ public boolean isOne()
+ {
+ return Nat256.isOne(x);
+ }
+
+ public boolean testBitZero()
+ {
+ return Nat256.getBit(x, 0) == 1;
+ }
+
+ public BigInteger toBigInteger()
+ {
+ return Nat256.toBigInteger(x);
+ }
+
+ public String getFieldName()
+ {
+ return "SecP256K1Field";
+ }
+
+ public int getFieldSize()
+ {
+ return Q.bitLength();
+ }
+
+ public ECFieldElement add(ECFieldElement b)
+ {
+ int[] z = Nat256.create();
+ SecP256K1Field.add(x, ((SecP256K1FieldElement)b).x, z);
+ return new SecP256K1FieldElement(z);
+ }
+
+ public ECFieldElement addOne()
+ {
+ int[] z = Nat256.create();
+ SecP256K1Field.addOne(x, z);
+ return new SecP256K1FieldElement(z);
+ }
+
+ public ECFieldElement subtract(ECFieldElement b)
+ {
+ int[] z = Nat256.create();
+ SecP256K1Field.subtract(x, ((SecP256K1FieldElement)b).x, z);
+ return new SecP256K1FieldElement(z);
+ }
+
+ public ECFieldElement multiply(ECFieldElement b)
+ {
+ int[] z = Nat256.create();
+ SecP256K1Field.multiply(x, ((SecP256K1FieldElement)b).x, z);
+ return new SecP256K1FieldElement(z);
+ }
+
+ public ECFieldElement divide(ECFieldElement b)
+ {
+// return multiply(b.invert());
+ int[] z = Nat256.create();
+ SecP256K1Field.inv(((SecP256K1FieldElement)b).x, z);
+ SecP256K1Field.multiply(z, x, z);
+ return new SecP256K1FieldElement(z);
+ }
+
+ public ECFieldElement negate()
+ {
+ int[] z = Nat256.create();
+ SecP256K1Field.negate(x, z);
+ return new SecP256K1FieldElement(z);
+ }
+
+ public ECFieldElement square()
+ {
+ int[] z = Nat256.create();
+ SecP256K1Field.square(x, z);
+ return new SecP256K1FieldElement(z);
+ }
+
+ public ECFieldElement invert()
+ {
+// return new SecP256K1FieldElement(toBigInteger().modInverse(Q));
+ int[] z = Nat256.create();
+ SecP256K1Field.inv(x, z);
+ return new SecP256K1FieldElement(z);
+ }
+
+ // D.1.4 91
+ /**
+ * return a sqrt root - the routine verifies that the calculation returns the right value - if
+ * none exists it returns null.
+ */
+ public ECFieldElement sqrt()
+ {
+ /*
+ * Raise this element to the exponent 2^254 - 2^30 - 2^7 - 2^6 - 2^5 - 2^4 - 2^2
+ *
+ * Breaking up the exponent's binary representation into "repunits", we get:
+ * { 223 1s } { 1 0s } { 22 1s } { 4 0s } { 2 1s } { 2 0s }
+ *
+ * Therefore we need an addition chain containing 2, 22, 223 (the lengths of the repunits)
+ * We use: 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223]
+ */
+
+ int[] x1 = this.x;
+ if (Nat256.isZero(x1) || Nat256.isOne(x1))
+ {
+ return this;
+ }
+
+ int[] x2 = Nat256.create();
+ SecP256K1Field.square(x1, x2);
+ SecP256K1Field.multiply(x2, x1, x2);
+ int[] x3 = Nat256.create();
+ SecP256K1Field.square(x2, x3);
+ SecP256K1Field.multiply(x3, x1, x3);
+ int[] x6 = Nat256.create();
+ SecP256K1Field.squareN(x3, 3, x6);
+ SecP256K1Field.multiply(x6, x3, x6);
+ int[] x9 = x6;
+ SecP256K1Field.squareN(x6, 3, x9);
+ SecP256K1Field.multiply(x9, x3, x9);
+ int[] x11 = x9;
+ SecP256K1Field.squareN(x9, 2, x11);
+ SecP256K1Field.multiply(x11, x2, x11);
+ int[] x22 = Nat256.create();
+ SecP256K1Field.squareN(x11, 11, x22);
+ SecP256K1Field.multiply(x22, x11, x22);
+ int[] x44 = x11;
+ SecP256K1Field.squareN(x22, 22, x44);
+ SecP256K1Field.multiply(x44, x22, x44);
+ int[] x88 = Nat256.create();
+ SecP256K1Field.squareN(x44, 44, x88);
+ SecP256K1Field.multiply(x88, x44, x88);
+ int[] x176 = Nat256.create();
+ SecP256K1Field.squareN(x88, 88, x176);
+ SecP256K1Field.multiply(x176, x88, x176);
+ int[] x220 = x88;
+ SecP256K1Field.squareN(x176, 44, x220);
+ SecP256K1Field.multiply(x220, x44, x220);
+ int[] x223 = x44;
+ SecP256K1Field.squareN(x220, 3, x223);
+ SecP256K1Field.multiply(x223, x3, x223);
+
+ int[] t1 = x223;
+ SecP256K1Field.squareN(t1, 23, t1);
+ SecP256K1Field.multiply(t1, x22, t1);
+ SecP256K1Field.squareN(t1, 6, t1);
+ SecP256K1Field.multiply(t1, x2, t1);
+ SecP256K1Field.squareN(t1, 2, t1);
+
+ int[] t2 = x2;
+ SecP256K1Field.square(t1, t2);
+
+ return Nat256.eq(x1, t2) ? new SecP256K1FieldElement(t1) : null;
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof SecP256K1FieldElement))
+ {
+ return false;
+ }
+
+ SecP256K1FieldElement o = (SecP256K1FieldElement)other;
+ return Nat256.eq(x, o.x);
+ }
+
+ public int hashCode()
+ {
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 8);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
new file mode 100644
index 00000000..283554e3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
@@ -0,0 +1,260 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat256;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP256K1Point extends ECPoint.AbstractFp
+{
+ SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ super(curve, x, y);
+ }
+
+ SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ super(curve, x, y, zs);
+ }
+
+ protected ECPoint detach()
+ {
+ return new SecP256K1Point(null, getAffineXCoord(), getAffineYCoord());
+ }
+
+ // B.3 pg 62
+ public ECPoint add(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return this;
+ }
+ if (this == b)
+ {
+ return twice();
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP256K1FieldElement X1 = (SecP256K1FieldElement)this.x, Y1 = (SecP256K1FieldElement)this.y;
+ SecP256K1FieldElement X2 = (SecP256K1FieldElement)b.getXCoord(), Y2 = (SecP256K1FieldElement)b.getYCoord();
+
+ SecP256K1FieldElement Z1 = (SecP256K1FieldElement)this.zs[0];
+ SecP256K1FieldElement Z2 = (SecP256K1FieldElement)b.getZCoord(0);
+
+ int c;
+ int[] tt1 = Nat256.createExt();
+ int[] t2 = Nat256.create();
+ int[] t3 = Nat256.create();
+ int[] t4 = Nat256.create();
+
+ boolean Z1IsOne = Z1.isOne();
+ int[] U2, S2;
+ if (Z1IsOne)
+ {
+ U2 = X2.x;
+ S2 = Y2.x;
+ }
+ else
+ {
+ S2 = t3;
+ SecP256K1Field.square(Z1.x, S2);
+
+ U2 = t2;
+ SecP256K1Field.multiply(S2, X2.x, U2);
+
+ SecP256K1Field.multiply(S2, Z1.x, S2);
+ SecP256K1Field.multiply(S2, Y2.x, S2);
+ }
+
+ boolean Z2IsOne = Z2.isOne();
+ int[] U1, S1;
+ if (Z2IsOne)
+ {
+ U1 = X1.x;
+ S1 = Y1.x;
+ }
+ else
+ {
+ S1 = t4;
+ SecP256K1Field.square(Z2.x, S1);
+
+ U1 = tt1;
+ SecP256K1Field.multiply(S1, X1.x, U1);
+
+ SecP256K1Field.multiply(S1, Z2.x, S1);
+ SecP256K1Field.multiply(S1, Y1.x, S1);
+ }
+
+ int[] H = Nat256.create();
+ SecP256K1Field.subtract(U1, U2, H);
+
+ int[] R = t2;
+ SecP256K1Field.subtract(S1, S2, R);
+
+ // Check if b == this or b == -this
+ if (Nat256.isZero(H))
+ {
+ if (Nat256.isZero(R))
+ {
+ // this == b, i.e. this must be doubled
+ return this.twice();
+ }
+
+ // this == -b, i.e. the result is the point at infinity
+ return curve.getInfinity();
+ }
+
+ int[] HSquared = t3;
+ SecP256K1Field.square(H, HSquared);
+
+ int[] G = Nat256.create();
+ SecP256K1Field.multiply(HSquared, H, G);
+
+ int[] V = t3;
+ SecP256K1Field.multiply(HSquared, U1, V);
+
+ SecP256K1Field.negate(G, G);
+ Nat256.mul(S1, G, tt1);
+
+ c = Nat256.addBothTo(V, V, G);
+ SecP256K1Field.reduce32(c, G);
+
+ SecP256K1FieldElement X3 = new SecP256K1FieldElement(t4);
+ SecP256K1Field.square(R, X3.x);
+ SecP256K1Field.subtract(X3.x, G, X3.x);
+
+ SecP256K1FieldElement Y3 = new SecP256K1FieldElement(G);
+ SecP256K1Field.subtract(V, X3.x, Y3.x);
+ SecP256K1Field.multiplyAddToExt(Y3.x, R, tt1);
+ SecP256K1Field.reduce(tt1, Y3.x);
+
+ SecP256K1FieldElement Z3 = new SecP256K1FieldElement(H);
+ if (!Z1IsOne)
+ {
+ SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+ if (!Z2IsOne)
+ {
+ SecP256K1Field.multiply(Z3.x, Z2.x, Z3.x);
+ }
+
+ ECFieldElement[] zs = new ECFieldElement[] { Z3 };
+
+ return new SecP256K1Point(curve, X3, Y3, zs);
+ }
+
+ // B.3 pg 62
+ public ECPoint twice()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP256K1FieldElement Y1 = (SecP256K1FieldElement)this.y;
+ if (Y1.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ SecP256K1FieldElement X1 = (SecP256K1FieldElement)this.x, Z1 = (SecP256K1FieldElement)this.zs[0];
+
+ int c;
+
+ int[] Y1Squared = Nat256.create();
+ SecP256K1Field.square(Y1.x, Y1Squared);
+
+ int[] T = Nat256.create();
+ SecP256K1Field.square(Y1Squared, T);
+
+ int[] M = Nat256.create();
+ SecP256K1Field.square(X1.x, M);
+ c = Nat256.addBothTo(M, M, M);
+ SecP256K1Field.reduce32(c, M);
+
+ int[] S = Y1Squared;
+ SecP256K1Field.multiply(Y1Squared, X1.x, S);
+ c = Nat.shiftUpBits(8, S, 2, 0);
+ SecP256K1Field.reduce32(c, S);
+
+ int[] t1 = Nat256.create();
+ c = Nat.shiftUpBits(8, T, 3, 0, t1);
+ SecP256K1Field.reduce32(c, t1);
+
+ SecP256K1FieldElement X3 = new SecP256K1FieldElement(T);
+ SecP256K1Field.square(M, X3.x);
+ SecP256K1Field.subtract(X3.x, S, X3.x);
+ SecP256K1Field.subtract(X3.x, S, X3.x);
+
+ SecP256K1FieldElement Y3 = new SecP256K1FieldElement(S);
+ SecP256K1Field.subtract(S, X3.x, Y3.x);
+ SecP256K1Field.multiply(Y3.x, M, Y3.x);
+ SecP256K1Field.subtract(Y3.x, t1, Y3.x);
+
+ SecP256K1FieldElement Z3 = new SecP256K1FieldElement(M);
+ SecP256K1Field.twice(Y1.x, Z3.x);
+ if (!Z1.isOne())
+ {
+ SecP256K1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+
+ return new SecP256K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 });
+ }
+
+ public ECPoint twicePlus(ECPoint b)
+ {
+ if (this == b)
+ {
+ return threeTimes();
+ }
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return twice();
+ }
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return b;
+ }
+
+ return twice().add(b);
+ }
+
+ public ECPoint threeTimes()
+ {
+ if (this.isInfinity() || this.y.isZero())
+ {
+ return this;
+ }
+
+ // NOTE: Be careful about recursions between twicePlus and threeTimes
+ return twice().add(this);
+ }
+
+ public ECPoint negate()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ return new SecP256K1Point(curve, this.x, this.y.negate(), this.zs);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java
new file mode 100644
index 00000000..9050b6cb
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java
@@ -0,0 +1,167 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.ec.AbstractECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat256;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP256R1Curve extends ECCurve.AbstractFp
+{
+ public static final BigInteger q = SecP256R1FieldElement.Q;
+
+ private static final int SECP256R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP256R1_AFFINE_ZS = new ECFieldElement[] { new SecP256R1FieldElement(ECConstants.ONE) };
+
+ protected SecP256R1Point infinity;
+
+ public SecP256R1Curve()
+ {
+ super(q);
+
+ this.infinity = new SecP256R1Point(this, null, null);
+
+ this.a = fromBigInteger(new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")));
+ this.b = fromBigInteger(new BigInteger(1,
+ Hex.decodeStrict("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"));
+ this.cofactor = BigInteger.valueOf(1);
+
+ this.coord = SECP256R1_DEFAULT_COORDS;
+ }
+
+ protected ECCurve cloneCurve()
+ {
+ return new SecP256R1Curve();
+ }
+
+ public boolean supportsCoordinateSystem(int coord)
+ {
+ switch (coord)
+ {
+ case COORD_JACOBIAN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public int getFieldSize()
+ {
+ return q.bitLength();
+ }
+
+ public ECFieldElement fromBigInteger(BigInteger x)
+ {
+ return new SecP256R1FieldElement(x);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
+ {
+ return new SecP256R1Point(this, x, y);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ return new SecP256R1Point(this, x, y, zs);
+ }
+
+ public ECPoint getInfinity()
+ {
+ return infinity;
+ }
+
+ public ECLookupTable createCacheSafeLookupTable(ECPoint[] points, int off, final int len)
+ {
+ final int FE_INTS = 8;
+
+ final int[] table = new int[len * FE_INTS * 2];
+ {
+ int pos = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ ECPoint p = points[off + i];
+ Nat256.copy(((SecP256R1FieldElement)p.getRawXCoord()).x, 0, table, pos); pos += FE_INTS;
+ Nat256.copy(((SecP256R1FieldElement)p.getRawYCoord()).x, 0, table, pos); pos += FE_INTS;
+ }
+ }
+
+ return new AbstractECLookupTable()
+ {
+ public int getSize()
+ {
+ return len;
+ }
+
+ public ECPoint lookup(int index)
+ {
+ int[] x = Nat256.create(), y = Nat256.create();
+ int pos = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ int MASK = ((i ^ index) - 1) >> 31;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] ^= table[pos + j] & MASK;
+ y[j] ^= table[pos + FE_INTS + j] & MASK;
+ }
+
+ pos += (FE_INTS * 2);
+ }
+
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat256.create(), y = Nat256.create();
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP256R1FieldElement(x), new SecP256R1FieldElement(y), SECP256R1_AFFINE_ZS);
+ }
+ };
+ }
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat256.create();
+ SecP256R1Field.random(r, x);
+ return new SecP256R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat256.create();
+ SecP256R1Field.randomMult(r, x);
+ return new SecP256R1FieldElement(x);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
new file mode 100644
index 00000000..b9cea7a8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
@@ -0,0 +1,356 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.raw.Mod;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat256;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP256R1Field
+{
+ private static final long M = 0xFFFFFFFFL;
+
+ // 2^256 - 2^224 + 2^192 + 2^96 - 1
+ static final int[] P = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000001, 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0x00000001, 0xFFFFFFFE, 0x00000002,
+ 0xFFFFFFFE };
+ private static final int P7 = 0xFFFFFFFF;
+ private static final int PExt15s1 = 0xFFFFFFFE >>> 1;
+
+ public static void add(int[] x, int[] y, int[] z)
+ {
+ int c = Nat256.add(x, y, z);
+ if (c != 0 || (z[7] == P7 && Nat256.gte(z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ public static void addExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.add(16, xx, yy, zz);
+ if (c != 0 || ((zz[15] >>> 1) >= PExt15s1 && Nat.gte(16, zz, PExt)))
+ {
+ Nat.subFrom(16, PExt, zz);
+ }
+ }
+
+ public static void addOne(int[] x, int[] z)
+ {
+ int c = Nat.inc(8, x, z);
+ if (c != 0 || (z[7] == P7 && Nat256.gte(z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ int[] z = Nat256.fromBigInteger(x);
+ if (z[7] == P7 && Nat256.gte(z, P))
+ {
+ Nat256.subFrom(P, z);
+ }
+ return z;
+ }
+
+ public static void half(int[] x, int[] z)
+ {
+ if ((x[0] & 1) == 0)
+ {
+ Nat.shiftDownBit(8, x, 0, z);
+ }
+ else
+ {
+ int c = Nat256.add(x, P, z);
+ Nat.shiftDownBit(8, z, c);
+ }
+ }
+
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 8; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static void multiply(int[] x, int[] y, int[] z)
+ {
+ int[] tt = Nat256.createExt();
+ Nat256.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
+ public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
+ {
+ int c = Nat256.mulAddTo(x, y, zz);
+ if (c != 0 || ((zz[15] >>> 1) >= PExt15s1 && Nat.gte(16, zz, PExt)))
+ {
+ Nat.subFrom(16, PExt, zz);
+ }
+ }
+
+ public static void negate(int[] x, int[] z)
+ {
+ if (0 != isZero(x))
+ {
+ Nat256.sub(P, P, z);
+ }
+ else
+ {
+ Nat256.sub(P, x, z);
+ }
+ }
+
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[8 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 8);
+ }
+ while (0 == Nat.lessThan(8, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
+ public static void reduce(int[] xx, int[] z)
+ {
+ long xx08 = xx[8] & M, xx09 = xx[9] & M, xx10 = xx[10] & M, xx11 = xx[11] & M;
+ long xx12 = xx[12] & M, xx13 = xx[13] & M, xx14 = xx[14] & M, xx15 = xx[15] & M;
+
+ final long n = 6;
+
+ xx08 -= n;
+
+ long t0 = xx08 + xx09;
+ long t1 = xx09 + xx10;
+ long t2 = xx10 + xx11 - xx15;
+ long t3 = xx11 + xx12;
+ long t4 = xx12 + xx13;
+ long t5 = xx13 + xx14;
+ long t6 = xx14 + xx15;
+ long t7 = t5 - t0;
+
+ long cc = 0;
+ cc += (xx[0] & M) - t3 - t7;
+ z[0] = (int)cc;
+ cc >>= 32;
+ cc += (xx[1] & M) + t1 - t4 - t6;
+ z[1] = (int)cc;
+ cc >>= 32;
+ cc += (xx[2] & M) + t2 - t5;
+ z[2] = (int)cc;
+ cc >>= 32;
+ cc += (xx[3] & M) + (t3 << 1) + t7 - t6;
+ z[3] = (int)cc;
+ cc >>= 32;
+ cc += (xx[4] & M) + (t4 << 1) + xx14 - t1;
+ z[4] = (int)cc;
+ cc >>= 32;
+ cc += (xx[5] & M) + (t5 << 1) - t2;
+ z[5] = (int)cc;
+ cc >>= 32;
+ cc += (xx[6] & M) + (t6 << 1) + t7;
+ z[6] = (int)cc;
+ cc >>= 32;
+ cc += (xx[7] & M) + (xx15 << 1) + xx08 - t2 - t4;
+ z[7] = (int)cc;
+ cc >>= 32;
+ cc += n;
+
+// assert cc >= 0;
+
+ reduce32((int)cc, z);
+ }
+
+ public static void reduce32(int x, int[] z)
+ {
+ long cc = 0;
+
+ if (x != 0)
+ {
+ long xx08 = x & M;
+
+ cc += (z[0] & M) + xx08;
+ z[0] = (int)cc;
+ cc >>= 32;
+ if (cc != 0)
+ {
+ cc += (z[1] & M);
+ z[1] = (int)cc;
+ cc >>= 32;
+ cc += (z[2] & M);
+ z[2] = (int)cc;
+ cc >>= 32;
+ }
+ cc += (z[3] & M) - xx08;
+ z[3] = (int)cc;
+ cc >>= 32;
+ if (cc != 0)
+ {
+ cc += (z[4] & M);
+ z[4] = (int)cc;
+ cc >>= 32;
+ cc += (z[5] & M);
+ z[5] = (int)cc;
+ cc >>= 32;
+ }
+ cc += (z[6] & M) - xx08;
+ z[6] = (int)cc;
+ cc >>= 32;
+ cc += (z[7] & M) + xx08;
+ z[7] = (int)cc;
+ cc >>= 32;
+
+// assert cc == 0 || cc == 1;
+ }
+
+ if (cc != 0 || (z[7] == P7 && Nat256.gte(z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ public static void square(int[] x, int[] z)
+ {
+ int[] tt = Nat256.createExt();
+ Nat256.square(x, tt);
+ reduce(tt, z);
+ }
+
+ public static void squareN(int[] x, int n, int[] z)
+ {
+// assert n > 0;
+
+ int[] tt = Nat256.createExt();
+ Nat256.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat256.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
+ public static void subtract(int[] x, int[] y, int[] z)
+ {
+ int c = Nat256.sub(x, y, z);
+ if (c != 0)
+ {
+ subPInvFrom(z);
+ }
+ }
+
+ public static void subtractExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.sub(16, xx, yy, zz);
+ if (c != 0)
+ {
+ Nat.addTo(16, PExt, zz);
+ }
+ }
+
+ public static void twice(int[] x, int[] z)
+ {
+ int c = Nat.shiftUpBit(8, x, 0, z);
+ if (c != 0 || (z[7] == P7 && Nat256.gte(z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ private static void addPInvTo(int[] z)
+ {
+ long c = (z[0] & M) + 1;
+ z[0] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ c += (z[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (z[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ }
+ c += (z[3] & M) - 1;
+ z[3] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ c += (z[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (z[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ }
+ c += (z[6] & M) - 1;
+ z[6] = (int)c;
+ c >>= 32;
+ c += (z[7] & M) + 1;
+ z[7] = (int)c;
+// c >>= 32;
+ }
+
+ private static void subPInvFrom(int[] z)
+ {
+ long c = (z[0] & M) - 1;
+ z[0] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ c += (z[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (z[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ }
+ c += (z[3] & M) + 1;
+ z[3] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ c += (z[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (z[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ }
+ c += (z[6] & M) + 1;
+ z[6] = (int)c;
+ c >>= 32;
+ c += (z[7] & M) - 1;
+ z[7] = (int)c;
+// c >>= 32;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
new file mode 100644
index 00000000..3cfbea6c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
@@ -0,0 +1,194 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.raw.Nat256;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP256R1FieldElement extends ECFieldElement.AbstractFp
+{
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"));
+
+ protected int[] x;
+
+ public SecP256R1FieldElement(BigInteger x)
+ {
+ if (x == null || x.signum() < 0 || x.compareTo(Q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid for SecP256R1FieldElement");
+ }
+
+ this.x = SecP256R1Field.fromBigInteger(x);
+ }
+
+ public SecP256R1FieldElement()
+ {
+ this.x = Nat256.create();
+ }
+
+ protected SecP256R1FieldElement(int[] x)
+ {
+ this.x = x;
+ }
+
+ public boolean isZero()
+ {
+ return Nat256.isZero(x);
+ }
+
+ public boolean isOne()
+ {
+ return Nat256.isOne(x);
+ }
+
+ public boolean testBitZero()
+ {
+ return Nat256.getBit(x, 0) == 1;
+ }
+
+ public BigInteger toBigInteger()
+ {
+ return Nat256.toBigInteger(x);
+ }
+
+ public String getFieldName()
+ {
+ return "SecP256R1Field";
+ }
+
+ public int getFieldSize()
+ {
+ return Q.bitLength();
+ }
+
+ public ECFieldElement add(ECFieldElement b)
+ {
+ int[] z = Nat256.create();
+ SecP256R1Field.add(x, ((SecP256R1FieldElement)b).x, z);
+ return new SecP256R1FieldElement(z);
+ }
+
+ public ECFieldElement addOne()
+ {
+ int[] z = Nat256.create();
+ SecP256R1Field.addOne(x, z);
+ return new SecP256R1FieldElement(z);
+ }
+
+ public ECFieldElement subtract(ECFieldElement b)
+ {
+ int[] z = Nat256.create();
+ SecP256R1Field.subtract(x, ((SecP256R1FieldElement)b).x, z);
+ return new SecP256R1FieldElement(z);
+ }
+
+ public ECFieldElement multiply(ECFieldElement b)
+ {
+ int[] z = Nat256.create();
+ SecP256R1Field.multiply(x, ((SecP256R1FieldElement)b).x, z);
+ return new SecP256R1FieldElement(z);
+ }
+
+ public ECFieldElement divide(ECFieldElement b)
+ {
+// return multiply(b.invert());
+ int[] z = Nat256.create();
+ SecP256R1Field.inv(((SecP256R1FieldElement)b).x, z);
+ SecP256R1Field.multiply(z, x, z);
+ return new SecP256R1FieldElement(z);
+ }
+
+ public ECFieldElement negate()
+ {
+ int[] z = Nat256.create();
+ SecP256R1Field.negate(x, z);
+ return new SecP256R1FieldElement(z);
+ }
+
+ public ECFieldElement square()
+ {
+ int[] z = Nat256.create();
+ SecP256R1Field.square(x, z);
+ return new SecP256R1FieldElement(z);
+ }
+
+ public ECFieldElement invert()
+ {
+// return new SecP256R1FieldElement(toBigInteger().modInverse(Q));
+ int[] z = Nat256.create();
+ SecP256R1Field.inv(x, z);
+ return new SecP256R1FieldElement(z);
+ }
+
+ /**
+ * return a sqrt root - the routine verifies that the calculation returns the right value - if
+ * none exists it returns null.
+ */
+ public ECFieldElement sqrt()
+ {
+ // Raise this element to the exponent 2^254 - 2^222 + 2^190 + 2^94
+
+ int[] x1 = this.x;
+ if (Nat256.isZero(x1) || Nat256.isOne(x1))
+ {
+ return this;
+ }
+
+ int[] t1 = Nat256.create();
+ int[] t2 = Nat256.create();
+
+ SecP256R1Field.square(x1, t1);
+ SecP256R1Field.multiply(t1, x1, t1);
+
+ SecP256R1Field.squareN(t1, 2, t2);
+ SecP256R1Field.multiply(t2, t1, t2);
+
+ SecP256R1Field.squareN(t2, 4, t1);
+ SecP256R1Field.multiply(t1, t2, t1);
+
+ SecP256R1Field.squareN(t1, 8, t2);
+ SecP256R1Field.multiply(t2, t1, t2);
+
+ SecP256R1Field.squareN(t2, 16, t1);
+ SecP256R1Field.multiply(t1, t2, t1);
+
+ SecP256R1Field.squareN(t1, 32, t1);
+ SecP256R1Field.multiply(t1, x1, t1);
+
+ SecP256R1Field.squareN(t1, 96, t1);
+ SecP256R1Field.multiply(t1, x1, t1);
+
+ SecP256R1Field.squareN(t1, 94, t1);
+ SecP256R1Field.square(t1, t2);
+
+ return Nat256.eq(x1, t2) ? new SecP256R1FieldElement(t1) : null;
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof SecP256R1FieldElement))
+ {
+ return false;
+ }
+
+ SecP256R1FieldElement o = (SecP256R1FieldElement)other;
+ return Nat256.eq(x, o.x);
+ }
+
+ public int hashCode()
+ {
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 8);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
new file mode 100644
index 00000000..475624a0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
@@ -0,0 +1,271 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat256;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP256R1Point extends ECPoint.AbstractFp
+{
+ SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ super(curve, x, y);
+ }
+
+ SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ super(curve, x, y, zs);
+ }
+
+ protected ECPoint detach()
+ {
+ return new SecP256R1Point(null, getAffineXCoord(), getAffineYCoord());
+ }
+
+ public ECPoint add(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return this;
+ }
+ if (this == b)
+ {
+ return twice();
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP256R1FieldElement X1 = (SecP256R1FieldElement)this.x, Y1 = (SecP256R1FieldElement)this.y;
+ SecP256R1FieldElement X2 = (SecP256R1FieldElement)b.getXCoord(), Y2 = (SecP256R1FieldElement)b.getYCoord();
+
+ SecP256R1FieldElement Z1 = (SecP256R1FieldElement)this.zs[0];
+ SecP256R1FieldElement Z2 = (SecP256R1FieldElement)b.getZCoord(0);
+
+ int c;
+ int[] tt1 = Nat256.createExt();
+ int[] t2 = Nat256.create();
+ int[] t3 = Nat256.create();
+ int[] t4 = Nat256.create();
+
+ boolean Z1IsOne = Z1.isOne();
+ int[] U2, S2;
+ if (Z1IsOne)
+ {
+ U2 = X2.x;
+ S2 = Y2.x;
+ }
+ else
+ {
+ S2 = t3;
+ SecP256R1Field.square(Z1.x, S2);
+
+ U2 = t2;
+ SecP256R1Field.multiply(S2, X2.x, U2);
+
+ SecP256R1Field.multiply(S2, Z1.x, S2);
+ SecP256R1Field.multiply(S2, Y2.x, S2);
+ }
+
+ boolean Z2IsOne = Z2.isOne();
+ int[] U1, S1;
+ if (Z2IsOne)
+ {
+ U1 = X1.x;
+ S1 = Y1.x;
+ }
+ else
+ {
+ S1 = t4;
+ SecP256R1Field.square(Z2.x, S1);
+
+ U1 = tt1;
+ SecP256R1Field.multiply(S1, X1.x, U1);
+
+ SecP256R1Field.multiply(S1, Z2.x, S1);
+ SecP256R1Field.multiply(S1, Y1.x, S1);
+ }
+
+ int[] H = Nat256.create();
+ SecP256R1Field.subtract(U1, U2, H);
+
+ int[] R = t2;
+ SecP256R1Field.subtract(S1, S2, R);
+
+ // Check if b == this or b == -this
+ if (Nat256.isZero(H))
+ {
+ if (Nat256.isZero(R))
+ {
+ // this == b, i.e. this must be doubled
+ return this.twice();
+ }
+
+ // this == -b, i.e. the result is the point at infinity
+ return curve.getInfinity();
+ }
+
+ int[] HSquared = t3;
+ SecP256R1Field.square(H, HSquared);
+
+ int[] G = Nat256.create();
+ SecP256R1Field.multiply(HSquared, H, G);
+
+ int[] V = t3;
+ SecP256R1Field.multiply(HSquared, U1, V);
+
+ SecP256R1Field.negate(G, G);
+ Nat256.mul(S1, G, tt1);
+
+ c = Nat256.addBothTo(V, V, G);
+ SecP256R1Field.reduce32(c, G);
+
+ SecP256R1FieldElement X3 = new SecP256R1FieldElement(t4);
+ SecP256R1Field.square(R, X3.x);
+ SecP256R1Field.subtract(X3.x, G, X3.x);
+
+ SecP256R1FieldElement Y3 = new SecP256R1FieldElement(G);
+ SecP256R1Field.subtract(V, X3.x, Y3.x);
+ SecP256R1Field.multiplyAddToExt(Y3.x, R, tt1);
+ SecP256R1Field.reduce(tt1, Y3.x);
+
+ SecP256R1FieldElement Z3 = new SecP256R1FieldElement(H);
+ if (!Z1IsOne)
+ {
+ SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+ if (!Z2IsOne)
+ {
+ SecP256R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ }
+
+ ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
+
+ return new SecP256R1Point(curve, X3, Y3, zs);
+ }
+
+ public ECPoint twice()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP256R1FieldElement Y1 = (SecP256R1FieldElement)this.y;
+ if (Y1.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ SecP256R1FieldElement X1 = (SecP256R1FieldElement)this.x, Z1 = (SecP256R1FieldElement)this.zs[0];
+
+ int c;
+ int[] t1 = Nat256.create();
+ int[] t2 = Nat256.create();
+
+ int[] Y1Squared = Nat256.create();
+ SecP256R1Field.square(Y1.x, Y1Squared);
+
+ int[] T = Nat256.create();
+ SecP256R1Field.square(Y1Squared, T);
+
+ boolean Z1IsOne = Z1.isOne();
+
+ int[] Z1Squared = Z1.x;
+ if (!Z1IsOne)
+ {
+ Z1Squared = t2;
+ SecP256R1Field.square(Z1.x, Z1Squared);
+ }
+
+ SecP256R1Field.subtract(X1.x, Z1Squared, t1);
+
+ int[] M = t2;
+ SecP256R1Field.add(X1.x, Z1Squared, M);
+ SecP256R1Field.multiply(M, t1, M);
+ c = Nat256.addBothTo(M, M, M);
+ SecP256R1Field.reduce32(c, M);
+
+ int[] S = Y1Squared;
+ SecP256R1Field.multiply(Y1Squared, X1.x, S);
+ c = Nat.shiftUpBits(8, S, 2, 0);
+ SecP256R1Field.reduce32(c, S);
+
+ c = Nat.shiftUpBits(8, T, 3, 0, t1);
+ SecP256R1Field.reduce32(c, t1);
+
+ SecP256R1FieldElement X3 = new SecP256R1FieldElement(T);
+ SecP256R1Field.square(M, X3.x);
+ SecP256R1Field.subtract(X3.x, S, X3.x);
+ SecP256R1Field.subtract(X3.x, S, X3.x);
+
+ SecP256R1FieldElement Y3 = new SecP256R1FieldElement(S);
+ SecP256R1Field.subtract(S, X3.x, Y3.x);
+ SecP256R1Field.multiply(Y3.x, M, Y3.x);
+ SecP256R1Field.subtract(Y3.x, t1, Y3.x);
+
+ SecP256R1FieldElement Z3 = new SecP256R1FieldElement(M);
+ SecP256R1Field.twice(Y1.x, Z3.x);
+ if (!Z1IsOne)
+ {
+ SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+
+ return new SecP256R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
+ }
+
+ public ECPoint twicePlus(ECPoint b)
+ {
+ if (this == b)
+ {
+ return threeTimes();
+ }
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return twice();
+ }
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return b;
+ }
+
+ return twice().add(b);
+ }
+
+ public ECPoint threeTimes()
+ {
+ if (this.isInfinity() || this.y.isZero())
+ {
+ return this;
+ }
+
+ // NOTE: Be careful about recursions between twicePlus and threeTimes
+ return twice().add(this);
+ }
+
+ public ECPoint negate()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ return new SecP256R1Point(curve, this.x, this.y.negate(), this.zs);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java
new file mode 100644
index 00000000..a652b010
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java
@@ -0,0 +1,167 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.ec.AbstractECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP384R1Curve extends ECCurve.AbstractFp
+{
+ public static final BigInteger q = SecP384R1FieldElement.Q;
+
+ private static final int SECP384R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP384R1_AFFINE_ZS = new ECFieldElement[] { new SecP384R1FieldElement(ECConstants.ONE) };
+
+ protected SecP384R1Point infinity;
+
+ public SecP384R1Curve()
+ {
+ super(q);
+
+ this.infinity = new SecP384R1Point(this, null, null);
+
+ this.a = fromBigInteger(new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")));
+ this.b = fromBigInteger(new BigInteger(1,
+ Hex.decodeStrict("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")));
+ this.order = new BigInteger(1, Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"));
+ this.cofactor = BigInteger.valueOf(1);
+
+ this.coord = SECP384R1_DEFAULT_COORDS;
+ }
+
+ protected ECCurve cloneCurve()
+ {
+ return new SecP384R1Curve();
+ }
+
+ public boolean supportsCoordinateSystem(int coord)
+ {
+ switch (coord)
+ {
+ case COORD_JACOBIAN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public int getFieldSize()
+ {
+ return q.bitLength();
+ }
+
+ public ECFieldElement fromBigInteger(BigInteger x)
+ {
+ return new SecP384R1FieldElement(x);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
+ {
+ return new SecP384R1Point(this, x, y);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ return new SecP384R1Point(this, x, y, zs);
+ }
+
+ public ECPoint getInfinity()
+ {
+ return infinity;
+ }
+
+ public ECLookupTable createCacheSafeLookupTable(ECPoint[] points, int off, final int len)
+ {
+ final int FE_INTS = 12;
+
+ final int[] table = new int[len * FE_INTS * 2];
+ {
+ int pos = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ ECPoint p = points[off + i];
+ Nat.copy(FE_INTS, ((SecP384R1FieldElement)p.getRawXCoord()).x, 0, table, pos); pos += FE_INTS;
+ Nat.copy(FE_INTS, ((SecP384R1FieldElement)p.getRawYCoord()).x, 0, table, pos); pos += FE_INTS;
+ }
+ }
+
+ return new AbstractECLookupTable()
+ {
+ public int getSize()
+ {
+ return len;
+ }
+
+ public ECPoint lookup(int index)
+ {
+ int[] x = Nat.create(FE_INTS), y = Nat.create(FE_INTS);
+ int pos = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ int MASK = ((i ^ index) - 1) >> 31;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] ^= table[pos + j] & MASK;
+ y[j] ^= table[pos + FE_INTS + j] & MASK;
+ }
+
+ pos += (FE_INTS * 2);
+ }
+
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat.create(FE_INTS), y = Nat.create(FE_INTS);
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] = table[pos + j];
+ y[j] = table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP384R1FieldElement(x), new SecP384R1FieldElement(y), SECP384R1_AFFINE_ZS);
+ }
+ };
+ }
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat.create(12);
+ SecP384R1Field.random(r, x);
+ return new SecP384R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat.create(12);
+ SecP384R1Field.randomMult(r, x);
+ return new SecP384R1FieldElement(x);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
new file mode 100644
index 00000000..c95f7599
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
@@ -0,0 +1,339 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.raw.Mod;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat384;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP384R1Field
+{
+ private static final long M = 0xFFFFFFFFL;
+
+ // 2^384 - 2^128 - 2^96 + 2^32 - 1
+ static final int[] P = new int[]{ 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExt = new int[]{ 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE,
+ 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x00000001, 0x00000000,
+ 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF,
+ 0x00000001, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0xFFFFFFFE,
+ 0xFFFFFFFF, 0x00000001, 0x00000002 };
+ private static final int P11 = 0xFFFFFFFF;
+ private static final int PExt23 = 0xFFFFFFFF;
+
+ public static void add(int[] x, int[] y, int[] z)
+ {
+ int c = Nat.add(12, x, y, z);
+ if (c != 0 || (z[11] == P11 && Nat.gte(12, z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ public static void addExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.add(24, xx, yy, zz);
+ if (c != 0 || (zz[23] == PExt23 && Nat.gte(24, zz, PExt)))
+ {
+ if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.incAt(24, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void addOne(int[] x, int[] z)
+ {
+ int c = Nat.inc(12, x, z);
+ if (c != 0 || (z[11] == P11 && Nat.gte(12, z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ int[] z = Nat.fromBigInteger(384, x);
+ if (z[11] == P11 && Nat.gte(12, z, P))
+ {
+ Nat.subFrom(12, P, z);
+ }
+ return z;
+ }
+
+ public static void half(int[] x, int[] z)
+ {
+ if ((x[0] & 1) == 0)
+ {
+ Nat.shiftDownBit(12, x, 0, z);
+ }
+ else
+ {
+ int c = Nat.add(12, x, P, z);
+ Nat.shiftDownBit(12, z, c);
+ }
+ }
+
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 12; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static void multiply(int[] x, int[] y, int[] z)
+ {
+ int[] tt = Nat.create(24);
+ Nat384.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
+ public static void negate(int[] x, int[] z)
+ {
+ if (0 != isZero(x))
+ {
+ Nat.sub(12, P, P, z);
+ }
+ else
+ {
+ Nat.sub(12, P, x, z);
+ }
+ }
+
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[12 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 12);
+ }
+ while (0 == Nat.lessThan(12, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
+ public static void reduce(int[] xx, int[] z)
+ {
+ long xx16 = xx[16] & M, xx17 = xx[17] & M, xx18 = xx[18] & M, xx19 = xx[19] & M;
+ long xx20 = xx[20] & M, xx21 = xx[21] & M, xx22 = xx[22] & M, xx23 = xx[23] & M;
+
+ final long n = 1;
+
+ long t0 = (xx[12] & M) + xx20 - n;
+ long t1 = (xx[13] & M) + xx22;
+ long t2 = (xx[14] & M) + xx22 + xx23;
+ long t3 = (xx[15] & M) + xx23;
+ long t4 = xx17 + xx21;
+ long t5 = xx21 - xx23;
+ long t6 = xx22 - xx23;
+ long t7 = t0 + t5;
+
+ long cc = 0;
+ cc += (xx[0] & M) + t7;
+ z[0] = (int)cc;
+ cc >>= 32;
+ cc += (xx[1] & M) + xx23 - t0 + t1;
+ z[1] = (int)cc;
+ cc >>= 32;
+ cc += (xx[2] & M) - xx21 - t1 + t2;
+ z[2] = (int)cc;
+ cc >>= 32;
+ cc += (xx[3] & M) - t2 + t3 + t7;
+ z[3] = (int)cc;
+ cc >>= 32;
+ cc += (xx[4] & M) + xx16 + xx21 + t1 - t3 + t7;
+ z[4] = (int)cc;
+ cc >>= 32;
+ cc += (xx[5] & M) - xx16 + t1 + t2 + t4;
+ z[5] = (int)cc;
+ cc >>= 32;
+ cc += (xx[6] & M) + xx18 - xx17 + t2 + t3;
+ z[6] = (int)cc;
+ cc >>= 32;
+ cc += (xx[7] & M) + xx16 + xx19 - xx18 + t3;
+ z[7] = (int)cc;
+ cc >>= 32;
+ cc += (xx[8] & M) + xx16 + xx17 + xx20 - xx19;
+ z[8] = (int)cc;
+ cc >>= 32;
+ cc += (xx[9] & M) + xx18 - xx20 + t4;
+ z[9] = (int)cc;
+ cc >>= 32;
+ cc += (xx[10] & M) + xx18 + xx19 - t5 + t6;
+ z[10] = (int)cc;
+ cc >>= 32;
+ cc += (xx[11] & M) + xx19 + xx20 - t6;
+ z[11] = (int)cc;
+ cc >>= 32;
+ cc += n;
+
+// assert cc >= 0;
+
+ reduce32((int)cc, z);
+ }
+
+ public static void reduce32(int x, int[] z)
+ {
+ long cc = 0;
+
+ if (x != 0)
+ {
+ long xx12 = x & M;
+
+ cc += (z[0] & M) + xx12;
+ z[0] = (int)cc;
+ cc >>= 32;
+ cc += (z[1] & M) - xx12;
+ z[1] = (int)cc;
+ cc >>= 32;
+ if (cc != 0)
+ {
+ cc += (z[2] & M);
+ z[2] = (int)cc;
+ cc >>= 32;
+ }
+ cc += (z[3] & M) + xx12;
+ z[3] = (int)cc;
+ cc >>= 32;
+ cc += (z[4] & M) + xx12;
+ z[4] = (int)cc;
+ cc >>= 32;
+
+// assert cc == 0 || cc == 1;
+ }
+
+ if ((cc != 0 && Nat.incAt(12, z, 5) != 0)
+ || (z[11] == P11 && Nat.gte(12, z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ public static void square(int[] x, int[] z)
+ {
+ int[] tt = Nat.create(24);
+ Nat384.square(x, tt);
+ reduce(tt, z);
+ }
+
+ public static void squareN(int[] x, int n, int[] z)
+ {
+// assert n > 0;
+
+ int[] tt = Nat.create(24);
+ Nat384.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat384.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
+ public static void subtract(int[] x, int[] y, int[] z)
+ {
+ int c = Nat.sub(12, x, y, z);
+ if (c != 0)
+ {
+ subPInvFrom(z);
+ }
+ }
+
+ public static void subtractExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.sub(24, xx, yy, zz);
+ if (c != 0)
+ {
+ if (Nat.subFrom(PExtInv.length, PExtInv, zz) != 0)
+ {
+ Nat.decAt(24, zz, PExtInv.length);
+ }
+ }
+ }
+
+ public static void twice(int[] x, int[] z)
+ {
+ int c = Nat.shiftUpBit(12, x, 0, z);
+ if (c != 0 || (z[11] == P11 && Nat.gte(12, z, P)))
+ {
+ addPInvTo(z);
+ }
+ }
+
+ private static void addPInvTo(int[] z)
+ {
+ long c = (z[0] & M) + 1;
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M) - 1;
+ z[1] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ c += (z[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ }
+ c += (z[3] & M) + 1;
+ z[3] = (int)c;
+ c >>= 32;
+ c += (z[4] & M) + 1;
+ z[4] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ Nat.incAt(12, z, 5);
+ }
+ }
+
+ private static void subPInvFrom(int[] z)
+ {
+ long c = (z[0] & M) - 1;
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M) + 1;
+ z[1] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ c += (z[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ }
+ c += (z[3] & M) - 1;
+ z[3] = (int)c;
+ c >>= 32;
+ c += (z[4] & M) - 1;
+ z[4] = (int)c;
+ c >>= 32;
+ if (c != 0)
+ {
+ Nat.decAt(12, z, 5);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
new file mode 100644
index 00000000..a2791d47
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
@@ -0,0 +1,216 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP384R1FieldElement extends ECFieldElement.AbstractFp
+{
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"));
+
+ protected int[] x;
+
+ public SecP384R1FieldElement(BigInteger x)
+ {
+ if (x == null || x.signum() < 0 || x.compareTo(Q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid for SecP384R1FieldElement");
+ }
+
+ this.x = SecP384R1Field.fromBigInteger(x);
+ }
+
+ public SecP384R1FieldElement()
+ {
+ this.x = Nat.create(12);
+ }
+
+ protected SecP384R1FieldElement(int[] x)
+ {
+ this.x = x;
+ }
+
+ public boolean isZero()
+ {
+ return Nat.isZero(12, x);
+ }
+
+ public boolean isOne()
+ {
+ return Nat.isOne(12, x);
+ }
+
+ public boolean testBitZero()
+ {
+ return Nat.getBit(x, 0) == 1;
+ }
+
+ public BigInteger toBigInteger()
+ {
+ return Nat.toBigInteger(12, x);
+ }
+
+ public String getFieldName()
+ {
+ return "SecP384R1Field";
+ }
+
+ public int getFieldSize()
+ {
+ return Q.bitLength();
+ }
+
+ public ECFieldElement add(ECFieldElement b)
+ {
+ int[] z = Nat.create(12);
+ SecP384R1Field.add(x, ((SecP384R1FieldElement)b).x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ public ECFieldElement addOne()
+ {
+ int[] z = Nat.create(12);
+ SecP384R1Field.addOne(x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ public ECFieldElement subtract(ECFieldElement b)
+ {
+ int[] z = Nat.create(12);
+ SecP384R1Field.subtract(x, ((SecP384R1FieldElement)b).x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ public ECFieldElement multiply(ECFieldElement b)
+ {
+ int[] z = Nat.create(12);
+ SecP384R1Field.multiply(x, ((SecP384R1FieldElement)b).x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ public ECFieldElement divide(ECFieldElement b)
+ {
+// return multiply(b.invert());
+ int[] z = Nat.create(12);
+ SecP384R1Field.inv(((SecP384R1FieldElement)b).x, z);
+ SecP384R1Field.multiply(z, x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ public ECFieldElement negate()
+ {
+ int[] z = Nat.create(12);
+ SecP384R1Field.negate(x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ public ECFieldElement square()
+ {
+ int[] z = Nat.create(12);
+ SecP384R1Field.square(x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ public ECFieldElement invert()
+ {
+// return new SecP384R1FieldElement(toBigInteger().modInverse(Q));
+ int[] z = Nat.create(12);
+ SecP384R1Field.inv(x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ /**
+ * return a sqrt root - the routine verifies that the calculation returns the right value - if
+ * none exists it returns null.
+ */
+ public ECFieldElement sqrt()
+ {
+ // Raise this element to the exponent 2^382 - 2^126 - 2^94 + 2^30
+
+ int[] x1 = this.x;
+ if (Nat.isZero(12, x1) || Nat.isOne(12, x1))
+ {
+ return this;
+ }
+
+ int[] t1 = Nat.create(12);
+ int[] t2 = Nat.create(12);
+ int[] t3 = Nat.create(12);
+ int[] t4 = Nat.create(12);
+
+ SecP384R1Field.square(x1, t1);
+ SecP384R1Field.multiply(t1, x1, t1);
+
+ SecP384R1Field.squareN(t1, 2, t2);
+ SecP384R1Field.multiply(t2, t1, t2);
+
+ SecP384R1Field.square(t2, t2);
+ SecP384R1Field.multiply(t2, x1, t2);
+
+ SecP384R1Field.squareN(t2, 5, t3);
+ SecP384R1Field.multiply(t3, t2, t3);
+
+ SecP384R1Field.squareN(t3, 5, t4);
+ SecP384R1Field.multiply(t4, t2, t4);
+
+ SecP384R1Field.squareN(t4, 15, t2);
+ SecP384R1Field.multiply(t2, t4, t2);
+
+ SecP384R1Field.squareN(t2, 2, t3);
+ SecP384R1Field.multiply(t1, t3, t1);
+
+ SecP384R1Field.squareN(t3, 28, t3);
+ SecP384R1Field.multiply(t2, t3, t2);
+
+ SecP384R1Field.squareN(t2, 60, t3);
+ SecP384R1Field.multiply(t3, t2, t3);
+
+ int[] r = t2;
+
+ SecP384R1Field.squareN(t3, 120, r);
+ SecP384R1Field.multiply(r, t3, r);
+
+ SecP384R1Field.squareN(r, 15, r);
+ SecP384R1Field.multiply(r, t4, r);
+
+ SecP384R1Field.squareN(r, 33, r);
+ SecP384R1Field.multiply(r, t1, r);
+
+ SecP384R1Field.squareN(r, 64, r);
+ SecP384R1Field.multiply(r, x1, r);
+
+ SecP384R1Field.squareN(r, 30, t1);
+ SecP384R1Field.square(t1, t2);
+
+ return Nat.eq(12, x1, t2) ? new SecP384R1FieldElement(t1) : null;
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof SecP384R1FieldElement))
+ {
+ return false;
+ }
+
+ SecP384R1FieldElement o = (SecP384R1FieldElement)other;
+ return Nat.eq(12, x, o.x);
+ }
+
+ public int hashCode()
+ {
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 12);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
new file mode 100644
index 00000000..27b6aa51
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
@@ -0,0 +1,272 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat384;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP384R1Point extends ECPoint.AbstractFp
+{
+ SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ super(curve, x, y);
+ }
+
+ SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ super(curve, x, y, zs);
+ }
+
+ protected ECPoint detach()
+ {
+ return new SecP384R1Point(null, getAffineXCoord(), getAffineYCoord());
+ }
+
+ public ECPoint add(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return this;
+ }
+ if (this == b)
+ {
+ return twice();
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP384R1FieldElement X1 = (SecP384R1FieldElement)this.x, Y1 = (SecP384R1FieldElement)this.y;
+ SecP384R1FieldElement X2 = (SecP384R1FieldElement)b.getXCoord(), Y2 = (SecP384R1FieldElement)b.getYCoord();
+
+ SecP384R1FieldElement Z1 = (SecP384R1FieldElement)this.zs[0];
+ SecP384R1FieldElement Z2 = (SecP384R1FieldElement)b.getZCoord(0);
+
+ int c;
+ int[] tt1 = Nat.create(24);
+ int[] tt2 = Nat.create(24);
+ int[] t3 = Nat.create(12);
+ int[] t4 = Nat.create(12);
+
+ boolean Z1IsOne = Z1.isOne();
+ int[] U2, S2;
+ if (Z1IsOne)
+ {
+ U2 = X2.x;
+ S2 = Y2.x;
+ }
+ else
+ {
+ S2 = t3;
+ SecP384R1Field.square(Z1.x, S2);
+
+ U2 = tt2;
+ SecP384R1Field.multiply(S2, X2.x, U2);
+
+ SecP384R1Field.multiply(S2, Z1.x, S2);
+ SecP384R1Field.multiply(S2, Y2.x, S2);
+ }
+
+ boolean Z2IsOne = Z2.isOne();
+ int[] U1, S1;
+ if (Z2IsOne)
+ {
+ U1 = X1.x;
+ S1 = Y1.x;
+ }
+ else
+ {
+ S1 = t4;
+ SecP384R1Field.square(Z2.x, S1);
+
+ U1 = tt1;
+ SecP384R1Field.multiply(S1, X1.x, U1);
+
+ SecP384R1Field.multiply(S1, Z2.x, S1);
+ SecP384R1Field.multiply(S1, Y1.x, S1);
+ }
+
+ int[] H = Nat.create(12);
+ SecP384R1Field.subtract(U1, U2, H);
+
+ int[] R = Nat.create(12);
+ SecP384R1Field.subtract(S1, S2, R);
+
+ // Check if b == this or b == -this
+ if (Nat.isZero(12, H))
+ {
+ if (Nat.isZero(12, R))
+ {
+ // this == b, i.e. this must be doubled
+ return this.twice();
+ }
+
+ // this == -b, i.e. the result is the point at infinity
+ return curve.getInfinity();
+ }
+
+ int[] HSquared = t3;
+ SecP384R1Field.square(H, HSquared);
+
+ int[] G = Nat.create(12);
+ SecP384R1Field.multiply(HSquared, H, G);
+
+ int[] V = t3;
+ SecP384R1Field.multiply(HSquared, U1, V);
+
+ SecP384R1Field.negate(G, G);
+ Nat384.mul(S1, G, tt1);
+
+ c = Nat.addBothTo(12, V, V, G);
+ SecP384R1Field.reduce32(c, G);
+
+ SecP384R1FieldElement X3 = new SecP384R1FieldElement(t4);
+ SecP384R1Field.square(R, X3.x);
+ SecP384R1Field.subtract(X3.x, G, X3.x);
+
+ SecP384R1FieldElement Y3 = new SecP384R1FieldElement(G);
+ SecP384R1Field.subtract(V, X3.x, Y3.x);
+ Nat384.mul(Y3.x, R, tt2);
+ SecP384R1Field.addExt(tt1, tt2, tt1);
+ SecP384R1Field.reduce(tt1, Y3.x);
+
+ SecP384R1FieldElement Z3 = new SecP384R1FieldElement(H);
+ if (!Z1IsOne)
+ {
+ SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+ if (!Z2IsOne)
+ {
+ SecP384R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ }
+
+ ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
+
+ return new SecP384R1Point(curve, X3, Y3, zs);
+ }
+
+ public ECPoint twice()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP384R1FieldElement Y1 = (SecP384R1FieldElement)this.y;
+ if (Y1.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ SecP384R1FieldElement X1 = (SecP384R1FieldElement)this.x, Z1 = (SecP384R1FieldElement)this.zs[0];
+
+ int c;
+ int[] t1 = Nat.create(12);
+ int[] t2 = Nat.create(12);
+
+ int[] Y1Squared = Nat.create(12);
+ SecP384R1Field.square(Y1.x, Y1Squared);
+
+ int[] T = Nat.create(12);
+ SecP384R1Field.square(Y1Squared, T);
+
+ boolean Z1IsOne = Z1.isOne();
+
+ int[] Z1Squared = Z1.x;
+ if (!Z1IsOne)
+ {
+ Z1Squared = t2;
+ SecP384R1Field.square(Z1.x, Z1Squared);
+ }
+
+ SecP384R1Field.subtract(X1.x, Z1Squared, t1);
+
+ int[] M = t2;
+ SecP384R1Field.add(X1.x, Z1Squared, M);
+ SecP384R1Field.multiply(M, t1, M);
+ c = Nat.addBothTo(12, M, M, M);
+ SecP384R1Field.reduce32(c, M);
+
+ int[] S = Y1Squared;
+ SecP384R1Field.multiply(Y1Squared, X1.x, S);
+ c = Nat.shiftUpBits(12, S, 2, 0);
+ SecP384R1Field.reduce32(c, S);
+
+ c = Nat.shiftUpBits(12, T, 3, 0, t1);
+ SecP384R1Field.reduce32(c, t1);
+
+ SecP384R1FieldElement X3 = new SecP384R1FieldElement(T);
+ SecP384R1Field.square(M, X3.x);
+ SecP384R1Field.subtract(X3.x, S, X3.x);
+ SecP384R1Field.subtract(X3.x, S, X3.x);
+
+ SecP384R1FieldElement Y3 = new SecP384R1FieldElement(S);
+ SecP384R1Field.subtract(S, X3.x, Y3.x);
+ SecP384R1Field.multiply(Y3.x, M, Y3.x);
+ SecP384R1Field.subtract(Y3.x, t1, Y3.x);
+
+ SecP384R1FieldElement Z3 = new SecP384R1FieldElement(M);
+ SecP384R1Field.twice(Y1.x, Z3.x);
+ if (!Z1IsOne)
+ {
+ SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+
+ return new SecP384R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
+ }
+
+ public ECPoint twicePlus(ECPoint b)
+ {
+ if (this == b)
+ {
+ return threeTimes();
+ }
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return twice();
+ }
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return b;
+ }
+
+ return twice().add(b);
+ }
+
+ public ECPoint threeTimes()
+ {
+ if (this.isInfinity() || this.y.isZero())
+ {
+ return this;
+ }
+
+ // NOTE: Be careful about recursions between twicePlus and threeTimes
+ return twice().add(this);
+ }
+
+ public ECPoint negate()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ return new SecP384R1Point(curve, this.x, this.y.negate(), this.zs);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java
new file mode 100644
index 00000000..2a004079
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java
@@ -0,0 +1,167 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.ec.AbstractECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECLookupTable;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP521R1Curve extends ECCurve.AbstractFp
+{
+ public static final BigInteger q = SecP521R1FieldElement.Q;
+
+ private static final int SECP521R1_DEFAULT_COORDS = COORD_JACOBIAN;
+ private static final ECFieldElement[] SECP521R1_AFFINE_ZS = new ECFieldElement[] { new SecP521R1FieldElement(ECConstants.ONE) };
+
+ protected SecP521R1Point infinity;
+
+ public SecP521R1Curve()
+ {
+ super(q);
+
+ this.infinity = new SecP521R1Point(this, null, null);
+
+ this.a = fromBigInteger(new BigInteger(1,
+ Hex.decodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC")));
+ this.b = fromBigInteger(new BigInteger(1,
+ Hex.decodeStrict("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00")));
+ this.order = new BigInteger(1, Hex.decodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"));
+ this.cofactor = BigInteger.valueOf(1);
+
+ this.coord = SECP521R1_DEFAULT_COORDS;
+ }
+
+ protected ECCurve cloneCurve()
+ {
+ return new SecP521R1Curve();
+ }
+
+ public boolean supportsCoordinateSystem(int coord)
+ {
+ switch (coord)
+ {
+ case COORD_JACOBIAN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public int getFieldSize()
+ {
+ return q.bitLength();
+ }
+
+ public ECFieldElement fromBigInteger(BigInteger x)
+ {
+ return new SecP521R1FieldElement(x);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y)
+ {
+ return new SecP521R1Point(this, x, y);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ return new SecP521R1Point(this, x, y, zs);
+ }
+
+ public ECPoint getInfinity()
+ {
+ return infinity;
+ }
+
+ public ECLookupTable createCacheSafeLookupTable(ECPoint[] points, int off, final int len)
+ {
+ final int FE_INTS = 17;
+
+ final int[] table = new int[len * FE_INTS * 2];
+ {
+ int pos = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ ECPoint p = points[off + i];
+ Nat.copy(FE_INTS, ((SecP521R1FieldElement)p.getRawXCoord()).x, 0, table, pos); pos += FE_INTS;
+ Nat.copy(FE_INTS, ((SecP521R1FieldElement)p.getRawYCoord()).x, 0, table, pos); pos += FE_INTS;
+ }
+ }
+
+ return new AbstractECLookupTable()
+ {
+ public int getSize()
+ {
+ return len;
+ }
+
+ public ECPoint lookup(int index)
+ {
+ int[] x = Nat.create(FE_INTS), y = Nat.create(FE_INTS);
+ int pos = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ int MASK = ((i ^ index) - 1) >> 31;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] ^= table[pos + j] & MASK;
+ y[j] ^= table[pos + FE_INTS + j] & MASK;
+ }
+
+ pos += (FE_INTS * 2);
+ }
+
+ return createPoint(x, y);
+ }
+
+ public ECPoint lookupVar(int index)
+ {
+ int[] x = Nat.create(FE_INTS), y = Nat.create(FE_INTS);
+ int pos = index * FE_INTS * 2;
+
+ for (int j = 0; j < FE_INTS; ++j)
+ {
+ x[j] ^= table[pos + j];
+ y[j] ^= table[pos + FE_INTS + j];
+ }
+
+ return createPoint(x, y);
+ }
+
+ private ECPoint createPoint(int[] x, int[] y)
+ {
+ return createRawPoint(new SecP521R1FieldElement(x), new SecP521R1FieldElement(y), SECP521R1_AFFINE_ZS);
+ }
+ };
+ }
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int[] x = Nat.create(17);
+ SecP521R1Field.random(r, x);
+ return new SecP521R1FieldElement(x);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ int[] x = Nat.create(17);
+ SecP521R1Field.randomMult(r, x);
+ return new SecP521R1FieldElement(x);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
new file mode 100644
index 00000000..d4780f3d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
@@ -0,0 +1,200 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.raw.Mod;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.math.raw.Nat512;
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP521R1Field
+{
+ // 2^521 - 1
+ static final int[] P = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x1FF };
+ private static final int P16 = 0x1FF;
+
+ public static void add(int[] x, int[] y, int[] z)
+ {
+ int c = Nat.add(16, x, y, z) + x[16] + y[16];
+ if (c > P16 || (c == P16 && Nat.eq(16, z, P)))
+ {
+ c += Nat.inc(16, z);
+ c &= P16;
+ }
+ z[16] = c;
+ }
+
+ public static void addOne(int[] x, int[] z)
+ {
+ int c = Nat.inc(16, x, z) + x[16];
+ if (c > P16 || (c == P16 && Nat.eq(16, z, P)))
+ {
+ c += Nat.inc(16, z);
+ c &= P16;
+ }
+ z[16] = c;
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ int[] z = Nat.fromBigInteger(521, x);
+ if (Nat.eq(17, z, P))
+ {
+ Nat.zero(17, z);
+ }
+ return z;
+ }
+
+ public static void half(int[] x, int[] z)
+ {
+ int x16 = x[16];
+ int c = Nat.shiftDownBit(16, x, x16, z);
+ z[16] = (x16 >>> 1) | (c >>> 23);
+ }
+
+ public static void inv(int[] x, int[] z)
+ {
+ Mod.checkedModOddInverse(P, x, z);
+ }
+
+ public static int isZero(int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < 17; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static void multiply(int[] x, int[] y, int[] z)
+ {
+ int[] tt = Nat.create(33);
+ implMultiply(x, y, tt);
+ reduce(tt, z);
+ }
+
+ public static void negate(int[] x, int[] z)
+ {
+ if (0 != isZero(x))
+ {
+ Nat.sub(17, P, P, z);
+ }
+ else
+ {
+ Nat.sub(17, P, x, z);
+ }
+ }
+
+ public static void random(SecureRandom r, int[] z)
+ {
+ byte[] bb = new byte[17 * 4];
+ do
+ {
+ r.nextBytes(bb);
+ Pack.littleEndianToInt(bb, 0, z, 0, 17);
+ z[16] &= P16;
+ }
+ while (0 == Nat.lessThan(17, z, P));
+ }
+
+ public static void randomMult(SecureRandom r, int[] z)
+ {
+ do
+ {
+ random(r, z);
+ }
+ while (0 != isZero(z));
+ }
+
+ public static void reduce(int[] xx, int[] z)
+ {
+// assert xx[32] >>> 18 == 0;
+
+ int xx32 = xx[32];
+ int c = Nat.shiftDownBits(16, xx, 16, 9, xx32, z, 0) >>> 23;
+ c += xx32 >>> 9;
+ c += Nat.addTo(16, xx, z);
+ if (c > P16 || (c == P16 && Nat.eq(16, z, P)))
+ {
+ c += Nat.inc(16, z);
+ c &= P16;
+ }
+ z[16] = c;
+ }
+
+ public static void reduce23(int[] z)
+ {
+ int z16 = z[16];
+ int c = Nat.addWordTo(16, z16 >>> 9, z) + (z16 & P16);
+ if (c > P16 || (c == P16 && Nat.eq(16, z, P)))
+ {
+ c += Nat.inc(16, z);
+ c &= P16;
+ }
+ z[16] = c;
+ }
+
+ public static void square(int[] x, int[] z)
+ {
+ int[] tt = Nat.create(33);
+ implSquare(x, tt);
+ reduce(tt, z);
+ }
+
+ public static void squareN(int[] x, int n, int[] z)
+ {
+// assert n > 0;
+
+ int[] tt = Nat.create(33);
+ implSquare(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ implSquare(z, tt);
+ reduce(tt, z);
+ }
+ }
+
+ public static void subtract(int[] x, int[] y, int[] z)
+ {
+ int c = Nat.sub(16, x, y, z) + x[16] - y[16];
+ if (c < 0)
+ {
+ c += Nat.dec(16, z);
+ c &= P16;
+ }
+ z[16] = c;
+ }
+
+ public static void twice(int[] x, int[] z)
+ {
+ int x16 = x[16];
+ int c = Nat.shiftUpBit(16, x, x16 << 23, z) | (x16 << 1);
+ z[16] = c & P16;
+ }
+
+ protected static void implMultiply(int[] x, int[] y, int[] zz)
+ {
+ Nat512.mul(x, y, zz);
+
+ int x16 = x[16], y16 = y[16];
+ zz[32] = Nat.mul31BothAdd(16, x16, y, y16, x, zz, 16) + (x16 * y16);
+ }
+
+ protected static void implSquare(int[] x, int[] zz)
+ {
+ Nat512.square(x, zz);
+
+ int x16 = x[16];
+ zz[32] = Nat.mulWordAddTo(16, x16 << 1, x, 0, zz, 16) + (x16 * x16);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
new file mode 100644
index 00000000..4e524721
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
@@ -0,0 +1,174 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.encoders.Hex;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP521R1FieldElement extends ECFieldElement.AbstractFp
+{
+ public static final BigInteger Q = new BigInteger(1,
+ Hex.decodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
+
+ protected int[] x;
+
+ public SecP521R1FieldElement(BigInteger x)
+ {
+ if (x == null || x.signum() < 0 || x.compareTo(Q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid for SecP521R1FieldElement");
+ }
+
+ this.x = SecP521R1Field.fromBigInteger(x);
+ }
+
+ public SecP521R1FieldElement()
+ {
+ this.x = Nat.create(17);
+ }
+
+ protected SecP521R1FieldElement(int[] x)
+ {
+ this.x = x;
+ }
+
+ public boolean isZero()
+ {
+ return Nat.isZero(17, x);
+ }
+
+ public boolean isOne()
+ {
+ return Nat.isOne(17, x);
+ }
+
+ public boolean testBitZero()
+ {
+ return Nat.getBit(x, 0) == 1;
+ }
+
+ public BigInteger toBigInteger()
+ {
+ return Nat.toBigInteger(17, x);
+ }
+
+ public String getFieldName()
+ {
+ return "SecP521R1Field";
+ }
+
+ public int getFieldSize()
+ {
+ return Q.bitLength();
+ }
+
+ public ECFieldElement add(ECFieldElement b)
+ {
+ int[] z = Nat.create(17);
+ SecP521R1Field.add(x, ((SecP521R1FieldElement)b).x, z);
+ return new SecP521R1FieldElement(z);
+ }
+
+ public ECFieldElement addOne()
+ {
+ int[] z = Nat.create(17);
+ SecP521R1Field.addOne(x, z);
+ return new SecP521R1FieldElement(z);
+ }
+
+ public ECFieldElement subtract(ECFieldElement b)
+ {
+ int[] z = Nat.create(17);
+ SecP521R1Field.subtract(x, ((SecP521R1FieldElement)b).x, z);
+ return new SecP521R1FieldElement(z);
+ }
+
+ public ECFieldElement multiply(ECFieldElement b)
+ {
+ int[] z = Nat.create(17);
+ SecP521R1Field.multiply(x, ((SecP521R1FieldElement)b).x, z);
+ return new SecP521R1FieldElement(z);
+ }
+
+ public ECFieldElement divide(ECFieldElement b)
+ {
+// return multiply(b.invert());
+ int[] z = Nat.create(17);
+ SecP521R1Field.inv(((SecP521R1FieldElement)b).x, z);
+ SecP521R1Field.multiply(z, x, z);
+ return new SecP521R1FieldElement(z);
+ }
+
+ public ECFieldElement negate()
+ {
+ int[] z = Nat.create(17);
+ SecP521R1Field.negate(x, z);
+ return new SecP521R1FieldElement(z);
+ }
+
+ public ECFieldElement square()
+ {
+ int[] z = Nat.create(17);
+ SecP521R1Field.square(x, z);
+ return new SecP521R1FieldElement(z);
+ }
+
+ public ECFieldElement invert()
+ {
+// return new SecP521R1FieldElement(toBigInteger().modInverse(Q));
+ int[] z = Nat.create(17);
+ SecP521R1Field.inv(x, z);
+ return new SecP521R1FieldElement(z);
+ }
+
+ // D.1.4 91
+ /**
+ * return a sqrt root - the routine verifies that the calculation returns the right value - if
+ * none exists it returns null.
+ */
+ public ECFieldElement sqrt()
+ {
+ // Raise this element to the exponent 2^519
+
+ int[] x1 = this.x;
+ if (Nat.isZero(17, x1) || Nat.isOne(17, x1))
+ {
+ return this;
+ }
+
+ int[] t1 = Nat.create(17);
+ int[] t2 = Nat.create(17);
+
+ SecP521R1Field.squareN(x1, 519, t1);
+ SecP521R1Field.square(t1, t2);
+
+ return Nat.eq(17, x1, t2) ? new SecP521R1FieldElement(t1) : null;
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof SecP521R1FieldElement))
+ {
+ return false;
+ }
+
+ SecP521R1FieldElement o = (SecP521R1FieldElement)other;
+ return Nat.eq(17, x, o.x);
+ }
+
+ public int hashCode()
+ {
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 17);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
new file mode 100644
index 00000000..3bb4f698
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
@@ -0,0 +1,296 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.custom.sec;
+
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECFieldElement;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SecP521R1Point extends ECPoint.AbstractFp
+{
+ SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ super(curve, x, y);
+ }
+
+ SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs)
+ {
+ super(curve, x, y, zs);
+ }
+
+ protected ECPoint detach()
+ {
+ return new SecP521R1Point(null, getAffineXCoord(), getAffineYCoord());
+ }
+
+ public ECPoint add(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return this;
+ }
+ if (this == b)
+ {
+ return twice();
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP521R1FieldElement X1 = (SecP521R1FieldElement)this.x, Y1 = (SecP521R1FieldElement)this.y;
+ SecP521R1FieldElement X2 = (SecP521R1FieldElement)b.getXCoord(), Y2 = (SecP521R1FieldElement)b.getYCoord();
+
+ SecP521R1FieldElement Z1 = (SecP521R1FieldElement)this.zs[0];
+ SecP521R1FieldElement Z2 = (SecP521R1FieldElement)b.getZCoord(0);
+
+ int[] t1 = Nat.create(17);
+ int[] t2 = Nat.create(17);
+ int[] t3 = Nat.create(17);
+ int[] t4 = Nat.create(17);
+
+ boolean Z1IsOne = Z1.isOne();
+ int[] U2, S2;
+ if (Z1IsOne)
+ {
+ U2 = X2.x;
+ S2 = Y2.x;
+ }
+ else
+ {
+ S2 = t3;
+ SecP521R1Field.square(Z1.x, S2);
+
+ U2 = t2;
+ SecP521R1Field.multiply(S2, X2.x, U2);
+
+ SecP521R1Field.multiply(S2, Z1.x, S2);
+ SecP521R1Field.multiply(S2, Y2.x, S2);
+ }
+
+ boolean Z2IsOne = Z2.isOne();
+ int[] U1, S1;
+ if (Z2IsOne)
+ {
+ U1 = X1.x;
+ S1 = Y1.x;
+ }
+ else
+ {
+ S1 = t4;
+ SecP521R1Field.square(Z2.x, S1);
+
+ U1 = t1;
+ SecP521R1Field.multiply(S1, X1.x, U1);
+
+ SecP521R1Field.multiply(S1, Z2.x, S1);
+ SecP521R1Field.multiply(S1, Y1.x, S1);
+ }
+
+ int[] H = Nat.create(17);
+ SecP521R1Field.subtract(U1, U2, H);
+
+ int[] R = t2;
+ SecP521R1Field.subtract(S1, S2, R);
+
+ // Check if b == this or b == -this
+ if (Nat.isZero(17, H))
+ {
+ if (Nat.isZero(17, R))
+ {
+ // this == b, i.e. this must be doubled
+ return this.twice();
+ }
+
+ // this == -b, i.e. the result is the point at infinity
+ return curve.getInfinity();
+ }
+
+ int[] HSquared = t3;
+ SecP521R1Field.square(H, HSquared);
+
+ int[] G = Nat.create(17);
+ SecP521R1Field.multiply(HSquared, H, G);
+
+ int[] V = t3;
+ SecP521R1Field.multiply(HSquared, U1, V);
+
+ SecP521R1Field.multiply(S1, G, t1);
+
+ SecP521R1FieldElement X3 = new SecP521R1FieldElement(t4);
+ SecP521R1Field.square(R, X3.x);
+ SecP521R1Field.add(X3.x, G, X3.x);
+ SecP521R1Field.subtract(X3.x, V, X3.x);
+ SecP521R1Field.subtract(X3.x, V, X3.x);
+
+ SecP521R1FieldElement Y3 = new SecP521R1FieldElement(G);
+ SecP521R1Field.subtract(V, X3.x, Y3.x);
+ SecP521R1Field.multiply(Y3.x, R, t2);
+ SecP521R1Field.subtract(t2, t1, Y3.x);
+
+ SecP521R1FieldElement Z3 = new SecP521R1FieldElement(H);
+ if (!Z1IsOne)
+ {
+ SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+ if (!Z2IsOne)
+ {
+ SecP521R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ }
+
+ ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
+
+ return new SecP521R1Point(curve, X3, Y3, zs);
+ }
+
+ public ECPoint twice()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP521R1FieldElement Y1 = (SecP521R1FieldElement)this.y;
+ if (Y1.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ SecP521R1FieldElement X1 = (SecP521R1FieldElement)this.x, Z1 = (SecP521R1FieldElement)this.zs[0];
+
+ int[] t1 = Nat.create(17);
+ int[] t2 = Nat.create(17);
+
+ int[] Y1Squared = Nat.create(17);
+ SecP521R1Field.square(Y1.x, Y1Squared);
+
+ int[] T = Nat.create(17);
+ SecP521R1Field.square(Y1Squared, T);
+
+ boolean Z1IsOne = Z1.isOne();
+
+ int[] Z1Squared = Z1.x;
+ if (!Z1IsOne)
+ {
+ Z1Squared = t2;
+ SecP521R1Field.square(Z1.x, Z1Squared);
+ }
+
+ SecP521R1Field.subtract(X1.x, Z1Squared, t1);
+
+ int[] M = t2;
+ SecP521R1Field.add(X1.x, Z1Squared, M);
+ SecP521R1Field.multiply(M, t1, M);
+ Nat.addBothTo(17, M, M, M);
+ SecP521R1Field.reduce23(M);
+
+ int[] S = Y1Squared;
+ SecP521R1Field.multiply(Y1Squared, X1.x, S);
+ Nat.shiftUpBits(17, S, 2, 0);
+ SecP521R1Field.reduce23(S);
+
+ Nat.shiftUpBits(17, T, 3, 0, t1);
+ SecP521R1Field.reduce23(t1);
+
+ SecP521R1FieldElement X3 = new SecP521R1FieldElement(T);
+ SecP521R1Field.square(M, X3.x);
+ SecP521R1Field.subtract(X3.x, S, X3.x);
+ SecP521R1Field.subtract(X3.x, S, X3.x);
+
+ SecP521R1FieldElement Y3 = new SecP521R1FieldElement(S);
+ SecP521R1Field.subtract(S, X3.x, Y3.x);
+ SecP521R1Field.multiply(Y3.x, M, Y3.x);
+ SecP521R1Field.subtract(Y3.x, t1, Y3.x);
+
+ SecP521R1FieldElement Z3 = new SecP521R1FieldElement(M);
+ SecP521R1Field.twice(Y1.x, Z3.x);
+ if (!Z1IsOne)
+ {
+ SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+
+ return new SecP521R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 });
+ }
+
+ public ECPoint twicePlus(ECPoint b)
+ {
+ if (this == b)
+ {
+ return threeTimes();
+ }
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return twice();
+ }
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return b;
+ }
+
+ return twice().add(b);
+ }
+
+ public ECPoint threeTimes()
+ {
+ if (this.isInfinity() || this.y.isZero())
+ {
+ return this;
+ }
+
+ // NOTE: Be careful about recursions between twicePlus and threeTimes
+ return twice().add(this);
+ }
+
+ protected ECFieldElement two(ECFieldElement x)
+ {
+ return x.add(x);
+ }
+
+ protected ECFieldElement three(ECFieldElement x)
+ {
+ return two(x).add(x);
+ }
+
+ protected ECFieldElement four(ECFieldElement x)
+ {
+ return two(two(x));
+ }
+
+ protected ECFieldElement eight(ECFieldElement x)
+ {
+ return four(two(x));
+ }
+
+ protected ECFieldElement doubleProductFromSquares(ECFieldElement a, ECFieldElement b,
+ ECFieldElement aSquared, ECFieldElement bSquared)
+ {
+ /*
+ * NOTE: If squaring in the field is faster than multiplication, then this is a quicker
+ * way to calculate 2.A.B, if A^2 and B^2 are already known.
+ */
+ return a.add(b).square().subtract(aSquared).subtract(bSquared);
+ }
+
+ public ECPoint negate()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ return new SecP521R1Point(curve, this.x, this.y.negate(), this.zs);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/ECEndomorphism.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/ECEndomorphism.java
new file mode 100644
index 00000000..33cbf99b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/ECEndomorphism.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.endo;
+
+import com.android.internal.org.bouncycastle.math.ec.ECPointMap;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ECEndomorphism
+{
+ ECPointMap getPointMap();
+
+ boolean hasEfficientPointMap();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/EndoPreCompInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/EndoPreCompInfo.java
new file mode 100644
index 00000000..cdcb3396
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/EndoPreCompInfo.java
@@ -0,0 +1,35 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.endo;
+
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.ec.PreCompInfo;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EndoPreCompInfo implements PreCompInfo
+{
+ protected ECEndomorphism endomorphism;
+
+ protected ECPoint mappedPoint;
+
+ public ECEndomorphism getEndomorphism()
+ {
+ return endomorphism;
+ }
+
+ public void setEndomorphism(ECEndomorphism endomorphism)
+ {
+ this.endomorphism = endomorphism;
+ }
+
+ public ECPoint getMappedPoint()
+ {
+ return mappedPoint;
+ }
+
+ public void setMappedPoint(ECPoint mappedPoint)
+ {
+ this.mappedPoint = mappedPoint;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/EndoUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/EndoUtil.java
new file mode 100644
index 00000000..07823658
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/EndoUtil.java
@@ -0,0 +1,77 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.ECConstants;
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECPoint;
+import com.android.internal.org.bouncycastle.math.ec.PreCompCallback;
+import com.android.internal.org.bouncycastle.math.ec.PreCompInfo;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class EndoUtil
+{
+ public static final String PRECOMP_NAME = "bc_endo";
+
+ public static BigInteger[] decomposeScalar(ScalarSplitParameters p, BigInteger k)
+ {
+ int bits = p.getBits();
+ BigInteger b1 = calculateB(k, p.getG1(), bits);
+ BigInteger b2 = calculateB(k, p.getG2(), bits);
+
+ BigInteger a = k.subtract((b1.multiply(p.getV1A())).add(b2.multiply(p.getV2A())));
+ BigInteger b = (b1.multiply(p.getV1B())).add(b2.multiply(p.getV2B())).negate();
+
+ return new BigInteger[]{ a, b };
+ }
+
+ public static ECPoint mapPoint(final ECEndomorphism endomorphism, final ECPoint p)
+ {
+ final ECCurve c = p.getCurve();
+
+ EndoPreCompInfo precomp = (EndoPreCompInfo)c.precompute(p, PRECOMP_NAME, new PreCompCallback()
+ {
+ public PreCompInfo precompute(PreCompInfo existing)
+ {
+ EndoPreCompInfo existingEndo = (existing instanceof EndoPreCompInfo) ? (EndoPreCompInfo)existing : null;
+
+ if (checkExisting(existingEndo, endomorphism))
+ {
+ return existingEndo;
+ }
+
+ ECPoint mappedPoint = endomorphism.getPointMap().map(p);
+
+ EndoPreCompInfo result = new EndoPreCompInfo();
+ result.setEndomorphism(endomorphism);
+ result.setMappedPoint(mappedPoint);
+ return result;
+ }
+
+ private boolean checkExisting(EndoPreCompInfo existingEndo, ECEndomorphism endomorphism)
+ {
+ return null != existingEndo
+ && existingEndo.getEndomorphism() == endomorphism
+ && existingEndo.getMappedPoint() != null;
+ }
+ });
+
+ return precomp.getMappedPoint();
+ }
+
+ private static BigInteger calculateB(BigInteger k, BigInteger g, int t)
+ {
+ boolean negative = (g.signum() < 0);
+ BigInteger b = k.multiply(g.abs());
+ boolean extra = b.testBit(t - 1);
+ b = b.shiftRight(t);
+ if (extra)
+ {
+ b = b.add(ECConstants.ONE);
+ }
+ return negative ? b.negate() : b;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVEndomorphism.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVEndomorphism.java
new file mode 100644
index 00000000..fe1e939f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVEndomorphism.java
@@ -0,0 +1,12 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface GLVEndomorphism extends ECEndomorphism
+{
+ BigInteger[] decomposeScalar(BigInteger k);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeAEndomorphism.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeAEndomorphism.java
new file mode 100644
index 00000000..1a4346d9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeAEndomorphism.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECPointMap;
+import com.android.internal.org.bouncycastle.math.ec.ScaleYNegateXPointMap;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GLVTypeAEndomorphism implements GLVEndomorphism
+{
+ protected final GLVTypeAParameters parameters;
+ protected final ECPointMap pointMap;
+
+ public GLVTypeAEndomorphism(ECCurve curve, GLVTypeAParameters parameters)
+ {
+ /*
+ * NOTE: 'curve' MUST only be used to create a suitable ECFieldElement. Due to the way
+ * ECCurve configuration works, 'curve' will not be the actual instance of ECCurve that the
+ * endomorphism is being used with.
+ */
+
+ this.parameters = parameters;
+ this.pointMap = new ScaleYNegateXPointMap(curve.fromBigInteger(parameters.getI()));
+ }
+
+ public BigInteger[] decomposeScalar(BigInteger k)
+ {
+ return EndoUtil.decomposeScalar(parameters.getSplitParams(), k);
+ }
+
+ public ECPointMap getPointMap()
+ {
+ return pointMap;
+ }
+
+ public boolean hasEfficientPointMap()
+ {
+ return true;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeAParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeAParameters.java
new file mode 100644
index 00000000..1e05d94b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeAParameters.java
@@ -0,0 +1,35 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GLVTypeAParameters
+{
+ protected final BigInteger i, lambda;
+ protected final ScalarSplitParameters splitParams;
+
+ public GLVTypeAParameters(BigInteger i, BigInteger lambda, ScalarSplitParameters splitParams)
+ {
+ this.i = i;
+ this.lambda = lambda;
+ this.splitParams = splitParams;
+ }
+
+ public BigInteger getI()
+ {
+ return i;
+ }
+
+ public BigInteger getLambda()
+ {
+ return lambda;
+ }
+
+ public ScalarSplitParameters getSplitParams()
+ {
+ return splitParams;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java
new file mode 100644
index 00000000..6471e248
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.math.ec.ECCurve;
+import com.android.internal.org.bouncycastle.math.ec.ECPointMap;
+import com.android.internal.org.bouncycastle.math.ec.ScaleXPointMap;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GLVTypeBEndomorphism implements GLVEndomorphism
+{
+ protected final GLVTypeBParameters parameters;
+ protected final ECPointMap pointMap;
+
+ public GLVTypeBEndomorphism(ECCurve curve, GLVTypeBParameters parameters)
+ {
+ /*
+ * NOTE: 'curve' MUST only be used to create a suitable ECFieldElement. Due to the way
+ * ECCurve configuration works, 'curve' will not be the actual instance of ECCurve that the
+ * endomorphism is being used with.
+ */
+
+ this.parameters = parameters;
+ this.pointMap = new ScaleXPointMap(curve.fromBigInteger(parameters.getBeta()));
+ }
+
+ public BigInteger[] decomposeScalar(BigInteger k)
+ {
+ return EndoUtil.decomposeScalar(parameters.getSplitParams(), k);
+ }
+
+ public ECPointMap getPointMap()
+ {
+ return pointMap;
+ }
+
+ public boolean hasEfficientPointMap()
+ {
+ return true;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
new file mode 100644
index 00000000..94dd7faa
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
@@ -0,0 +1,102 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class GLVTypeBParameters
+{
+ protected final BigInteger beta, lambda;
+ protected final ScalarSplitParameters splitParams;
+
+ /**
+ * @deprecated Use constructor taking a {@link ScalarSplitParameters} instead.
+ */
+ public GLVTypeBParameters(BigInteger beta, BigInteger lambda, BigInteger[] v1, BigInteger[] v2, BigInteger g1,
+ BigInteger g2, int bits)
+ {
+ this.beta = beta;
+ this.lambda = lambda;
+ this.splitParams = new ScalarSplitParameters(v1, v2, g1, g2, bits);
+ }
+
+ public GLVTypeBParameters(BigInteger beta, BigInteger lambda, ScalarSplitParameters splitParams)
+ {
+ this.beta = beta;
+ this.lambda = lambda;
+ this.splitParams = splitParams;
+ }
+
+ public BigInteger getBeta()
+ {
+ return beta;
+ }
+
+ public BigInteger getLambda()
+ {
+ return lambda;
+ }
+
+ public ScalarSplitParameters getSplitParams()
+ {
+ return splitParams;
+ }
+
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
+ public BigInteger getV1A()
+ {
+ return getSplitParams().getV1A();
+ }
+
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
+ public BigInteger getV1B()
+ {
+ return getSplitParams().getV1B();
+ }
+
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
+ public BigInteger getV2A()
+ {
+ return getSplitParams().getV2A();
+ }
+
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
+ public BigInteger getV2B()
+ {
+ return getSplitParams().getV2B();
+ }
+
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
+ public BigInteger getG1()
+ {
+ return getSplitParams().getG1();
+ }
+
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
+ public BigInteger getG2()
+ {
+ return getSplitParams().getG2();
+ }
+
+ /**
+ * @deprecated Access via {@link #getSplitParams()} instead.
+ */
+ public int getBits()
+ {
+ return getSplitParams().getBits();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/ScalarSplitParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/ScalarSplitParameters.java
new file mode 100644
index 00000000..5dd88bce
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/ScalarSplitParameters.java
@@ -0,0 +1,72 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.ec.endo;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ScalarSplitParameters
+{
+ private static void checkVector(BigInteger[] v, String name)
+ {
+ if (v == null || v.length != 2 || v[0] == null || v[1] == null)
+ {
+ throw new IllegalArgumentException("'" + name + "' must consist of exactly 2 (non-null) values");
+ }
+ }
+
+ protected final BigInteger v1A, v1B, v2A, v2B;
+ protected final BigInteger g1, g2;
+ protected final int bits;
+
+ public ScalarSplitParameters(BigInteger[] v1, BigInteger[] v2, BigInteger g1,
+ BigInteger g2, int bits)
+ {
+ checkVector(v1, "v1");
+ checkVector(v2, "v2");
+
+ this.v1A = v1[0];
+ this.v1B = v1[1];
+ this.v2A = v2[0];
+ this.v2B = v2[1];
+ this.g1 = g1;
+ this.g2 = g2;
+ this.bits = bits;
+ }
+
+ public BigInteger getV1A()
+ {
+ return v1A;
+ }
+
+ public BigInteger getV1B()
+ {
+ return v1B;
+ }
+
+ public BigInteger getV2A()
+ {
+ return v2A;
+ }
+
+ public BigInteger getV2B()
+ {
+ return v2B;
+ }
+
+ public BigInteger getG1()
+ {
+ return g1;
+ }
+
+ public BigInteger getG2()
+ {
+ return g2;
+ }
+
+ public int getBits()
+ {
+ return bits;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/ExtensionField.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/ExtensionField.java
new file mode 100644
index 00000000..9f12727b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/ExtensionField.java
@@ -0,0 +1,12 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.field;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ExtensionField extends FiniteField
+{
+ FiniteField getSubfield();
+
+ int getDegree();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteField.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteField.java
new file mode 100644
index 00000000..32c64bfe
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteField.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.field;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface FiniteField
+{
+ BigInteger getCharacteristic();
+
+ int getDimension();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteFields.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteFields.java
new file mode 100644
index 00000000..45cc70f7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteFields.java
@@ -0,0 +1,57 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.field;
+
+import java.math.BigInteger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class FiniteFields
+{
+ static final FiniteField GF_2 = new PrimeField(BigInteger.valueOf(2));
+ static final FiniteField GF_3 = new PrimeField(BigInteger.valueOf(3));
+
+ public static PolynomialExtensionField getBinaryExtensionField(int[] exponents)
+ {
+ if (exponents[0] != 0)
+ {
+ throw new IllegalArgumentException("Irreducible polynomials in GF(2) must have constant term");
+ }
+ for (int i = 1; i < exponents.length; ++i)
+ {
+ if (exponents[i] <= exponents[i - 1])
+ {
+ throw new IllegalArgumentException("Polynomial exponents must be monotonically increasing");
+ }
+ }
+
+ return new GenericPolynomialExtensionField(GF_2, new GF2Polynomial(exponents));
+ }
+
+// public static PolynomialExtensionField getTernaryExtensionField(Term[] terms)
+// {
+// return new GenericPolynomialExtensionField(GF_3, new GF3Polynomial(terms));
+// }
+
+ public static FiniteField getPrimeField(BigInteger characteristic)
+ {
+ int bitLength = characteristic.bitLength();
+ if (characteristic.signum() <= 0 || bitLength < 2)
+ {
+ throw new IllegalArgumentException("'characteristic' must be >= 2");
+ }
+
+ if (bitLength < 3)
+ {
+ switch (characteristic.intValue())
+ {
+ case 2:
+ return GF_2;
+ case 3:
+ return GF_3;
+ }
+ }
+
+ return new PrimeField(characteristic);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/GF2Polynomial.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/GF2Polynomial.java
new file mode 100644
index 00000000..181e0a91
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/GF2Polynomial.java
@@ -0,0 +1,43 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.field;
+
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+class GF2Polynomial implements Polynomial
+{
+ protected final int[] exponents;
+
+ GF2Polynomial(int[] exponents)
+ {
+ this.exponents = Arrays.clone(exponents);
+ }
+
+ public int getDegree()
+ {
+ return exponents[exponents.length - 1];
+ }
+
+ public int[] getExponentsPresent()
+ {
+ return Arrays.clone(exponents);
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ if (!(obj instanceof GF2Polynomial))
+ {
+ return false;
+ }
+ GF2Polynomial other = (GF2Polynomial)obj;
+ return Arrays.areEqual(exponents, other.exponents);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(exponents);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/GenericPolynomialExtensionField.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/GenericPolynomialExtensionField.java
new file mode 100644
index 00000000..a3523eb6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/GenericPolynomialExtensionField.java
@@ -0,0 +1,63 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.field;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.util.Integers;
+
+class GenericPolynomialExtensionField implements PolynomialExtensionField
+{
+ protected final FiniteField subfield;
+ protected final Polynomial minimalPolynomial;
+
+ GenericPolynomialExtensionField(FiniteField subfield, Polynomial polynomial)
+ {
+ this.subfield = subfield;
+ this.minimalPolynomial = polynomial;
+ }
+
+ public BigInteger getCharacteristic()
+ {
+ return subfield.getCharacteristic();
+ }
+
+ public int getDimension()
+ {
+ return subfield.getDimension() * minimalPolynomial.getDegree();
+ }
+
+ public FiniteField getSubfield()
+ {
+ return subfield;
+ }
+
+ public int getDegree()
+ {
+ return minimalPolynomial.getDegree();
+ }
+
+ public Polynomial getMinimalPolynomial()
+ {
+ return minimalPolynomial;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ if (!(obj instanceof GenericPolynomialExtensionField))
+ {
+ return false;
+ }
+ GenericPolynomialExtensionField other = (GenericPolynomialExtensionField)obj;
+ return subfield.equals(other.subfield) && minimalPolynomial.equals(other.minimalPolynomial);
+ }
+
+ public int hashCode()
+ {
+ return subfield.hashCode()
+ ^ Integers.rotateLeft(minimalPolynomial.hashCode(), 16);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/Polynomial.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/Polynomial.java
new file mode 100644
index 00000000..c4d9322c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/Polynomial.java
@@ -0,0 +1,16 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.field;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Polynomial
+{
+ int getDegree();
+
+// BigInteger[] getCoefficients();
+
+ int[] getExponentsPresent();
+
+// Term[] getNonZeroTerms();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/PolynomialExtensionField.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/PolynomialExtensionField.java
new file mode 100644
index 00000000..4d087459
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/PolynomialExtensionField.java
@@ -0,0 +1,10 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.field;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PolynomialExtensionField extends ExtensionField
+{
+ Polynomial getMinimalPolynomial();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/PrimeField.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/PrimeField.java
new file mode 100644
index 00000000..ebfe73f4
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/PrimeField.java
@@ -0,0 +1,43 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.field;
+
+import java.math.BigInteger;
+
+class PrimeField implements FiniteField
+{
+ protected final BigInteger characteristic;
+
+ PrimeField(BigInteger characteristic)
+ {
+ this.characteristic = characteristic;
+ }
+
+ public BigInteger getCharacteristic()
+ {
+ return characteristic;
+ }
+
+ public int getDimension()
+ {
+ return 1;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ if (!(obj instanceof PrimeField))
+ {
+ return false;
+ }
+ PrimeField other = (PrimeField)obj;
+ return characteristic.equals(other.characteristic);
+ }
+
+ public int hashCode()
+ {
+ return characteristic.hashCode();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Bits.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Bits.java
new file mode 100644
index 00000000..996ce285
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Bits.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.raw;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class Bits
+{
+ public static int bitPermuteStep(int x, int m, int s)
+ {
+ int t = (x ^ (x >>> s)) & m;
+ return (t ^ (t << s)) ^ x;
+ }
+
+ public static long bitPermuteStep(long x, long m, int s)
+ {
+ long t = (x ^ (x >>> s)) & m;
+ return (t ^ (t << s)) ^ x;
+ }
+
+ public static int bitPermuteStepSimple(int x, int m, int s)
+ {
+ return ((x & m) << s) | ((x >>> s) & m);
+ }
+
+ public static long bitPermuteStepSimple(long x, long m, int s)
+ {
+ return ((x & m) << s) | ((x >>> s) & m);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Interleave.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Interleave.java
new file mode 100644
index 00000000..1cd7c3b9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Interleave.java
@@ -0,0 +1,216 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.raw;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Interleave
+{
+ private static final long M32 = 0x55555555L;
+ private static final long M64 = 0x5555555555555555L;
+ private static final long M64R = 0xAAAAAAAAAAAAAAAAL;
+
+ /*
+ * This expands 8 bit indices into 16 bit contents (high bit 14), by inserting 0s between bits.
+ * In a binary field, this operation is the same as squaring an 8 bit number.
+ *
+ * NOTE: All entries are positive so sign-extension is not an issue.
+ */
+// private static final short[] INTERLEAVE2_TABLE = new short[]
+// {
+// 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015,
+// 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055,
+// 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115,
+// 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155,
+// 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415,
+// 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455,
+// 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515,
+// 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555,
+// 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015,
+// 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055,
+// 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115,
+// 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155,
+// 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415,
+// 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455,
+// 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515,
+// 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555,
+// 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015,
+// 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055,
+// 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115,
+// 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155,
+// 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415,
+// 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455,
+// 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515,
+// 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555,
+// 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015,
+// 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055,
+// 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115,
+// 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155,
+// 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415,
+// 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455,
+// 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515,
+// 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555
+// };
+
+ public static int expand8to16(int x)
+ {
+ x &= 0xFF;
+ x = (x | (x << 4)) & 0x0F0F;
+ x = (x | (x << 2)) & 0x3333;
+ x = (x | (x << 1)) & 0x5555;
+ return x;
+ }
+
+ public static int expand16to32(int x)
+ {
+ x &= 0xFFFF;
+ x = (x | (x << 8)) & 0x00FF00FF;
+ x = (x | (x << 4)) & 0x0F0F0F0F;
+ x = (x | (x << 2)) & 0x33333333;
+ x = (x | (x << 1)) & 0x55555555;
+ return x;
+ }
+
+ public static long expand32to64(int x)
+ {
+ // "shuffle" low half to even bits and high half to odd bits
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C, 2);
+ x = Bits.bitPermuteStep(x, 0x22222222, 1);
+
+ return ((x >>> 1) & M32) << 32 | (x & M32);
+ }
+
+ public static void expand64To128(long x, long[] z, int zOff)
+ {
+ // "shuffle" low half to even bits and high half to odd bits
+ x = Bits.bitPermuteStep(x, 0x00000000FFFF0000L, 16);
+ x = Bits.bitPermuteStep(x, 0x0000FF000000FF00L, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F000F000F0L, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C0C0C0C0CL, 2);
+ x = Bits.bitPermuteStep(x, 0x2222222222222222L, 1);
+
+ z[zOff ] = (x ) & M64;
+ z[zOff + 1] = (x >>> 1) & M64;
+ }
+
+ public static void expand64To128(long[] xs, int xsOff, int xsLen, long[] zs, int zsOff)
+ {
+ for (int i = 0; i < xsLen; ++i)
+ {
+ expand64To128(xs[xsOff + i], zs, zsOff);
+ zsOff += 2;
+ }
+ }
+
+ public static void expand64To128Rev(long x, long[] z, int zOff)
+ {
+ // "shuffle" low half to even bits and high half to odd bits
+ x = Bits.bitPermuteStep(x, 0x00000000FFFF0000L, 16);
+ x = Bits.bitPermuteStep(x, 0x0000FF000000FF00L, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F000F000F0L, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C0C0C0C0CL, 2);
+ x = Bits.bitPermuteStep(x, 0x2222222222222222L, 1);
+
+ z[zOff ] = (x ) & M64R;
+ z[zOff + 1] = (x << 1) & M64R;
+ }
+
+ public static int shuffle(int x)
+ {
+ // "shuffle" low half to even bits and high half to odd bits
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C, 2);
+ x = Bits.bitPermuteStep(x, 0x22222222, 1);
+ return x;
+ }
+
+ public static long shuffle(long x)
+ {
+ // "shuffle" low half to even bits and high half to odd bits
+ x = Bits.bitPermuteStep(x, 0x00000000FFFF0000L, 16);
+ x = Bits.bitPermuteStep(x, 0x0000FF000000FF00L, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F000F000F0L, 4);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C0C0C0C0CL, 2);
+ x = Bits.bitPermuteStep(x, 0x2222222222222222L, 1);
+ return x;
+ }
+
+ public static int shuffle2(int x)
+ {
+ // "shuffle" (twice) low half to even bits and high half to odd bits
+ x = Bits.bitPermuteStep(x, 0x00AA00AA, 7);
+ x = Bits.bitPermuteStep(x, 0x0000CCCC, 14);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
+ return x;
+ }
+
+ public static long shuffle2(long x)
+ {
+ // "shuffle" (twice) low half to even bits and high half to odd bits
+ x = Bits.bitPermuteStep(x, 0x00000000FF00FF00L, 24);
+ x = Bits.bitPermuteStep(x, 0x00CC00CC00CC00CCL, 6);
+ x = Bits.bitPermuteStep(x, 0x0000F0F00000F0F0L, 12);
+ x = Bits.bitPermuteStep(x, 0x0A0A0A0A0A0A0A0AL, 3);
+ return x;
+ }
+
+ public static long shuffle3(long x)
+ {
+ // "shuffle" (thrice) low half to even bits and high half to odd bits
+ x = Bits.bitPermuteStep(x, 0x00AA00AA00AA00AAL, 7);
+ x = Bits.bitPermuteStep(x, 0x0000CCCC0000CCCCL, 14);
+ x = Bits.bitPermuteStep(x, 0x00000000F0F0F0F0L, 28);
+ return x;
+ }
+
+ public static int unshuffle(int x)
+ {
+ // "unshuffle" even bits to low half and odd bits to high half
+ x = Bits.bitPermuteStep(x, 0x22222222, 1);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C, 2);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
+ return x;
+ }
+
+ public static long unshuffle(long x)
+ {
+ // "unshuffle" even bits to low half and odd bits to high half
+ x = Bits.bitPermuteStep(x, 0x2222222222222222L, 1);
+ x = Bits.bitPermuteStep(x, 0x0C0C0C0C0C0C0C0CL, 2);
+ x = Bits.bitPermuteStep(x, 0x00F000F000F000F0L, 4);
+ x = Bits.bitPermuteStep(x, 0x0000FF000000FF00L, 8);
+ x = Bits.bitPermuteStep(x, 0x00000000FFFF0000L, 16);
+ return x;
+ }
+
+ public static int unshuffle2(int x)
+ {
+ // "unshuffle" (twice) even bits to low half and odd bits to high half
+ x = Bits.bitPermuteStep(x, 0x0000FF00, 8);
+ x = Bits.bitPermuteStep(x, 0x00F000F0, 4);
+ x = Bits.bitPermuteStep(x, 0x0000CCCC, 14);
+ x = Bits.bitPermuteStep(x, 0x00AA00AA, 7);
+ return x;
+ }
+
+ public static long unshuffle2(long x)
+ {
+ // "unshuffle" (twice) even bits to low half and odd bits to high half
+ x = Bits.bitPermuteStep(x, 0x0A0A0A0A0A0A0A0AL, 3);
+ x = Bits.bitPermuteStep(x, 0x0000F0F00000F0F0L, 12);
+ x = Bits.bitPermuteStep(x, 0x00CC00CC00CC00CCL, 6);
+ x = Bits.bitPermuteStep(x, 0x00000000FF00FF00L, 24);
+ return x;
+ }
+
+ public static long unshuffle3(long x)
+ {
+ // "unshuffle" (thrice) even bits to low half and odd bits to high half
+ return shuffle3(x);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Mod.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Mod.java
new file mode 100644
index 00000000..c6d6bece
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Mod.java
@@ -0,0 +1,589 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.raw;
+
+import java.util.Random;
+
+import com.android.internal.org.bouncycastle.util.Integers;
+
+/*
+ * Modular inversion as implemented in this class is based on the paper "Fast constant-time gcd
+ * computation and modular inversion" by Daniel J. Bernstein and Bo-Yin Yang.
+ */
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class Mod
+{
+ private static final int M30 = 0x3FFFFFFF;
+ private static final long M32L = 0xFFFFFFFFL;
+
+ /** @deprecated Will be removed. */
+ public static void add(int[] p, int[] x, int[] y, int[] z)
+ {
+ int len = p.length;
+ int c = Nat.add(len, x, y, z);
+ if (c != 0)
+ {
+ Nat.subFrom(len, p, z);
+ }
+ }
+
+ public static void checkedModOddInverse(int[] m, int[] x, int[] z)
+ {
+ if (0 == modOddInverse(m, x, z))
+ {
+ throw new ArithmeticException("Inverse does not exist.");
+ }
+ }
+
+ public static void checkedModOddInverseVar(int[] m, int[] x, int[] z)
+ {
+ if (!modOddInverseVar(m, x, z))
+ {
+ throw new ArithmeticException("Inverse does not exist.");
+ }
+ }
+
+ public static int inverse32(int d)
+ {
+// assert (d & 1) == 1;
+// int x = d + (((d + 1) & 4) << 1); // d.x == 1 mod 2**4
+ int x = d; // d.x == 1 mod 2**3
+ x *= 2 - d * x; // d.x == 1 mod 2**6
+ x *= 2 - d * x; // d.x == 1 mod 2**12
+ x *= 2 - d * x; // d.x == 1 mod 2**24
+ x *= 2 - d * x; // d.x == 1 mod 2**48
+// assert d * x == 1;
+ return x;
+ }
+
+ /** @deprecated Use {@link #checkedModOddInverseVar(int[], int[], int[])} instead. */
+ public static void invert(int[] m, int[] x, int[] z)
+ {
+ checkedModOddInverseVar(m, x, z);
+ }
+
+ public static int modOddInverse(int[] m, int[] x, int[] z)
+ {
+ int len32 = m.length;
+// assert len32 > 0;
+// assert (m[0] & 1) != 0;
+// assert m[len32 - 1] != 0;
+
+ int bits = (len32 << 5) - Integers.numberOfLeadingZeros(m[len32 - 1]);
+ int len30 = (bits + 29) / 30;
+
+ int[] t = new int[4];
+ int[] D = new int[len30];
+ int[] E = new int[len30];
+ int[] F = new int[len30];
+ int[] G = new int[len30];
+ int[] M = new int[len30];
+
+ E[0] = 1;
+ encode30(bits, x, 0, G, 0);
+ encode30(bits, m, 0, M, 0);
+ System.arraycopy(M, 0, F, 0, len30);
+
+ int eta = -1;
+ int m0Inv32 = inverse32(M[0]);
+ int maxDivsteps = getMaximumDivsteps(bits);
+
+ for (int divSteps = 0; divSteps < maxDivsteps; divSteps += 30)
+ {
+ eta = divsteps30(eta, F[0], G[0], t);
+ updateDE30(len30, D, E, t, m0Inv32, M);
+ updateFG30(len30, F, G, t);
+ }
+
+ int signF = F[len30 - 1] >> 31;
+ cnegate30(len30, signF, F);
+
+ /*
+ * D is in the range (-2.M, M). First, conditionally add M if D is negative, to bring it
+ * into the range (-M, M). Then normalize by conditionally negating (according to signF)
+ * and/or then adding M, to bring it into the range [0, M).
+ */
+ cnormalize30(len30, signF, D, M);
+
+ decode30(bits, D, 0, z, 0);
+// assert 0 != Nat.lessThan(len32, z, m);
+
+ return Nat.equalTo(len30, F, 1) & Nat.equalToZero(len30, G);
+ }
+
+ public static boolean modOddInverseVar(int[] m, int[] x, int[] z)
+ {
+ int len32 = m.length;
+// assert len32 > 0;
+// assert (m[0] & 1) != 0;
+// assert m[len32 - 1] != 0;
+
+ int bits = (len32 << 5) - Integers.numberOfLeadingZeros(m[len32 - 1]);
+ int len30 = (bits + 29) / 30;
+
+ int[] t = new int[4];
+ int[] D = new int[len30];
+ int[] E = new int[len30];
+ int[] F = new int[len30];
+ int[] G = new int[len30];
+ int[] M = new int[len30];
+
+ E[0] = 1;
+ encode30(bits, x, 0, G, 0);
+ encode30(bits, m, 0, M, 0);
+ System.arraycopy(M, 0, F, 0, len30);
+
+ int clzG = Integers.numberOfLeadingZeros(G[len30 - 1] | 1) - (len30 * 30 + 2 - bits);
+ int eta = -1 - clzG;
+ int lenDE = len30, lenFG = len30;
+ int m0Inv32 = inverse32(M[0]);
+ int maxDivsteps = getMaximumDivsteps(bits);
+
+ int divsteps = 0;
+ while (!Nat.isZero(lenFG, G))
+ {
+ if (divsteps >= maxDivsteps)
+ {
+ return false;
+ }
+
+ divsteps += 30;
+
+ eta = divsteps30Var(eta, F[0], G[0], t);
+ updateDE30(lenDE, D, E, t, m0Inv32, M);
+ updateFG30(lenFG, F, G, t);
+
+ int fn = F[lenFG - 1];
+ int gn = G[lenFG - 1];
+
+ int cond = (lenFG - 2) >> 31;
+ cond |= fn ^ (fn >> 31);
+ cond |= gn ^ (gn >> 31);
+
+ if (cond == 0)
+ {
+ F[lenFG - 2] |= fn << 30;
+ G[lenFG - 2] |= gn << 30;
+ --lenFG;
+ }
+ }
+
+ int signF = F[lenFG - 1] >> 31;
+
+ /*
+ * D is in the range (-2.M, M). First, conditionally add M if D is negative, to bring it
+ * into the range (-M, M). Then normalize by conditionally negating (according to signF)
+ * and/or then adding M, to bring it into the range [0, M).
+ */
+ int signD = D[lenDE - 1] >> 31;
+ if (signD < 0)
+ {
+ signD = add30(lenDE, D, M);
+ }
+ if (signF < 0)
+ {
+ signD = negate30(lenDE, D);
+ signF = negate30(lenFG, F);
+ }
+// assert 0 == signF;
+
+ if (!Nat.isOne(lenFG, F))
+ {
+ return false;
+ }
+
+ if (signD < 0)
+ {
+ signD = add30(lenDE, D, M);
+ }
+// assert 0 == signD;
+
+ decode30(bits, D, 0, z, 0);
+// assert !Nat.gte(len32, z, m);
+
+ return true;
+ }
+
+ public static int[] random(int[] p)
+ {
+ int len = p.length;
+ Random rand = new Random();
+ int[] s = Nat.create(len);
+
+ int m = p[len - 1];
+ m |= m >>> 1;
+ m |= m >>> 2;
+ m |= m >>> 4;
+ m |= m >>> 8;
+ m |= m >>> 16;
+
+ do
+ {
+ for (int i = 0; i != len; i++)
+ {
+ s[i] = rand.nextInt();
+ }
+ s[len - 1] &= m;
+ }
+ while (Nat.gte(len, s, p));
+
+ return s;
+ }
+
+ /** @deprecated Will be removed. */
+ public static void subtract(int[] p, int[] x, int[] y, int[] z)
+ {
+ int len = p.length;
+ int c = Nat.sub(len, x, y, z);
+ if (c != 0)
+ {
+ Nat.addTo(len, p, z);
+ }
+ }
+
+ private static int add30(int len30, int[] D, int[] M)
+ {
+// assert len30 > 0;
+// assert D.length >= len30;
+// assert M.length >= len30;
+
+ int c = 0, last = len30 - 1;
+ for (int i = 0; i < last; ++i)
+ {
+ c += D[i] + M[i];
+ D[i] = c & M30; c >>= 30;
+ }
+ c += D[last] + M[last];
+ D[last] = c; c >>= 30;
+ return c;
+ }
+
+ private static void cnegate30(int len30, int cond, int[] D)
+ {
+// assert len30 > 0;
+// assert D.length >= len30;
+
+ int c = 0, last = len30 - 1;
+ for (int i = 0; i < last; ++i)
+ {
+ c += (D[i] ^ cond) - cond;
+ D[i] = c & M30; c >>= 30;
+ }
+ c += (D[last] ^ cond) - cond;
+ D[last] = c;
+ }
+
+ private static void cnormalize30(int len30, int condNegate, int[] D, int[] M)
+ {
+// assert len30 > 0;
+// assert D.length >= len30;
+// assert M.length >= len30;
+
+ int last = len30 - 1;
+
+ {
+ int c = 0, condAdd = D[last] >> 31;
+ for (int i = 0; i < last; ++i)
+ {
+ int di = D[i] + (M[i] & condAdd);
+ di = (di ^ condNegate) - condNegate;
+ c += di; D[i] = c & M30; c >>= 30;
+ }
+ {
+ int di = D[last] + (M[last] & condAdd);
+ di = (di ^ condNegate) - condNegate;
+ c += di; D[last] = c;
+ }
+ }
+
+ {
+ int c = 0, condAdd = D[last] >> 31;
+ for (int i = 0; i < last; ++i)
+ {
+ int di = D[i] + (M[i] & condAdd);
+ c += di; D[i] = c & M30; c >>= 30;
+ }
+ {
+ int di = D[last] + (M[last] & condAdd);
+ c += di; D[last] = c;
+ }
+// assert c >> 30 == 0;
+ }
+ }
+
+ private static void decode30(int bits, int[] x, int xOff, int[] z, int zOff)
+ {
+// assert bits > 0;
+// assert x != z;
+
+ int avail = 0;
+ long data = 0L;
+
+ while (bits > 0)
+ {
+ while (avail < Math.min(32, bits))
+ {
+ data |= (long)x[xOff++] << avail;
+ avail += 30;
+ }
+
+ z[zOff++] = (int)data; data >>>= 32;
+ avail -= 32;
+ bits -= 32;
+ }
+ }
+
+ private static int divsteps30(int eta, int f0, int g0, int[] t)
+ {
+ int u = 1, v = 0, q = 0, r = 1;
+ int f = f0, g = g0;
+
+ for (int i = 0; i < 30; ++i)
+ {
+// assert (f & 1) == 1;
+// assert (u * f0 + v * g0) == f << i;
+// assert (q * f0 + r * g0) == g << i;
+
+ int c1 = eta >> 31;
+ int c2 = -(g & 1);
+
+ int x = (f ^ c1) - c1;
+ int y = (u ^ c1) - c1;
+ int z = (v ^ c1) - c1;
+
+ g += x & c2;
+ q += y & c2;
+ r += z & c2;
+
+ c1 &= c2;
+ eta = (eta ^ c1) - (c1 + 1);
+
+ f += g & c1;
+ u += q & c1;
+ v += r & c1;
+
+ g >>= 1;
+ u <<= 1;
+ v <<= 1;
+ }
+
+ t[0] = u;
+ t[1] = v;
+ t[2] = q;
+ t[3] = r;
+
+ return eta;
+ }
+
+ private static int divsteps30Var(int eta, int f0, int g0, int[] t)
+ {
+ int u = 1, v = 0, q = 0, r = 1;
+ int f = f0, g = g0, m, w, x, y, z;
+ int i = 30, limit, zeros;
+
+ for (;;)
+ {
+ // Use a sentinel bit to count zeros only up to i.
+ zeros = Integers.numberOfTrailingZeros(g | (-1 << i));
+
+ g >>= zeros;
+ u <<= zeros;
+ v <<= zeros;
+ eta -= zeros;
+ i -= zeros;
+
+ if (i <= 0)
+ {
+ break;
+ }
+
+// assert (f & 1) == 1;
+// assert (g & 1) == 1;
+// assert (u * f0 + v * g0) == f << (30 - i);
+// assert (q * f0 + r * g0) == g << (30 - i);
+
+ if (eta < 0)
+ {
+ eta = -eta;
+ x = f; f = g; g = -x;
+ y = u; u = q; q = -y;
+ z = v; v = r; r = -z;
+
+ // Handle up to 6 divsteps at once, subject to eta and i.
+ limit = (eta + 1) > i ? i : (eta + 1);
+ m = (-1 >>> (32 - limit)) & 63;
+
+ w = (f * g * (f * f - 2)) & m;
+ }
+ else
+ {
+ // Handle up to 4 divsteps at once, subject to eta and i.
+ limit = (eta + 1) > i ? i : (eta + 1);
+ m = (-1 >>> (32 - limit)) & 15;
+
+ w = f + (((f + 1) & 4) << 1);
+ w = (-w * g) & m;
+ }
+
+ g += f * w;
+ q += u * w;
+ r += v * w;
+
+// assert (g & m) == 0;
+ }
+
+ t[0] = u;
+ t[1] = v;
+ t[2] = q;
+ t[3] = r;
+
+ return eta;
+ }
+
+ private static void encode30(int bits, int[] x, int xOff, int[] z, int zOff)
+ {
+// assert bits > 0;
+// assert x != z;
+
+ int avail = 0;
+ long data = 0L;
+
+ while (bits > 0)
+ {
+ if (avail < Math.min(30, bits))
+ {
+ data |= (x[xOff++] & M32L) << avail;
+ avail += 32;
+ }
+
+ z[zOff++] = (int)data & M30; data >>>= 30;
+ avail -= 30;
+ bits -= 30;
+ }
+ }
+
+ private static int getMaximumDivsteps(int bits)
+ {
+ return (49 * bits + (bits < 46 ? 80 : 47)) / 17;
+ }
+
+ private static int negate30(int len30, int[] D)
+ {
+// assert len30 > 0;
+// assert D.length >= len30;
+
+ int c = 0, last = len30 - 1;
+ for (int i = 0; i < last; ++i)
+ {
+ c -= D[i];
+ D[i] = c & M30; c >>= 30;
+ }
+ c -= D[last];
+ D[last] = c; c >>= 30;
+ return c;
+ }
+
+ private static void updateDE30(int len30, int[] D, int[] E, int[] t, int m0Inv32, int[] M)
+ {
+// assert len30 > 0;
+// assert D.length >= len30;
+// assert E.length >= len30;
+// assert M.length >= len30;
+// assert m0Inv32 * M[0] == 1;
+
+ final int u = t[0], v = t[1], q = t[2], r = t[3];
+ int di, ei, i, md, me, mi, sd, se;
+ long cd, ce;
+
+ /*
+ * We accept D (E) in the range (-2.M, M) and conceptually add the modulus to the input
+ * value if it is initially negative. Instead of adding it explicitly, we add u and/or v (q
+ * and/or r) to md (me).
+ */
+ sd = D[len30 - 1] >> 31;
+ se = E[len30 - 1] >> 31;
+
+ md = (u & sd) + (v & se);
+ me = (q & sd) + (r & se);
+
+ mi = M[0];
+ di = D[0];
+ ei = E[0];
+
+ cd = (long)u * di + (long)v * ei;
+ ce = (long)q * di + (long)r * ei;
+
+ /*
+ * Subtract from md/me an extra term in the range [0, 2^30) such that the low 30 bits of the
+ * intermediate D/E values will be 0, allowing clean division by 2^30. The final D/E are
+ * thus in the range (-2.M, M), consistent with the input constraint.
+ */
+ md -= (m0Inv32 * (int)cd + md) & M30;
+ me -= (m0Inv32 * (int)ce + me) & M30;
+
+ cd += (long)mi * md;
+ ce += (long)mi * me;
+
+// assert ((int)cd & M30) == 0;
+// assert ((int)ce & M30) == 0;
+
+ cd >>= 30;
+ ce >>= 30;
+
+ for (i = 1; i < len30; ++i)
+ {
+ mi = M[i];
+ di = D[i];
+ ei = E[i];
+
+ cd += (long)u * di + (long)v * ei + (long)mi * md;
+ ce += (long)q * di + (long)r * ei + (long)mi * me;
+
+ D[i - 1] = (int)cd & M30; cd >>= 30;
+ E[i - 1] = (int)ce & M30; ce >>= 30;
+ }
+
+ D[len30 - 1] = (int)cd;
+ E[len30 - 1] = (int)ce;
+ }
+
+ private static void updateFG30(int len30, int[] F, int[] G, int[] t)
+ {
+// assert len30 > 0;
+// assert F.length >= len30;
+// assert G.length >= len30;
+
+ final int u = t[0], v = t[1], q = t[2], r = t[3];
+ int fi, gi, i;
+ long cf, cg;
+
+ fi = F[0];
+ gi = G[0];
+
+ cf = (long)u * fi + (long)v * gi;
+ cg = (long)q * fi + (long)r * gi;
+
+// assert ((int)cf & M30) == 0;
+// assert ((int)cg & M30) == 0;
+
+ cf >>= 30;
+ cg >>= 30;
+
+ for (i = 1; i < len30; ++i)
+ {
+ fi = F[i];
+ gi = G[i];
+
+ cf += (long)u * fi + (long)v * gi;
+ cg += (long)q * fi + (long)r * gi;
+
+ F[i - 1] = (int)cf & M30; cf >>= 30;
+ G[i - 1] = (int)cg & M30; cg >>= 30;
+ }
+
+ F[len30 - 1] = (int)cf;
+ G[len30 - 1] = (int)cg;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat.java
new file mode 100644
index 00000000..515ac476
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat.java
@@ -0,0 +1,1431 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.raw;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class Nat
+{
+ private static final long M = 0xFFFFFFFFL;
+
+ public static int add(int len, int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[i] & M) + (y[i] & M);
+ z[i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int add33At(int len, int x, int[] z, int zPos)
+ {
+ // assert zPos <= (len - 2);
+ long c = (z[zPos + 0] & M) + (x & M);
+ z[zPos + 0] = (int)c;
+ c >>>= 32;
+ c += (z[zPos + 1] & M) + 1L;
+ z[zPos + 1] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : incAt(len, z, zPos + 2);
+ }
+
+ public static int add33At(int len, int x, int[] z, int zOff, int zPos)
+ {
+ // assert zPos <= (len - 2);
+ long c = (z[zOff + zPos] & M) + (x & M);
+ z[zOff + zPos] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + zPos + 1] & M) + 1L;
+ z[zOff + zPos + 1] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : incAt(len, z, zOff, zPos + 2);
+ }
+
+ public static int add33To(int len, int x, int[] z)
+ {
+ long c = (z[0] & M) + (x & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (z[1] & M) + 1L;
+ z[1] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : incAt(len, z, 2);
+ }
+
+ public static int add33To(int len, int x, int[] z, int zOff)
+ {
+ long c = (z[zOff + 0] & M) + (x & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 1] & M) + 1L;
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : incAt(len, z, zOff, 2);
+ }
+
+ public static int addBothTo(int len, int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[i] & M) + (y[i] & M) + (z[i] & M);
+ z[i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int addBothTo(int len, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[xOff + i] & M) + (y[yOff + i] & M) + (z[zOff + i] & M);
+ z[zOff + i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int addDWordAt(int len, long x, int[] z, int zPos)
+ {
+ // assert zPos <= (len - 2);
+ long c = (z[zPos + 0] & M) + (x & M);
+ z[zPos + 0] = (int)c;
+ c >>>= 32;
+ c += (z[zPos + 1] & M) + (x >>> 32);
+ z[zPos + 1] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : incAt(len, z, zPos + 2);
+ }
+
+ public static int addDWordAt(int len, long x, int[] z, int zOff, int zPos)
+ {
+ // assert zPos <= (len - 2);
+ long c = (z[zOff + zPos] & M) + (x & M);
+ z[zOff + zPos] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + zPos + 1] & M) + (x >>> 32);
+ z[zOff + zPos + 1] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : incAt(len, z, zOff, zPos + 2);
+ }
+
+ public static int addDWordTo(int len, long x, int[] z)
+ {
+ long c = (z[0] & M) + (x & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (z[1] & M) + (x >>> 32);
+ z[1] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : incAt(len, z, 2);
+ }
+
+ public static int addDWordTo(int len, long x, int[] z, int zOff)
+ {
+ long c = (z[zOff + 0] & M) + (x & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 1] & M) + (x >>> 32);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : incAt(len, z, zOff, 2);
+ }
+
+ public static int addTo(int len, int[] x, int[] z)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[i] & M) + (z[i] & M);
+ z[i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int addTo(int len, int[] x, int xOff, int[] z, int zOff)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[xOff + i] & M) + (z[zOff + i] & M);
+ z[zOff + i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int addTo(int len, int[] x, int xOff, int[] z, int zOff, int cIn)
+ {
+ long c = cIn & M;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[xOff + i] & M) + (z[zOff + i] & M);
+ z[zOff + i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int addToEachOther(int len, int[] u, int uOff, int[] v, int vOff)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (u[uOff + i] & M) + (v[vOff + i] & M);
+ u[uOff + i] = (int)c;
+ v[vOff + i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int addWordAt(int len, int x, int[] z, int zPos)
+ {
+ // assert zPos <= (len - 1);
+ long c = (x & M) + (z[zPos] & M);
+ z[zPos] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : incAt(len, z, zPos + 1);
+ }
+
+ public static int addWordAt(int len, int x, int[] z, int zOff, int zPos)
+ {
+ // assert zPos <= (len - 1);
+ long c = (x & M) + (z[zOff + zPos] & M);
+ z[zOff + zPos] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : incAt(len, z, zOff, zPos + 1);
+ }
+
+ public static int addWordTo(int len, int x, int[] z)
+ {
+ long c = (x & M) + (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : incAt(len, z, 1);
+ }
+
+ public static int addWordTo(int len, int x, int[] z, int zOff)
+ {
+ long c = (x & M) + (z[zOff] & M);
+ z[zOff] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : incAt(len, z, zOff, 1);
+ }
+
+ public static int cadd(int len, int mask, int[] x, int[] y, int[] z)
+ {
+ long MASK = -(mask & 1) & M;
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[i] & M) + (y[i] & MASK);
+ z[i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
+ public static void cmov(int len, int mask, int[] x, int xOff, int[] z, int zOff)
+ {
+ mask = -(mask & 1);
+
+ for (int i = 0; i < len; ++i)
+ {
+ int z_i = z[zOff + i], diff = z_i ^ x[xOff + i];
+ z_i ^= (diff & mask);
+ z[zOff + i] = z_i;
+ }
+
+// final int half = 0x55555555, rest = half << (-mask);
+//
+// for (int i = 0; i < len; ++i)
+// {
+// int z_i = z[zOff + i], diff = z_i ^ x[xOff + i];
+// z_i ^= (diff & half);
+// z_i ^= (diff & rest);
+// z[zOff + i] = z_i;
+// }
+ }
+
+ public static int compare(int len, int[] x, int[] y)
+ {
+ for (int i = len - 1; i >= 0; --i)
+ {
+ int x_i = x[i] ^ Integer.MIN_VALUE;
+ int y_i = y[i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return -1;
+ if (x_i > y_i)
+ return 1;
+ }
+ return 0;
+ }
+
+ public static int compare(int len, int[] x, int xOff, int[] y, int yOff)
+ {
+ for (int i = len - 1; i >= 0; --i)
+ {
+ int x_i = x[xOff + i] ^ Integer.MIN_VALUE;
+ int y_i = y[yOff + i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return -1;
+ if (x_i > y_i)
+ return 1;
+ }
+ return 0;
+ }
+
+ public static int[] copy(int len, int[] x)
+ {
+ int[] z = new int[len];
+ System.arraycopy(x, 0, z, 0, len);
+ return z;
+ }
+
+ public static void copy(int len, int[] x, int[] z)
+ {
+ System.arraycopy(x, 0, z, 0, len);
+ }
+
+ public static void copy(int len, int[] x, int xOff, int[] z, int zOff)
+ {
+ System.arraycopy(x, xOff, z, zOff, len);
+ }
+
+ public static long[] copy64(int len, long[] x)
+ {
+ long[] z = new long[len];
+ System.arraycopy(x, 0, z, 0, len);
+ return z;
+ }
+
+ public static void copy64(int len, long[] x, long[] z)
+ {
+ System.arraycopy(x, 0, z, 0, len);
+ }
+
+ public static void copy64(int len, long[] x, int xOff, long[] z, int zOff)
+ {
+ System.arraycopy(x, xOff, z, zOff, len);
+ }
+
+ public static int[] create(int len)
+ {
+ return new int[len];
+ }
+
+ public static long[] create64(int len)
+ {
+ return new long[len];
+ }
+
+ public static int csub(int len, int mask, int[] x, int[] y, int[] z)
+ {
+ long MASK = -(mask & 1) & M;
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[i] & M) - (y[i] & MASK);
+ z[i] = (int)c;
+ c >>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int csub(int len, int mask, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long MASK = -(mask & 1) & M;
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[xOff + i] & M) - (y[yOff + i] & MASK);
+ z[zOff + i] = (int)c;
+ c >>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int dec(int len, int[] z)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ if (--z[i] != -1)
+ {
+ return 0;
+ }
+ }
+ return -1;
+ }
+
+ public static int dec(int len, int[] x, int[] z)
+ {
+ int i = 0;
+ while (i < len)
+ {
+ int c = x[i] - 1;
+ z[i] = c;
+ ++i;
+ if (c != -1)
+ {
+ while (i < len)
+ {
+ z[i] = x[i];
+ ++i;
+ }
+ return 0;
+ }
+ }
+ return -1;
+ }
+
+ public static int decAt(int len, int[] z, int zPos)
+ {
+ // assert zPos <= len;
+ for (int i = zPos; i < len; ++i)
+ {
+ if (--z[i] != -1)
+ {
+ return 0;
+ }
+ }
+ return -1;
+ }
+
+ public static int decAt(int len, int[] z, int zOff, int zPos)
+ {
+ // assert zPos <= len;
+ for (int i = zPos; i < len; ++i)
+ {
+ if (--z[zOff + i] != -1)
+ {
+ return 0;
+ }
+ }
+ return -1;
+ }
+
+ public static boolean diff(int len, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ boolean pos = gte(len, x, xOff, y, yOff);
+ if (pos)
+ {
+ sub(len, x, xOff, y, yOff, z, zOff);
+ }
+ else
+ {
+ sub(len, y, yOff, x, xOff, z, zOff);
+ }
+ return pos;
+ }
+
+ public static boolean eq(int len, int[] x, int[] y)
+ {
+ for (int i = len - 1; i >= 0; --i)
+ {
+ if (x[i] != y[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static int equalTo(int len, int[] x, int y)
+ {
+ int d = x[0] ^ y;
+ for (int i = 1; i < len; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalTo(int len, int[] x, int xOff, int y)
+ {
+ int d = x[xOff] ^ y;
+ for (int i = 1; i < len; ++i)
+ {
+ d |= x[xOff + i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalTo(int len, int[] x, int[] y)
+ {
+ int d = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ d |= x[i] ^ y[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalTo(int len, int[] x, int xOff, int[] y, int yOff)
+ {
+ int d = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ d |= x[xOff + i] ^ y[yOff + i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalToZero(int len, int[] x)
+ {
+ int d = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int equalToZero(int len, int[] x, int xOff)
+ {
+ int d = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ d |= x[xOff + i];
+ }
+ d = (d >>> 1) | (d & 1);
+ return (d - 1) >> 31;
+ }
+
+ public static int[] fromBigInteger(int bits, BigInteger x)
+ {
+ if (x.signum() < 0 || x.bitLength() > bits)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ int len = (bits + 31) >> 5;
+ int[] z = create(len);
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < len; ++i)
+ {
+ z[i] = x.intValue();
+ x = x.shiftRight(32);
+ }
+ return z;
+ }
+
+ public static long[] fromBigInteger64(int bits, BigInteger x)
+ {
+ if (x.signum() < 0 || x.bitLength() > bits)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ int len = (bits + 63) >> 6;
+ long[] z = create64(len);
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < len; ++i)
+ {
+ z[i] = x.longValue();
+ x = x.shiftRight(64);
+ }
+ return z;
+ }
+
+ public static int getBit(int[] x, int bit)
+ {
+ if (bit == 0)
+ {
+ return x[0] & 1;
+ }
+ int w = bit >> 5;
+ if (w < 0 || w >= x.length)
+ {
+ return 0;
+ }
+ int b = bit & 31;
+ return (x[w] >>> b) & 1;
+ }
+
+ public static boolean gte(int len, int[] x, int[] y)
+ {
+ for (int i = len - 1; i >= 0; --i)
+ {
+ int x_i = x[i] ^ Integer.MIN_VALUE;
+ int y_i = y[i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return false;
+ if (x_i > y_i)
+ return true;
+ }
+ return true;
+ }
+
+ public static boolean gte(int len, int[] x, int xOff, int[] y, int yOff)
+ {
+ for (int i = len - 1; i >= 0; --i)
+ {
+ int x_i = x[xOff + i] ^ Integer.MIN_VALUE;
+ int y_i = y[yOff + i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return false;
+ if (x_i > y_i)
+ return true;
+ }
+ return true;
+ }
+
+ public static int inc(int len, int[] z)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ if (++z[i] != 0)
+ {
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+ public static int inc(int len, int[] x, int[] z)
+ {
+ int i = 0;
+ while (i < len)
+ {
+ int c = x[i] + 1;
+ z[i] = c;
+ ++i;
+ if (c != 0)
+ {
+ while (i < len)
+ {
+ z[i] = x[i];
+ ++i;
+ }
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+ public static int incAt(int len, int[] z, int zPos)
+ {
+ // assert zPos <= len;
+ for (int i = zPos; i < len; ++i)
+ {
+ if (++z[i] != 0)
+ {
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+ public static int incAt(int len, int[] z, int zOff, int zPos)
+ {
+ // assert zPos <= len;
+ for (int i = zPos; i < len; ++i)
+ {
+ if (++z[zOff + i] != 0)
+ {
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+ public static boolean isOne(int len, int[] x)
+ {
+ if (x[0] != 1)
+ {
+ return false;
+ }
+ for (int i = 1; i < len; ++i)
+ {
+ if (x[i] != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean isZero(int len, int[] x)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ if (x[i] != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static int lessThan(int len, int[] x, int[] y)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[i] & M) - (y[i] & M);
+ c >>= 32;
+ }
+// assert c == 0L || c == -1L;
+ return (int)c;
+ }
+
+ public static int lessThan(int len, int[] x, int xOff, int[] y, int yOff)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[xOff + i] & M) - (y[yOff + i] & M);
+ c >>= 32;
+ }
+// assert c == 0L || c == -1L;
+ return (int)c;
+ }
+
+ public static void mul(int len, int[] x, int[] y, int[] zz)
+ {
+ zz[len] = mulWord(len, x[0], y, zz);
+
+ for (int i = 1; i < len; ++i)
+ {
+ zz[i + len] = mulWordAddTo(len, x[i], y, 0, zz, i);
+ }
+ }
+
+ public static void mul(int len, int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
+ {
+ zz[zzOff + len] = mulWord(len, x[xOff], y, yOff, zz, zzOff);
+
+ for (int i = 1; i < len; ++i)
+ {
+ zz[zzOff + i + len] = mulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff + i);
+ }
+ }
+
+ public static void mul(int[] x, int xOff, int xLen, int[] y, int yOff, int yLen, int[] zz, int zzOff)
+ {
+ zz[zzOff + yLen] = mulWord(yLen, x[xOff], y, yOff, zz, zzOff);
+
+ for (int i = 1; i < xLen; ++i)
+ {
+ zz[zzOff + i + yLen] = mulWordAddTo(yLen, x[xOff + i], y, yOff, zz, zzOff + i);
+ }
+ }
+
+ public static int mulAddTo(int len, int[] x, int[] y, int[] zz)
+ {
+ long zc = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ zc += mulWordAddTo(len, x[i], y, 0, zz, i) & M;
+ zc += zz[i + len] & M;
+ zz[i + len] = (int)zc;
+ zc >>>= 32;
+ }
+ return (int)zc;
+ }
+
+ public static int mulAddTo(int len, int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
+ {
+ long zc = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ zc += mulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff) & M;
+ zc += zz[zzOff + len] & M;
+ zz[zzOff + len] = (int)zc;
+ zc >>>= 32;
+ ++zzOff;
+ }
+ return (int)zc;
+ }
+
+ public static int mul31BothAdd(int len, int a, int[] x, int b, int[] y, int[] z, int zOff)
+ {
+ long c = 0, aVal = a & M, bVal = b & M;
+ int i = 0;
+ do
+ {
+ c += aVal * (x[i] & M) + bVal * (y[i] & M) + (z[zOff + i] & M);
+ z[zOff + i] = (int)c;
+ c >>>= 32;
+ }
+ while (++i < len);
+ return (int)c;
+ }
+
+ public static int mulWord(int len, int x, int[] y, int[] z)
+ {
+ long c = 0, xVal = x & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (y[i] & M);
+ z[i] = (int)c;
+ c >>>= 32;
+ }
+ while (++i < len);
+ return (int)c;
+ }
+
+ public static int mulWord(int len, int x, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0, xVal = x & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (y[yOff + i] & M);
+ z[zOff + i] = (int)c;
+ c >>>= 32;
+ }
+ while (++i < len);
+ return (int)c;
+ }
+
+ public static int mulWordAddTo(int len, int x, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0, xVal = x & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (y[yOff + i] & M) + (z[zOff + i] & M);
+ z[zOff + i] = (int)c;
+ c >>>= 32;
+ }
+ while (++i < len);
+ return (int)c;
+ }
+
+ public static int mulWordDwordAddAt(int len, int x, long y, int[] z, int zPos)
+ {
+ // assert zPos <= (len - 3);
+ long c = 0, xVal = x & M;
+ c += xVal * (y & M) + (z[zPos + 0] & M);
+ z[zPos + 0] = (int)c;
+ c >>>= 32;
+ c += xVal * (y >>> 32) + (z[zPos + 1] & M);
+ z[zPos + 1] = (int)c;
+ c >>>= 32;
+ c += (z[zPos + 2] & M);
+ z[zPos + 2] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : incAt(len, z, zPos + 3);
+ }
+
+ public static int shiftDownBit(int len, int[] z, int c)
+ {
+ int i = len;
+ while (--i >= 0)
+ {
+ int next = z[i];
+ z[i] = (next >>> 1) | (c << 31);
+ c = next;
+ }
+ return c << 31;
+ }
+
+ public static int shiftDownBit(int len, int[] z, int zOff, int c)
+ {
+ int i = len;
+ while (--i >= 0)
+ {
+ int next = z[zOff + i];
+ z[zOff + i] = (next >>> 1) | (c << 31);
+ c = next;
+ }
+ return c << 31;
+ }
+
+ public static int shiftDownBit(int len, int[] x, int c, int[] z)
+ {
+ int i = len;
+ while (--i >= 0)
+ {
+ int next = x[i];
+ z[i] = (next >>> 1) | (c << 31);
+ c = next;
+ }
+ return c << 31;
+ }
+
+ public static int shiftDownBit(int len, int[] x, int xOff, int c, int[] z, int zOff)
+ {
+ int i = len;
+ while (--i >= 0)
+ {
+ int next = x[xOff + i];
+ z[zOff + i] = (next >>> 1) | (c << 31);
+ c = next;
+ }
+ return c << 31;
+ }
+
+ public static int shiftDownBits(int len, int[] z, int bits, int c)
+ {
+// assert bits > 0 && bits < 32;
+ int i = len;
+ while (--i >= 0)
+ {
+ int next = z[i];
+ z[i] = (next >>> bits) | (c << -bits);
+ c = next;
+ }
+ return c << -bits;
+ }
+
+ public static int shiftDownBits(int len, int[] z, int zOff, int bits, int c)
+ {
+// assert bits > 0 && bits < 32;
+ int i = len;
+ while (--i >= 0)
+ {
+ int next = z[zOff + i];
+ z[zOff + i] = (next >>> bits) | (c << -bits);
+ c = next;
+ }
+ return c << -bits;
+ }
+
+ public static int shiftDownBits(int len, int[] x, int bits, int c, int[] z)
+ {
+// assert bits > 0 && bits < 32;
+ int i = len;
+ while (--i >= 0)
+ {
+ int next = x[i];
+ z[i] = (next >>> bits) | (c << -bits);
+ c = next;
+ }
+ return c << -bits;
+ }
+
+ public static int shiftDownBits(int len, int[] x, int xOff, int bits, int c, int[] z, int zOff)
+ {
+// assert bits > 0 && bits < 32;
+ int i = len;
+ while (--i >= 0)
+ {
+ int next = x[xOff + i];
+ z[zOff + i] = (next >>> bits) | (c << -bits);
+ c = next;
+ }
+ return c << -bits;
+ }
+
+ public static int shiftDownWord(int len, int[] z, int c)
+ {
+ int i = len;
+ while (--i >= 0)
+ {
+ int next = z[i];
+ z[i] = c;
+ c = next;
+ }
+ return c;
+ }
+
+ public static int shiftUpBit(int len, int[] z, int c)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ int next = z[i];
+ z[i] = (next << 1) | (c >>> 31);
+ c = next;
+ }
+ return c >>> 31;
+ }
+
+ public static int shiftUpBit(int len, int[] z, int zOff, int c)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ int next = z[zOff + i];
+ z[zOff + i] = (next << 1) | (c >>> 31);
+ c = next;
+ }
+ return c >>> 31;
+ }
+
+ public static int shiftUpBit(int len, int[] x, int c, int[] z)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ int next = x[i];
+ z[i] = (next << 1) | (c >>> 31);
+ c = next;
+ }
+ return c >>> 31;
+ }
+
+ public static int shiftUpBit(int len, int[] x, int xOff, int c, int[] z, int zOff)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ int next = x[xOff + i];
+ z[zOff + i] = (next << 1) | (c >>> 31);
+ c = next;
+ }
+ return c >>> 31;
+ }
+
+ public static long shiftUpBit64(int len, long[] x, int xOff, long c, long[] z, int zOff)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ long next = x[xOff + i];
+ z[zOff + i] = (next << 1) | (c >>> 63);
+ c = next;
+ }
+ return c >>> 63;
+ }
+
+ public static int shiftUpBits(int len, int[] z, int bits, int c)
+ {
+// assert bits > 0 && bits < 32;
+ for (int i = 0; i < len; ++i)
+ {
+ int next = z[i];
+ z[i] = (next << bits) | (c >>> -bits);
+ c = next;
+ }
+ return c >>> -bits;
+ }
+
+ public static int shiftUpBits(int len, int[] z, int zOff, int bits, int c)
+ {
+// assert bits > 0 && bits < 32;
+ for (int i = 0; i < len; ++i)
+ {
+ int next = z[zOff + i];
+ z[zOff + i] = (next << bits) | (c >>> -bits);
+ c = next;
+ }
+ return c >>> -bits;
+ }
+
+ public static long shiftUpBits64(int len, long[] z, int zOff, int bits, long c)
+ {
+// assert bits > 0 && bits < 64;
+ for (int i = 0; i < len; ++i)
+ {
+ long next = z[zOff + i];
+ z[zOff + i] = (next << bits) | (c >>> -bits);
+ c = next;
+ }
+ return c >>> -bits;
+ }
+
+ public static int shiftUpBits(int len, int[] x, int bits, int c, int[] z)
+ {
+// assert bits > 0 && bits < 32;
+ for (int i = 0; i < len; ++i)
+ {
+ int next = x[i];
+ z[i] = (next << bits) | (c >>> -bits);
+ c = next;
+ }
+ return c >>> -bits;
+ }
+
+ public static int shiftUpBits(int len, int[] x, int xOff, int bits, int c, int[] z, int zOff)
+ {
+// assert bits > 0 && bits < 32;
+ for (int i = 0; i < len; ++i)
+ {
+ int next = x[xOff + i];
+ z[zOff + i] = (next << bits) | (c >>> -bits);
+ c = next;
+ }
+ return c >>> -bits;
+ }
+
+ public static long shiftUpBits64(int len, long[] x, int xOff, int bits, long c, long[] z, int zOff)
+ {
+// assert bits > 0 && bits < 64;
+ for (int i = 0; i < len; ++i)
+ {
+ long next = x[xOff + i];
+ z[zOff + i] = (next << bits) | (c >>> -bits);
+ c = next;
+ }
+ return c >>> -bits;
+ }
+
+ public static void square(int len, int[] x, int[] zz)
+ {
+ int extLen = len << 1;
+ int c = 0;
+ int j = len, k = extLen;
+ do
+ {
+ long xVal = (x[--j] & M);
+ long p = xVal * xVal;
+ zz[--k] = (c << 31) | (int)(p >>> 33);
+ zz[--k] = (int)(p >>> 1);
+ c = (int)p;
+ }
+ while (j > 0);
+
+ long d = 0L;
+ int zzPos = 2;
+
+ for (int i = 1; i < len; ++i)
+ {
+ d += squareWordAddTo(x, i, zz) & M;
+ d += zz[zzPos] & M;
+ zz[zzPos++] = (int)d; d >>>= 32;
+ d += zz[zzPos] & M;
+ zz[zzPos++] = (int)d; d >>>= 32;
+ }
+// assert 0L == d;
+
+ shiftUpBit(extLen, zz, x[0] << 31);
+ }
+
+ public static void square(int len, int[] x, int xOff, int[] zz, int zzOff)
+ {
+ int extLen = len << 1;
+ int c = 0;
+ int j = len, k = extLen;
+ do
+ {
+ long xVal = (x[xOff + --j] & M);
+ long p = xVal * xVal;
+ zz[zzOff + --k] = (c << 31) | (int)(p >>> 33);
+ zz[zzOff + --k] = (int)(p >>> 1);
+ c = (int)p;
+ }
+ while (j > 0);
+
+ long d = 0L;
+ int zzPos = zzOff + 2;
+
+ for (int i = 1; i < len; ++i)
+ {
+ d += squareWordAddTo(x, xOff, i, zz, zzOff) & M;
+ d += zz[zzPos] & M;
+ zz[zzPos++] = (int)d; d >>>= 32;
+ d += zz[zzPos] & M;
+ zz[zzPos++] = (int)d; d >>>= 32;
+ }
+// assert 0L == d;
+
+ shiftUpBit(extLen, zz, zzOff, x[xOff] << 31);
+ }
+
+ /**
+ * @deprecated Use {@link #squareWordAddTo(int[], int, int[])} instead.
+ */
+ public static int squareWordAdd(int[] x, int xPos, int[] z)
+ {
+ long c = 0, xVal = x[xPos] & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (x[i] & M) + (z[xPos + i] & M);
+ z[xPos + i] = (int)c;
+ c >>>= 32;
+ }
+ while (++i < xPos);
+ return (int)c;
+ }
+
+ /**
+ * @deprecated Use {@link #squareWordAddTo(int[], int, int, int[], int)} instead.
+ */
+ public static int squareWordAdd(int[] x, int xOff, int xPos, int[] z, int zOff)
+ {
+ long c = 0, xVal = x[xOff + xPos] & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M);
+ z[xPos + zOff] = (int)c;
+ c >>>= 32;
+ ++zOff;
+ }
+ while (++i < xPos);
+ return (int)c;
+ }
+
+ public static int squareWordAddTo(int[] x, int xPos, int[] z)
+ {
+ long c = 0, xVal = x[xPos] & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (x[i] & M) + (z[xPos + i] & M);
+ z[xPos + i] = (int)c;
+ c >>>= 32;
+ }
+ while (++i < xPos);
+ return (int)c;
+ }
+
+ public static int squareWordAddTo(int[] x, int xOff, int xPos, int[] z, int zOff)
+ {
+ long c = 0, xVal = x[xOff + xPos] & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M);
+ z[xPos + zOff] = (int)c;
+ c >>>= 32;
+ ++zOff;
+ }
+ while (++i < xPos);
+ return (int)c;
+ }
+
+ public static int sub(int len, int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[i] & M) - (y[i] & M);
+ z[i] = (int)c;
+ c >>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int sub(int len, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (x[xOff + i] & M) - (y[yOff + i] & M);
+ z[zOff + i] = (int)c;
+ c >>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int sub33At(int len, int x, int[] z, int zPos)
+ {
+ // assert zPos <= (len - 2);
+ long c = (z[zPos + 0] & M) - (x & M);
+ z[zPos + 0] = (int)c;
+ c >>= 32;
+ c += (z[zPos + 1] & M) - 1;
+ z[zPos + 1] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : decAt(len, z, zPos + 2);
+ }
+
+ public static int sub33At(int len, int x, int[] z, int zOff, int zPos)
+ {
+ // assert zPos <= (len - 2);
+ long c = (z[zOff + zPos] & M) - (x & M);
+ z[zOff + zPos] = (int)c;
+ c >>= 32;
+ c += (z[zOff + zPos + 1] & M) - 1;
+ z[zOff + zPos + 1] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : decAt(len, z, zOff, zPos + 2);
+ }
+
+ public static int sub33From(int len, int x, int[] z)
+ {
+ long c = (z[0] & M) - (x & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M) - 1;
+ z[1] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : decAt(len, z, 2);
+ }
+
+ public static int sub33From(int len, int x, int[] z, int zOff)
+ {
+ long c = (z[zOff + 0] & M) - (x & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 1] & M) - 1;
+ z[zOff + 1] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : decAt(len, z, zOff, 2);
+ }
+
+ public static int subBothFrom(int len, int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (z[i] & M) - (x[i] & M) - (y[i] & M);
+ z[i] = (int)c;
+ c >>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int subBothFrom(int len, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (z[zOff + i] & M) - (x[xOff + i] & M) - (y[yOff + i] & M);
+ z[zOff + i] = (int)c;
+ c >>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int subDWordAt(int len, long x, int[] z, int zPos)
+ {
+ // assert zPos <= (len - 2);
+ long c = (z[zPos + 0] & M) - (x & M);
+ z[zPos + 0] = (int)c;
+ c >>= 32;
+ c += (z[zPos + 1] & M) - (x >>> 32);
+ z[zPos + 1] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : decAt(len, z, zPos + 2);
+ }
+
+ public static int subDWordAt(int len, long x, int[] z, int zOff, int zPos)
+ {
+ // assert zPos <= (len - 2);
+ long c = (z[zOff + zPos] & M) - (x & M);
+ z[zOff + zPos] = (int)c;
+ c >>= 32;
+ c += (z[zOff + zPos + 1] & M) - (x >>> 32);
+ z[zOff + zPos + 1] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : decAt(len, z, zOff, zPos + 2);
+ }
+
+ public static int subDWordFrom(int len, long x, int[] z)
+ {
+ long c = (z[0] & M) - (x & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M) - (x >>> 32);
+ z[1] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : decAt(len, z, 2);
+ }
+
+ public static int subDWordFrom(int len, long x, int[] z, int zOff)
+ {
+ long c = (z[zOff + 0] & M) - (x & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 1] & M) - (x >>> 32);
+ z[zOff + 1] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : decAt(len, z, zOff, 2);
+ }
+
+ public static int subFrom(int len, int[] x, int[] z)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (z[i] & M) - (x[i] & M);
+ z[i] = (int)c;
+ c >>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int subFrom(int len, int[] x, int xOff, int[] z, int zOff)
+ {
+ long c = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ c += (z[zOff + i] & M) - (x[xOff + i] & M);
+ z[zOff + i] = (int)c;
+ c >>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int subWordAt(int len, int x, int[] z, int zPos)
+ {
+ // assert zPos <= (len - 1);
+ long c = (z[zPos] & M) - (x & M);
+ z[zPos] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : decAt(len, z, zPos + 1);
+ }
+
+ public static int subWordAt(int len, int x, int[] z, int zOff, int zPos)
+ {
+ // assert zPos <= (len - 1);
+ long c = (z[zOff + zPos] & M) - (x & M);
+ z[zOff + zPos] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : decAt(len, z, zOff, zPos + 1);
+ }
+
+ public static int subWordFrom(int len, int x, int[] z)
+ {
+ long c = (z[0] & M) - (x & M);
+ z[0] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : decAt(len, z, 1);
+ }
+
+ public static int subWordFrom(int len, int x, int[] z, int zOff)
+ {
+ long c = (z[zOff + 0] & M) - (x & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : decAt(len, z, zOff, 1);
+ }
+
+ public static BigInteger toBigInteger(int len, int[] x)
+ {
+ byte[] bs = new byte[len << 2];
+ for (int i = 0; i < len; ++i)
+ {
+ int x_i = x[i];
+ if (x_i != 0)
+ {
+ Pack.intToBigEndian(x_i, bs, (len - 1 - i) << 2);
+ }
+ }
+ return new BigInteger(1, bs);
+ }
+
+ public static void zero(int len, int[] z)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[i] = 0;
+ }
+ }
+
+ public static void zero(int len, int[] z, int zOff)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[zOff + i] = 0;
+ }
+ }
+
+ public static void zero64(int len, long[] z)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ z[i] = 0L;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat192.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat192.java
new file mode 100644
index 00000000..2931d21d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat192.java
@@ -0,0 +1,1081 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.raw;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class Nat192
+{
+ private static final long M = 0xFFFFFFFFL;
+
+ public static int add(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) + (y[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (y[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (y[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (y[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (y[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (y[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addBothTo(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) + (y[0] & M) + (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (y[1] & M) + (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (y[2] & M) + (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (y[3] & M) + (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (y[4] & M) + (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (y[5] & M) + (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addTo(int[] x, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) + (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn)
+ {
+ long c = cIn & M;
+ c += (x[xOff + 0] & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 1] & M) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 2] & M) + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 3] & M) + (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 4] & M) + (z[zOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 5] & M) + (z[zOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addToEachOther(int[] u, int uOff, int[] v, int vOff)
+ {
+ long c = 0;
+ c += (u[uOff + 0] & M) + (v[vOff + 0] & M);
+ u[uOff + 0] = (int)c;
+ v[vOff + 0] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 1] & M) + (v[vOff + 1] & M);
+ u[uOff + 1] = (int)c;
+ v[vOff + 1] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 2] & M) + (v[vOff + 2] & M);
+ u[uOff + 2] = (int)c;
+ v[vOff + 2] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 3] & M) + (v[vOff + 3] & M);
+ u[uOff + 3] = (int)c;
+ v[vOff + 3] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 4] & M) + (v[vOff + 4] & M);
+ u[uOff + 4] = (int)c;
+ v[vOff + 4] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 5] & M) + (v[vOff + 5] & M);
+ u[uOff + 5] = (int)c;
+ v[vOff + 5] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static void copy(int[] x, int[] z)
+ {
+ z[0] = x[0];
+ z[1] = x[1];
+ z[2] = x[2];
+ z[3] = x[3];
+ z[4] = x[4];
+ z[5] = x[5];
+ }
+
+ public static void copy(int[] x, int xOff, int[] z, int zOff)
+ {
+ z[zOff + 0] = x[xOff + 0];
+ z[zOff + 1] = x[xOff + 1];
+ z[zOff + 2] = x[xOff + 2];
+ z[zOff + 3] = x[xOff + 3];
+ z[zOff + 4] = x[xOff + 4];
+ z[zOff + 5] = x[xOff + 5];
+ }
+
+ public static void copy64(long[] x, long[] z)
+ {
+ z[0] = x[0];
+ z[1] = x[1];
+ z[2] = x[2];
+ }
+
+ public static void copy64(long[] x, int xOff, long[] z, int zOff)
+ {
+ z[zOff + 0] = x[xOff + 0];
+ z[zOff + 1] = x[xOff + 1];
+ z[zOff + 2] = x[xOff + 2];
+ }
+
+ public static int[] create()
+ {
+ return new int[6];
+ }
+
+ public static long[] create64()
+ {
+ return new long[3];
+ }
+
+ public static int[] createExt()
+ {
+ return new int[12];
+ }
+
+ public static long[] createExt64()
+ {
+ return new long[6];
+ }
+
+ public static boolean diff(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ boolean pos = gte(x, xOff, y, yOff);
+ if (pos)
+ {
+ sub(x, xOff, y, yOff, z, zOff);
+ }
+ else
+ {
+ sub(y, yOff, x, xOff, z, zOff);
+ }
+ return pos;
+ }
+
+ public static boolean eq(int[] x, int[] y)
+ {
+ for (int i = 5; i >= 0; --i)
+ {
+ if (x[i] != y[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean eq64(long[] x, long[] y)
+ {
+ for (int i = 2; i >= 0; --i)
+ {
+ if (x[i] != y[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ if (x.signum() < 0 || x.bitLength() > 192)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ int[] z = create();
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 6; ++i)
+ {
+ z[i] = x.intValue();
+ x = x.shiftRight(32);
+ }
+ return z;
+ }
+
+ public static long[] fromBigInteger64(BigInteger x)
+ {
+ if (x.signum() < 0 || x.bitLength() > 192)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ long[] z = create64();
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 3; ++i)
+ {
+ z[i] = x.longValue();
+ x = x.shiftRight(64);
+ }
+ return z;
+ }
+
+ public static int getBit(int[] x, int bit)
+ {
+ if (bit == 0)
+ {
+ return x[0] & 1;
+ }
+ int w = bit >> 5;
+ if (w < 0 || w >= 6)
+ {
+ return 0;
+ }
+ int b = bit & 31;
+ return (x[w] >>> b) & 1;
+ }
+
+ public static boolean gte(int[] x, int[] y)
+ {
+ for (int i = 5; i >= 0; --i)
+ {
+ int x_i = x[i] ^ Integer.MIN_VALUE;
+ int y_i = y[i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return false;
+ if (x_i > y_i)
+ return true;
+ }
+ return true;
+ }
+
+ public static boolean gte(int[] x, int xOff, int[] y, int yOff)
+ {
+ for (int i = 5; i >= 0; --i)
+ {
+ int x_i = x[xOff + i] ^ Integer.MIN_VALUE;
+ int y_i = y[yOff + i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return false;
+ if (x_i > y_i)
+ return true;
+ }
+ return true;
+ }
+
+ public static boolean isOne(int[] x)
+ {
+ if (x[0] != 1)
+ {
+ return false;
+ }
+ for (int i = 1; i < 6; ++i)
+ {
+ if (x[i] != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean isOne64(long[] x)
+ {
+ if (x[0] != 1L)
+ {
+ return false;
+ }
+ for (int i = 1; i < 3; ++i)
+ {
+ if (x[i] != 0L)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean isZero(int[] x)
+ {
+ for (int i = 0; i < 6; ++i)
+ {
+ if (x[i] != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean isZero64(long[] x)
+ {
+ for (int i = 0; i < 3; ++i)
+ {
+ if (x[i] != 0L)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static void mul(int[] x, int[] y, int[] zz)
+ {
+ long y_0 = y[0] & M;
+ long y_1 = y[1] & M;
+ long y_2 = y[2] & M;
+ long y_3 = y[3] & M;
+ long y_4 = y[4] & M;
+ long y_5 = y[5] & M;
+
+ {
+ long c = 0, x_0 = x[0] & M;
+ c += x_0 * y_0;
+ zz[0] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_1;
+ zz[1] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_2;
+ zz[2] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_3;
+ zz[3] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_4;
+ zz[4] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_5;
+ zz[5] = (int)c;
+ c >>>= 32;
+ zz[6] = (int)c;
+ }
+
+ for (int i = 1; i < 6; ++i)
+ {
+ long c = 0, x_i = x[i] & M;
+ c += x_i * y_0 + (zz[i + 0] & M);
+ zz[i + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[i + 1] & M);
+ zz[i + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[i + 2] & M);
+ zz[i + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[i + 3] & M);
+ zz[i + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[i + 4] & M);
+ zz[i + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[i + 5] & M);
+ zz[i + 5] = (int)c;
+ c >>>= 32;
+ zz[i + 6] = (int)c;
+ }
+ }
+
+ public static void mul(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
+ {
+ long y_0 = y[yOff + 0] & M;
+ long y_1 = y[yOff + 1] & M;
+ long y_2 = y[yOff + 2] & M;
+ long y_3 = y[yOff + 3] & M;
+ long y_4 = y[yOff + 4] & M;
+ long y_5 = y[yOff + 5] & M;
+
+ {
+ long c = 0, x_0 = x[xOff + 0] & M;
+ c += x_0 * y_0;
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_1;
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_2;
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_3;
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_4;
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_5;
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+ zz[zzOff + 6] = (int)c;
+ }
+
+ for (int i = 1; i < 6; ++i)
+ {
+ ++zzOff;
+ long c = 0, x_i = x[xOff + i] & M;
+ c += x_i * y_0 + (zz[zzOff + 0] & M);
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[zzOff + 1] & M);
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[zzOff + 2] & M);
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[zzOff + 3] & M);
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[zzOff + 4] & M);
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[zzOff + 5] & M);
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+ zz[zzOff + 6] = (int)c;
+ }
+ }
+
+ public static int mulAddTo(int[] x, int[] y, int[] zz)
+ {
+ long y_0 = y[0] & M;
+ long y_1 = y[1] & M;
+ long y_2 = y[2] & M;
+ long y_3 = y[3] & M;
+ long y_4 = y[4] & M;
+ long y_5 = y[5] & M;
+
+ long zc = 0;
+ for (int i = 0; i < 6; ++i)
+ {
+ long c = 0, x_i = x[i] & M;
+ c += x_i * y_0 + (zz[i + 0] & M);
+ zz[i + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[i + 1] & M);
+ zz[i + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[i + 2] & M);
+ zz[i + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[i + 3] & M);
+ zz[i + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[i + 4] & M);
+ zz[i + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[i + 5] & M);
+ zz[i + 5] = (int)c;
+ c >>>= 32;
+
+ zc += c + (zz[i + 6] & M);
+ zz[i + 6] = (int)zc;
+ zc >>>= 32;
+ }
+ return (int)zc;
+ }
+
+ public static int mulAddTo(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
+ {
+ long y_0 = y[yOff + 0] & M;
+ long y_1 = y[yOff + 1] & M;
+ long y_2 = y[yOff + 2] & M;
+ long y_3 = y[yOff + 3] & M;
+ long y_4 = y[yOff + 4] & M;
+ long y_5 = y[yOff + 5] & M;
+
+ long zc = 0;
+ for (int i = 0; i < 6; ++i)
+ {
+ long c = 0, x_i = x[xOff + i] & M;
+ c += x_i * y_0 + (zz[zzOff + 0] & M);
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[zzOff + 1] & M);
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[zzOff + 2] & M);
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[zzOff + 3] & M);
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[zzOff + 4] & M);
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[zzOff + 5] & M);
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+
+ zc += c + (zz[zzOff + 6] & M);
+ zz[zzOff + 6] = (int)zc;
+ zc >>>= 32;
+ ++zzOff;
+ }
+ return (int)zc;
+ }
+
+ public static long mul33Add(int w, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ // assert w >>> 31 == 0;
+
+ long c = 0, wVal = w & M;
+ long x0 = x[xOff + 0] & M;
+ c += wVal * x0 + (y[yOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ long x1 = x[xOff + 1] & M;
+ c += wVal * x1 + x0 + (y[yOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ long x2 = x[xOff + 2] & M;
+ c += wVal * x2 + x1 + (y[yOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ long x3 = x[xOff + 3] & M;
+ c += wVal * x3 + x2 + (y[yOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ long x4 = x[xOff + 4] & M;
+ c += wVal * x4 + x3 + (y[yOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ long x5 = x[xOff + 5] & M;
+ c += wVal * x5 + x4 + (y[yOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ c += x5;
+ return c;
+ }
+
+ public static int mulWordAddExt(int x, int[] yy, int yyOff, int[] zz, int zzOff)
+ {
+ // assert yyOff <= 6;
+ // assert zzOff <= 6;
+ long c = 0, xVal = x & M;
+ c += xVal * (yy[yyOff + 0] & M) + (zz[zzOff + 0] & M);
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += xVal * (yy[yyOff + 1] & M) + (zz[zzOff + 1] & M);
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += xVal * (yy[yyOff + 2] & M) + (zz[zzOff + 2] & M);
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += xVal * (yy[yyOff + 3] & M) + (zz[zzOff + 3] & M);
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += xVal * (yy[yyOff + 4] & M) + (zz[zzOff + 4] & M);
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += xVal * (yy[yyOff + 5] & M) + (zz[zzOff + 5] & M);
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int mul33DWordAdd(int x, long y, int[] z, int zOff)
+ {
+ // assert x >>> 31 == 0;
+ // assert zOff <= 2;
+
+ long c = 0, xVal = x & M;
+ long y00 = y & M;
+ c += xVal * y00 + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ long y01 = y >>> 32;
+ c += xVal * y01 + y00 + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += y01 + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : Nat.incAt(6, z, zOff, 4);
+ }
+
+ public static int mul33WordAdd(int x, int y, int[] z, int zOff)
+ {
+ // assert x >>> 31 == 0;
+ // assert zOff <= 3;
+
+ long c = 0, xVal = x & M, yVal = y & M;
+ c += yVal * xVal + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += yVal + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : Nat.incAt(6, z, zOff, 3);
+ }
+
+ public static int mulWordDwordAdd(int x, long y, int[] z, int zOff)
+ {
+ // assert zOff <= 3;
+ long c = 0, xVal = x & M;
+ c += xVal * (y & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += xVal * (y >>> 32) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : Nat.incAt(6, z, zOff, 3);
+ }
+
+ public static int mulWord(int x, int[] y, int[] z, int zOff)
+ {
+ long c = 0, xVal = x & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (y[i] & M);
+ z[zOff + i] = (int)c;
+ c >>>= 32;
+ }
+ while (++i < 6);
+ return (int)c;
+ }
+
+ public static void square(int[] x, int[] zz)
+ {
+ long x_0 = x[0] & M;
+ long zz_1;
+
+ int c = 0, w;
+ {
+ int i = 5, j = 12;
+ do
+ {
+ long xVal = (x[i--] & M);
+ long p = xVal * xVal;
+ zz[--j] = (c << 31) | (int)(p >>> 33);
+ zz[--j] = (int)(p >>> 1);
+ c = (int)p;
+ }
+ while (i > 0);
+
+ {
+ long p = x_0 * x_0;
+ zz_1 = ((c << 31) & M) | (p >>> 33);
+ zz[0] = (int)p;
+ c = (int)(p >>> 32) & 1;
+ }
+ }
+
+ long x_1 = x[1] & M;
+ long zz_2 = zz[2] & M;
+
+ {
+ zz_1 += x_1 * x_0;
+ w = (int)zz_1;
+ zz[1] = (w << 1) | c;
+ c = w >>> 31;
+ zz_2 += zz_1 >>> 32;
+ }
+
+ long x_2 = x[2] & M;
+ long zz_3 = zz[3] & M;
+ long zz_4 = zz[4] & M;
+ {
+ zz_2 += x_2 * x_0;
+ w = (int)zz_2;
+ zz[2] = (w << 1) | c;
+ c = w >>> 31;
+ zz_3 += (zz_2 >>> 32) + x_2 * x_1;
+ zz_4 += zz_3 >>> 32;
+ zz_3 &= M;
+ }
+
+ long x_3 = x[3] & M;
+ long zz_5 = (zz[5] & M) + (zz_4 >>> 32); zz_4 &= M;
+ long zz_6 = (zz[6] & M) + (zz_5 >>> 32); zz_5 &= M;
+ {
+ zz_3 += x_3 * x_0;
+ w = (int)zz_3;
+ zz[3] = (w << 1) | c;
+ c = w >>> 31;
+ zz_4 += (zz_3 >>> 32) + x_3 * x_1;
+ zz_5 += (zz_4 >>> 32) + x_3 * x_2;
+ zz_4 &= M;
+ zz_6 += zz_5 >>> 32;
+ zz_5 &= M;
+ }
+
+ long x_4 = x[4] & M;
+ long zz_7 = (zz[7] & M) + (zz_6 >>> 32); zz_6 &= M;
+ long zz_8 = (zz[8] & M) + (zz_7 >>> 32); zz_7 &= M;
+ {
+ zz_4 += x_4 * x_0;
+ w = (int)zz_4;
+ zz[4] = (w << 1) | c;
+ c = w >>> 31;
+ zz_5 += (zz_4 >>> 32) + x_4 * x_1;
+ zz_6 += (zz_5 >>> 32) + x_4 * x_2;
+ zz_5 &= M;
+ zz_7 += (zz_6 >>> 32) + x_4 * x_3;
+ zz_6 &= M;
+ zz_8 += zz_7 >>> 32;
+ zz_7 &= M;
+ }
+
+ long x_5 = x[5] & M;
+ long zz_9 = (zz[9] & M) + (zz_8 >>> 32); zz_8 &= M;
+ long zz_10 = (zz[10] & M) + (zz_9 >>> 32); zz_9 &= M;
+ {
+ zz_5 += x_5 * x_0;
+ w = (int)zz_5;
+ zz[5] = (w << 1) | c;
+ c = w >>> 31;
+ zz_6 += (zz_5 >>> 32) + x_5 * x_1;
+ zz_7 += (zz_6 >>> 32) + x_5 * x_2;
+ zz_8 += (zz_7 >>> 32) + x_5 * x_3;
+ zz_9 += (zz_8 >>> 32) + x_5 * x_4;
+ zz_10 += zz_9 >>> 32;
+ }
+
+ w = (int)zz_6;
+ zz[6] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_7;
+ zz[7] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_8;
+ zz[8] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_9;
+ zz[9] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_10;
+ zz[10] = (w << 1) | c;
+ c = w >>> 31;
+ w = zz[11] + (int)(zz_10 >>> 32);
+ zz[11] = (w << 1) | c;
+ }
+
+ public static void square(int[] x, int xOff, int[] zz, int zzOff)
+ {
+ long x_0 = x[xOff + 0] & M;
+ long zz_1;
+
+ int c = 0, w;
+ {
+ int i = 5, j = 12;
+ do
+ {
+ long xVal = (x[xOff + i--] & M);
+ long p = xVal * xVal;
+ zz[zzOff + --j] = (c << 31) | (int)(p >>> 33);
+ zz[zzOff + --j] = (int)(p >>> 1);
+ c = (int)p;
+ }
+ while (i > 0);
+
+ {
+ long p = x_0 * x_0;
+ zz_1 = ((c << 31) & M) | (p >>> 33);
+ zz[zzOff + 0] = (int)p;
+ c = (int)(p >>> 32) & 1;
+ }
+ }
+
+ long x_1 = x[xOff + 1] & M;
+ long zz_2 = zz[zzOff + 2] & M;
+
+ {
+ zz_1 += x_1 * x_0;
+ w = (int)zz_1;
+ zz[zzOff + 1] = (w << 1) | c;
+ c = w >>> 31;
+ zz_2 += zz_1 >>> 32;
+ }
+
+ long x_2 = x[xOff + 2] & M;
+ long zz_3 = zz[zzOff + 3] & M;
+ long zz_4 = zz[zzOff + 4] & M;
+ {
+ zz_2 += x_2 * x_0;
+ w = (int)zz_2;
+ zz[zzOff + 2] = (w << 1) | c;
+ c = w >>> 31;
+ zz_3 += (zz_2 >>> 32) + x_2 * x_1;
+ zz_4 += zz_3 >>> 32;
+ zz_3 &= M;
+ }
+
+ long x_3 = x[xOff + 3] & M;
+ long zz_5 = (zz[zzOff + 5] & M) + (zz_4 >>> 32); zz_4 &= M;
+ long zz_6 = (zz[zzOff + 6] & M) + (zz_5 >>> 32); zz_5 &= M;
+ {
+ zz_3 += x_3 * x_0;
+ w = (int)zz_3;
+ zz[zzOff + 3] = (w << 1) | c;
+ c = w >>> 31;
+ zz_4 += (zz_3 >>> 32) + x_3 * x_1;
+ zz_5 += (zz_4 >>> 32) + x_3 * x_2;
+ zz_4 &= M;
+ zz_6 += zz_5 >>> 32;
+ zz_5 &= M;
+ }
+
+ long x_4 = x[xOff + 4] & M;
+ long zz_7 = (zz[zzOff + 7] & M) + (zz_6 >>> 32); zz_6 &= M;
+ long zz_8 = (zz[zzOff + 8] & M) + (zz_7 >>> 32); zz_7 &= M;
+ {
+ zz_4 += x_4 * x_0;
+ w = (int)zz_4;
+ zz[zzOff + 4] = (w << 1) | c;
+ c = w >>> 31;
+ zz_5 += (zz_4 >>> 32) + x_4 * x_1;
+ zz_6 += (zz_5 >>> 32) + x_4 * x_2;
+ zz_5 &= M;
+ zz_7 += (zz_6 >>> 32) + x_4 * x_3;
+ zz_6 &= M;
+ zz_8 += zz_7 >>> 32;
+ zz_7 &= M;
+ }
+
+ long x_5 = x[xOff + 5] & M;
+ long zz_9 = (zz[zzOff + 9] & M) + (zz_8 >>> 32); zz_8 &= M;
+ long zz_10 = (zz[zzOff + 10] & M) + (zz_9 >>> 32); zz_9 &= M;
+ {
+ zz_5 += x_5 * x_0;
+ w = (int)zz_5;
+ zz[zzOff + 5] = (w << 1) | c;
+ c = w >>> 31;
+ zz_6 += (zz_5 >>> 32) + x_5 * x_1;
+ zz_7 += (zz_6 >>> 32) + x_5 * x_2;
+ zz_8 += (zz_7 >>> 32) + x_5 * x_3;
+ zz_9 += (zz_8 >>> 32) + x_5 * x_4;
+ zz_10 += zz_9 >>> 32;
+ }
+
+ w = (int)zz_6;
+ zz[zzOff + 6] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_7;
+ zz[zzOff + 7] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_8;
+ zz[zzOff + 8] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_9;
+ zz[zzOff + 9] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_10;
+ zz[zzOff + 10] = (w << 1) | c;
+ c = w >>> 31;
+ w = zz[zzOff + 11] + (int)(zz_10 >>> 32);
+ zz[zzOff + 11] = (w << 1) | c;
+ }
+
+ public static int sub(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) - (y[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (x[1] & M) - (y[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (x[2] & M) - (y[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ c += (x[3] & M) - (y[3] & M);
+ z[3] = (int)c;
+ c >>= 32;
+ c += (x[4] & M) - (y[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (x[5] & M) - (y[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int sub(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0;
+ c += (x[xOff + 0] & M) - (y[yOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 1] & M) - (y[yOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 2] & M) - (y[yOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 3] & M) - (y[yOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 4] & M) - (y[yOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 5] & M) - (y[yOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int subBothFrom(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (z[0] & M) - (x[0] & M) - (y[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M) - (x[1] & M) - (y[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (z[2] & M) - (x[2] & M) - (y[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ c += (z[3] & M) - (x[3] & M) - (y[3] & M);
+ z[3] = (int)c;
+ c >>= 32;
+ c += (z[4] & M) - (x[4] & M) - (y[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (z[5] & M) - (x[5] & M) - (y[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int subFrom(int[] x, int[] z)
+ {
+ long c = 0;
+ c += (z[0] & M) - (x[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M) - (x[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (z[2] & M) - (x[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ c += (z[3] & M) - (x[3] & M);
+ z[3] = (int)c;
+ c >>= 32;
+ c += (z[4] & M) - (x[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (z[5] & M) - (x[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int subFrom(int[] x, int xOff, int[] z, int zOff)
+ {
+ long c = 0;
+ c += (z[zOff + 0] & M) - (x[xOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 1] & M) - (x[xOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 2] & M) - (x[xOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 3] & M) - (x[xOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 4] & M) - (x[xOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 5] & M) - (x[xOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static BigInteger toBigInteger(int[] x)
+ {
+ byte[] bs = new byte[24];
+ for (int i = 0; i < 6; ++i)
+ {
+ int x_i = x[i];
+ if (x_i != 0)
+ {
+ Pack.intToBigEndian(x_i, bs, (5 - i) << 2);
+ }
+ }
+ return new BigInteger(1, bs);
+ }
+
+ public static BigInteger toBigInteger64(long[] x)
+ {
+ byte[] bs = new byte[24];
+ for (int i = 0; i < 3; ++i)
+ {
+ long x_i = x[i];
+ if (x_i != 0L)
+ {
+ Pack.longToBigEndian(x_i, bs, (2 - i) << 3);
+ }
+ }
+ return new BigInteger(1, bs);
+ }
+
+ public static void zero(int[] z)
+ {
+ z[0] = 0;
+ z[1] = 0;
+ z[2] = 0;
+ z[3] = 0;
+ z[4] = 0;
+ z[5] = 0;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat224.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat224.java
new file mode 100644
index 00000000..8f8423df
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat224.java
@@ -0,0 +1,1200 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.raw;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class Nat224
+{
+ private static final long M = 0xFFFFFFFFL;
+
+ public static int add(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) + (y[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (y[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (y[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (y[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (y[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (y[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += (x[6] & M) + (y[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int add(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0;
+ c += (x[xOff + 0] & M) + (y[yOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 1] & M) + (y[yOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 2] & M) + (y[yOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 3] & M) + (y[yOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 4] & M) + (y[yOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 5] & M) + (y[yOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 6] & M) + (y[yOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addBothTo(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) + (y[0] & M) + (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (y[1] & M) + (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (y[2] & M) + (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (y[3] & M) + (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (y[4] & M) + (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (y[5] & M) + (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += (x[6] & M) + (y[6] & M) + (z[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addBothTo(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0;
+ c += (x[xOff + 0] & M) + (y[yOff + 0] & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 1] & M) + (y[yOff + 1] & M) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 2] & M) + (y[yOff + 2] & M) + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 3] & M) + (y[yOff + 3] & M) + (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 4] & M) + (y[yOff + 4] & M) + (z[zOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 5] & M) + (y[yOff + 5] & M) + (z[zOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 6] & M) + (y[yOff + 6] & M) + (z[zOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addTo(int[] x, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) + (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += (x[6] & M) + (z[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn)
+ {
+ long c = cIn & M;
+ c += (x[xOff + 0] & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 1] & M) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 2] & M) + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 3] & M) + (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 4] & M) + (z[zOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 5] & M) + (z[zOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 6] & M) + (z[zOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addToEachOther(int[] u, int uOff, int[] v, int vOff)
+ {
+ long c = 0;
+ c += (u[uOff + 0] & M) + (v[vOff + 0] & M);
+ u[uOff + 0] = (int)c;
+ v[vOff + 0] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 1] & M) + (v[vOff + 1] & M);
+ u[uOff + 1] = (int)c;
+ v[vOff + 1] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 2] & M) + (v[vOff + 2] & M);
+ u[uOff + 2] = (int)c;
+ v[vOff + 2] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 3] & M) + (v[vOff + 3] & M);
+ u[uOff + 3] = (int)c;
+ v[vOff + 3] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 4] & M) + (v[vOff + 4] & M);
+ u[uOff + 4] = (int)c;
+ v[vOff + 4] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 5] & M) + (v[vOff + 5] & M);
+ u[uOff + 5] = (int)c;
+ v[vOff + 5] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 6] & M) + (v[vOff + 6] & M);
+ u[uOff + 6] = (int)c;
+ v[vOff + 6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static void copy(int[] x, int[] z)
+ {
+ z[0] = x[0];
+ z[1] = x[1];
+ z[2] = x[2];
+ z[3] = x[3];
+ z[4] = x[4];
+ z[5] = x[5];
+ z[6] = x[6];
+ }
+
+ public static void copy(int[] x, int xOff, int[] z, int zOff)
+ {
+ z[zOff + 0] = x[xOff + 0];
+ z[zOff + 1] = x[xOff + 1];
+ z[zOff + 2] = x[xOff + 2];
+ z[zOff + 3] = x[xOff + 3];
+ z[zOff + 4] = x[xOff + 4];
+ z[zOff + 5] = x[xOff + 5];
+ z[zOff + 6] = x[xOff + 6];
+ }
+
+ public static int[] create()
+ {
+ return new int[7];
+ }
+
+ public static int[] createExt()
+ {
+ return new int[14];
+ }
+
+ public static boolean diff(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ boolean pos = gte(x, xOff, y, yOff);
+ if (pos)
+ {
+ sub(x, xOff, y, yOff, z, zOff);
+ }
+ else
+ {
+ sub(y, yOff, x, xOff, z, zOff);
+ }
+ return pos;
+ }
+
+ public static boolean eq(int[] x, int[] y)
+ {
+ for (int i = 6; i >= 0; --i)
+ {
+ if (x[i] != y[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ if (x.signum() < 0 || x.bitLength() > 224)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ int[] z = create();
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 7; ++i)
+ {
+ z[i] = x.intValue();
+ x = x.shiftRight(32);
+ }
+ return z;
+ }
+
+ public static int getBit(int[] x, int bit)
+ {
+ if (bit == 0)
+ {
+ return x[0] & 1;
+ }
+ int w = bit >> 5;
+ if (w < 0 || w >= 7)
+ {
+ return 0;
+ }
+ int b = bit & 31;
+ return (x[w] >>> b) & 1;
+ }
+
+ public static boolean gte(int[] x, int[] y)
+ {
+ for (int i = 6; i >= 0; --i)
+ {
+ int x_i = x[i] ^ Integer.MIN_VALUE;
+ int y_i = y[i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return false;
+ if (x_i > y_i)
+ return true;
+ }
+ return true;
+ }
+
+ public static boolean gte(int[] x, int xOff, int[] y, int yOff)
+ {
+ for (int i = 6; i >= 0; --i)
+ {
+ int x_i = x[xOff + i] ^ Integer.MIN_VALUE;
+ int y_i = y[yOff + i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return false;
+ if (x_i > y_i)
+ return true;
+ }
+ return true;
+ }
+
+ public static boolean isOne(int[] x)
+ {
+ if (x[0] != 1)
+ {
+ return false;
+ }
+ for (int i = 1; i < 7; ++i)
+ {
+ if (x[i] != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean isZero(int[] x)
+ {
+ for (int i = 0; i < 7; ++i)
+ {
+ if (x[i] != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static void mul(int[] x, int[] y, int[] zz)
+ {
+ long y_0 = y[0] & M;
+ long y_1 = y[1] & M;
+ long y_2 = y[2] & M;
+ long y_3 = y[3] & M;
+ long y_4 = y[4] & M;
+ long y_5 = y[5] & M;
+ long y_6 = y[6] & M;
+
+ {
+ long c = 0, x_0 = x[0] & M;
+ c += x_0 * y_0;
+ zz[0] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_1;
+ zz[1] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_2;
+ zz[2] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_3;
+ zz[3] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_4;
+ zz[4] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_5;
+ zz[5] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_6;
+ zz[6] = (int)c;
+ c >>>= 32;
+ zz[7] = (int)c;
+ }
+
+ for (int i = 1; i < 7; ++i)
+ {
+ long c = 0, x_i = x[i] & M;
+ c += x_i * y_0 + (zz[i + 0] & M);
+ zz[i + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[i + 1] & M);
+ zz[i + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[i + 2] & M);
+ zz[i + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[i + 3] & M);
+ zz[i + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[i + 4] & M);
+ zz[i + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[i + 5] & M);
+ zz[i + 5] = (int)c;
+ c >>>= 32;
+ c += x_i * y_6 + (zz[i + 6] & M);
+ zz[i + 6] = (int)c;
+ c >>>= 32;
+ zz[i + 7] = (int)c;
+ }
+ }
+
+ public static void mul(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
+ {
+ long y_0 = y[yOff + 0] & M;
+ long y_1 = y[yOff + 1] & M;
+ long y_2 = y[yOff + 2] & M;
+ long y_3 = y[yOff + 3] & M;
+ long y_4 = y[yOff + 4] & M;
+ long y_5 = y[yOff + 5] & M;
+ long y_6 = y[yOff + 6] & M;
+
+ {
+ long c = 0, x_0 = x[xOff + 0] & M;
+ c += x_0 * y_0;
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_1;
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_2;
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_3;
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_4;
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_5;
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_6;
+ zz[zzOff + 6] = (int)c;
+ c >>>= 32;
+ zz[zzOff + 7] = (int)c;
+ }
+
+ for (int i = 1; i < 7; ++i)
+ {
+ ++zzOff;
+ long c = 0, x_i = x[xOff + i] & M;
+ c += x_i * y_0 + (zz[zzOff + 0] & M);
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[zzOff + 1] & M);
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[zzOff + 2] & M);
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[zzOff + 3] & M);
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[zzOff + 4] & M);
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[zzOff + 5] & M);
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+ c += x_i * y_6 + (zz[zzOff + 6] & M);
+ zz[zzOff + 6] = (int)c;
+ c >>>= 32;
+ zz[zzOff + 7] = (int)c;
+ }
+ }
+
+ public static int mulAddTo(int[] x, int[] y, int[] zz)
+ {
+ long y_0 = y[0] & M;
+ long y_1 = y[1] & M;
+ long y_2 = y[2] & M;
+ long y_3 = y[3] & M;
+ long y_4 = y[4] & M;
+ long y_5 = y[5] & M;
+ long y_6 = y[6] & M;
+
+ long zc = 0;
+ for (int i = 0; i < 7; ++i)
+ {
+ long c = 0, x_i = x[i] & M;
+ c += x_i * y_0 + (zz[i + 0] & M);
+ zz[i + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[i + 1] & M);
+ zz[i + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[i + 2] & M);
+ zz[i + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[i + 3] & M);
+ zz[i + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[i + 4] & M);
+ zz[i + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[i + 5] & M);
+ zz[i + 5] = (int)c;
+ c >>>= 32;
+ c += x_i * y_6 + (zz[i + 6] & M);
+ zz[i + 6] = (int)c;
+ c >>>= 32;
+
+ zc += c + (zz[i + 7] & M);
+ zz[i + 7] = (int)zc;
+ zc >>>= 32;
+ }
+ return (int)zc;
+ }
+
+ public static int mulAddTo(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
+ {
+ long y_0 = y[yOff + 0] & M;
+ long y_1 = y[yOff + 1] & M;
+ long y_2 = y[yOff + 2] & M;
+ long y_3 = y[yOff + 3] & M;
+ long y_4 = y[yOff + 4] & M;
+ long y_5 = y[yOff + 5] & M;
+ long y_6 = y[yOff + 6] & M;
+
+ long zc = 0;
+ for (int i = 0; i < 7; ++i)
+ {
+ long c = 0, x_i = x[xOff + i] & M;
+ c += x_i * y_0 + (zz[zzOff + 0] & M);
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[zzOff + 1] & M);
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[zzOff + 2] & M);
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[zzOff + 3] & M);
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[zzOff + 4] & M);
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[zzOff + 5] & M);
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+ c += x_i * y_6 + (zz[zzOff + 6] & M);
+ zz[zzOff + 6] = (int)c;
+ c >>>= 32;
+
+ zc += c + (zz[zzOff + 7] & M);
+ zz[zzOff + 7] = (int)zc;
+ zc >>>= 32;
+ ++zzOff;
+ }
+ return (int)zc;
+ }
+
+ public static long mul33Add(int w, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ // assert w >>> 31 == 0;
+
+ long c = 0, wVal = w & M;
+ long x0 = x[xOff + 0] & M;
+ c += wVal * x0 + (y[yOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ long x1 = x[xOff + 1] & M;
+ c += wVal * x1 + x0 + (y[yOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ long x2 = x[xOff + 2] & M;
+ c += wVal * x2 + x1 + (y[yOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ long x3 = x[xOff + 3] & M;
+ c += wVal * x3 + x2 + (y[yOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ long x4 = x[xOff + 4] & M;
+ c += wVal * x4 + x3 + (y[yOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ long x5 = x[xOff + 5] & M;
+ c += wVal * x5 + x4 + (y[yOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ long x6 = x[xOff + 6] & M;
+ c += wVal * x6 + x5 + (y[yOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ c += x6;
+ return c;
+ }
+
+ public static int mulByWord(int x, int[] z)
+ {
+ long c = 0, xVal = x & M;
+ c += xVal * (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int mulByWordAddTo(int x, int[] y, int[] z)
+ {
+ long c = 0, xVal = x & M;
+ c += xVal * (z[0] & M) + (y[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[1] & M) + (y[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[2] & M) + (y[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[3] & M) + (y[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[4] & M) + (y[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[5] & M) + (y[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[6] & M) + (y[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int mulWordAddTo(int x, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0, xVal = x & M;
+ c += xVal * (y[yOff + 0] & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 1] & M) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 2] & M) + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 3] & M) + (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 4] & M) + (z[zOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 5] & M) + (z[zOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 6] & M) + (z[zOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int mul33DWordAdd(int x, long y, int[] z, int zOff)
+ {
+ // assert x >>> 31 == 0;
+ // assert zOff <= 3;
+
+ long c = 0, xVal = x & M;
+ long y00 = y & M;
+ c += xVal * y00 + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ long y01 = y >>> 32;
+ c += xVal * y01 + y00 + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += y01 + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : Nat.incAt(7, z, zOff, 4);
+ }
+
+ public static int mul33WordAdd(int x, int y, int[] z, int zOff)
+ {
+ // assert x >>> 31 == 0;
+ // assert zOff <= 4;
+
+ long c = 0, xVal = x & M, yVal = y & M;
+ c += yVal * xVal + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += yVal + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : Nat.incAt(7, z, zOff, 3);
+ }
+
+ public static int mulWordDwordAdd(int x, long y, int[] z, int zOff)
+ {
+ // assert zOff <= 4;
+ long c = 0, xVal = x & M;
+ c += xVal * (y & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += xVal * (y >>> 32) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : Nat.incAt(7, z, zOff, 3);
+ }
+
+ public static int mulWord(int x, int[] y, int[] z, int zOff)
+ {
+ long c = 0, xVal = x & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (y[i] & M);
+ z[zOff + i] = (int)c;
+ c >>>= 32;
+ }
+ while (++i < 7);
+ return (int)c;
+ }
+
+ public static void square(int[] x, int[] zz)
+ {
+ long x_0 = x[0] & M;
+ long zz_1;
+
+ int c = 0, w;
+ {
+ int i = 6, j = 14;
+ do
+ {
+ long xVal = (x[i--] & M);
+ long p = xVal * xVal;
+ zz[--j] = (c << 31) | (int)(p >>> 33);
+ zz[--j] = (int)(p >>> 1);
+ c = (int)p;
+ }
+ while (i > 0);
+
+ {
+ long p = x_0 * x_0;
+ zz_1 = ((c << 31) & M) | (p >>> 33);
+ zz[0] = (int)p;
+ c = (int)(p >>> 32) & 1;
+ }
+ }
+
+ long x_1 = x[1] & M;
+ long zz_2 = zz[2] & M;
+
+ {
+ zz_1 += x_1 * x_0;
+ w = (int)zz_1;
+ zz[1] = (w << 1) | c;
+ c = w >>> 31;
+ zz_2 += zz_1 >>> 32;
+ }
+
+ long x_2 = x[2] & M;
+ long zz_3 = zz[3] & M;
+ long zz_4 = zz[4] & M;
+ {
+ zz_2 += x_2 * x_0;
+ w = (int)zz_2;
+ zz[2] = (w << 1) | c;
+ c = w >>> 31;
+ zz_3 += (zz_2 >>> 32) + x_2 * x_1;
+ zz_4 += zz_3 >>> 32;
+ zz_3 &= M;
+ }
+
+ long x_3 = x[3] & M;
+ long zz_5 = (zz[5] & M) + (zz_4 >>> 32); zz_4 &= M;
+ long zz_6 = (zz[6] & M) + (zz_5 >>> 32); zz_5 &= M;
+ {
+ zz_3 += x_3 * x_0;
+ w = (int)zz_3;
+ zz[3] = (w << 1) | c;
+ c = w >>> 31;
+ zz_4 += (zz_3 >>> 32) + x_3 * x_1;
+ zz_5 += (zz_4 >>> 32) + x_3 * x_2;
+ zz_4 &= M;
+ zz_6 += zz_5 >>> 32;
+ zz_5 &= M;
+ }
+
+ long x_4 = x[4] & M;
+ long zz_7 = (zz[7] & M) + (zz_6 >>> 32); zz_6 &= M;
+ long zz_8 = (zz[8] & M) + (zz_7 >>> 32); zz_7 &= M;
+ {
+ zz_4 += x_4 * x_0;
+ w = (int)zz_4;
+ zz[4] = (w << 1) | c;
+ c = w >>> 31;
+ zz_5 += (zz_4 >>> 32) + x_4 * x_1;
+ zz_6 += (zz_5 >>> 32) + x_4 * x_2;
+ zz_5 &= M;
+ zz_7 += (zz_6 >>> 32) + x_4 * x_3;
+ zz_6 &= M;
+ zz_8 += zz_7 >>> 32;
+ zz_7 &= M;
+ }
+
+ long x_5 = x[5] & M;
+ long zz_9 = (zz[9] & M) + (zz_8 >>> 32); zz_8 &= M;
+ long zz_10 = (zz[10] & M) + (zz_9 >>> 32); zz_9 &= M;
+ {
+ zz_5 += x_5 * x_0;
+ w = (int)zz_5;
+ zz[5] = (w << 1) | c;
+ c = w >>> 31;
+ zz_6 += (zz_5 >>> 32) + x_5 * x_1;
+ zz_7 += (zz_6 >>> 32) + x_5 * x_2;
+ zz_6 &= M;
+ zz_8 += (zz_7 >>> 32) + x_5 * x_3;
+ zz_7 &= M;
+ zz_9 += (zz_8 >>> 32) + x_5 * x_4;
+ zz_8 &= M;
+ zz_10 += zz_9 >>> 32;
+ zz_9 &= M;
+ }
+
+ long x_6 = x[6] & M;
+ long zz_11 = (zz[11] & M) + (zz_10 >>> 32); zz_10 &= M;
+ long zz_12 = (zz[12] & M) + (zz_11 >>> 32); zz_11 &= M;
+ {
+ zz_6 += x_6 * x_0;
+ w = (int)zz_6;
+ zz[6] = (w << 1) | c;
+ c = w >>> 31;
+ zz_7 += (zz_6 >>> 32) + x_6 * x_1;
+ zz_8 += (zz_7 >>> 32) + x_6 * x_2;
+ zz_9 += (zz_8 >>> 32) + x_6 * x_3;
+ zz_10 += (zz_9 >>> 32) + x_6 * x_4;
+ zz_11 += (zz_10 >>> 32) + x_6 * x_5;
+ zz_12 += zz_11 >>> 32;
+ }
+
+ w = (int)zz_7;
+ zz[7] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_8;
+ zz[8] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_9;
+ zz[9] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_10;
+ zz[10] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_11;
+ zz[11] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_12;
+ zz[12] = (w << 1) | c;
+ c = w >>> 31;
+ w = zz[13] + (int)(zz_12 >>> 32);
+ zz[13] = (w << 1) | c;
+ }
+
+ public static void square(int[] x, int xOff, int[] zz, int zzOff)
+ {
+ long x_0 = x[xOff + 0] & M;
+ long zz_1;
+
+ int c = 0, w;
+ {
+ int i = 6, j = 14;
+ do
+ {
+ long xVal = (x[xOff + i--] & M);
+ long p = xVal * xVal;
+ zz[zzOff + --j] = (c << 31) | (int)(p >>> 33);
+ zz[zzOff + --j] = (int)(p >>> 1);
+ c = (int)p;
+ }
+ while (i > 0);
+
+ {
+ long p = x_0 * x_0;
+ zz_1 = ((c << 31) & M) | (p >>> 33);
+ zz[zzOff + 0] = (int)p;
+ c = (int)(p >>> 32) & 1;
+ }
+ }
+
+ long x_1 = x[xOff + 1] & M;
+ long zz_2 = zz[zzOff + 2] & M;
+
+ {
+ zz_1 += x_1 * x_0;
+ w = (int)zz_1;
+ zz[zzOff + 1] = (w << 1) | c;
+ c = w >>> 31;
+ zz_2 += zz_1 >>> 32;
+ }
+
+ long x_2 = x[xOff + 2] & M;
+ long zz_3 = zz[zzOff + 3] & M;
+ long zz_4 = zz[zzOff + 4] & M;
+ {
+ zz_2 += x_2 * x_0;
+ w = (int)zz_2;
+ zz[zzOff + 2] = (w << 1) | c;
+ c = w >>> 31;
+ zz_3 += (zz_2 >>> 32) + x_2 * x_1;
+ zz_4 += zz_3 >>> 32;
+ zz_3 &= M;
+ }
+
+ long x_3 = x[xOff + 3] & M;
+ long zz_5 = (zz[zzOff + 5] & M) + (zz_4 >>> 32); zz_4 &= M;
+ long zz_6 = (zz[zzOff + 6] & M) + (zz_5 >>> 32); zz_5 &= M;
+ {
+ zz_3 += x_3 * x_0;
+ w = (int)zz_3;
+ zz[zzOff + 3] = (w << 1) | c;
+ c = w >>> 31;
+ zz_4 += (zz_3 >>> 32) + x_3 * x_1;
+ zz_5 += (zz_4 >>> 32) + x_3 * x_2;
+ zz_4 &= M;
+ zz_6 += zz_5 >>> 32;
+ zz_5 &= M;
+ }
+
+ long x_4 = x[xOff + 4] & M;
+ long zz_7 = (zz[zzOff + 7] & M) + (zz_6 >>> 32); zz_6 &= M;
+ long zz_8 = (zz[zzOff + 8] & M) + (zz_7 >>> 32); zz_7 &= M;
+ {
+ zz_4 += x_4 * x_0;
+ w = (int)zz_4;
+ zz[zzOff + 4] = (w << 1) | c;
+ c = w >>> 31;
+ zz_5 += (zz_4 >>> 32) + x_4 * x_1;
+ zz_6 += (zz_5 >>> 32) + x_4 * x_2;
+ zz_5 &= M;
+ zz_7 += (zz_6 >>> 32) + x_4 * x_3;
+ zz_6 &= M;
+ zz_8 += zz_7 >>> 32;
+ zz_7 &= M;
+ }
+
+ long x_5 = x[xOff + 5] & M;
+ long zz_9 = (zz[zzOff + 9] & M) + (zz_8 >>> 32); zz_8 &= M;
+ long zz_10 = (zz[zzOff + 10] & M) + (zz_9 >>> 32); zz_9 &= M;
+ {
+ zz_5 += x_5 * x_0;
+ w = (int)zz_5;
+ zz[zzOff + 5] = (w << 1) | c;
+ c = w >>> 31;
+ zz_6 += (zz_5 >>> 32) + x_5 * x_1;
+ zz_7 += (zz_6 >>> 32) + x_5 * x_2;
+ zz_6 &= M;
+ zz_8 += (zz_7 >>> 32) + x_5 * x_3;
+ zz_7 &= M;
+ zz_9 += (zz_8 >>> 32) + x_5 * x_4;
+ zz_8 &= M;
+ zz_10 += zz_9 >>> 32;
+ zz_9 &= M;
+ }
+
+ long x_6 = x[xOff + 6] & M;
+ long zz_11 = (zz[zzOff + 11] & M) + (zz_10 >>> 32); zz_10 &= M;
+ long zz_12 = (zz[zzOff + 12] & M) + (zz_11 >>> 32); zz_11 &= M;
+ {
+ zz_6 += x_6 * x_0;
+ w = (int)zz_6;
+ zz[zzOff + 6] = (w << 1) | c;
+ c = w >>> 31;
+ zz_7 += (zz_6 >>> 32) + x_6 * x_1;
+ zz_8 += (zz_7 >>> 32) + x_6 * x_2;
+ zz_9 += (zz_8 >>> 32) + x_6 * x_3;
+ zz_10 += (zz_9 >>> 32) + x_6 * x_4;
+ zz_11 += (zz_10 >>> 32) + x_6 * x_5;
+ zz_12 += zz_11 >>> 32;
+ }
+
+ w = (int)zz_7;
+ zz[zzOff + 7] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_8;
+ zz[zzOff + 8] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_9;
+ zz[zzOff + 9] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_10;
+ zz[zzOff + 10] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_11;
+ zz[zzOff + 11] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_12;
+ zz[zzOff + 12] = (w << 1) | c;
+ c = w >>> 31;
+ w = zz[zzOff + 13] + (int)(zz_12 >>> 32);
+ zz[zzOff + 13] = (w << 1) | c;
+ }
+
+ public static int sub(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) - (y[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (x[1] & M) - (y[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (x[2] & M) - (y[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ c += (x[3] & M) - (y[3] & M);
+ z[3] = (int)c;
+ c >>= 32;
+ c += (x[4] & M) - (y[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (x[5] & M) - (y[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ c += (x[6] & M) - (y[6] & M);
+ z[6] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int sub(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0;
+ c += (x[xOff + 0] & M) - (y[yOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 1] & M) - (y[yOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 2] & M) - (y[yOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 3] & M) - (y[yOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 4] & M) - (y[yOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 5] & M) - (y[yOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 6] & M) - (y[yOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int subBothFrom(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (z[0] & M) - (x[0] & M) - (y[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M) - (x[1] & M) - (y[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (z[2] & M) - (x[2] & M) - (y[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ c += (z[3] & M) - (x[3] & M) - (y[3] & M);
+ z[3] = (int)c;
+ c >>= 32;
+ c += (z[4] & M) - (x[4] & M) - (y[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (z[5] & M) - (x[5] & M) - (y[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ c += (z[6] & M) - (x[6] & M) - (y[6] & M);
+ z[6] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int subFrom(int[] x, int[] z)
+ {
+ long c = 0;
+ c += (z[0] & M) - (x[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M) - (x[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (z[2] & M) - (x[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ c += (z[3] & M) - (x[3] & M);
+ z[3] = (int)c;
+ c >>= 32;
+ c += (z[4] & M) - (x[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (z[5] & M) - (x[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ c += (z[6] & M) - (x[6] & M);
+ z[6] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int subFrom(int[] x, int xOff, int[] z, int zOff)
+ {
+ long c = 0;
+ c += (z[zOff + 0] & M) - (x[xOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 1] & M) - (x[xOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 2] & M) - (x[xOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 3] & M) - (x[xOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 4] & M) - (x[xOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 5] & M) - (x[xOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 6] & M) - (x[xOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static BigInteger toBigInteger(int[] x)
+ {
+ byte[] bs = new byte[28];
+ for (int i = 0; i < 7; ++i)
+ {
+ int x_i = x[i];
+ if (x_i != 0)
+ {
+ Pack.intToBigEndian(x_i, bs, (6 - i) << 2);
+ }
+ }
+ return new BigInteger(1, bs);
+ }
+
+ public static void zero(int[] z)
+ {
+ z[0] = 0;
+ z[1] = 0;
+ z[2] = 0;
+ z[3] = 0;
+ z[4] = 0;
+ z[5] = 0;
+ z[6] = 0;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat256.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat256.java
new file mode 100644
index 00000000..0771409b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat256.java
@@ -0,0 +1,1423 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.raw;
+
+import java.math.BigInteger;
+
+import com.android.internal.org.bouncycastle.util.Pack;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class Nat256
+{
+ private static final long M = 0xFFFFFFFFL;
+
+ public static int add(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) + (y[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (y[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (y[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (y[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (y[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (y[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += (x[6] & M) + (y[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ c += (x[7] & M) + (y[7] & M);
+ z[7] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int add(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0;
+ c += (x[xOff + 0] & M) + (y[yOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 1] & M) + (y[yOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 2] & M) + (y[yOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 3] & M) + (y[yOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 4] & M) + (y[yOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 5] & M) + (y[yOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 6] & M) + (y[yOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 7] & M) + (y[yOff + 7] & M);
+ z[zOff + 7] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addBothTo(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) + (y[0] & M) + (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (y[1] & M) + (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (y[2] & M) + (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (y[3] & M) + (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (y[4] & M) + (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (y[5] & M) + (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += (x[6] & M) + (y[6] & M) + (z[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ c += (x[7] & M) + (y[7] & M) + (z[7] & M);
+ z[7] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addBothTo(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0;
+ c += (x[xOff + 0] & M) + (y[yOff + 0] & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 1] & M) + (y[yOff + 1] & M) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 2] & M) + (y[yOff + 2] & M) + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 3] & M) + (y[yOff + 3] & M) + (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 4] & M) + (y[yOff + 4] & M) + (z[zOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 5] & M) + (y[yOff + 5] & M) + (z[zOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 6] & M) + (y[yOff + 6] & M) + (z[zOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 7] & M) + (y[yOff + 7] & M) + (z[zOff + 7] & M);
+ z[zOff + 7] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addTo(int[] x, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) + (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += (x[6] & M) + (z[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ c += (x[7] & M) + (z[7] & M);
+ z[7] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn)
+ {
+ long c = cIn & M;
+ c += (x[xOff + 0] & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 1] & M) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 2] & M) + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 3] & M) + (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 4] & M) + (z[zOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 5] & M) + (z[zOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 6] & M) + (z[zOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 7] & M) + (z[zOff + 7] & M);
+ z[zOff + 7] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addToEachOther(int[] u, int uOff, int[] v, int vOff)
+ {
+ long c = 0;
+ c += (u[uOff + 0] & M) + (v[vOff + 0] & M);
+ u[uOff + 0] = (int)c;
+ v[vOff + 0] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 1] & M) + (v[vOff + 1] & M);
+ u[uOff + 1] = (int)c;
+ v[vOff + 1] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 2] & M) + (v[vOff + 2] & M);
+ u[uOff + 2] = (int)c;
+ v[vOff + 2] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 3] & M) + (v[vOff + 3] & M);
+ u[uOff + 3] = (int)c;
+ v[vOff + 3] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 4] & M) + (v[vOff + 4] & M);
+ u[uOff + 4] = (int)c;
+ v[vOff + 4] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 5] & M) + (v[vOff + 5] & M);
+ u[uOff + 5] = (int)c;
+ v[vOff + 5] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 6] & M) + (v[vOff + 6] & M);
+ u[uOff + 6] = (int)c;
+ v[vOff + 6] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 7] & M) + (v[vOff + 7] & M);
+ u[uOff + 7] = (int)c;
+ v[vOff + 7] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static void copy(int[] x, int[] z)
+ {
+ z[0] = x[0];
+ z[1] = x[1];
+ z[2] = x[2];
+ z[3] = x[3];
+ z[4] = x[4];
+ z[5] = x[5];
+ z[6] = x[6];
+ z[7] = x[7];
+ }
+
+ public static void copy(int[] x, int xOff, int[] z, int zOff)
+ {
+ z[zOff + 0] = x[xOff + 0];
+ z[zOff + 1] = x[xOff + 1];
+ z[zOff + 2] = x[xOff + 2];
+ z[zOff + 3] = x[xOff + 3];
+ z[zOff + 4] = x[xOff + 4];
+ z[zOff + 5] = x[xOff + 5];
+ z[zOff + 6] = x[xOff + 6];
+ z[zOff + 7] = x[xOff + 7];
+ }
+
+ public static void copy64(long[] x, long[] z)
+ {
+ z[0] = x[0];
+ z[1] = x[1];
+ z[2] = x[2];
+ z[3] = x[3];
+ }
+
+ public static void copy64(long[] x, int xOff, long[] z, int zOff)
+ {
+ z[zOff + 0] = x[xOff + 0];
+ z[zOff + 1] = x[xOff + 1];
+ z[zOff + 2] = x[xOff + 2];
+ z[zOff + 3] = x[xOff + 3];
+ }
+
+ public static int[] create()
+ {
+ return new int[8];
+ }
+
+ public static long[] create64()
+ {
+ return new long[4];
+ }
+
+ public static int[] createExt()
+ {
+ return new int[16];
+ }
+
+ public static long[] createExt64()
+ {
+ return new long[8];
+ }
+
+ public static boolean diff(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ boolean pos = gte(x, xOff, y, yOff);
+ if (pos)
+ {
+ sub(x, xOff, y, yOff, z, zOff);
+ }
+ else
+ {
+ sub(y, yOff, x, xOff, z, zOff);
+ }
+ return pos;
+ }
+
+ public static boolean eq(int[] x, int[] y)
+ {
+ for (int i = 7; i >= 0; --i)
+ {
+ if (x[i] != y[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean eq64(long[] x, long[] y)
+ {
+ for (int i = 3; i >= 0; --i)
+ {
+ if (x[i] != y[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ if (x.signum() < 0 || x.bitLength() > 256)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ int[] z = create();
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 8; ++i)
+ {
+ z[i] = x.intValue();
+ x = x.shiftRight(32);
+ }
+ return z;
+ }
+
+ public static long[] fromBigInteger64(BigInteger x)
+ {
+ if (x.signum() < 0 || x.bitLength() > 256)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ long[] z = create64();
+
+ // NOTE: Use a fixed number of loop iterations
+ for (int i = 0; i < 4; ++i)
+ {
+ z[i] = x.longValue();
+ x = x.shiftRight(64);
+ }
+ return z;
+ }
+
+ public static int getBit(int[] x, int bit)
+ {
+ if (bit == 0)
+ {
+ return x[0] & 1;
+ }
+ if ((bit & 255) != bit)
+ {
+ return 0;
+ }
+ int w = bit >>> 5;
+ int b = bit & 31;
+ return (x[w] >>> b) & 1;
+ }
+
+ public static boolean gte(int[] x, int[] y)
+ {
+ for (int i = 7; i >= 0; --i)
+ {
+ int x_i = x[i] ^ Integer.MIN_VALUE;
+ int y_i = y[i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return false;
+ if (x_i > y_i)
+ return true;
+ }
+ return true;
+ }
+
+ public static boolean gte(int[] x, int xOff, int[] y, int yOff)
+ {
+ for (int i = 7; i >= 0; --i)
+ {
+ int x_i = x[xOff + i] ^ Integer.MIN_VALUE;
+ int y_i = y[yOff + i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return false;
+ if (x_i > y_i)
+ return true;
+ }
+ return true;
+ }
+
+ public static boolean isOne(int[] x)
+ {
+ if (x[0] != 1)
+ {
+ return false;
+ }
+ for (int i = 1; i < 8; ++i)
+ {
+ if (x[i] != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean isOne64(long[] x)
+ {
+ if (x[0] != 1L)
+ {
+ return false;
+ }
+ for (int i = 1; i < 4; ++i)
+ {
+ if (x[i] != 0L)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean isZero(int[] x)
+ {
+ for (int i = 0; i < 8; ++i)
+ {
+ if (x[i] != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean isZero64(long[] x)
+ {
+ for (int i = 0; i < 4; ++i)
+ {
+ if (x[i] != 0L)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static void mul(int[] x, int[] y, int[] zz)
+ {
+ long y_0 = y[0] & M;
+ long y_1 = y[1] & M;
+ long y_2 = y[2] & M;
+ long y_3 = y[3] & M;
+ long y_4 = y[4] & M;
+ long y_5 = y[5] & M;
+ long y_6 = y[6] & M;
+ long y_7 = y[7] & M;
+
+ {
+ long c = 0, x_0 = x[0] & M;
+ c += x_0 * y_0;
+ zz[0] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_1;
+ zz[1] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_2;
+ zz[2] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_3;
+ zz[3] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_4;
+ zz[4] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_5;
+ zz[5] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_6;
+ zz[6] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_7;
+ zz[7] = (int)c;
+ c >>>= 32;
+ zz[8] = (int)c;
+ }
+
+ for (int i = 1; i < 8; ++i)
+ {
+ long c = 0, x_i = x[i] & M;
+ c += x_i * y_0 + (zz[i + 0] & M);
+ zz[i + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[i + 1] & M);
+ zz[i + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[i + 2] & M);
+ zz[i + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[i + 3] & M);
+ zz[i + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[i + 4] & M);
+ zz[i + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[i + 5] & M);
+ zz[i + 5] = (int)c;
+ c >>>= 32;
+ c += x_i * y_6 + (zz[i + 6] & M);
+ zz[i + 6] = (int)c;
+ c >>>= 32;
+ c += x_i * y_7 + (zz[i + 7] & M);
+ zz[i + 7] = (int)c;
+ c >>>= 32;
+ zz[i + 8] = (int)c;
+ }
+ }
+
+ public static void mul(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
+ {
+ long y_0 = y[yOff + 0] & M;
+ long y_1 = y[yOff + 1] & M;
+ long y_2 = y[yOff + 2] & M;
+ long y_3 = y[yOff + 3] & M;
+ long y_4 = y[yOff + 4] & M;
+ long y_5 = y[yOff + 5] & M;
+ long y_6 = y[yOff + 6] & M;
+ long y_7 = y[yOff + 7] & M;
+
+ {
+ long c = 0, x_0 = x[xOff + 0] & M;
+ c += x_0 * y_0;
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_1;
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_2;
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_3;
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_4;
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_5;
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_6;
+ zz[zzOff + 6] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_7;
+ zz[zzOff + 7] = (int)c;
+ c >>>= 32;
+ zz[zzOff + 8] = (int)c;
+ }
+
+ for (int i = 1; i < 8; ++i)
+ {
+ ++zzOff;
+ long c = 0, x_i = x[xOff + i] & M;
+ c += x_i * y_0 + (zz[zzOff + 0] & M);
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[zzOff + 1] & M);
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[zzOff + 2] & M);
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[zzOff + 3] & M);
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[zzOff + 4] & M);
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[zzOff + 5] & M);
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+ c += x_i * y_6 + (zz[zzOff + 6] & M);
+ zz[zzOff + 6] = (int)c;
+ c >>>= 32;
+ c += x_i * y_7 + (zz[zzOff + 7] & M);
+ zz[zzOff + 7] = (int)c;
+ c >>>= 32;
+ zz[zzOff + 8] = (int)c;
+ }
+ }
+
+ public static int mulAddTo(int[] x, int[] y, int[] zz)
+ {
+ long y_0 = y[0] & M;
+ long y_1 = y[1] & M;
+ long y_2 = y[2] & M;
+ long y_3 = y[3] & M;
+ long y_4 = y[4] & M;
+ long y_5 = y[5] & M;
+ long y_6 = y[6] & M;
+ long y_7 = y[7] & M;
+
+ long zc = 0;
+ for (int i = 0; i < 8; ++i)
+ {
+ long c = 0, x_i = x[i] & M;
+ c += x_i * y_0 + (zz[i + 0] & M);
+ zz[i + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[i + 1] & M);
+ zz[i + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[i + 2] & M);
+ zz[i + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[i + 3] & M);
+ zz[i + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[i + 4] & M);
+ zz[i + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[i + 5] & M);
+ zz[i + 5] = (int)c;
+ c >>>= 32;
+ c += x_i * y_6 + (zz[i + 6] & M);
+ zz[i + 6] = (int)c;
+ c >>>= 32;
+ c += x_i * y_7 + (zz[i + 7] & M);
+ zz[i + 7] = (int)c;
+ c >>>= 32;
+
+ zc += c + (zz[i + 8] & M);
+ zz[i + 8] = (int)zc;
+ zc >>>= 32;
+ }
+ return (int)zc;
+ }
+
+ public static int mulAddTo(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
+ {
+ long y_0 = y[yOff + 0] & M;
+ long y_1 = y[yOff + 1] & M;
+ long y_2 = y[yOff + 2] & M;
+ long y_3 = y[yOff + 3] & M;
+ long y_4 = y[yOff + 4] & M;
+ long y_5 = y[yOff + 5] & M;
+ long y_6 = y[yOff + 6] & M;
+ long y_7 = y[yOff + 7] & M;
+
+ long zc = 0;
+ for (int i = 0; i < 8; ++i)
+ {
+ long c = 0, x_i = x[xOff + i] & M;
+ c += x_i * y_0 + (zz[zzOff + 0] & M);
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[zzOff + 1] & M);
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[zzOff + 2] & M);
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[zzOff + 3] & M);
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[zzOff + 4] & M);
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[zzOff + 5] & M);
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+ c += x_i * y_6 + (zz[zzOff + 6] & M);
+ zz[zzOff + 6] = (int)c;
+ c >>>= 32;
+ c += x_i * y_7 + (zz[zzOff + 7] & M);
+ zz[zzOff + 7] = (int)c;
+ c >>>= 32;
+
+ zc += c + (zz[zzOff + 8] & M);
+ zz[zzOff + 8] = (int)zc;
+ zc >>>= 32;
+ ++zzOff;
+ }
+ return (int)zc;
+ }
+
+ public static long mul33Add(int w, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ // assert w >>> 31 == 0;
+
+ long c = 0, wVal = w & M;
+ long x0 = x[xOff + 0] & M;
+ c += wVal * x0 + (y[yOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ long x1 = x[xOff + 1] & M;
+ c += wVal * x1 + x0 + (y[yOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ long x2 = x[xOff + 2] & M;
+ c += wVal * x2 + x1 + (y[yOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ long x3 = x[xOff + 3] & M;
+ c += wVal * x3 + x2 + (y[yOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ long x4 = x[xOff + 4] & M;
+ c += wVal * x4 + x3 + (y[yOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ long x5 = x[xOff + 5] & M;
+ c += wVal * x5 + x4 + (y[yOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ long x6 = x[xOff + 6] & M;
+ c += wVal * x6 + x5 + (y[yOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ long x7 = x[xOff + 7] & M;
+ c += wVal * x7 + x6 + (y[yOff + 7] & M);
+ z[zOff + 7] = (int)c;
+ c >>>= 32;
+ c += x7;
+ return c;
+ }
+
+ public static int mulByWord(int x, int[] z)
+ {
+ long c = 0, xVal = x & M;
+ c += xVal * (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[7] & M);
+ z[7] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int mulByWordAddTo(int x, int[] y, int[] z)
+ {
+ long c = 0, xVal = x & M;
+ c += xVal * (z[0] & M) + (y[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[1] & M) + (y[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[2] & M) + (y[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[3] & M) + (y[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[4] & M) + (y[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[5] & M) + (y[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[6] & M) + (y[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[7] & M) + (y[7] & M);
+ z[7] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int mulWordAddTo(int x, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0, xVal = x & M;
+ c += xVal * (y[yOff + 0] & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 1] & M) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 2] & M) + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 3] & M) + (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 4] & M) + (z[zOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 5] & M) + (z[zOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 6] & M) + (z[zOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 7] & M) + (z[zOff + 7] & M);
+ z[zOff + 7] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int mul33DWordAdd(int x, long y, int[] z, int zOff)
+ {
+ // assert x >>> 31 == 0;
+ // assert zOff <= 4;
+
+ long c = 0, xVal = x & M;
+ long y00 = y & M;
+ c += xVal * y00 + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ long y01 = y >>> 32;
+ c += xVal * y01 + y00 + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += y01 + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : Nat.incAt(8, z, zOff, 4);
+ }
+
+ public static int mul33WordAdd(int x, int y, int[] z, int zOff)
+ {
+ // assert x >>> 31 == 0;
+ // assert zOff <= 5;
+
+ long c = 0, xVal = x & M, yVal = y & M;
+ c += yVal * xVal + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += yVal + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : Nat.incAt(8, z, zOff, 3);
+ }
+
+ public static int mulWordDwordAdd(int x, long y, int[] z, int zOff)
+ {
+ // assert zOff <= 5;
+ long c = 0, xVal = x & M;
+ c += xVal * (y & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += xVal * (y >>> 32) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : Nat.incAt(8, z, zOff, 3);
+ }
+
+ public static int mulWord(int x, int[] y, int[] z, int zOff)
+ {
+ long c = 0, xVal = x & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (y[i] & M);
+ z[zOff + i] = (int)c;
+ c >>>= 32;
+ }
+ while (++i < 8);
+ return (int)c;
+ }
+
+ public static void square(int[] x, int[] zz)
+ {
+ long x_0 = x[0] & M;
+ long zz_1;
+
+ int c = 0, w;
+ {
+ int i = 7, j = 16;
+ do
+ {
+ long xVal = (x[i--] & M);
+ long p = xVal * xVal;
+ zz[--j] = (c << 31) | (int)(p >>> 33);
+ zz[--j] = (int)(p >>> 1);
+ c = (int)p;
+ }
+ while (i > 0);
+
+ {
+ long p = x_0 * x_0;
+ zz_1 = ((c << 31) & M) | (p >>> 33);
+ zz[0] = (int)p;
+ c = (int)(p >>> 32) & 1;
+ }
+ }
+
+ long x_1 = x[1] & M;
+ long zz_2 = zz[2] & M;
+
+ {
+ zz_1 += x_1 * x_0;
+ w = (int)zz_1;
+ zz[1] = (w << 1) | c;
+ c = w >>> 31;
+ zz_2 += zz_1 >>> 32;
+ }
+
+ long x_2 = x[2] & M;
+ long zz_3 = zz[3] & M;
+ long zz_4 = zz[4] & M;
+ {
+ zz_2 += x_2 * x_0;
+ w = (int)zz_2;
+ zz[2] = (w << 1) | c;
+ c = w >>> 31;
+ zz_3 += (zz_2 >>> 32) + x_2 * x_1;
+ zz_4 += zz_3 >>> 32;
+ zz_3 &= M;
+ }
+
+ long x_3 = x[3] & M;
+ long zz_5 = (zz[5] & M) + (zz_4 >>> 32); zz_4 &= M;
+ long zz_6 = (zz[6] & M) + (zz_5 >>> 32); zz_5 &= M;
+ {
+ zz_3 += x_3 * x_0;
+ w = (int)zz_3;
+ zz[3] = (w << 1) | c;
+ c = w >>> 31;
+ zz_4 += (zz_3 >>> 32) + x_3 * x_1;
+ zz_5 += (zz_4 >>> 32) + x_3 * x_2;
+ zz_4 &= M;
+ zz_6 += zz_5 >>> 32;
+ zz_5 &= M;
+ }
+
+ long x_4 = x[4] & M;
+ long zz_7 = (zz[7] & M) + (zz_6 >>> 32); zz_6 &= M;
+ long zz_8 = (zz[8] & M) + (zz_7 >>> 32); zz_7 &= M;
+ {
+ zz_4 += x_4 * x_0;
+ w = (int)zz_4;
+ zz[4] = (w << 1) | c;
+ c = w >>> 31;
+ zz_5 += (zz_4 >>> 32) + x_4 * x_1;
+ zz_6 += (zz_5 >>> 32) + x_4 * x_2;
+ zz_5 &= M;
+ zz_7 += (zz_6 >>> 32) + x_4 * x_3;
+ zz_6 &= M;
+ zz_8 += zz_7 >>> 32;
+ zz_7 &= M;
+ }
+
+ long x_5 = x[5] & M;
+ long zz_9 = (zz[9] & M) + (zz_8 >>> 32); zz_8 &= M;
+ long zz_10 = (zz[10] & M) + (zz_9 >>> 32); zz_9 &= M;
+ {
+ zz_5 += x_5 * x_0;
+ w = (int)zz_5;
+ zz[5] = (w << 1) | c;
+ c = w >>> 31;
+ zz_6 += (zz_5 >>> 32) + x_5 * x_1;
+ zz_7 += (zz_6 >>> 32) + x_5 * x_2;
+ zz_6 &= M;
+ zz_8 += (zz_7 >>> 32) + x_5 * x_3;
+ zz_7 &= M;
+ zz_9 += (zz_8 >>> 32) + x_5 * x_4;
+ zz_8 &= M;
+ zz_10 += zz_9 >>> 32;
+ zz_9 &= M;
+ }
+
+ long x_6 = x[6] & M;
+ long zz_11 = (zz[11] & M) + (zz_10 >>> 32); zz_10 &= M;
+ long zz_12 = (zz[12] & M) + (zz_11 >>> 32); zz_11 &= M;
+ {
+ zz_6 += x_6 * x_0;
+ w = (int)zz_6;
+ zz[6] = (w << 1) | c;
+ c = w >>> 31;
+ zz_7 += (zz_6 >>> 32) + x_6 * x_1;
+ zz_8 += (zz_7 >>> 32) + x_6 * x_2;
+ zz_7 &= M;
+ zz_9 += (zz_8 >>> 32) + x_6 * x_3;
+ zz_8 &= M;
+ zz_10 += (zz_9 >>> 32) + x_6 * x_4;
+ zz_9 &= M;
+ zz_11 += (zz_10 >>> 32) + x_6 * x_5;
+ zz_10 &= M;
+ zz_12 += zz_11 >>> 32;
+ zz_11 &= M;
+ }
+
+ long x_7 = x[7] & M;
+ long zz_13 = (zz[13] & M) + (zz_12 >>> 32); zz_12 &= M;
+ long zz_14 = (zz[14] & M) + (zz_13 >>> 32); zz_13 &= M;
+ {
+ zz_7 += x_7 * x_0;
+ w = (int)zz_7;
+ zz[7] = (w << 1) | c;
+ c = w >>> 31;
+ zz_8 += (zz_7 >>> 32) + x_7 * x_1;
+ zz_9 += (zz_8 >>> 32) + x_7 * x_2;
+ zz_10 += (zz_9 >>> 32) + x_7 * x_3;
+ zz_11 += (zz_10 >>> 32) + x_7 * x_4;
+ zz_12 += (zz_11 >>> 32) + x_7 * x_5;
+ zz_13 += (zz_12 >>> 32) + x_7 * x_6;
+ zz_14 += zz_13 >>> 32;
+ }
+
+ w = (int)zz_8;
+ zz[8] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_9;
+ zz[9] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_10;
+ zz[10] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_11;
+ zz[11] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_12;
+ zz[12] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_13;
+ zz[13] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_14;
+ zz[14] = (w << 1) | c;
+ c = w >>> 31;
+ w = zz[15] + (int)(zz_14 >>> 32);
+ zz[15] = (w << 1) | c;
+ }
+
+ public static void square(int[] x, int xOff, int[] zz, int zzOff)
+ {
+ long x_0 = x[xOff + 0] & M;
+ long zz_1;
+
+ int c = 0, w;
+ {
+ int i = 7, j = 16;
+ do
+ {
+ long xVal = (x[xOff + i--] & M);
+ long p = xVal * xVal;
+ zz[zzOff + --j] = (c << 31) | (int)(p >>> 33);
+ zz[zzOff + --j] = (int)(p >>> 1);
+ c = (int)p;
+ }
+ while (i > 0);
+
+ {
+ long p = x_0 * x_0;
+ zz_1 = ((c << 31) & M) | (p >>> 33);
+ zz[zzOff + 0] = (int)p;
+ c = (int)(p >>> 32) & 1;
+ }
+ }
+
+ long x_1 = x[xOff + 1] & M;
+ long zz_2 = zz[zzOff + 2] & M;
+
+ {
+ zz_1 += x_1 * x_0;
+ w = (int)zz_1;
+ zz[zzOff + 1] = (w << 1) | c;
+ c = w >>> 31;
+ zz_2 += zz_1 >>> 32;
+ }
+
+ long x_2 = x[xOff + 2] & M;
+ long zz_3 = zz[zzOff + 3] & M;
+ long zz_4 = zz[zzOff + 4] & M;
+ {
+ zz_2 += x_2 * x_0;
+ w = (int)zz_2;
+ zz[zzOff + 2] = (w << 1) | c;
+ c = w >>> 31;
+ zz_3 += (zz_2 >>> 32) + x_2 * x_1;
+ zz_4 += zz_3 >>> 32;
+ zz_3 &= M;
+ }
+
+ long x_3 = x[xOff + 3] & M;
+ long zz_5 = (zz[zzOff + 5] & M) + (zz_4 >>> 32); zz_4 &= M;
+ long zz_6 = (zz[zzOff + 6] & M) + (zz_5 >>> 32); zz_5 &= M;
+ {
+ zz_3 += x_3 * x_0;
+ w = (int)zz_3;
+ zz[zzOff + 3] = (w << 1) | c;
+ c = w >>> 31;
+ zz_4 += (zz_3 >>> 32) + x_3 * x_1;
+ zz_5 += (zz_4 >>> 32) + x_3 * x_2;
+ zz_4 &= M;
+ zz_6 += zz_5 >>> 32;
+ zz_5 &= M;
+ }
+
+ long x_4 = x[xOff + 4] & M;
+ long zz_7 = (zz[zzOff + 7] & M) + (zz_6 >>> 32); zz_6 &= M;
+ long zz_8 = (zz[zzOff + 8] & M) + (zz_7 >>> 32); zz_7 &= M;
+ {
+ zz_4 += x_4 * x_0;
+ w = (int)zz_4;
+ zz[zzOff + 4] = (w << 1) | c;
+ c = w >>> 31;
+ zz_5 += (zz_4 >>> 32) + x_4 * x_1;
+ zz_6 += (zz_5 >>> 32) + x_4 * x_2;
+ zz_5 &= M;
+ zz_7 += (zz_6 >>> 32) + x_4 * x_3;
+ zz_6 &= M;
+ zz_8 += zz_7 >>> 32;
+ zz_7 &= M;
+ }
+
+ long x_5 = x[xOff + 5] & M;
+ long zz_9 = (zz[zzOff + 9] & M) + (zz_8 >>> 32); zz_8 &= M;
+ long zz_10 = (zz[zzOff + 10] & M) + (zz_9 >>> 32); zz_9 &= M;
+ {
+ zz_5 += x_5 * x_0;
+ w = (int)zz_5;
+ zz[zzOff + 5] = (w << 1) | c;
+ c = w >>> 31;
+ zz_6 += (zz_5 >>> 32) + x_5 * x_1;
+ zz_7 += (zz_6 >>> 32) + x_5 * x_2;
+ zz_6 &= M;
+ zz_8 += (zz_7 >>> 32) + x_5 * x_3;
+ zz_7 &= M;
+ zz_9 += (zz_8 >>> 32) + x_5 * x_4;
+ zz_8 &= M;
+ zz_10 += zz_9 >>> 32;
+ zz_9 &= M;
+ }
+
+ long x_6 = x[xOff + 6] & M;
+ long zz_11 = (zz[zzOff + 11] & M) + (zz_10 >>> 32); zz_10 &= M;
+ long zz_12 = (zz[zzOff + 12] & M) + (zz_11 >>> 32); zz_11 &= M;
+ {
+ zz_6 += x_6 * x_0;
+ w = (int)zz_6;
+ zz[zzOff + 6] = (w << 1) | c;
+ c = w >>> 31;
+ zz_7 += (zz_6 >>> 32) + x_6 * x_1;
+ zz_8 += (zz_7 >>> 32) + x_6 * x_2;
+ zz_7 &= M;
+ zz_9 += (zz_8 >>> 32) + x_6 * x_3;
+ zz_8 &= M;
+ zz_10 += (zz_9 >>> 32) + x_6 * x_4;
+ zz_9 &= M;
+ zz_11 += (zz_10 >>> 32) + x_6 * x_5;
+ zz_10 &= M;
+ zz_12 += zz_11 >>> 32;
+ zz_11 &= M;
+ }
+
+ long x_7 = x[xOff + 7] & M;
+ long zz_13 = (zz[zzOff + 13] & M) + (zz_12 >>> 32); zz_12 &= M;
+ long zz_14 = (zz[zzOff + 14] & M) + (zz_13 >>> 32); zz_13 &= M;
+ {
+ zz_7 += x_7 * x_0;
+ w = (int)zz_7;
+ zz[zzOff + 7] = (w << 1) | c;
+ c = w >>> 31;
+ zz_8 += (zz_7 >>> 32) + x_7 * x_1;
+ zz_9 += (zz_8 >>> 32) + x_7 * x_2;
+ zz_10 += (zz_9 >>> 32) + x_7 * x_3;
+ zz_11 += (zz_10 >>> 32) + x_7 * x_4;
+ zz_12 += (zz_11 >>> 32) + x_7 * x_5;
+ zz_13 += (zz_12 >>> 32) + x_7 * x_6;
+ zz_14 += zz_13 >>> 32;
+ }
+
+ w = (int)zz_8;
+ zz[zzOff + 8] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_9;
+ zz[zzOff + 9] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_10;
+ zz[zzOff + 10] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_11;
+ zz[zzOff + 11] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_12;
+ zz[zzOff + 12] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_13;
+ zz[zzOff + 13] = (w << 1) | c;
+ c = w >>> 31;
+ w = (int)zz_14;
+ zz[zzOff + 14] = (w << 1) | c;
+ c = w >>> 31;
+ w = zz[zzOff + 15] + (int)(zz_14 >>> 32);
+ zz[zzOff + 15] = (w << 1) | c;
+ }
+
+ public static int sub(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) - (y[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (x[1] & M) - (y[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (x[2] & M) - (y[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ c += (x[3] & M) - (y[3] & M);
+ z[3] = (int)c;
+ c >>= 32;
+ c += (x[4] & M) - (y[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (x[5] & M) - (y[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ c += (x[6] & M) - (y[6] & M);
+ z[6] = (int)c;
+ c >>= 32;
+ c += (x[7] & M) - (y[7] & M);
+ z[7] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int sub(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0;
+ c += (x[xOff + 0] & M) - (y[yOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 1] & M) - (y[yOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 2] & M) - (y[yOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 3] & M) - (y[yOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 4] & M) - (y[yOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 5] & M) - (y[yOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 6] & M) - (y[yOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 7] & M) - (y[yOff + 7] & M);
+ z[zOff + 7] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int subBothFrom(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (z[0] & M) - (x[0] & M) - (y[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M) - (x[1] & M) - (y[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (z[2] & M) - (x[2] & M) - (y[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ c += (z[3] & M) - (x[3] & M) - (y[3] & M);
+ z[3] = (int)c;
+ c >>= 32;
+ c += (z[4] & M) - (x[4] & M) - (y[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (z[5] & M) - (x[5] & M) - (y[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ c += (z[6] & M) - (x[6] & M) - (y[6] & M);
+ z[6] = (int)c;
+ c >>= 32;
+ c += (z[7] & M) - (x[7] & M) - (y[7] & M);
+ z[7] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int subFrom(int[] x, int[] z)
+ {
+ long c = 0;
+ c += (z[0] & M) - (x[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M) - (x[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (z[2] & M) - (x[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ c += (z[3] & M) - (x[3] & M);
+ z[3] = (int)c;
+ c >>= 32;
+ c += (z[4] & M) - (x[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (z[5] & M) - (x[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ c += (z[6] & M) - (x[6] & M);
+ z[6] = (int)c;
+ c >>= 32;
+ c += (z[7] & M) - (x[7] & M);
+ z[7] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int subFrom(int[] x, int xOff, int[] z, int zOff)
+ {
+ long c = 0;
+ c += (z[zOff + 0] & M) - (x[xOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 1] & M) - (x[xOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 2] & M) - (x[xOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 3] & M) - (x[xOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 4] & M) - (x[xOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 5] & M) - (x[xOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 6] & M) - (x[xOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>= 32;
+ c += (z[zOff + 7] & M) - (x[xOff + 7] & M);
+ z[zOff + 7] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static BigInteger toBigInteger(int[] x)
+ {
+ byte[] bs = new byte[32];
+ for (int i = 0; i < 8; ++i)
+ {
+ int x_i = x[i];
+ if (x_i != 0)
+ {
+ Pack.intToBigEndian(x_i, bs, (7 - i) << 2);
+ }
+ }
+ return new BigInteger(1, bs);
+ }
+
+ public static BigInteger toBigInteger64(long[] x)
+ {
+ byte[] bs = new byte[32];
+ for (int i = 0; i < 4; ++i)
+ {
+ long x_i = x[i];
+ if (x_i != 0L)
+ {
+ Pack.longToBigEndian(x_i, bs, (3 - i) << 3);
+ }
+ }
+ return new BigInteger(1, bs);
+ }
+
+ public static void zero(int[] z)
+ {
+ z[0] = 0;
+ z[1] = 0;
+ z[2] = 0;
+ z[3] = 0;
+ z[4] = 0;
+ z[5] = 0;
+ z[6] = 0;
+ z[7] = 0;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat384.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat384.java
new file mode 100644
index 00000000..6bb1b172
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat384.java
@@ -0,0 +1,47 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.raw;
+
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class Nat384
+{
+ public static void mul(int[] x, int[] y, int[] zz)
+ {
+ Nat192.mul(x, y, zz);
+ Nat192.mul(x, 6, y, 6, zz, 12);
+
+ int c18 = Nat192.addToEachOther(zz, 6, zz, 12);
+ int c12 = c18 + Nat192.addTo(zz, 0, zz, 6, 0);
+ c18 += Nat192.addTo(zz, 18, zz, 12, c12);
+
+ int[] dx = Nat192.create(), dy = Nat192.create();
+ boolean neg = Nat192.diff(x, 6, x, 0, dx, 0) != Nat192.diff(y, 6, y, 0, dy, 0);
+
+ int[] tt = Nat192.createExt();
+ Nat192.mul(dx, dy, tt);
+
+ c18 += neg ? Nat.addTo(12, tt, 0, zz, 6) : Nat.subFrom(12, tt, 0, zz, 6);
+ Nat.addWordAt(24, c18, zz, 18);
+ }
+
+ public static void square(int[] x, int[] zz)
+ {
+ Nat192.square(x, zz);
+ Nat192.square(x, 6, zz, 12);
+
+ int c18 = Nat192.addToEachOther(zz, 6, zz, 12);
+ int c12 = c18 + Nat192.addTo(zz, 0, zz, 6, 0);
+ c18 += Nat192.addTo(zz, 18, zz, 12, c12);
+
+ int[] dx = Nat192.create();
+ Nat192.diff(x, 6, x, 0, dx, 0);
+
+ int[] tt = Nat192.createExt();
+ Nat192.square(dx, tt);
+
+ c18 += Nat.subFrom(12, tt, 0, zz, 6);
+ Nat.addWordAt(24, c18, zz, 18);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat512.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat512.java
new file mode 100644
index 00000000..bf4d5ac2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat512.java
@@ -0,0 +1,47 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.math.raw;
+
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class Nat512
+{
+ public static void mul(int[] x, int[] y, int[] zz)
+ {
+ Nat256.mul(x, y, zz);
+ Nat256.mul(x, 8, y, 8, zz, 16);
+
+ int c24 = Nat256.addToEachOther(zz, 8, zz, 16);
+ int c16 = c24 + Nat256.addTo(zz, 0, zz, 8, 0);
+ c24 += Nat256.addTo(zz, 24, zz, 16, c16);
+
+ int[] dx = Nat256.create(), dy = Nat256.create();
+ boolean neg = Nat256.diff(x, 8, x, 0, dx, 0) != Nat256.diff(y, 8, y, 0, dy, 0);
+
+ int[] tt = Nat256.createExt();
+ Nat256.mul(dx, dy, tt);
+
+ c24 += neg ? Nat.addTo(16, tt, 0, zz, 8) : Nat.subFrom(16, tt, 0, zz, 8);
+ Nat.addWordAt(32, c24, zz, 24);
+ }
+
+ public static void square(int[] x, int[] zz)
+ {
+ Nat256.square(x, zz);
+ Nat256.square(x, 8, zz, 16);
+
+ int c24 = Nat256.addToEachOther(zz, 8, zz, 16);
+ int c16 = c24 + Nat256.addTo(zz, 0, zz, 8, 0);
+ c24 += Nat256.addTo(zz, 24, zz, 16, c16);
+
+ int[] dx = Nat256.create();
+ Nat256.diff(x, 8, x, 0, dx, 0);
+
+ int[] tt = Nat256.createExt();
+ Nat256.square(dx, tt);
+
+ c24 += Nat.subFrom(16, tt, 0, zz, 8);
+ Nat.addWordAt(32, c24, zz, 24);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Arrays.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Arrays.java
new file mode 100644
index 00000000..3ce0b11b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Arrays.java
@@ -0,0 +1,1165 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+import java.math.BigInteger;
+import java.util.NoSuchElementException;
+
+/**
+ * General array utilities.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Arrays
+{
+ private Arrays()
+ {
+ // static class, hide constructor
+ }
+
+ public static boolean areAllZeroes(byte[] buf, int off, int len)
+ {
+ int bits = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ bits |= buf[off + i];
+ }
+ return bits == 0;
+ }
+
+ public static boolean areEqual(boolean[] a, boolean[] b)
+ {
+ return java.util.Arrays.equals(a, b);
+ }
+
+ public static boolean areEqual(byte[] a, byte[] b)
+ {
+ return java.util.Arrays.equals(a, b);
+ }
+
+ public static boolean areEqual(byte[] a, int aFromIndex, int aToIndex, byte[] b, int bFromIndex, int bToIndex)
+ {
+ int aLength = aToIndex - aFromIndex;
+ int bLength = bToIndex - bFromIndex;
+
+ if (aLength != bLength)
+ {
+ return false;
+ }
+
+ for (int i = 0; i < aLength; ++i)
+ {
+ if (a[aFromIndex + i] != b[bFromIndex + i])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean areEqual(char[] a, char[] b)
+ {
+ return java.util.Arrays.equals(a, b);
+ }
+
+ public static boolean areEqual(int[] a, int[] b)
+ {
+ return java.util.Arrays.equals(a, b);
+ }
+
+ public static boolean areEqual(long[] a, long[] b)
+ {
+ return java.util.Arrays.equals(a, b);
+ }
+
+ public static boolean areEqual(Object[] a, Object[] b)
+ {
+ return java.util.Arrays.equals(a, b);
+ }
+
+ public static boolean areEqual(short[] a, short[] b)
+ {
+ return java.util.Arrays.equals(a, b);
+ }
+
+ /**
+ * A constant time equals comparison - does not terminate early if
+ * test will fail. For best results always pass the expected value
+ * as the first parameter.
+ *
+ * @param expected first array
+ * @param supplied second array
+ * @return true if arrays equal, false otherwise.
+ */
+ public static boolean constantTimeAreEqual(
+ byte[] expected,
+ byte[] supplied)
+ {
+ if (expected == null || supplied == null)
+ {
+ return false;
+ }
+
+ if (expected == supplied)
+ {
+ return true;
+ }
+
+ int len = (expected.length < supplied.length) ? expected.length : supplied.length;
+
+ int nonEqual = expected.length ^ supplied.length;
+
+ for (int i = 0; i != len; i++)
+ {
+ nonEqual |= (expected[i] ^ supplied[i]);
+ }
+ for (int i = len; i < supplied.length; i++)
+ {
+ nonEqual |= (supplied[i] ^ ~supplied[i]);
+ }
+
+ return nonEqual == 0;
+ }
+
+ public static boolean constantTimeAreEqual(int len, byte[] a, int aOff, byte[] b, int bOff)
+ {
+ if (null == a)
+ {
+ throw new NullPointerException("'a' cannot be null");
+ }
+ if (null == b)
+ {
+ throw new NullPointerException("'b' cannot be null");
+ }
+ if (len < 0)
+ {
+ throw new IllegalArgumentException("'len' cannot be negative");
+ }
+ if (aOff > (a.length - len))
+ {
+ throw new IndexOutOfBoundsException("'aOff' value invalid for specified length");
+ }
+ if (bOff > (b.length - len))
+ {
+ throw new IndexOutOfBoundsException("'bOff' value invalid for specified length");
+ }
+
+ int d = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ d |= (a[aOff + i] ^ b[bOff + i]);
+ }
+ return 0 == d;
+ }
+
+ public static int compareUnsigned(byte[] a, byte[] b)
+ {
+ if (a == b)
+ {
+ return 0;
+ }
+ if (a == null)
+ {
+ return -1;
+ }
+ if (b == null)
+ {
+ return 1;
+ }
+ int minLen = Math.min(a.length, b.length);
+ for (int i = 0; i < minLen; ++i)
+ {
+ int aVal = a[i] & 0xFF, bVal = b[i] & 0xFF;
+ if (aVal < bVal)
+ {
+ return -1;
+ }
+ if (aVal > bVal)
+ {
+ return 1;
+ }
+ }
+ if (a.length < b.length)
+ {
+ return -1;
+ }
+ if (a.length > b.length)
+ {
+ return 1;
+ }
+ return 0;
+ }
+
+ public static boolean contains(boolean[] a, boolean val)
+ {
+ for (int i = 0; i < a.length; ++i)
+ {
+ if (a[i] == val)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean contains(byte[] a, byte val)
+ {
+ for (int i = 0; i < a.length; ++i)
+ {
+ if (a[i] == val)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean contains(char[] a, char val)
+ {
+ for (int i = 0; i < a.length; ++i)
+ {
+ if (a[i] == val)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean contains(int[] a, int val)
+ {
+ for (int i = 0; i < a.length; ++i)
+ {
+ if (a[i] == val)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean contains(long[] a, long val)
+ {
+ for (int i = 0; i < a.length; ++i)
+ {
+ if (a[i] == val)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean contains(short[] a, short val)
+ {
+ for (int i = 0; i < a.length; ++i)
+ {
+ if (a[i] == val)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static void fill(boolean[] a, boolean val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ public static void fill(boolean[] a, int fromIndex, int toIndex, boolean val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static void fill(byte[] a, byte val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ /**
+ * @deprecated Use {@link #fill(byte[], int, int, byte)} instead.
+ */
+ public static void fill(byte[] a, int fromIndex, byte val)
+ {
+ fill(a, fromIndex, a.length, val);
+ }
+
+ public static void fill(byte[] a, int fromIndex, int toIndex, byte val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static void fill(char[] a, char val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ public static void fill(char[] a, int fromIndex, int toIndex, char val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static void fill(int[] a, int val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ /**
+ * @deprecated Use {@link #fill(int[], int, int, int)} instead.
+ */
+ public static void fill(int[] a, int fromIndex, int val)
+ {
+ java.util.Arrays.fill(a, fromIndex, a.length, val);
+ }
+
+ public static void fill(int[] a, int fromIndex, int toIndex, int val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static void fill(long[] a, long val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ /**
+ * @deprecated Use {@link #fill(long[], int, int, long)} instead.
+ */
+ public static void fill(long[] a, int fromIndex, long val)
+ {
+ java.util.Arrays.fill(a, fromIndex, a.length, val);
+ }
+
+ public static void fill(long[] a, int fromIndex, int toIndex, long val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static void fill(Object[] a, Object val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ public static void fill(Object[] a, int fromIndex, int toIndex, Object val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static void fill(short[] a, short val)
+ {
+ java.util.Arrays.fill(a, val);
+ }
+
+ /**
+ * @deprecated Use {@link #fill(short[], int, int, short)} instead.
+ */
+ public static void fill(short[] a, int fromIndex, short val)
+ {
+ java.util.Arrays.fill(a, fromIndex, a.length, val);
+ }
+
+ public static void fill(short[] a, int fromIndex, int toIndex, short val)
+ {
+ java.util.Arrays.fill(a, fromIndex, toIndex, val);
+ }
+
+ public static int hashCode(byte[] data)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = data.length;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ hc *= 257;
+ hc ^= data[i];
+ }
+
+ return hc;
+ }
+
+ public static int hashCode(byte[] data, int off, int len)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = len;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ hc *= 257;
+ hc ^= data[off + i];
+ }
+
+ return hc;
+ }
+
+ public static int hashCode(char[] data)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = data.length;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ hc *= 257;
+ hc ^= data[i];
+ }
+
+ return hc;
+ }
+
+ public static int hashCode(int[][] ints)
+ {
+ int hc = 0;
+
+ for (int i = 0; i != ints.length; i++)
+ {
+ hc = hc * 257 + hashCode(ints[i]);
+ }
+
+ return hc;
+ }
+
+ public static int hashCode(int[] data)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = data.length;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ hc *= 257;
+ hc ^= data[i];
+ }
+
+ return hc;
+ }
+
+ public static int hashCode(int[] data, int off, int len)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = len;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ hc *= 257;
+ hc ^= data[off + i];
+ }
+
+ return hc;
+ }
+
+ public static int hashCode(long[] data)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = data.length;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ long di = data[i];
+ hc *= 257;
+ hc ^= (int)di;
+ hc *= 257;
+ hc ^= (int)(di >>> 32);
+ }
+
+ return hc;
+ }
+
+ public static int hashCode(long[] data, int off, int len)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = len;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ long di = data[off + i];
+ hc *= 257;
+ hc ^= (int)di;
+ hc *= 257;
+ hc ^= (int)(di >>> 32);
+ }
+
+ return hc;
+ }
+
+ public static int hashCode(short[][][] shorts)
+ {
+ int hc = 0;
+
+ for (int i = 0; i != shorts.length; i++)
+ {
+ hc = hc * 257 + hashCode(shorts[i]);
+ }
+
+ return hc;
+ }
+
+ public static int hashCode(short[][] shorts)
+ {
+ int hc = 0;
+
+ for (int i = 0; i != shorts.length; i++)
+ {
+ hc = hc * 257 + hashCode(shorts[i]);
+ }
+
+ return hc;
+ }
+
+ public static int hashCode(short[] data)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = data.length;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ hc *= 257;
+ hc ^= (data[i] & 0xff);
+ }
+
+ return hc;
+ }
+
+ public static int hashCode(Object[] data)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = data.length;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ hc *= 257;
+ hc ^= Objects.hashCode(data[i]);
+ }
+
+ return hc;
+ }
+
+ public static boolean[] clone(boolean[] data)
+ {
+ return null == data ? null : data.clone();
+ }
+
+ public static byte[] clone(byte[] data)
+ {
+ return null == data ? null : data.clone();
+ }
+
+ public static char[] clone(char[] data)
+ {
+ return null == data ? null : data.clone();
+ }
+
+ public static int[] clone(int[] data)
+ {
+ return null == data ? null : data.clone();
+ }
+
+ public static long[] clone(long[] data)
+ {
+ return null == data ? null : data.clone();
+ }
+
+ public static short[] clone(short[] data)
+ {
+ return null == data ? null : data.clone();
+ }
+
+ public static BigInteger[] clone(BigInteger[] data)
+ {
+ return null == data ? null : data.clone();
+ }
+
+ public static byte[] clone(byte[] data, byte[] existing)
+ {
+ if (data == null)
+ {
+ return null;
+ }
+ if ((existing == null) || (existing.length != data.length))
+ {
+ return clone(data);
+ }
+ System.arraycopy(data, 0, existing, 0, existing.length);
+ return existing;
+ }
+
+ public static long[] clone(long[] data, long[] existing)
+ {
+ if (data == null)
+ {
+ return null;
+ }
+ if ((existing == null) || (existing.length != data.length))
+ {
+ return clone(data);
+ }
+ System.arraycopy(data, 0, existing, 0, existing.length);
+ return existing;
+ }
+
+ public static byte[][] clone(byte[][] data)
+ {
+ if (data == null)
+ {
+ return null;
+ }
+
+ byte[][] copy = new byte[data.length][];
+
+ for (int i = 0; i != copy.length; i++)
+ {
+ copy[i] = clone(data[i]);
+ }
+
+ return copy;
+ }
+
+ public static byte[][][] clone(byte[][][] data)
+ {
+ if (data == null)
+ {
+ return null;
+ }
+
+ byte[][][] copy = new byte[data.length][][];
+
+ for (int i = 0; i != copy.length; i++)
+ {
+ copy[i] = clone(data[i]);
+ }
+
+ return copy;
+ }
+
+ public static boolean[] copyOf(boolean[] original, int newLength)
+ {
+ boolean[] copy = new boolean[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
+ }
+
+ public static byte[] copyOf(byte[] original, int newLength)
+ {
+ byte[] copy = new byte[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
+ }
+
+ public static char[] copyOf(char[] original, int newLength)
+ {
+ char[] copy = new char[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
+ }
+
+ public static int[] copyOf(int[] original, int newLength)
+ {
+ int[] copy = new int[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
+ }
+
+ public static long[] copyOf(long[] original, int newLength)
+ {
+ long[] copy = new long[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
+ }
+
+ public static short[] copyOf(short[] original, int newLength)
+ {
+ short[] copy = new short[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
+ }
+
+ public static BigInteger[] copyOf(BigInteger[] original, int newLength)
+ {
+ BigInteger[] copy = new BigInteger[newLength];
+ System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+ return copy;
+ }
+
+ public static boolean[] copyOfRange(boolean[] original, int from, int to)
+ {
+ int newLength = getLength(from, to);
+ boolean[] copy = new boolean[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
+ }
+
+ /**
+ * Make a copy of a range of bytes from the passed in array. The range can extend beyond the end
+ * of the input array, in which case the returned array will be padded with zeroes.
+ *
+ * @param original
+ * the array from which the data is to be copied.
+ * @param from
+ * the start index at which the copying should take place.
+ * @param to
+ * the final index of the range (exclusive).
+ *
+ * @return a new byte array containing the range given.
+ */
+ public static byte[] copyOfRange(byte[] original, int from, int to)
+ {
+ int newLength = getLength(from, to);
+ byte[] copy = new byte[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
+ }
+
+ public static char[] copyOfRange(char[] original, int from, int to)
+ {
+ int newLength = getLength(from, to);
+ char[] copy = new char[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
+ }
+
+ public static int[] copyOfRange(int[] original, int from, int to)
+ {
+ int newLength = getLength(from, to);
+ int[] copy = new int[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
+ }
+
+ public static long[] copyOfRange(long[] original, int from, int to)
+ {
+ int newLength = getLength(from, to);
+ long[] copy = new long[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
+ }
+
+ public static short[] copyOfRange(short[] original, int from, int to)
+ {
+ int newLength = getLength(from, to);
+ short[] copy = new short[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
+ }
+
+ public static BigInteger[] copyOfRange(BigInteger[] original, int from, int to)
+ {
+ int newLength = getLength(from, to);
+ BigInteger[] copy = new BigInteger[newLength];
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
+ }
+
+ private static int getLength(int from, int to)
+ {
+ int newLength = to - from;
+ if (newLength < 0)
+ {
+ StringBuffer sb = new StringBuffer(from);
+ sb.append(" > ").append(to);
+ throw new IllegalArgumentException(sb.toString());
+ }
+ return newLength;
+ }
+
+ public static byte[] append(byte[] a, byte b)
+ {
+ if (a == null)
+ {
+ return new byte[]{ b };
+ }
+
+ int length = a.length;
+ byte[] result = new byte[length + 1];
+ System.arraycopy(a, 0, result, 0, length);
+ result[length] = b;
+ return result;
+ }
+
+ public static short[] append(short[] a, short b)
+ {
+ if (a == null)
+ {
+ return new short[]{ b };
+ }
+
+ int length = a.length;
+ short[] result = new short[length + 1];
+ System.arraycopy(a, 0, result, 0, length);
+ result[length] = b;
+ return result;
+ }
+
+ public static int[] append(int[] a, int b)
+ {
+ if (a == null)
+ {
+ return new int[]{ b };
+ }
+
+ int length = a.length;
+ int[] result = new int[length + 1];
+ System.arraycopy(a, 0, result, 0, length);
+ result[length] = b;
+ return result;
+ }
+
+ public static String[] append(String[] a, String b)
+ {
+ if (a == null)
+ {
+ return new String[]{ b };
+ }
+
+ int length = a.length;
+ String[] result = new String[length + 1];
+ System.arraycopy(a, 0, result, 0, length);
+ result[length] = b;
+ return result;
+ }
+
+ public static byte[] concatenate(byte[] a, byte[] b)
+ {
+ if (null == a)
+ {
+ // b might also be null
+ return clone(b);
+ }
+ if (null == b)
+ {
+ // a might also be null
+ return clone(a);
+ }
+
+ byte[] r = new byte[a.length + b.length];
+ System.arraycopy(a, 0, r, 0, a.length);
+ System.arraycopy(b, 0, r, a.length, b.length);
+ return r;
+ }
+
+ public static short[] concatenate(short[] a, short[] b)
+ {
+ if (null == a)
+ {
+ // b might also be null
+ return clone(b);
+ }
+ if (null == b)
+ {
+ // a might also be null
+ return clone(a);
+ }
+
+ short[] r = new short[a.length + b.length];
+ System.arraycopy(a, 0, r, 0, a.length);
+ System.arraycopy(b, 0, r, a.length, b.length);
+ return r;
+ }
+
+ public static byte[] concatenate(byte[] a, byte[] b, byte[] c)
+ {
+ if (null == a)
+ {
+ return concatenate(b, c);
+ }
+ if (null == b)
+ {
+ return concatenate(a, c);
+ }
+ if (null == c)
+ {
+ return concatenate(a, b);
+ }
+
+ byte[] r = new byte[a.length + b.length + c.length];
+ int pos = 0;
+ System.arraycopy(a, 0, r, pos, a.length); pos += a.length;
+ System.arraycopy(b, 0, r, pos, b.length); pos += b.length;
+ System.arraycopy(c, 0, r, pos, c.length);
+ return r;
+ }
+
+ public static byte[] concatenate(byte[] a, byte[] b, byte[] c, byte[] d)
+ {
+ if (null == a)
+ {
+ return concatenate(b, c, d);
+ }
+ if (null == b)
+ {
+ return concatenate(a, c, d);
+ }
+ if (null == c)
+ {
+ return concatenate(a, b, d);
+ }
+ if (null == d)
+ {
+ return concatenate(a, b, c);
+ }
+
+ byte[] r = new byte[a.length + b.length + c.length + d.length];
+ int pos = 0;
+ System.arraycopy(a, 0, r, pos, a.length); pos += a.length;
+ System.arraycopy(b, 0, r, pos, b.length); pos += b.length;
+ System.arraycopy(c, 0, r, pos, c.length); pos += c.length;
+ System.arraycopy(d, 0, r, pos, d.length);
+ return r;
+ }
+
+ public static byte[] concatenate(byte[][] arrays)
+ {
+ int size = 0;
+ for (int i = 0; i != arrays.length; i++)
+ {
+ size += arrays[i].length;
+ }
+
+ byte[] rv = new byte[size];
+
+ int offSet = 0;
+ for (int i = 0; i != arrays.length; i++)
+ {
+ System.arraycopy(arrays[i], 0, rv, offSet, arrays[i].length);
+ offSet += arrays[i].length;
+ }
+
+ return rv;
+ }
+
+ public static int[] concatenate(int[] a, int[] b)
+ {
+ if (null == a)
+ {
+ // b might also be null
+ return clone(b);
+ }
+ if (null == b)
+ {
+ // a might also be null
+ return clone(a);
+ }
+
+ int[] r = new int[a.length + b.length];
+ System.arraycopy(a, 0, r, 0, a.length);
+ System.arraycopy(b, 0, r, a.length, b.length);
+ return r;
+ }
+
+ public static byte[] prepend(byte[] a, byte b)
+ {
+ if (a == null)
+ {
+ return new byte[]{ b };
+ }
+
+ int length = a.length;
+ byte[] result = new byte[length + 1];
+ System.arraycopy(a, 0, result, 1, length);
+ result[0] = b;
+ return result;
+ }
+
+ public static short[] prepend(short[] a, short b)
+ {
+ if (a == null)
+ {
+ return new short[]{ b };
+ }
+
+ int length = a.length;
+ short[] result = new short[length + 1];
+ System.arraycopy(a, 0, result, 1, length);
+ result[0] = b;
+ return result;
+ }
+
+ public static int[] prepend(int[] a, int b)
+ {
+ if (a == null)
+ {
+ return new int[]{ b };
+ }
+
+ int length = a.length;
+ int[] result = new int[length + 1];
+ System.arraycopy(a, 0, result, 1, length);
+ result[0] = b;
+ return result;
+ }
+
+ public static byte[] reverse(byte[] a)
+ {
+ if (a == null)
+ {
+ return null;
+ }
+
+ int p1 = 0, p2 = a.length;
+ byte[] result = new byte[p2];
+
+ while (--p2 >= 0)
+ {
+ result[p2] = a[p1++];
+ }
+
+ return result;
+ }
+
+ public static int[] reverse(int[] a)
+ {
+ if (a == null)
+ {
+ return null;
+ }
+
+ int p1 = 0, p2 = a.length;
+ int[] result = new int[p2];
+
+ while (--p2 >= 0)
+ {
+ result[p2] = a[p1++];
+ }
+
+ return result;
+ }
+
+ /**
+ * Iterator backed by a specific array.
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class Iterator<T>
+ implements java.util.Iterator<T>
+ {
+ private final T[] dataArray;
+
+ private int position = 0;
+
+ /**
+ * Base constructor.
+ * <p>
+ * Note: the array is not cloned, changes to it will affect the values returned by next().
+ * </p>
+ *
+ * @param dataArray array backing the iterator.
+ */
+ public Iterator(T[] dataArray)
+ {
+ this.dataArray = dataArray;
+ }
+
+ public boolean hasNext()
+ {
+ return position < dataArray.length;
+ }
+
+ public T next()
+ {
+ if (position == dataArray.length)
+ {
+ throw new NoSuchElementException("Out of elements: " + position);
+ }
+
+ return dataArray[position++];
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException("Cannot remove element from an Array.");
+ }
+ }
+
+ /**
+ * Fill input array by zeros
+ *
+ * @param data input array
+ */
+ public static void clear(byte[] data)
+ {
+ if (null != data)
+ {
+ java.util.Arrays.fill(data, (byte)0x00);
+ }
+ }
+
+ public static void clear(int[] data)
+ {
+ if (null != data)
+ {
+ java.util.Arrays.fill(data, 0);
+ }
+ }
+
+ public static boolean isNullOrContainsNull(Object[] array)
+ {
+ if (null == array)
+ {
+ return true;
+ }
+ int count = array.length;
+ for (int i = 0; i < count; ++i)
+ {
+ if (null == array[i])
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean isNullOrEmpty(byte[] array)
+ {
+ return null == array || array.length < 1;
+ }
+
+ public static boolean isNullOrEmpty(int[] array)
+ {
+ return null == array || array.length < 1;
+ }
+
+ public static boolean isNullOrEmpty(Object[] array)
+ {
+ return null == array || array.length < 1;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/BigIntegers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/BigIntegers.java
new file mode 100644
index 00000000..62a5367c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/BigIntegers.java
@@ -0,0 +1,352 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import com.android.internal.org.bouncycastle.math.raw.Mod;
+import com.android.internal.org.bouncycastle.math.raw.Nat;
+
+/**
+ * BigInteger utilities.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class BigIntegers
+{
+ public static final BigInteger ZERO = BigInteger.valueOf(0);
+ public static final BigInteger ONE = BigInteger.valueOf(1);
+ public static final BigInteger TWO = BigInteger.valueOf(2);
+
+ private static final BigInteger THREE = BigInteger.valueOf(3);
+
+ private static final int MAX_ITERATIONS = 1000;
+
+ /**
+ * Return the passed in value as an unsigned byte array.
+ *
+ * @param value the value to be converted.
+ * @return a byte array without a leading zero byte if present in the signed encoding.
+ */
+ public static byte[] asUnsignedByteArray(
+ BigInteger value)
+ {
+ byte[] bytes = value.toByteArray();
+
+ if (bytes[0] == 0 && bytes.length != 1)
+ {
+ byte[] tmp = new byte[bytes.length - 1];
+
+ System.arraycopy(bytes, 1, tmp, 0, tmp.length);
+
+ return tmp;
+ }
+
+ return bytes;
+ }
+
+ /**
+ * Return the passed in value as an unsigned byte array of the specified length, padded with
+ * leading zeros as necessary..
+ *
+ * @param length
+ * the fixed length of the result
+ * @param value
+ * the value to be converted.
+ * @return a byte array padded to a fixed length with leading zeros.
+ */
+ public static byte[] asUnsignedByteArray(int length, BigInteger value)
+ {
+ byte[] bytes = value.toByteArray();
+ if (bytes.length == length)
+ {
+ return bytes;
+ }
+
+ int start = (bytes[0] == 0 && bytes.length != 1) ? 1 : 0;
+ int count = bytes.length - start;
+
+ if (count > length)
+ {
+ throw new IllegalArgumentException("standard length exceeded for value");
+ }
+
+ byte[] tmp = new byte[length];
+ System.arraycopy(bytes, start, tmp, tmp.length - count, count);
+ return tmp;
+ }
+
+ /**
+ * Write the passed in value as unsigned bytes to the specified buffer range, padded with
+ * leading zeros as necessary.
+ *
+ * @param value
+ * the value to be converted.
+ * @param buf
+ * the buffer to which the value is written.
+ * @param off
+ * the start offset in array <code>buf</code> at which the data is written.
+ * @param len
+ * the fixed length of data written (possibly padded with leading zeros).
+ */
+ public static void asUnsignedByteArray(BigInteger value, byte[] buf, int off, int len)
+ {
+ byte[] bytes = value.toByteArray();
+ if (bytes.length == len)
+ {
+ System.arraycopy(bytes, 0, buf, off, len);
+ return;
+ }
+
+ int start = (bytes[0] == 0 && bytes.length != 1) ? 1 : 0;
+ int count = bytes.length - start;
+
+ if (count > len)
+ {
+ throw new IllegalArgumentException("standard length exceeded for value");
+ }
+
+ int padLen = len - count;
+ Arrays.fill(buf, off, off + padLen, (byte)0x00);
+ System.arraycopy(bytes, start, buf, off + padLen, count);
+ }
+
+ /**
+ * Return a random BigInteger not less than 'min' and not greater than 'max'
+ *
+ * @param min the least value that may be generated
+ * @param max the greatest value that may be generated
+ * @param random the source of randomness
+ * @return a random BigInteger value in the range [min,max]
+ */
+ public static BigInteger createRandomInRange(
+ BigInteger min,
+ BigInteger max,
+ SecureRandom random)
+ {
+ int cmp = min.compareTo(max);
+ if (cmp >= 0)
+ {
+ if (cmp > 0)
+ {
+ throw new IllegalArgumentException("'min' may not be greater than 'max'");
+ }
+
+ return min;
+ }
+
+ if (min.bitLength() > max.bitLength() / 2)
+ {
+ return createRandomInRange(ZERO, max.subtract(min), random).add(min);
+ }
+
+ for (int i = 0; i < MAX_ITERATIONS; ++i)
+ {
+ BigInteger x = createRandomBigInteger(max.bitLength(), random);
+ if (x.compareTo(min) >= 0 && x.compareTo(max) <= 0)
+ {
+ return x;
+ }
+ }
+
+ // fall back to a faster (restricted) method
+ return createRandomBigInteger(max.subtract(min).bitLength() - 1, random).add(min);
+ }
+
+ public static BigInteger fromUnsignedByteArray(byte[] buf)
+ {
+ return new BigInteger(1, buf);
+ }
+
+ public static BigInteger fromUnsignedByteArray(byte[] buf, int off, int length)
+ {
+ byte[] mag = buf;
+ if (off != 0 || length != buf.length)
+ {
+ mag = new byte[length];
+ System.arraycopy(buf, off, mag, 0, length);
+ }
+ return new BigInteger(1, mag);
+ }
+
+ public static int intValueExact(BigInteger x)
+ {
+ // Since Java 1.8 could use BigInteger.intValueExact instead
+ if (x.bitLength() > 31)
+ {
+ throw new ArithmeticException("BigInteger out of int range");
+ }
+
+ return x.intValue();
+ }
+
+ public static long longValueExact(BigInteger x)
+ {
+ // Since Java 1.8 could use BigInteger.longValueExact instead
+ if (x.bitLength() > 63)
+ {
+ throw new ArithmeticException("BigInteger out of long range");
+ }
+
+ return x.longValue();
+ }
+
+ public static BigInteger modOddInverse(BigInteger M, BigInteger X)
+ {
+ if (!M.testBit(0))
+ {
+ throw new IllegalArgumentException("'M' must be odd");
+ }
+ if (M.signum() != 1)
+ {
+ throw new ArithmeticException("BigInteger: modulus not positive");
+ }
+ if (X.signum() < 0 || X.compareTo(M) >= 0)
+ {
+ X = X.mod(M);
+ }
+
+ int bits = M.bitLength();
+ int[] m = Nat.fromBigInteger(bits, M);
+ int[] x = Nat.fromBigInteger(bits, X);
+ int len = m.length;
+ int[] z = Nat.create(len);
+ if (0 == Mod.modOddInverse(m, x, z))
+ {
+ throw new ArithmeticException("BigInteger not invertible.");
+ }
+ return Nat.toBigInteger(len, z);
+ }
+
+ public static BigInteger modOddInverseVar(BigInteger M, BigInteger X)
+ {
+ if (!M.testBit(0))
+ {
+ throw new IllegalArgumentException("'M' must be odd");
+ }
+ if (M.signum() != 1)
+ {
+ throw new ArithmeticException("BigInteger: modulus not positive");
+ }
+ if (M.equals(ONE))
+ {
+ return ZERO;
+ }
+ if (X.signum() < 0 || X.compareTo(M) >= 0)
+ {
+ X = X.mod(M);
+ }
+ if (X.equals(ONE))
+ {
+ return ONE;
+ }
+
+ int bits = M.bitLength();
+ int[] m = Nat.fromBigInteger(bits, M);
+ int[] x = Nat.fromBigInteger(bits, X);
+ int len = m.length;
+ int[] z = Nat.create(len);
+ if (!Mod.modOddInverseVar(m, x, z))
+ {
+ throw new ArithmeticException("BigInteger not invertible.");
+ }
+ return Nat.toBigInteger(len, z);
+ }
+
+ public static int getUnsignedByteLength(BigInteger n)
+ {
+ if (n.equals(ZERO))
+ {
+ return 1;
+ }
+
+ return (n.bitLength() + 7) / 8;
+ }
+
+ /**
+ * Return a positive BigInteger in the range of 0 to 2**bitLength - 1.
+ *
+ * @param bitLength maximum bit length for the generated BigInteger.
+ * @param random a source of randomness.
+ * @return a positive BigInteger
+ */
+ public static BigInteger createRandomBigInteger(int bitLength, SecureRandom random)
+ {
+ return new BigInteger(1, createRandom(bitLength, random));
+ }
+
+ // Hexadecimal value of the product of the 131 smallest odd primes from 3 to 743
+ private static final BigInteger SMALL_PRIMES_PRODUCT = new BigInteger(
+ "8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
+ + "73d893fa424cd2edc8636a6c3285e022b0e3866a565ae8108eed8591cd4fe8d2"
+ + "ce86165a978d719ebf647f362d33fca29cd179fb42401cbaf3df0c614056f9c8"
+ + "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f",
+ 16);
+ private static final int MAX_SMALL = BigInteger.valueOf(743).bitLength(); // bitlength of 743 * 743
+
+ /**
+ * Return a prime number candidate of the specified bit length.
+ *
+ * @param bitLength bit length for the generated BigInteger.
+ * @param random a source of randomness.
+ * @return a positive BigInteger of numBits length
+ */
+ public static BigInteger createRandomPrime(int bitLength, int certainty, SecureRandom random)
+ {
+ if (bitLength < 2)
+ {
+ throw new IllegalArgumentException("bitLength < 2");
+ }
+
+ BigInteger rv;
+
+ if (bitLength == 2)
+ {
+ return (random.nextInt() < 0) ? TWO : THREE;
+ }
+
+ do
+ {
+ byte[] base = createRandom(bitLength, random);
+
+ int xBits = 8 * base.length - bitLength;
+ byte lead = (byte)(1 << (7 - xBits));
+
+ // ensure top and bottom bit set
+ base[0] |= lead;
+ base[base.length - 1] |= 0x01;
+
+ rv = new BigInteger(1, base);
+ if (bitLength > MAX_SMALL)
+ {
+ while (!rv.gcd(SMALL_PRIMES_PRODUCT).equals(ONE))
+ {
+ rv = rv.add(TWO);
+ }
+ }
+ }
+ while (!rv.isProbablePrime(certainty));
+
+ return rv;
+ }
+
+ private static byte[] createRandom(int bitLength, SecureRandom random)
+ throws IllegalArgumentException
+ {
+ if (bitLength < 1)
+ {
+ throw new IllegalArgumentException("bitLength must be at least 1");
+ }
+
+ int nBytes = (bitLength + 7) / 8;
+
+ byte[] rv = new byte[nBytes];
+
+ random.nextBytes(rv);
+
+ // strip off any excess bits in the MSB
+ int xBits = 8 * nBytes - bitLength;
+ rv[0] &= (byte)(255 >>> xBits);
+
+ return rv;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/CollectionStore.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/CollectionStore.java
new file mode 100644
index 00000000..f1c1c3b8
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/CollectionStore.java
@@ -0,0 +1,64 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A simple collection backed store.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CollectionStore<T>
+ implements Store<T>, Iterable<T>
+{
+ private Collection<T> _local;
+
+ /**
+ * Basic constructor.
+ *
+ * @param collection - initial contents for the store, this is copied.
+ */
+ public CollectionStore(
+ Collection<T> collection)
+ {
+ _local = new ArrayList<T>(collection);
+ }
+
+ /**
+ * Return the matches in the collection for the passed in selector.
+ *
+ * @param selector the selector to match against.
+ * @return a possibly empty collection of matching objects.
+ */
+ public Collection<T> getMatches(Selector<T> selector)
+ {
+ if (selector == null)
+ {
+ return new ArrayList<T>(_local);
+ }
+ else
+ {
+ List<T> col = new ArrayList<T>();
+ Iterator<T> iter = _local.iterator();
+
+ while (iter.hasNext())
+ {
+ T obj = iter.next();
+
+ if (selector.match(obj))
+ {
+ col.add(obj);
+ }
+ }
+
+ return col;
+ }
+ }
+
+ public Iterator<T> iterator()
+ {
+ return getMatches(null).iterator();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Doubles.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Doubles.java
new file mode 100644
index 00000000..af8eaf92
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Doubles.java
@@ -0,0 +1,13 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Doubles
+{
+ public static Double valueOf(double value)
+ {
+ return Double.valueOf(value);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Encodable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Encodable.java
new file mode 100644
index 00000000..5cdbe5a6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Encodable.java
@@ -0,0 +1,20 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+import java.io.IOException;
+
+/**
+ * Interface implemented by objects that can be converted into byte arrays.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Encodable
+{
+ /**
+ * Return a byte array representing the implementing object.
+ *
+ * @return a byte array representing the encoding.
+ * @throws java.io.IOException if an issue arises generation the encoding.
+ */
+ byte[] getEncoded()
+ throws IOException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Fingerprint.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Fingerprint.java
new file mode 100644
index 00000000..21bdf6b9
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Fingerprint.java
@@ -0,0 +1,182 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+// Android-changed: Use Android digests
+// import org.bouncycastle.crypto.digests.SHA512tDigest;
+// import org.bouncycastle.crypto.digests.SHAKEDigest;
+import com.android.internal.org.bouncycastle.crypto.Digest;
+import com.android.internal.org.bouncycastle.crypto.digests.AndroidDigestFactory;
+
+/**
+ * Basic 20 byte finger print class.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Fingerprint
+{
+ private static char[] encodingTable =
+ {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+ };
+
+ private final byte[] fingerprint;
+
+ /**
+ * Base constructor - use SHAKE-256 (160 bits). This is the recommended one as it is also
+ * produced by the FIPS API.
+ *
+ * @param source original data to calculate the fingerprint from.
+ */
+ public Fingerprint(byte[] source)
+ {
+ this(source, 160);
+ }
+
+ /**
+ * Constructor with length - use SHAKE-256 (bitLength bits). This is the recommended one as it is also
+ * produced by the FIPS API.
+ *
+ * @param source original data to calculate the fingerprint from.
+ */
+ public Fingerprint(byte[] source, int bitLength)
+ {
+ this.fingerprint = calculateFingerprint(source, bitLength);
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /*
+ /**
+ * Base constructor - for backwards compatibility.
+ *
+ * @param source original data to calculate the fingerprint from.
+ * @param useSHA512t use the old SHA512/160 calculation.
+ * @deprecated use the SHAKE only version.
+ *
+ public Fingerprint(byte[] source, boolean useSHA512t)
+ {
+ if (useSHA512t)
+ {
+ this.fingerprint = calculateFingerprintSHA512_160(source);
+ }
+ else
+ {
+ this.fingerprint = calculateFingerprint(source);
+ }
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+
+ public byte[] getFingerprint()
+ {
+ return Arrays.clone(fingerprint);
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i != fingerprint.length; i++)
+ {
+ if (i > 0)
+ {
+ sb.append(":");
+ }
+ sb.append(encodingTable[(fingerprint[i] >>> 4) & 0xf]);
+ sb.append(encodingTable[fingerprint[i] & 0x0f]);
+ }
+
+ return sb.toString();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+ if (o instanceof Fingerprint)
+ {
+ return Arrays.areEqual(((Fingerprint)o).fingerprint, fingerprint);
+ }
+
+ return false;
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(fingerprint);
+ }
+
+ /**
+ * Return a byte array containing a calculated fingerprint for the passed in input data.
+ * This calculation is compatible with the BC FIPS API.
+ *
+ * @param input data to base the fingerprint on.
+ * @return a byte array containing a 160 bit fingerprint.
+ */
+ public static byte[] calculateFingerprint(byte[] input)
+ {
+ return calculateFingerprint(input, 160);
+ }
+
+ /*
+ /**
+ * Return a byte array containing a calculated fingerprint for the passed in input data.
+ * This calculation is compatible with the BC FIPS API.
+ *
+ * @param input data to base the fingerprint on.
+ * @param bitLength bit length of finger print to be produced.
+ * @return a byte array containing a 20 byte fingerprint.
+ */
+ public static byte[] calculateFingerprint(byte[] input, int bitLength)
+ {
+ if (bitLength % 8 != 0)
+ {
+ throw new IllegalArgumentException("bitLength must be a multiple of 8");
+ }
+
+ // Android-changed: Use SHA-256 instead of SHAKE-256, since we don't support SHAKE
+ // SHAKEDigest digest = new SHAKEDigest(256);
+ Digest digest = AndroidDigestFactory.getSHA256();
+
+ digest.update(input, 0, input.length);
+
+ byte[] rv = new byte[bitLength / 8];
+
+ // Android-changed: Hash and truncate since SHA-256 doesn't support variable length output
+ //
+ // digest.doFinal(rv, 0, bitLength / 8);
+ byte[] untruncated = new byte[32];
+ digest.doFinal(untruncated, 0);
+ if ((bitLength / 8) >= 32) {
+ return untruncated;
+ }
+
+ System.arraycopy(untruncated, 0, rv, 0, rv.length);
+
+ return rv;
+ }
+
+ // BEGIN Android-removed: Unsupported algorithms
+ /**
+ * Return a byte array containing a calculated fingerprint for the passed in input data.
+ * The fingerprint is based on SHA512/160.
+ *
+ * @param input data to base the fingerprint on.
+ * @return a byte array containing a 20 byte fingerprint.
+ * @deprecated use the SHAKE based version.
+ *
+ public static byte[] calculateFingerprintSHA512_160(byte[] input)
+ {
+ SHA512tDigest digest = new SHA512tDigest(160);
+
+ digest.update(input, 0, input.length);
+
+ byte[] rv = new byte[digest.getDigestSize()];
+
+ digest.doFinal(rv, 0);
+
+ return rv;
+ }
+ */
+ // END Android-removed: Unsupported algorithms
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/IPAddress.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/IPAddress.java
new file mode 100644
index 00000000..47c159a7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/IPAddress.java
@@ -0,0 +1,193 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+/**
+ * Utility methods for processing String objects containing IP addresses.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class IPAddress
+{
+ /**
+ * Validate the given IPv4 or IPv6 address.
+ *
+ * @param address the IP address as a String.
+ *
+ * @return true if a valid address, false otherwise
+ */
+ public static boolean isValid(
+ String address)
+ {
+ return isValidIPv4(address) || isValidIPv6(address);
+ }
+
+ /**
+ * Validate the given IPv4 or IPv6 address and netmask.
+ *
+ * @param address the IP address as a String.
+ *
+ * @return true if a valid address with netmask, false otherwise
+ */
+ public static boolean isValidWithNetMask(
+ String address)
+ {
+ return isValidIPv4WithNetmask(address) || isValidIPv6WithNetmask(address);
+ }
+
+ /**
+ * Validate the given IPv4 address.
+ *
+ * @param address the IP address as a String.
+ *
+ * @return true if a valid IPv4 address, false otherwise
+ */
+ public static boolean isValidIPv4(
+ String address)
+ {
+ if (address.length() == 0)
+ {
+ return false;
+ }
+
+ int octet;
+ int octets = 0;
+
+ String temp = address+".";
+
+ int pos;
+ int start = 0;
+ while (start < temp.length()
+ && (pos = temp.indexOf('.', start)) > start)
+ {
+ if (octets == 4)
+ {
+ return false;
+ }
+ try
+ {
+ octet = Integer.parseInt(temp.substring(start, pos));
+ }
+ catch (NumberFormatException ex)
+ {
+ return false;
+ }
+ if (octet < 0 || octet > 255)
+ {
+ return false;
+ }
+ start = pos + 1;
+ octets++;
+ }
+
+ return octets == 4;
+ }
+
+ public static boolean isValidIPv4WithNetmask(
+ String address)
+ {
+ int index = address.indexOf("/");
+ String mask = address.substring(index + 1);
+
+ return (index > 0) && isValidIPv4(address.substring(0, index))
+ && (isValidIPv4(mask) || isMaskValue(mask, 32));
+ }
+
+ public static boolean isValidIPv6WithNetmask(
+ String address)
+ {
+ int index = address.indexOf("/");
+ String mask = address.substring(index + 1);
+
+ return (index > 0) && (isValidIPv6(address.substring(0, index))
+ && (isValidIPv6(mask) || isMaskValue(mask, 128)));
+ }
+
+ private static boolean isMaskValue(String component, int size)
+ {
+ try
+ {
+ int value = Integer.parseInt(component);
+
+ return value >= 0 && value <= size;
+ }
+ catch (NumberFormatException e)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Validate the given IPv6 address.
+ *
+ * @param address the IP address as a String.
+ *
+ * @return true if a valid IPv6 address, false otherwise
+ */
+ public static boolean isValidIPv6(
+ String address)
+ {
+ if (address.length() == 0)
+ {
+ return false;
+ }
+
+ int octet;
+ int octets = 0;
+
+ String temp = address + ":";
+ boolean doubleColonFound = false;
+ int pos;
+ int start = 0;
+ while (start < temp.length()
+ && (pos = temp.indexOf(':', start)) >= start)
+ {
+ if (octets == 8)
+ {
+ return false;
+ }
+
+ if (start != pos)
+ {
+ String value = temp.substring(start, pos);
+
+ if (pos == (temp.length() - 1) && value.indexOf('.') > 0)
+ {
+ if (!isValidIPv4(value))
+ {
+ return false;
+ }
+
+ octets++; // add an extra one as address covers 2 words.
+ }
+ else
+ {
+ try
+ {
+ octet = Integer.parseInt(temp.substring(start, pos), 16);
+ }
+ catch (NumberFormatException ex)
+ {
+ return false;
+ }
+ if (octet < 0 || octet > 0xffff)
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ if (pos != 1 && pos != temp.length() - 1 && doubleColonFound)
+ {
+ return false;
+ }
+ doubleColonFound = true;
+ }
+ start = pos + 1;
+ octets++;
+ }
+
+ return octets == 8 || doubleColonFound;
+ }
+}
+
+
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Integers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Integers.java
new file mode 100644
index 00000000..09db1219
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Integers.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+/**
+ * Utility methods for ints.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Integers
+{
+ public static int numberOfLeadingZeros(int i)
+ {
+ return Integer.numberOfLeadingZeros(i);
+ }
+
+ public static int numberOfTrailingZeros(int i)
+ {
+ return Integer.numberOfTrailingZeros(i);
+ }
+
+ public static int reverse(int i)
+ {
+ return Integer.reverse(i);
+ }
+
+ public static int reverseBytes(int i)
+ {
+ return Integer.reverseBytes(i);
+ }
+
+ public static int rotateLeft(int i, int distance)
+ {
+ return Integer.rotateLeft(i, distance);
+ }
+
+ public static int rotateRight(int i, int distance)
+ {
+ return Integer.rotateRight(i, distance);
+ }
+
+ public static Integer valueOf(int value)
+ {
+ return Integer.valueOf(value);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Iterable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Iterable.java
new file mode 100644
index 00000000..79094a19
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Iterable.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+import java.util.Iterator;
+
+/**
+ * Utility class to allow use of Iterable feature in JDK 1.5+
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Iterable<T>
+ extends java.lang.Iterable<T>
+{
+ /**
+ * Returns an iterator over a set of elements of type T.
+ *
+ * @return an Iterator.
+ */
+ Iterator<T> iterator();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Longs.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Longs.java
new file mode 100644
index 00000000..f41ee5f3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Longs.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Longs
+{
+ public static long reverse(long i)
+ {
+ return Long.reverse(i);
+ }
+
+ public static long reverseBytes(long i)
+ {
+ return Long.reverseBytes(i);
+ }
+
+ public static long rotateLeft(long i, int distance)
+ {
+ return Long.rotateLeft(i, distance);
+ }
+
+ public static long rotateRight(long i, int distance)
+ {
+ return Long.rotateRight(i, distance);
+ }
+
+ public static Long valueOf(long value)
+ {
+ return Long.valueOf(value);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Memoable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Memoable.java
new file mode 100644
index 00000000..75ce09a7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Memoable.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+/**
+ * Interface for Memoable objects. Memoable objects allow the taking of a snapshot of their internal state
+ * via the copy() method and then reseting the object back to that state later using the reset() method.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Memoable
+{
+ /**
+ * Produce a copy of this object with its configuration and in its current state.
+ * <p>
+ * The returned object may be used simply to store the state, or may be used as a similar object
+ * starting from the copied state.
+ */
+ Memoable copy();
+
+ /**
+ * Restore a copied object state into this object.
+ * <p>
+ * Implementations of this method <em>should</em> try to avoid or minimise memory allocation to perform the reset.
+ *
+ * @param other an object originally {@link #copy() copied} from an object of the same type as this instance.
+ * @throws ClassCastException if the provided object is not of the correct type.
+ * @throws MemoableResetException if the <b>other</b> parameter is in some other way invalid.
+ */
+ void reset(Memoable other);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Objects.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Objects.java
new file mode 100644
index 00000000..231fff67
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Objects.java
@@ -0,0 +1,18 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Objects
+{
+ public static boolean areEqual(Object a, Object b)
+ {
+ return a == b || (null != a && null != b && a.equals(b));
+ }
+
+ public static int hashCode(Object obj)
+ {
+ return null == obj ? 0 : obj.hashCode();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Pack.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Pack.java
new file mode 100644
index 00000000..ef00137e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Pack.java
@@ -0,0 +1,339 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+/**
+ * Utility methods for converting byte arrays into ints and longs, and back again.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class Pack
+{
+ public static short bigEndianToShort(byte[] bs, int off)
+ {
+ int n = (bs[off] & 0xff) << 8;
+ n |= (bs[++off] & 0xff);
+ return (short)n;
+ }
+
+ public static int bigEndianToInt(byte[] bs, int off)
+ {
+ int n = bs[off] << 24;
+ n |= (bs[++off] & 0xff) << 16;
+ n |= (bs[++off] & 0xff) << 8;
+ n |= (bs[++off] & 0xff);
+ return n;
+ }
+
+ public static void bigEndianToInt(byte[] bs, int off, int[] ns)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ ns[i] = bigEndianToInt(bs, off);
+ off += 4;
+ }
+ }
+
+ public static void bigEndianToInt(byte[] bs, int off, int[] ns, int nsOff, int nsLen)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ ns[nsOff + i] = bigEndianToInt(bs, off);
+ off += 4;
+ }
+ }
+
+ public static byte[] intToBigEndian(int n)
+ {
+ byte[] bs = new byte[4];
+ intToBigEndian(n, bs, 0);
+ return bs;
+ }
+
+ public static void intToBigEndian(int n, byte[] bs, int off)
+ {
+ bs[off] = (byte)(n >>> 24);
+ bs[++off] = (byte)(n >>> 16);
+ bs[++off] = (byte)(n >>> 8);
+ bs[++off] = (byte)(n);
+ }
+
+ public static byte[] intToBigEndian(int[] ns)
+ {
+ byte[] bs = new byte[4 * ns.length];
+ intToBigEndian(ns, bs, 0);
+ return bs;
+ }
+
+ public static void intToBigEndian(int[] ns, byte[] bs, int off)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ intToBigEndian(ns[i], bs, off);
+ off += 4;
+ }
+ }
+
+ public static void intToBigEndian(int[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ intToBigEndian(ns[nsOff + i], bs, bsOff);
+ bsOff += 4;
+ }
+ }
+
+ public static long bigEndianToLong(byte[] bs, int off)
+ {
+ int hi = bigEndianToInt(bs, off);
+ int lo = bigEndianToInt(bs, off + 4);
+ return ((long)(hi & 0xffffffffL) << 32) | (long)(lo & 0xffffffffL);
+ }
+
+ public static void bigEndianToLong(byte[] bs, int off, long[] ns)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ ns[i] = bigEndianToLong(bs, off);
+ off += 8;
+ }
+ }
+
+ public static void bigEndianToLong(byte[] bs, int bsOff, long[] ns, int nsOff, int nsLen)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ ns[nsOff + i] = bigEndianToLong(bs, bsOff);
+ bsOff += 8;
+ }
+ }
+
+ public static byte[] longToBigEndian(long n)
+ {
+ byte[] bs = new byte[8];
+ longToBigEndian(n, bs, 0);
+ return bs;
+ }
+
+ public static void longToBigEndian(long n, byte[] bs, int off)
+ {
+ intToBigEndian((int)(n >>> 32), bs, off);
+ intToBigEndian((int)(n & 0xffffffffL), bs, off + 4);
+ }
+
+ public static byte[] longToBigEndian(long[] ns)
+ {
+ byte[] bs = new byte[8 * ns.length];
+ longToBigEndian(ns, bs, 0);
+ return bs;
+ }
+
+ public static void longToBigEndian(long[] ns, byte[] bs, int off)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ longToBigEndian(ns[i], bs, off);
+ off += 8;
+ }
+ }
+
+ public static void longToBigEndian(long[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ longToBigEndian(ns[nsOff + i], bs, bsOff);
+ bsOff += 8;
+ }
+ }
+
+ /**
+ * @param value The number
+ * @param bs The target.
+ * @param off Position in target to start.
+ * @param bytes number of bytes to write.
+ *
+ * @deprecated Will be removed
+ */
+ public static void longToBigEndian(long value, byte[] bs, int off, int bytes)
+ {
+ for (int i = bytes - 1; i >= 0; i--)
+ {
+ bs[i + off] = (byte)(value & 0xff);
+ value >>>= 8;
+ }
+ }
+
+ public static short littleEndianToShort(byte[] bs, int off)
+ {
+ int n = bs[off] & 0xff;
+ n |= (bs[++off] & 0xff) << 8;
+ return (short)n;
+ }
+
+ public static int littleEndianToInt(byte[] bs, int off)
+ {
+ int n = bs[off] & 0xff;
+ n |= (bs[++off] & 0xff) << 8;
+ n |= (bs[++off] & 0xff) << 16;
+ n |= bs[++off] << 24;
+ return n;
+ }
+
+ public static void littleEndianToInt(byte[] bs, int off, int[] ns)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ ns[i] = littleEndianToInt(bs, off);
+ off += 4;
+ }
+ }
+
+ public static void littleEndianToInt(byte[] bs, int bOff, int[] ns, int nOff, int count)
+ {
+ for (int i = 0; i < count; ++i)
+ {
+ ns[nOff + i] = littleEndianToInt(bs, bOff);
+ bOff += 4;
+ }
+ }
+
+ public static int[] littleEndianToInt(byte[] bs, int off, int count)
+ {
+ int[] ns = new int[count];
+ for (int i = 0; i < ns.length; ++i)
+ {
+ ns[i] = littleEndianToInt(bs, off);
+ off += 4;
+ }
+ return ns;
+ }
+
+ public static byte[] shortToLittleEndian(short n)
+ {
+ byte[] bs = new byte[2];
+ shortToLittleEndian(n, bs, 0);
+ return bs;
+ }
+
+ public static void shortToLittleEndian(short n, byte[] bs, int off)
+ {
+ bs[off] = (byte)(n);
+ bs[++off] = (byte)(n >>> 8);
+ }
+
+
+ public static byte[] shortToBigEndian(short n)
+ {
+ byte[] r = new byte[2];
+ shortToBigEndian(n, r, 0);
+ return r;
+ }
+
+ public static void shortToBigEndian(short n, byte[] bs, int off)
+ {
+ bs[off] = (byte)(n >>> 8);
+ bs[++off] = (byte)(n);
+ }
+
+
+ public static byte[] intToLittleEndian(int n)
+ {
+ byte[] bs = new byte[4];
+ intToLittleEndian(n, bs, 0);
+ return bs;
+ }
+
+ public static void intToLittleEndian(int n, byte[] bs, int off)
+ {
+ bs[off] = (byte)(n);
+ bs[++off] = (byte)(n >>> 8);
+ bs[++off] = (byte)(n >>> 16);
+ bs[++off] = (byte)(n >>> 24);
+ }
+
+ public static byte[] intToLittleEndian(int[] ns)
+ {
+ byte[] bs = new byte[4 * ns.length];
+ intToLittleEndian(ns, bs, 0);
+ return bs;
+ }
+
+ public static void intToLittleEndian(int[] ns, byte[] bs, int off)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ intToLittleEndian(ns[i], bs, off);
+ off += 4;
+ }
+ }
+
+ public static void intToLittleEndian(int[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ intToLittleEndian(ns[nsOff + i], bs, bsOff);
+ bsOff += 4;
+ }
+ }
+
+ public static long littleEndianToLong(byte[] bs, int off)
+ {
+ int lo = littleEndianToInt(bs, off);
+ int hi = littleEndianToInt(bs, off + 4);
+ return ((long)(hi & 0xffffffffL) << 32) | (long)(lo & 0xffffffffL);
+ }
+
+ public static void littleEndianToLong(byte[] bs, int off, long[] ns)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ ns[i] = littleEndianToLong(bs, off);
+ off += 8;
+ }
+ }
+
+ public static void littleEndianToLong(byte[] bs, int bsOff, long[] ns, int nsOff, int nsLen)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ ns[nsOff + i] = littleEndianToLong(bs, bsOff);
+ bsOff += 8;
+ }
+ }
+
+ public static byte[] longToLittleEndian(long n)
+ {
+ byte[] bs = new byte[8];
+ longToLittleEndian(n, bs, 0);
+ return bs;
+ }
+
+ public static void longToLittleEndian(long n, byte[] bs, int off)
+ {
+ intToLittleEndian((int)(n & 0xffffffffL), bs, off);
+ intToLittleEndian((int)(n >>> 32), bs, off + 4);
+ }
+
+ public static byte[] longToLittleEndian(long[] ns)
+ {
+ byte[] bs = new byte[8 * ns.length];
+ longToLittleEndian(ns, bs, 0);
+ return bs;
+ }
+
+ public static void longToLittleEndian(long[] ns, byte[] bs, int off)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ longToLittleEndian(ns[i], bs, off);
+ off += 8;
+ }
+ }
+
+ public static void longToLittleEndian(long[] ns, int nsOff, int nsLen, byte[] bs, int bsOff)
+ {
+ for (int i = 0; i < nsLen; ++i)
+ {
+ longToLittleEndian(ns[nsOff + i], bs, bsOff);
+ bsOff += 8;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Properties.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Properties.java
new file mode 100644
index 00000000..4817548e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Properties.java
@@ -0,0 +1,209 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+import java.math.BigInteger;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.Security;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * Utility method for accessing system properties.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Properties
+{
+ private Properties()
+ {
+ }
+
+ private static final ThreadLocal threadProperties = new ThreadLocal();
+
+ /**
+ * Return whether a particular override has been set to true.
+ *
+ * @param propertyName the property name for the override.
+ * @return true if the property is set to "true", false otherwise.
+ */
+ public static boolean isOverrideSet(String propertyName)
+ {
+ try
+ {
+ return isSetTrue(getPropertyValue(propertyName));
+ }
+ catch (AccessControlException e)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Return whether a particular override has been set to false.
+ *
+ * @param propertyName the property name for the override.
+ * @param isTrue true if the override should be true, false otherwise.
+ * @return true if the property is set to the value of isTrue, false otherwise.
+ */
+ public static boolean isOverrideSetTo(String propertyName, boolean isTrue)
+ {
+ try
+ {
+ String propertyValue = getPropertyValue(propertyName);
+ if (isTrue)
+ {
+ return isSetTrue(propertyValue);
+ }
+ return isSetFalse(propertyValue);
+ }
+ catch (AccessControlException e)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Enable the specified override property for the current thread only.
+ *
+ * @param propertyName the property name for the override.
+ * @param enable true if the override should be enabled, false if it should be disabled.
+ * @return true if the override was already set true, false otherwise.
+ */
+ public static boolean setThreadOverride(String propertyName, boolean enable)
+ {
+ boolean isSet = isOverrideSet(propertyName);
+
+ Map localProps = (Map)threadProperties.get();
+ if (localProps == null)
+ {
+ localProps = new HashMap();
+
+ threadProperties.set(localProps);
+ }
+
+ localProps.put(propertyName, enable ? "true" : "false");
+
+ return isSet;
+ }
+
+ /**
+ * Remove any value for the specified override property for the current thread only.
+ *
+ * @param propertyName the property name for the override.
+ * @return true if the override was already set true in thread local, false otherwise.
+ */
+ public static boolean removeThreadOverride(String propertyName)
+ {
+ Map localProps = (Map)threadProperties.get();
+ if (localProps != null)
+ {
+ String p = (String)localProps.remove(propertyName);
+ if (p != null)
+ {
+ if (localProps.isEmpty())
+ {
+ threadProperties.remove();
+ }
+
+ return "true".equals(Strings.toLowerCase(p));
+ }
+ }
+
+ return false;
+ }
+
+ public static BigInteger asBigInteger(String propertyName)
+ {
+ String p = getPropertyValue(propertyName);
+
+ if (p != null)
+ {
+ return new BigInteger(p);
+ }
+
+ return null;
+ }
+
+ public static Set<String> asKeySet(String propertyName)
+ {
+ Set<String> set = new HashSet<String>();
+
+ String p = getPropertyValue(propertyName);
+
+ if (p != null)
+ {
+ StringTokenizer sTok = new StringTokenizer(p, ",");
+ while (sTok.hasMoreElements())
+ {
+ set.add(Strings.toLowerCase(sTok.nextToken()).trim());
+ }
+ }
+
+ return Collections.unmodifiableSet(set);
+ }
+
+ public static String getPropertyValue(final String propertyName)
+ {
+ String val = (String)AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return Security.getProperty(propertyName);
+ }
+ });
+ if (val != null)
+ {
+ return val;
+ }
+
+ Map localProps = (Map)threadProperties.get();
+ if (localProps != null)
+ {
+ String p = (String)localProps.get(propertyName);
+ if (p != null)
+ {
+ return p;
+ }
+ }
+
+ return (String)AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return System.getProperty(propertyName);
+ }
+ });
+ }
+
+ private static boolean isSetFalse(String p)
+ {
+ if (p == null || p.length() != 5)
+ {
+ return false;
+ }
+
+ return (p.charAt(0) == 'f' || p.charAt(0) == 'F')
+ && (p.charAt(1) == 'a' || p.charAt(1) == 'A')
+ && (p.charAt(2) == 'l' || p.charAt(2) == 'L')
+ && (p.charAt(3) == 's' || p.charAt(3) == 'S')
+ && (p.charAt(4) == 'e' || p.charAt(4) == 'E');
+ }
+
+ private static boolean isSetTrue(String p)
+ {
+ if (p == null || p.length() != 4)
+ {
+ return false;
+ }
+
+ return (p.charAt(0) == 't' || p.charAt(0) == 'T')
+ && (p.charAt(1) == 'r' || p.charAt(1) == 'R')
+ && (p.charAt(2) == 'u' || p.charAt(2) == 'U')
+ && (p.charAt(3) == 'e' || p.charAt(3) == 'E');
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Selector.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Selector.java
new file mode 100644
index 00000000..f36d1219
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Selector.java
@@ -0,0 +1,22 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+/**
+ * Interface a selector from a store should conform to.
+ *
+ * @param <T> the type stored in the store.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Selector<T>
+ extends Cloneable
+{
+ /**
+ * Match the passed in object, returning true if it would be selected by this selector, false otherwise.
+ *
+ * @param obj the object to be matched.
+ * @return true if the object is a match for this selector, false otherwise.
+ */
+ boolean match(T obj);
+
+ Object clone();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Store.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Store.java
new file mode 100644
index 00000000..afbdea9f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Store.java
@@ -0,0 +1,24 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+import java.util.Collection;
+
+/**
+ * A generic interface describing a simple store of objects.
+ *
+ * @param <T> the object type stored.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Store<T>
+{
+ /**
+ * Return a possibly empty collection of objects that match the criteria implemented
+ * in the passed in Selector.
+ *
+ * @param selector the selector defining the match criteria.
+ * @return a collection of matching objects, empty if none available.
+ * @throws StoreException if there is a failure during matching.
+ */
+ Collection<T> getMatches(Selector<T> selector)
+ throws StoreException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/StoreException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/StoreException.java
new file mode 100644
index 00000000..62f4020b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/StoreException.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+/**
+ * Exception thrown if there's an issue doing a match in store.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class StoreException
+ extends RuntimeException
+{
+ private Throwable _e;
+
+ /**
+ * Basic Constructor.
+ *
+ * @param msg message to be associated with this exception.
+ * @param cause the throwable that caused this exception to be raised.
+ */
+ public StoreException(String msg, Throwable cause)
+ {
+ super(msg);
+ _e = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return _e;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/StringList.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/StringList.java
new file mode 100644
index 00000000..b73cc757
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/StringList.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+/**
+ * An interface defining a list of strings.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface StringList
+ extends Iterable<String>
+{
+ /**
+ * Add a String to the list.
+ *
+ * @param s the String to add.
+ * @return true
+ */
+ boolean add(String s);
+
+ /**
+ * Get the string at index index.
+ *
+ * @param index the index position of the String of interest.
+ * @return the String at position index.
+ */
+ String get(int index);
+
+ int size();
+
+ /**
+ * Return the contents of the list as an array.
+ *
+ * @return an array of String.
+ */
+ String[] toStringArray();
+
+ /**
+ * Return a section of the contents of the list. If the list is too short the array is filled with nulls.
+ *
+ * @param from the initial index of the range to be copied, inclusive
+ * @param to the final index of the range to be copied, exclusive.
+ * @return an array of length to - from
+ */
+ String[] toStringArray(int from, int to);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Strings.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Strings.java
new file mode 100644
index 00000000..dfbc7f92
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Strings.java
@@ -0,0 +1,347 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Vector;
+
+import com.android.internal.org.bouncycastle.util.encoders.UTF8;
+
+/**
+ * String utilities.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Strings
+{
+ private static String LINE_SEPARATOR;
+
+ static
+ {
+ try
+ {
+ LINE_SEPARATOR = AccessController.doPrivileged(new PrivilegedAction<String>()
+ {
+ public String run()
+ {
+ // the easy way
+ return System.getProperty("line.separator");
+ }
+ });
+
+ }
+ catch (Exception e)
+ {
+ try
+ {
+ // the harder way
+ LINE_SEPARATOR = String.format("%n");
+ }
+ catch (Exception ef)
+ {
+ LINE_SEPARATOR = "\n"; // we're desperate use this...
+ }
+ }
+ }
+
+ public static String fromUTF8ByteArray(byte[] bytes)
+ {
+ char[] chars = new char[bytes.length];
+ int len = UTF8.transcodeToUTF16(bytes, chars);
+ if (len < 0)
+ {
+ throw new IllegalArgumentException("Invalid UTF-8 input");
+ }
+ return new String(chars, 0, len);
+ }
+
+ public static byte[] toUTF8ByteArray(String string)
+ {
+ return toUTF8ByteArray(string.toCharArray());
+ }
+
+ public static byte[] toUTF8ByteArray(char[] string)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ try
+ {
+ toUTF8ByteArray(string, bOut);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("cannot encode string to byte array!");
+ }
+
+ return bOut.toByteArray();
+ }
+
+ public static void toUTF8ByteArray(char[] string, OutputStream sOut)
+ throws IOException
+ {
+ char[] c = string;
+ int i = 0;
+
+ while (i < c.length)
+ {
+ char ch = c[i];
+
+ if (ch < 0x0080)
+ {
+ sOut.write(ch);
+ }
+ else if (ch < 0x0800)
+ {
+ sOut.write(0xc0 | (ch >> 6));
+ sOut.write(0x80 | (ch & 0x3f));
+ }
+ // surrogate pair
+ else if (ch >= 0xD800 && ch <= 0xDFFF)
+ {
+ // in error - can only happen, if the Java String class has a
+ // bug.
+ if (i + 1 >= c.length)
+ {
+ throw new IllegalStateException("invalid UTF-16 codepoint");
+ }
+ char W1 = ch;
+ ch = c[++i];
+ char W2 = ch;
+ // in error - can only happen, if the Java String class has a
+ // bug.
+ if (W1 > 0xDBFF)
+ {
+ throw new IllegalStateException("invalid UTF-16 codepoint");
+ }
+ int codePoint = (((W1 & 0x03FF) << 10) | (W2 & 0x03FF)) + 0x10000;
+ sOut.write(0xf0 | (codePoint >> 18));
+ sOut.write(0x80 | ((codePoint >> 12) & 0x3F));
+ sOut.write(0x80 | ((codePoint >> 6) & 0x3F));
+ sOut.write(0x80 | (codePoint & 0x3F));
+ }
+ else
+ {
+ sOut.write(0xe0 | (ch >> 12));
+ sOut.write(0x80 | ((ch >> 6) & 0x3F));
+ sOut.write(0x80 | (ch & 0x3F));
+ }
+
+ i++;
+ }
+ }
+
+ /**
+ * A locale independent version of toUpperCase.
+ *
+ * @param string input to be converted
+ * @return a US Ascii uppercase version
+ */
+ public static String toUpperCase(String string)
+ {
+ boolean changed = false;
+ char[] chars = string.toCharArray();
+
+ for (int i = 0; i != chars.length; i++)
+ {
+ char ch = chars[i];
+ if ('a' <= ch && 'z' >= ch)
+ {
+ changed = true;
+ chars[i] = (char)(ch - 'a' + 'A');
+ }
+ }
+
+ if (changed)
+ {
+ return new String(chars);
+ }
+
+ return string;
+ }
+
+ /**
+ * A locale independent version of toLowerCase.
+ *
+ * @param string input to be converted
+ * @return a US ASCII lowercase version
+ */
+ public static String toLowerCase(String string)
+ {
+ boolean changed = false;
+ char[] chars = string.toCharArray();
+
+ for (int i = 0; i != chars.length; i++)
+ {
+ char ch = chars[i];
+ if ('A' <= ch && 'Z' >= ch)
+ {
+ changed = true;
+ chars[i] = (char)(ch - 'A' + 'a');
+ }
+ }
+
+ if (changed)
+ {
+ return new String(chars);
+ }
+
+ return string;
+ }
+
+ public static byte[] toByteArray(char[] chars)
+ {
+ byte[] bytes = new byte[chars.length];
+
+ for (int i = 0; i != bytes.length; i++)
+ {
+ bytes[i] = (byte)chars[i];
+ }
+
+ return bytes;
+ }
+
+
+ public static byte[] toByteArray(String string)
+ {
+ byte[] bytes = new byte[string.length()];
+
+ for (int i = 0; i != bytes.length; i++)
+ {
+ char ch = string.charAt(i);
+
+ bytes[i] = (byte)ch;
+ }
+
+ return bytes;
+ }
+
+ public static int toByteArray(String s, byte[] buf, int off)
+ {
+ int count = s.length();
+ for (int i = 0; i < count; ++i)
+ {
+ char c = s.charAt(i);
+ buf[off + i] = (byte)c;
+ }
+ return count;
+ }
+
+ /**
+ * Convert an array of 8 bit characters into a string.
+ *
+ * @param bytes 8 bit characters.
+ * @return resulting String.
+ */
+ public static String fromByteArray(byte[] bytes)
+ {
+ return new String(asCharArray(bytes));
+ }
+
+ /**
+ * Do a simple conversion of an array of 8 bit characters into a string.
+ *
+ * @param bytes 8 bit characters.
+ * @return resulting String.
+ */
+ public static char[] asCharArray(byte[] bytes)
+ {
+ char[] chars = new char[bytes.length];
+
+ for (int i = 0; i != chars.length; i++)
+ {
+ chars[i] = (char)(bytes[i] & 0xff);
+ }
+
+ return chars;
+ }
+
+ public static String[] split(String input, char delimiter)
+ {
+ Vector v = new Vector();
+ boolean moreTokens = true;
+ String subString;
+
+ while (moreTokens)
+ {
+ int tokenLocation = input.indexOf(delimiter);
+ if (tokenLocation > 0)
+ {
+ subString = input.substring(0, tokenLocation);
+ v.addElement(subString);
+ input = input.substring(tokenLocation + 1);
+ }
+ else
+ {
+ moreTokens = false;
+ v.addElement(input);
+ }
+ }
+
+ String[] res = new String[v.size()];
+
+ for (int i = 0; i != res.length; i++)
+ {
+ res[i] = (String)v.elementAt(i);
+ }
+ return res;
+ }
+
+ public static StringList newList()
+ {
+ return new StringListImpl();
+ }
+
+ public static String lineSeparator()
+ {
+ return LINE_SEPARATOR;
+ }
+
+ private static class StringListImpl
+ extends ArrayList<String>
+ implements StringList
+ {
+ public boolean add(String s)
+ {
+ return super.add(s);
+ }
+
+ public String set(int index, String element)
+ {
+ return super.set(index, element);
+ }
+
+ public void add(int index, String element)
+ {
+ super.add(index, element);
+ }
+
+ public String[] toStringArray()
+ {
+ String[] strs = new String[this.size()];
+
+ for (int i = 0; i != strs.length; i++)
+ {
+ strs[i] = this.get(i);
+ }
+
+ return strs;
+ }
+
+ public String[] toStringArray(int from, int to)
+ {
+ String[] strs = new String[to - from];
+
+ for (int i = from; i != this.size() && i != to; i++)
+ {
+ strs[i - from] = this.get(i);
+ }
+
+ return strs;
+ }
+ }
+
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64.java
new file mode 100644
index 00000000..fa5bebf1
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64.java
@@ -0,0 +1,177 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.encoders;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * Utility class for converting Base64 data to bytes and back again.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Base64
+{
+ private static final Encoder encoder = new Base64Encoder();
+
+ public static String toBase64String(
+ byte[] data)
+ {
+ return toBase64String(data, 0, data.length);
+ }
+
+ public static String toBase64String(
+ byte[] data,
+ int off,
+ int length)
+ {
+ byte[] encoded = encode(data, off, length);
+ return Strings.fromByteArray(encoded);
+ }
+
+ /**
+ * encode the input data producing a base 64 encoded byte array.
+ *
+ * @return a byte array containing the base 64 encoded data.
+ */
+ public static byte[] encode(
+ byte[] data)
+ {
+ return encode(data, 0, data.length);
+ }
+
+ /**
+ * encode the input data producing a base 64 encoded byte array.
+ *
+ * @return a byte array containing the base 64 encoded data.
+ */
+ public static byte[] encode(
+ byte[] data,
+ int off,
+ int length)
+ {
+ int len = (length + 2) / 3 * 4;
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
+
+ try
+ {
+ encoder.encode(data, off, length, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new EncoderException("exception encoding base64 string: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * Encode the byte data to base 64 writing it to the given output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int encode(
+ byte[] data,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.encode(data, 0, data.length, out);
+ }
+
+ /**
+ * Encode the byte data to base 64 writing it to the given output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int encode(
+ byte[] data,
+ int off,
+ int length,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.encode(data, off, length, out);
+ }
+
+ /**
+ * decode the base 64 encoded input data. It is assumed the input data is valid.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ byte[] data)
+ {
+ int len = data.length / 4 * 3;
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
+
+ try
+ {
+ encoder.decode(data, 0, data.length, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("unable to decode base64 data: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * decode the base 64 encoded String data - whitespace will be ignored.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ String data)
+ {
+ int len = data.length() / 4 * 3;
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream(len);
+
+ try
+ {
+ encoder.decode(data, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("unable to decode base64 string: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * decode the base 64 encoded String data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int decode(
+ String data,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.decode(data, out);
+ }
+
+ /**
+ * Decode to an output stream;
+ *
+ * @param base64Data The source data.
+ * @param start Start position.
+ * @param length the length.
+ * @param out The output stream to write to.
+ */
+ public static int decode(byte[] base64Data, int start, int length, OutputStream out)
+ {
+ try
+ {
+ return encoder.decode(base64Data, start, length, out);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("unable to decode base64 data: " + e.getMessage(), e);
+ }
+
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64Encoder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64Encoder.java
new file mode 100644
index 00000000..cda38c11
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64Encoder.java
@@ -0,0 +1,405 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.encoders;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * A streaming Base64 encoder.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Base64Encoder
+ implements Encoder
+{
+ protected final byte[] encodingTable =
+ {
+ (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
+ (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
+ (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
+ (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
+ (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
+ (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
+ (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
+ (byte)'v',
+ (byte)'w', (byte)'x', (byte)'y', (byte)'z',
+ (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
+ (byte)'7', (byte)'8', (byte)'9',
+ (byte)'+', (byte)'/'
+ };
+
+ protected byte padding = (byte)'=';
+
+ /*
+ * set up the decoding table.
+ */
+ protected final byte[] decodingTable = new byte[128];
+
+ protected void initialiseDecodingTable()
+ {
+ for (int i = 0; i < decodingTable.length; i++)
+ {
+ decodingTable[i] = (byte)0xff;
+ }
+
+ for (int i = 0; i < encodingTable.length; i++)
+ {
+ decodingTable[encodingTable[i]] = (byte)i;
+ }
+ }
+
+ public Base64Encoder()
+ {
+ initialiseDecodingTable();
+ }
+
+ public int encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) throws IOException
+ {
+ int inPos = inOff;
+ int inEnd = inOff + inLen - 2;
+ int outPos = outOff;
+
+ while (inPos < inEnd)
+ {
+ int a1 = inBuf[inPos++];
+ int a2 = inBuf[inPos++] & 0xFF;
+ int a3 = inBuf[inPos++] & 0xFF;
+
+ outBuf[outPos++] = encodingTable[(a1 >>> 2) & 0x3F];
+ outBuf[outPos++] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3F];
+ outBuf[outPos++] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3F];
+ outBuf[outPos++] = encodingTable[a3 & 0x3F];
+ }
+
+ switch (inLen - (inPos - inOff))
+ {
+ case 1:
+ {
+ int a1 = inBuf[inPos++] & 0xFF;
+
+ outBuf[outPos++] = encodingTable[(a1 >>> 2) & 0x3F];
+ outBuf[outPos++] = encodingTable[(a1 << 4) & 0x3F];
+ outBuf[outPos++] = padding;
+ outBuf[outPos++] = padding;
+ break;
+ }
+ case 2:
+ {
+ int a1 = inBuf[inPos++] & 0xFF;
+ int a2 = inBuf[inPos++] & 0xFF;
+
+ outBuf[outPos++] = encodingTable[(a1 >>> 2) & 0x3F];
+ outBuf[outPos++] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3F];
+ outBuf[outPos++] = encodingTable[(a2 << 2) & 0x3F];
+ outBuf[outPos++] = padding;
+ break;
+ }
+ }
+
+ return outPos - outOff;
+ }
+
+ /**
+ * encode the input data producing a base 64 output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public int encode(byte[] buf, int off, int len, OutputStream out)
+ throws IOException
+ {
+ byte[] tmp = new byte[72];
+ while (len > 0)
+ {
+ int inLen = Math.min(54, len);
+ int outLen = encode(buf, off, inLen, tmp, 0);
+ out.write(tmp, 0, outLen);
+ off += inLen;
+ len -= inLen;
+ }
+ return ((len + 2) / 3) * 4;
+ }
+
+ private boolean ignore(
+ char c)
+ {
+ return (c == '\n' || c =='\r' || c == '\t' || c == ' ');
+ }
+
+ /**
+ * decode the base 64 encoded byte data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public int decode(
+ byte[] data,
+ int off,
+ int length,
+ OutputStream out)
+ throws IOException
+ {
+ byte b1, b2, b3, b4;
+ byte[] outBuffer = new byte[54]; // S/MIME standard
+ int bufOff = 0;
+ int outLen = 0;
+
+ int end = off + length;
+
+ while (end > off)
+ {
+ if (!ignore((char)data[end - 1]))
+ {
+ break;
+ }
+
+ end--;
+ }
+
+ // empty data!
+ if (end == 0)
+ {
+ return 0;
+ }
+
+ int i = 0;
+ int finish = end;
+
+ while (finish > off && i != 4)
+ {
+ if (!ignore((char)data[finish - 1]))
+ {
+ i++;
+ }
+
+ finish--;
+ }
+
+ i = nextI(data, off, finish);
+
+ while (i < finish)
+ {
+ b1 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b2 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b3 = decodingTable[data[i++]];
+
+ i = nextI(data, i, finish);
+
+ b4 = decodingTable[data[i++]];
+
+ if ((b1 | b2 | b3 | b4) < 0)
+ {
+ throw new IOException("invalid characters encountered in base64 data");
+ }
+
+ outBuffer[bufOff++] = (byte)((b1 << 2) | (b2 >> 4));
+ outBuffer[bufOff++] = (byte)((b2 << 4) | (b3 >> 2));
+ outBuffer[bufOff++] = (byte)((b3 << 6) | b4);
+
+ if (bufOff == outBuffer.length)
+ {
+ out.write(outBuffer);
+ bufOff = 0;
+ }
+
+ outLen += 3;
+
+ i = nextI(data, i, finish);
+ }
+
+ if (bufOff > 0)
+ {
+ out.write(outBuffer, 0, bufOff);
+ }
+
+ int e0 = nextI(data, i, end);
+ int e1 = nextI(data, e0 + 1, end);
+ int e2 = nextI(data, e1 + 1, end);
+ int e3 = nextI(data, e2 + 1, end);
+
+ outLen += decodeLastBlock(out, (char)data[e0], (char)data[e1], (char)data[e2], (char)data[e3]);
+
+ return outLen;
+ }
+
+ private int nextI(byte[] data, int i, int finish)
+ {
+ while ((i < finish) && ignore((char)data[i]))
+ {
+ i++;
+ }
+ return i;
+ }
+
+ /**
+ * decode the base 64 encoded String data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public int decode(
+ String data,
+ OutputStream out)
+ throws IOException
+ {
+ byte b1, b2, b3, b4;
+ byte[] outBuffer = new byte[54]; // S/MIME standard
+ int bufOff = 0;
+ int length = 0;
+
+ int end = data.length();
+
+ while (end > 0)
+ {
+ if (!ignore(data.charAt(end - 1)))
+ {
+ break;
+ }
+
+ end--;
+ }
+
+ // empty data!
+ if (end == 0)
+ {
+ return 0;
+ }
+
+ int i = 0;
+ int finish = end;
+
+ while (finish > 0 && i != 4)
+ {
+ if (!ignore(data.charAt(finish - 1)))
+ {
+ i++;
+ }
+
+ finish--;
+ }
+
+ i = nextI(data, 0, finish);
+
+ while (i < finish)
+ {
+ b1 = decodingTable[data.charAt(i++)];
+
+ i = nextI(data, i, finish);
+
+ b2 = decodingTable[data.charAt(i++)];
+
+ i = nextI(data, i, finish);
+
+ b3 = decodingTable[data.charAt(i++)];
+
+ i = nextI(data, i, finish);
+
+ b4 = decodingTable[data.charAt(i++)];
+
+ if ((b1 | b2 | b3 | b4) < 0)
+ {
+ throw new IOException("invalid characters encountered in base64 data");
+ }
+
+ outBuffer[bufOff++] = (byte)((b1 << 2) | (b2 >> 4));
+ outBuffer[bufOff++] = (byte)((b2 << 4) | (b3 >> 2));
+ outBuffer[bufOff++] = (byte)((b3 << 6) | b4);
+
+ length += 3;
+ if (bufOff == outBuffer.length)
+ {
+ out.write(outBuffer);
+ bufOff = 0;
+ }
+
+ i = nextI(data, i, finish);
+ }
+
+ if (bufOff > 0)
+ {
+ out.write(outBuffer, 0, bufOff);
+ }
+
+ int e0 = nextI(data, i, end);
+ int e1 = nextI(data, e0 + 1, end);
+ int e2 = nextI(data, e1 + 1, end);
+ int e3 = nextI(data, e2 + 1, end);
+
+ length += decodeLastBlock(out, data.charAt(e0), data.charAt(e1), data.charAt(e2), data.charAt(e3));
+
+ return length;
+ }
+
+ private int decodeLastBlock(OutputStream out, char c1, char c2, char c3, char c4)
+ throws IOException
+ {
+ byte b1, b2, b3, b4;
+
+ if (c3 == padding)
+ {
+ if (c4 != padding)
+ {
+ throw new IOException("invalid characters encountered at end of base64 data");
+ }
+
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+
+ if ((b1 | b2) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base64 data");
+ }
+
+ out.write((b1 << 2) | (b2 >> 4));
+
+ return 1;
+ }
+ else if (c4 == padding)
+ {
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+ b3 = decodingTable[c3];
+
+ if ((b1 | b2 | b3) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base64 data");
+ }
+
+ out.write((b1 << 2) | (b2 >> 4));
+ out.write((b2 << 4) | (b3 >> 2));
+
+ return 2;
+ }
+ else
+ {
+ b1 = decodingTable[c1];
+ b2 = decodingTable[c2];
+ b3 = decodingTable[c3];
+ b4 = decodingTable[c4];
+
+ if ((b1 | b2 | b3 | b4) < 0)
+ {
+ throw new IOException("invalid characters encountered at end of base64 data");
+ }
+
+ out.write((b1 << 2) | (b2 >> 4));
+ out.write((b2 << 4) | (b3 >> 2));
+ out.write((b3 << 6) | b4);
+
+ return 3;
+ }
+ }
+
+ private int nextI(String data, int i, int finish)
+ {
+ while ((i < finish) && ignore(data.charAt(i)))
+ {
+ i++;
+ }
+ return i;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/DecoderException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/DecoderException.java
new file mode 100644
index 00000000..8ae8dc9f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/DecoderException.java
@@ -0,0 +1,24 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.encoders;
+
+/**
+ * Exception thrown if an attempt is made to decode invalid data, or some other failure occurs.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DecoderException
+ extends IllegalStateException
+{
+ private Throwable cause;
+
+ DecoderException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Encoder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Encoder.java
new file mode 100644
index 00000000..59a51141
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Encoder.java
@@ -0,0 +1,19 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.encoders;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Encode and decode byte arrays (typically from binary to 7-bit ASCII
+ * encodings).
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Encoder
+{
+ int encode(byte[] data, int off, int length, OutputStream out) throws IOException;
+
+ int decode(byte[] data, int off, int length, OutputStream out) throws IOException;
+
+ int decode(String data, OutputStream out) throws IOException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/EncoderException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/EncoderException.java
new file mode 100644
index 00000000..eda43c7a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/EncoderException.java
@@ -0,0 +1,24 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.encoders;
+
+/**
+ * Exception thrown if an attempt is made to encode invalid data, or some other failure occurs.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EncoderException
+ extends IllegalStateException
+{
+ private Throwable cause;
+
+ EncoderException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Hex.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Hex.java
new file mode 100644
index 00000000..ad53cbf6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Hex.java
@@ -0,0 +1,189 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.encoders;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.android.internal.org.bouncycastle.util.Strings;
+
+/**
+ * Utility class for converting hex data to bytes and back again.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Hex
+{
+ private static final HexEncoder encoder = new HexEncoder();
+
+ public static String toHexString(
+ byte[] data)
+ {
+ return toHexString(data, 0, data.length);
+ }
+
+ public static String toHexString(
+ byte[] data,
+ int off,
+ int length)
+ {
+ byte[] encoded = encode(data, off, length);
+ return Strings.fromByteArray(encoded);
+ }
+
+ /**
+ * encode the input data producing a Hex encoded byte array.
+ *
+ * @return a byte array containing the Hex encoded data.
+ */
+ public static byte[] encode(
+ byte[] data)
+ {
+ return encode(data, 0, data.length);
+ }
+
+ /**
+ * encode the input data producing a Hex encoded byte array.
+ *
+ * @return a byte array containing the Hex encoded data.
+ */
+ public static byte[] encode(
+ byte[] data,
+ int off,
+ int length)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ try
+ {
+ encoder.encode(data, off, length, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new EncoderException("exception encoding Hex string: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * Hex encode the byte data writing it to the given output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int encode(
+ byte[] data,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.encode(data, 0, data.length, out);
+ }
+
+ /**
+ * Hex encode the byte data writing it to the given output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int encode(
+ byte[] data,
+ int off,
+ int length,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.encode(data, off, length, out);
+ }
+
+ /**
+ * decode the Hex encoded input data. It is assumed the input data is valid.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ byte[] data)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ try
+ {
+ encoder.decode(data, 0, data.length, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("exception decoding Hex data: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * decode the Hex encoded String data - whitespace will be ignored.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ String data)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ try
+ {
+ encoder.decode(data, bOut);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e);
+ }
+
+ return bOut.toByteArray();
+ }
+
+ /**
+ * decode the Hex encoded String data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public static int decode(
+ String data,
+ OutputStream out)
+ throws IOException
+ {
+ return encoder.decode(data, out);
+ }
+
+ /**
+ * Decode the hexadecimal-encoded string strictly i.e. any non-hexadecimal characters will be
+ * considered an error.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decodeStrict(String str)
+ {
+ try
+ {
+ return encoder.decodeStrict(str, 0, str.length());
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Decode the hexadecimal-encoded string strictly i.e. any non-hexadecimal characters will be
+ * considered an error.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decodeStrict(String str, int off, int len)
+ {
+ try
+ {
+ return encoder.decodeStrict(str, off, len);
+ }
+ catch (Exception e)
+ {
+ throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e);
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/HexEncoder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/HexEncoder.java
new file mode 100644
index 00000000..93ec0684
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/HexEncoder.java
@@ -0,0 +1,266 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.encoders;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * A streaming Hex encoder.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class HexEncoder
+ implements Encoder
+{
+ protected final byte[] encodingTable =
+ {
+ (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7',
+ (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f'
+ };
+
+ /*
+ * set up the decoding table.
+ */
+ protected final byte[] decodingTable = new byte[128];
+
+ protected void initialiseDecodingTable()
+ {
+ for (int i = 0; i < decodingTable.length; i++)
+ {
+ decodingTable[i] = (byte)0xff;
+ }
+
+ for (int i = 0; i < encodingTable.length; i++)
+ {
+ decodingTable[encodingTable[i]] = (byte)i;
+ }
+
+ decodingTable['A'] = decodingTable['a'];
+ decodingTable['B'] = decodingTable['b'];
+ decodingTable['C'] = decodingTable['c'];
+ decodingTable['D'] = decodingTable['d'];
+ decodingTable['E'] = decodingTable['e'];
+ decodingTable['F'] = decodingTable['f'];
+ }
+
+ public HexEncoder()
+ {
+ initialiseDecodingTable();
+ }
+
+ public int encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) throws IOException
+ {
+ int inPos = inOff;
+ int inEnd = inOff + inLen;
+ int outPos = outOff;
+
+ while (inPos < inEnd)
+ {
+ int b = inBuf[inPos++] & 0xFF;
+
+ outBuf[outPos++] = encodingTable[b >>> 4];
+ outBuf[outPos++] = encodingTable[b & 0xF];
+ }
+
+ return outPos - outOff;
+ }
+
+ /**
+ * encode the input data producing a Hex output stream.
+ *
+ * @return the number of bytes produced.
+ */
+ public int encode(byte[] buf, int off, int len, OutputStream out)
+ throws IOException
+ {
+ byte[] tmp = new byte[72];
+ while (len > 0)
+ {
+ int inLen = Math.min(36, len);
+ int outLen = encode(buf, off, inLen, tmp, 0);
+ out.write(tmp, 0, outLen);
+ off += inLen;
+ len -= inLen;
+ }
+ return len * 2;
+ }
+
+ private static boolean ignore(
+ char c)
+ {
+ return c == '\n' || c =='\r' || c == '\t' || c == ' ';
+ }
+
+ /**
+ * decode the Hex encoded byte data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public int decode(
+ byte[] data,
+ int off,
+ int length,
+ OutputStream out)
+ throws IOException
+ {
+ byte b1, b2;
+ int outLen = 0;
+ byte[] buf = new byte[36];
+ int bufOff = 0;
+
+ int end = off + length;
+
+ while (end > off)
+ {
+ if (!ignore((char)data[end - 1]))
+ {
+ break;
+ }
+
+ end--;
+ }
+
+ int i = off;
+ while (i < end)
+ {
+ while (i < end && ignore((char)data[i]))
+ {
+ i++;
+ }
+
+ b1 = decodingTable[data[i++]];
+
+ while (i < end && ignore((char)data[i]))
+ {
+ i++;
+ }
+
+ b2 = decodingTable[data[i++]];
+
+ if ((b1 | b2) < 0)
+ {
+ throw new IOException("invalid characters encountered in Hex data");
+ }
+
+ buf[bufOff++] = (byte)((b1 << 4) | b2);
+
+ if (bufOff == buf.length)
+ {
+ out.write(buf);
+ bufOff = 0;
+ }
+ outLen++;
+ }
+
+ if (bufOff > 0)
+ {
+ out.write(buf, 0, bufOff);
+ }
+
+ return outLen;
+ }
+
+ /**
+ * decode the Hex encoded String data writing it to the given output stream,
+ * whitespace characters will be ignored.
+ *
+ * @return the number of bytes produced.
+ */
+ public int decode(
+ String data,
+ OutputStream out)
+ throws IOException
+ {
+ byte b1, b2;
+ int length = 0;
+ byte[] buf = new byte[36];
+ int bufOff = 0;
+
+ int end = data.length();
+
+ while (end > 0)
+ {
+ if (!ignore(data.charAt(end - 1)))
+ {
+ break;
+ }
+
+ end--;
+ }
+
+ int i = 0;
+ while (i < end)
+ {
+ while (i < end && ignore(data.charAt(i)))
+ {
+ i++;
+ }
+
+ b1 = decodingTable[data.charAt(i++)];
+
+ while (i < end && ignore(data.charAt(i)))
+ {
+ i++;
+ }
+
+ b2 = decodingTable[data.charAt(i++)];
+
+ if ((b1 | b2) < 0)
+ {
+ throw new IOException("invalid characters encountered in Hex string");
+ }
+
+ buf[bufOff++] = (byte)((b1 << 4) | b2);
+
+ if (bufOff == buf.length)
+ {
+ out.write(buf);
+ bufOff = 0;
+ }
+
+ length++;
+ }
+
+ if (bufOff > 0)
+ {
+ out.write(buf, 0, bufOff);
+ }
+
+ return length;
+ }
+
+ byte[] decodeStrict(String str, int off, int len) throws IOException
+ {
+ if (null == str)
+ {
+ throw new NullPointerException("'str' cannot be null");
+ }
+ if (off < 0 || len < 0 || off > (str.length() - len))
+ {
+ throw new IndexOutOfBoundsException("invalid offset and/or length specified");
+ }
+ if (0 != (len & 1))
+ {
+ throw new IOException("a hexadecimal encoding must have an even number of characters");
+ }
+
+ int resultLen = len >>> 1;
+ byte[] result = new byte[resultLen];
+
+ int strPos = off;
+ for (int i = 0; i < resultLen; ++i)
+ {
+ byte b1 = decodingTable[str.charAt(strPos++)];
+ byte b2 = decodingTable[str.charAt(strPos++)];
+
+ int n = (b1 << 4) | b2;
+ if (n < 0)
+ {
+ throw new IOException("invalid characters encountered in Hex string");
+ }
+
+ result[i] = (byte)n;
+ }
+ return result;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/UTF8.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/UTF8.java
new file mode 100644
index 00000000..c6f49f69
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/UTF8.java
@@ -0,0 +1,158 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.encoders;
+
+/**
+ * Utilities for working with UTF-8 encodings.
+ *
+ * Decoding of UTF-8 is based on a presentation by Bob Steagall at CppCon2018 (see
+ * https://github.com/BobSteagall/CppCon2018). It uses a Deterministic Finite Automaton (DFA) to
+ * recognize and decode multi-byte code points.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class UTF8
+{
+ // Constants for the categorization of code units
+ private static final byte C_ILL = 0; //- C0..C1, F5..FF ILLEGAL octets that should never appear in a UTF-8 sequence
+ private static final byte C_CR1 = 1; //- 80..8F Continuation range 1
+ private static final byte C_CR2 = 2; //- 90..9F Continuation range 2
+ private static final byte C_CR3 = 3; //- A0..BF Continuation range 3
+ private static final byte C_L2A = 4; //- C2..DF Leading byte range A / 2-byte sequence
+ private static final byte C_L3A = 5; //- E0 Leading byte range A / 3-byte sequence
+ private static final byte C_L3B = 6; //- E1..EC, EE..EF Leading byte range B / 3-byte sequence
+ private static final byte C_L3C = 7; //- ED Leading byte range C / 3-byte sequence
+ private static final byte C_L4A = 8; //- F0 Leading byte range A / 4-byte sequence
+ private static final byte C_L4B = 9; //- F1..F3 Leading byte range B / 4-byte sequence
+ private static final byte C_L4C = 10; //- F4 Leading byte range C / 4-byte sequence
+// private static final byte C_ASC = 11; //- 00..7F ASCII leading byte range
+
+ // Constants for the states of a DFA
+ private static final byte S_ERR = -2; //- Error state
+ private static final byte S_END = -1; //- End (or Accept) state
+ private static final byte S_CS1 = 0x00; //- Continuation state 1
+ private static final byte S_CS2 = 0x10; //- Continuation state 2
+ private static final byte S_CS3 = 0x20; //- Continuation state 3
+ private static final byte S_P3A = 0x30; //- Partial 3-byte sequence state A
+ private static final byte S_P3B = 0x40; //- Partial 3-byte sequence state B
+ private static final byte S_P4A = 0x50; //- Partial 4-byte sequence state A
+ private static final byte S_P4B = 0x60; //- Partial 4-byte sequence state B
+
+ private static final short[] firstUnitTable = new short[128];
+ private static final byte[] transitionTable = new byte[S_P4B + 16];
+
+ private static void fill(byte[] table, int first, int last, byte b)
+ {
+ for (int i = first; i <= last; ++i)
+ {
+ table[i] = b;
+ }
+ }
+
+ static
+ {
+ byte[] categories = new byte[128];
+ fill(categories, 0x00, 0x0F, C_CR1);
+ fill(categories, 0x10, 0x1F, C_CR2);
+ fill(categories, 0x20, 0x3F, C_CR3);
+ fill(categories, 0x40, 0x41, C_ILL);
+ fill(categories, 0x42, 0x5F, C_L2A);
+ fill(categories, 0x60, 0x60, C_L3A);
+ fill(categories, 0x61, 0x6C, C_L3B);
+ fill(categories, 0x6D, 0x6D, C_L3C);
+ fill(categories, 0x6E, 0x6F, C_L3B);
+ fill(categories, 0x70, 0x70, C_L4A);
+ fill(categories, 0x71, 0x73, C_L4B);
+ fill(categories, 0x74, 0x74, C_L4C);
+ fill(categories, 0x75, 0x7F, C_ILL);
+
+ fill(transitionTable, 0, transitionTable.length - 1, S_ERR);
+ fill(transitionTable, S_CS1 + 0x8, S_CS1 + 0xB, S_END);
+ fill(transitionTable, S_CS2 + 0x8, S_CS2 + 0xB, S_CS1);
+ fill(transitionTable, S_CS3 + 0x8, S_CS3 + 0xB, S_CS2);
+ fill(transitionTable, S_P3A + 0xA, S_P3A + 0xB, S_CS1);
+ fill(transitionTable, S_P3B + 0x8, S_P3B + 0x9, S_CS1);
+ fill(transitionTable, S_P4A + 0x9, S_P4A + 0xB, S_CS2);
+ fill(transitionTable, S_P4B + 0x8, S_P4B + 0x8, S_CS2);
+
+ byte[] firstUnitMasks = { 0x00, 0x00, 0x00, 0x00, 0x1F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07 };
+ byte[] firstUnitTransitions = { S_ERR, S_ERR, S_ERR, S_ERR, S_CS1, S_P3A, S_CS2, S_P3B, S_P4A, S_CS3, S_P4B };
+
+ for (int i = 0x00; i < 0x80; ++i)
+ {
+ byte category = categories[i];
+
+ int codePoint = i & firstUnitMasks[category];
+ byte state = firstUnitTransitions[category];
+
+ firstUnitTable[i] = (short)((codePoint << 8) | state);
+ }
+ }
+
+ /**
+ * Transcode a UTF-8 encoding into a UTF-16 representation. In the general case the output
+ * {@code utf16} array should be at least as long as the input {@code utf8} one to handle
+ * arbitrary inputs. The number of output UTF-16 code units is returned, or -1 if any errors are
+ * encountered (in which case an arbitrary amount of data may have been written into the output
+ * array). Errors that will be detected are malformed UTF-8, including incomplete, truncated or
+ * "overlong" encodings, and unmappable code points. In particular, no unmatched surrogates will
+ * be produced. An error will also result if {@code utf16} is found to be too small to store the
+ * complete output.
+ *
+ * @param utf8
+ * A non-null array containing a well-formed UTF-8 encoding.
+ * @param utf16
+ * A non-null array, at least as long as the {@code utf8} array in order to ensure
+ * the output will fit.
+ * @return The number of UTF-16 code units written to {@code utf16} (beginning from index 0), or
+ * else -1 if the input was either malformed or encoded any unmappable characters, or if
+ * the {@code utf16} is too small.
+ */
+ public static int transcodeToUTF16(byte[] utf8, char[] utf16)
+ {
+ int i = 0, j = 0;
+
+ while (i < utf8.length)
+ {
+ byte codeUnit = utf8[i++];
+ if (codeUnit >= 0)
+ {
+ if (j >= utf16.length) { return -1; }
+
+ utf16[j++] = (char)codeUnit;
+ continue;
+ }
+
+ short first = firstUnitTable[codeUnit & 0x7F];
+ int codePoint = first >>> 8;
+ byte state = (byte)first;
+
+ while (state >= 0)
+ {
+ if (i >= utf8.length) { return -1; }
+
+ codeUnit = utf8[i++];
+ codePoint = (codePoint << 6) | (codeUnit & 0x3F);
+ state = transitionTable[state + ((codeUnit & 0xFF) >>> 4)];
+ }
+
+ if (state == S_ERR) { return -1; }
+
+ if (codePoint <= 0xFFFF)
+ {
+ if (j >= utf16.length) { return -1; }
+
+ // Code points from U+D800 to U+DFFF are caught by the DFA
+ utf16[j++] = (char)codePoint;
+ }
+ else
+ {
+ if (j >= utf16.length - 1) { return -1; }
+
+ // Code points above U+10FFFF are caught by the DFA
+ utf16[j++] = (char)(0xD7C0 + (codePoint >>> 10));
+ utf16[j++] = (char)(0xDC00 | (codePoint & 0x3FF));
+ }
+ }
+
+ return j;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/SimpleOutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/SimpleOutputStream.java
new file mode 100644
index 00000000..b7d673e0
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/SimpleOutputStream.java
@@ -0,0 +1,25 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class SimpleOutputStream extends OutputStream
+{
+ public void close()
+ {
+ }
+
+ public void flush()
+ {
+ }
+
+ public void write(int b) throws IOException
+ {
+ byte[] buf = new byte[]{ (byte)b };
+ write(buf, 0, 1);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/StreamOverflowException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/StreamOverflowException.java
new file mode 100644
index 00000000..f493b210
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/StreamOverflowException.java
@@ -0,0 +1,17 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.io;
+
+import java.io.IOException;
+
+/**
+ * Exception thrown when too much data is written to an InputStream
+ * @hide This class is not part of the Android public SDK API
+ */
+public class StreamOverflowException
+ extends IOException
+{
+ public StreamOverflowException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/Streams.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/Streams.java
new file mode 100644
index 00000000..2c0a2ad7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/Streams.java
@@ -0,0 +1,153 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.io;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Utility methods to assist with stream processing.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Streams
+{
+ private static int BUFFER_SIZE = 4096;
+
+ /**
+ * Read stream till EOF is encountered.
+ *
+ * @param inStr stream to be emptied.
+ * @throws IOException in case of underlying IOException.
+ */
+ public static void drain(InputStream inStr)
+ throws IOException
+ {
+ byte[] bs = new byte[BUFFER_SIZE];
+ while (inStr.read(bs, 0, bs.length) >= 0)
+ {
+ }
+ }
+
+ /**
+ * Read stream fully, returning contents in a byte array.
+ *
+ * @param inStr stream to be read.
+ * @return a byte array representing the contents of inStr.
+ * @throws IOException in case of underlying IOException.
+ */
+ public static byte[] readAll(InputStream inStr)
+ throws IOException
+ {
+ ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ pipeAll(inStr, buf);
+ return buf.toByteArray();
+ }
+
+ /**
+ * Read from inStr up to a maximum number of bytes, throwing an exception if more the maximum amount
+ * of requested data is available.
+ *
+ * @param inStr stream to be read.
+ * @param limit maximum number of bytes that can be read.
+ * @return a byte array representing the contents of inStr.
+ * @throws IOException in case of underlying IOException, or if limit is reached on inStr still has data in it.
+ */
+ public static byte[] readAllLimited(InputStream inStr, int limit)
+ throws IOException
+ {
+ ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ pipeAllLimited(inStr, limit, buf);
+ return buf.toByteArray();
+ }
+
+ /**
+ * Fully read in buf's length in data, or up to EOF, whichever occurs first,
+ *
+ * @param inStr the stream to be read.
+ * @param buf the buffer to be read into.
+ * @return the number of bytes read into the buffer.
+ * @throws IOException in case of underlying IOException.
+ */
+ public static int readFully(InputStream inStr, byte[] buf)
+ throws IOException
+ {
+ return readFully(inStr, buf, 0, buf.length);
+ }
+
+ /**
+ * Fully read in len's bytes of data into buf, or up to EOF, whichever occurs first,
+ *
+ * @param inStr the stream to be read.
+ * @param buf the buffer to be read into.
+ * @param off offset into buf to start putting bytes into.
+ * @param len the number of bytes to be read.
+ * @return the number of bytes read into the buffer.
+ * @throws IOException in case of underlying IOException.
+ */
+ public static int readFully(InputStream inStr, byte[] buf, int off, int len)
+ throws IOException
+ {
+ int totalRead = 0;
+ while (totalRead < len)
+ {
+ int numRead = inStr.read(buf, off + totalRead, len - totalRead);
+ if (numRead < 0)
+ {
+ break;
+ }
+ totalRead += numRead;
+ }
+ return totalRead;
+ }
+
+ /**
+ * Write the full contents of inStr to the destination stream outStr.
+ *
+ * @param inStr source input stream.
+ * @param outStr destination output stream.
+ * @throws IOException in case of underlying IOException.
+ */
+ public static void pipeAll(InputStream inStr, OutputStream outStr)
+ throws IOException
+ {
+ byte[] bs = new byte[BUFFER_SIZE];
+ int numRead;
+ while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
+ {
+ outStr.write(bs, 0, numRead);
+ }
+ }
+
+ /**
+ * Write up to limit bytes of data from inStr to the destination stream outStr.
+ *
+ * @param inStr source input stream.
+ * @param limit the maximum number of bytes allowed to be read.
+ * @param outStr destination output stream.
+ * @throws IOException in case of underlying IOException, or if limit is reached on inStr still has data in it.
+ */
+ public static long pipeAllLimited(InputStream inStr, long limit, OutputStream outStr)
+ throws IOException
+ {
+ long total = 0;
+ byte[] bs = new byte[BUFFER_SIZE];
+ int numRead;
+ while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
+ {
+ if ((limit - total) < numRead)
+ {
+ throw new StreamOverflowException("Data Overflow");
+ }
+ total += numRead;
+ outStr.write(bs, 0, numRead);
+ }
+ return total;
+ }
+
+ public static void writeBufTo(ByteArrayOutputStream buf, OutputStream output)
+ throws IOException
+ {
+ buf.writeTo(output);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/TeeInputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/TeeInputStream.java
new file mode 100644
index 00000000..7f9f9871
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/TeeInputStream.java
@@ -0,0 +1,78 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * An input stream which copies anything read through it to another stream.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TeeInputStream
+ extends InputStream
+{
+ private final InputStream input;
+ private final OutputStream output;
+
+ /**
+ * Base constructor.
+ *
+ * @param input input stream to be wrapped.
+ * @param output output stream to copy any input read to.
+ */
+ public TeeInputStream(InputStream input, OutputStream output)
+ {
+ this.input = input;
+ this.output = output;
+ }
+
+ public int available() throws IOException
+ {
+ return input.available();
+ }
+
+ public int read(byte[] buf)
+ throws IOException
+ {
+ return read(buf, 0, buf.length);
+ }
+
+ public int read(byte[] buf, int off, int len)
+ throws IOException
+ {
+ int i = input.read(buf, off, len);
+
+ if (i > 0)
+ {
+ output.write(buf, off, i);
+ }
+
+ return i;
+ }
+
+ public int read()
+ throws IOException
+ {
+ int i = input.read();
+
+ if (i >= 0)
+ {
+ output.write(i);
+ }
+
+ return i;
+ }
+
+ public void close()
+ throws IOException
+ {
+ this.input.close();
+ this.output.close();
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return output;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/TeeOutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/TeeOutputStream.java
new file mode 100644
index 00000000..6ad76cf3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/TeeOutputStream.java
@@ -0,0 +1,64 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+
+/**
+ * An output stream which copies anything written into it to another stream.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TeeOutputStream
+ extends OutputStream
+{
+ private OutputStream output1;
+ private OutputStream output2;
+
+ /**
+ * Base constructor.
+ *
+ * @param output1 the output stream that is wrapped.
+ * @param output2 a secondary stream that anything written to output1 is also written to.
+ */
+ public TeeOutputStream(OutputStream output1, OutputStream output2)
+ {
+ this.output1 = output1;
+ this.output2 = output2;
+ }
+
+ public void write(byte[] buf)
+ throws IOException
+ {
+ this.output1.write(buf);
+ this.output2.write(buf);
+ }
+
+ public void write(byte[] buf, int off, int len)
+ throws IOException
+ {
+ this.output1.write(buf, off, len);
+ this.output2.write(buf, off, len);
+ }
+
+ public void write(int b)
+ throws IOException
+ {
+ this.output1.write(b);
+ this.output2.write(b);
+ }
+
+ public void flush()
+ throws IOException
+ {
+ this.output1.flush();
+ this.output2.flush();
+ }
+
+ public void close()
+ throws IOException
+ {
+ this.output1.close();
+ this.output2.close();
+ }
+} \ No newline at end of file
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemGenerationException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemGenerationException.java
new file mode 100644
index 00000000..0ceacaf6
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemGenerationException.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.io.pem;
+
+import java.io.IOException;
+
+/**
+ * Exception thrown on failure to generate a PEM object.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PemGenerationException
+ extends IOException
+{
+ private Throwable cause;
+
+ public PemGenerationException(String message, Throwable cause)
+ {
+ super(message);
+ this.cause = cause;
+ }
+
+ public PemGenerationException(String message)
+ {
+ super(message);
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemHeader.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemHeader.java
new file mode 100644
index 00000000..4cdf6d46
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemHeader.java
@@ -0,0 +1,77 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.io.pem;
+
+/**
+ * Class representing a PEM header (name, value) pair.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PemHeader
+{
+ private String name;
+ private String value;
+
+ /**
+ * Base constructor.
+ *
+ * @param name name of the header property.
+ * @param value value of the header property.
+ */
+ public PemHeader(String name, String value)
+ {
+ this.name = name;
+ this.value = value;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getValue()
+ {
+ return value;
+ }
+
+ public int hashCode()
+ {
+ return getHashCode(this.name) + 31 * getHashCode(this.value);
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof PemHeader))
+ {
+ return false;
+ }
+
+ PemHeader other = (PemHeader)o;
+
+ return other == this || (isEqual(this.name, other.name) && isEqual(this.value, other.value));
+ }
+
+ private int getHashCode(String s)
+ {
+ if (s == null)
+ {
+ return 1;
+ }
+
+ return s.hashCode();
+ }
+
+ private boolean isEqual(String s1, String s2)
+ {
+ if (s1 == s2)
+ {
+ return true;
+ }
+
+ if (s1 == null || s2 == null)
+ {
+ return false;
+ }
+
+ return s1.equals(s2);
+ }
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemObject.java
new file mode 100644
index 00000000..0125b03d
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemObject.java
@@ -0,0 +1,66 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.io.pem;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A generic PEM object - type, header properties, and byte content.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PemObject
+ implements PemObjectGenerator
+{
+ private static final List EMPTY_LIST = Collections.unmodifiableList(new ArrayList());
+
+ private String type;
+ private List headers;
+ private byte[] content;
+
+ /**
+ * Generic constructor for object without headers.
+ *
+ * @param type pem object type.
+ * @param content the binary content of the object.
+ */
+ public PemObject(String type, byte[] content)
+ {
+ this(type, EMPTY_LIST, content);
+ }
+
+ /**
+ * Generic constructor for object with headers.
+ *
+ * @param type pem object type.
+ * @param headers a list of PemHeader objects.
+ * @param content the binary content of the object.
+ */
+ public PemObject(String type, List headers, byte[] content)
+ {
+ this.type = type;
+ this.headers = Collections.unmodifiableList(headers);
+ this.content = content;
+ }
+
+ public String getType()
+ {
+ return type;
+ }
+
+ public List getHeaders()
+ {
+ return headers;
+ }
+
+ public byte[] getContent()
+ {
+ return content;
+ }
+
+ public PemObject generate()
+ throws PemGenerationException
+ {
+ return this;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemObjectGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemObjectGenerator.java
new file mode 100644
index 00000000..07843b23
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemObjectGenerator.java
@@ -0,0 +1,18 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.io.pem;
+
+/**
+ * Base interface for generators of PEM objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PemObjectGenerator
+{
+ /**
+ * Generate a PEM object.
+ *
+ * @return the generated object.
+ * @throws PemGenerationException on failure.
+ */
+ PemObject generate()
+ throws PemGenerationException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemObjectParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemObjectParser.java
new file mode 100644
index 00000000..95bf9aa2
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemObjectParser.java
@@ -0,0 +1,21 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.io.pem;
+
+import java.io.IOException;
+
+/**
+ * Base interface for parsers to convert PEM objects into specific objects.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PemObjectParser
+{
+ /**
+ * Parse an object out of the PEM object passed in.
+ *
+ * @param obj the PEM object containing the details for the specific object.
+ * @return a specific object represented by the PEM object.
+ * @throws IOException on a parsing error.
+ */
+ Object parseObject(PemObject obj)
+ throws IOException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemReader.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemReader.java
new file mode 100644
index 00000000..a192b36c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemReader.java
@@ -0,0 +1,96 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.io.pem;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.android.internal.org.bouncycastle.util.encoders.Base64;
+
+/**
+ * A generic PEM reader, based on the format outlined in RFC 1421
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PemReader
+ extends BufferedReader
+{
+ private static final String BEGIN = "-----BEGIN ";
+ private static final String END = "-----END ";
+
+ public PemReader(Reader reader)
+ {
+ super(reader);
+ }
+
+ /**
+ * Read the next PEM object as a blob of raw data with header information.
+ *
+ * @return the next object in the stream, null if no objects left.
+ * @throws IOException in case of a parse error.
+ */
+ public PemObject readPemObject()
+ throws IOException
+ {
+ String line = readLine();
+
+ while (line != null && !line.startsWith(BEGIN))
+ {
+ line = readLine();
+ }
+
+ if (line != null)
+ {
+ line = line.substring(BEGIN.length());
+ int index = line.indexOf('-');
+
+ if (index > 0 && line.endsWith("-----") && (line.length() - index) == 5)
+ {
+ String type = line.substring(0, index);
+
+ return loadObject(type);
+ }
+ }
+
+ return null;
+ }
+
+ private PemObject loadObject(String type)
+ throws IOException
+ {
+ String line;
+ String endMarker = END + type;
+ StringBuffer buf = new StringBuffer();
+ List headers = new ArrayList();
+
+ while ((line = readLine()) != null)
+ {
+ if (line.indexOf(":") >= 0)
+ {
+ int index = line.indexOf(':');
+ String hdr = line.substring(0, index);
+ String value = line.substring(index + 1).trim();
+
+ headers.add(new PemHeader(hdr, value));
+
+ continue;
+ }
+
+ if (line.indexOf(endMarker) != -1)
+ {
+ break;
+ }
+
+ buf.append(line.trim());
+ }
+
+ if (line == null)
+ {
+ throw new IOException(endMarker + " not found");
+ }
+
+ return new PemObject(type, headers, Base64.decode(buf.toString()));
+ }
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemWriter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemWriter.java
new file mode 100644
index 00000000..48132c71
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemWriter.java
@@ -0,0 +1,140 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.util.io.pem;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Iterator;
+
+import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.org.bouncycastle.util.encoders.Base64;
+
+/**
+ * A generic PEM writer, based on RFC 1421
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PemWriter
+ extends BufferedWriter
+{
+ private static final int LINE_LENGTH = 64;
+
+ private final int nlLength;
+ private char[] buf = new char[LINE_LENGTH];
+
+ /**
+ * Base constructor.
+ *
+ * @param out output stream to use.
+ */
+ public PemWriter(Writer out)
+ {
+ super(out);
+
+ String nl = Strings.lineSeparator();
+ if (nl != null)
+ {
+ nlLength = nl.length();
+ }
+ else
+ {
+ nlLength = 2;
+ }
+ }
+
+ /**
+ * Return the number of bytes or characters required to contain the
+ * passed in object if it is PEM encoded.
+ *
+ * @param obj pem object to be output
+ * @return an estimate of the number of bytes
+ */
+ public int getOutputSize(PemObject obj)
+ {
+ // BEGIN and END boundaries.
+ int size = (2 * (obj.getType().length() + 10 + nlLength)) + 6 + 4;
+
+ if (!obj.getHeaders().isEmpty())
+ {
+ for (Iterator it = obj.getHeaders().iterator(); it.hasNext();)
+ {
+ PemHeader hdr = (PemHeader)it.next();
+
+ size += hdr.getName().length() + ": ".length() + hdr.getValue().length() + nlLength;
+ }
+
+ size += nlLength;
+ }
+
+ // base64 encoding
+ int dataLen = ((obj.getContent().length + 2) / 3) * 4;
+
+ size += dataLen + (((dataLen + LINE_LENGTH - 1) / LINE_LENGTH) * nlLength);
+
+ return size;
+ }
+
+ public void writeObject(PemObjectGenerator objGen)
+ throws IOException
+ {
+ PemObject obj = objGen.generate();
+
+ writePreEncapsulationBoundary(obj.getType());
+
+ if (!obj.getHeaders().isEmpty())
+ {
+ for (Iterator it = obj.getHeaders().iterator(); it.hasNext();)
+ {
+ PemHeader hdr = (PemHeader)it.next();
+
+ this.write(hdr.getName());
+ this.write(": ");
+ this.write(hdr.getValue());
+ this.newLine();
+ }
+
+ this.newLine();
+ }
+
+ writeEncoded(obj.getContent());
+ writePostEncapsulationBoundary(obj.getType());
+ }
+
+ private void writeEncoded(byte[] bytes)
+ throws IOException
+ {
+ bytes = Base64.encode(bytes);
+
+ for (int i = 0; i < bytes.length; i += buf.length)
+ {
+ int index = 0;
+
+ while (index != buf.length)
+ {
+ if ((i + index) >= bytes.length)
+ {
+ break;
+ }
+ buf[index] = (char)bytes[i + index];
+ index++;
+ }
+ this.write(buf, 0, index);
+ this.newLine();
+ }
+ }
+
+ private void writePreEncapsulationBoundary(
+ String type)
+ throws IOException
+ {
+ this.write("-----BEGIN " + type + "-----");
+ this.newLine();
+ }
+
+ private void writePostEncapsulationBoundary(
+ String type)
+ throws IOException
+ {
+ this.write("-----END " + type + "-----");
+ this.newLine();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/AttributeCertificateHolder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/AttributeCertificateHolder.java
new file mode 100644
index 00000000..8c340679
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/AttributeCertificateHolder.java
@@ -0,0 +1,421 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.Principal;
+import java.security.cert.CertSelector;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.security.auth.x500.X500Principal;
+
+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.DERSequence;
+import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralNames;
+import com.android.internal.org.bouncycastle.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.jce.PrincipalUtil;
+import com.android.internal.org.bouncycastle.jce.X509Principal;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Selector;
+
+/**
+ * The Holder object.
+ *
+ * <pre>
+ * Holder ::= SEQUENCE {
+ * baseCertificateID [0] IssuerSerial OPTIONAL,
+ * -- the issuer and serial number of
+ * -- the holder's Public Key Certificate
+ * entityName [1] GeneralNames OPTIONAL,
+ * -- the name of the claimant or role
+ * objectDigestInfo [2] ObjectDigestInfo OPTIONAL
+ * -- used to directly authenticate the holder,
+ * -- for example, an executable
+ * }
+ * </pre>
+ * @deprecated use org.bouncycastle.cert.AttributeCertificateHolder
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AttributeCertificateHolder
+ implements CertSelector, Selector
+{
+ final Holder holder;
+
+ AttributeCertificateHolder(ASN1Sequence seq)
+ {
+ holder = Holder.getInstance(seq);
+ }
+
+ public AttributeCertificateHolder(X509Principal issuerName,
+ BigInteger serialNumber)
+ {
+ holder = new com.android.internal.org.bouncycastle.asn1.x509.Holder(new IssuerSerial(
+ GeneralNames.getInstance(new DERSequence(new GeneralName(issuerName))),
+ new ASN1Integer(serialNumber)));
+ }
+
+ public AttributeCertificateHolder(X500Principal issuerName,
+ BigInteger serialNumber)
+ {
+ this(X509Util.convertPrincipal(issuerName), serialNumber);
+ }
+
+ public AttributeCertificateHolder(X509Certificate cert)
+ throws CertificateParsingException
+ {
+ X509Principal name;
+
+ try
+ {
+ name = PrincipalUtil.getIssuerX509Principal(cert);
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException(e.getMessage());
+ }
+
+ holder = new Holder(new IssuerSerial(generateGeneralNames(name),
+ new ASN1Integer(cert.getSerialNumber())));
+ }
+
+ public AttributeCertificateHolder(X509Principal principal)
+ {
+ holder = new Holder(generateGeneralNames(principal));
+ }
+
+ public AttributeCertificateHolder(X500Principal principal)
+ {
+ this(X509Util.convertPrincipal(principal));
+ }
+
+ /**
+ * Constructs a holder for v2 attribute certificates with a hash value for
+ * some type of object.
+ * <p>
+ * <code>digestedObjectType</code> can be one of the following:
+ * <ul>
+ * <li>0 - publicKey - A hash of the public key of the holder must be
+ * passed.
+ * <li>1 - publicKeyCert - A hash of the public key certificate of the
+ * holder must be passed.
+ * <li>2 - otherObjectDigest - A hash of some other object type must be
+ * passed. <code>otherObjectTypeID</code> must not be empty.
+ * </ul>
+ * <p>
+ * This cannot be used if a v1 attribute certificate is used.
+ *
+ * @param digestedObjectType The digest object type.
+ * @param digestAlgorithm The algorithm identifier for the hash.
+ * @param otherObjectTypeID The object type ID if
+ * <code>digestedObjectType</code> is
+ * <code>otherObjectDigest</code>.
+ * @param objectDigest The hash value.
+ */
+ public AttributeCertificateHolder(int digestedObjectType,
+ String digestAlgorithm, String otherObjectTypeID, byte[] objectDigest)
+ {
+ holder = new Holder(new ObjectDigestInfo(digestedObjectType,
+ new ASN1ObjectIdentifier(otherObjectTypeID), new AlgorithmIdentifier(new ASN1ObjectIdentifier(digestAlgorithm)), Arrays
+ .clone(objectDigest)));
+ }
+
+ /**
+ * Returns the digest object type if an object digest info is used.
+ * <p>
+ * <ul>
+ * <li>0 - publicKey - A hash of the public key of the holder must be
+ * passed.
+ * <li>1 - publicKeyCert - A hash of the public key certificate of the
+ * holder must be passed.
+ * <li>2 - otherObjectDigest - A hash of some other object type must be
+ * passed. <code>otherObjectTypeID</code> must not be empty.
+ * </ul>
+ *
+ * @return The digest object type or -1 if no object digest info is set.
+ */
+ public int getDigestedObjectType()
+ {
+ if (holder.getObjectDigestInfo() != null)
+ {
+ return holder.getObjectDigestInfo().getDigestedObjectType().intValueExact();
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the other object type ID if an object digest info is used.
+ *
+ * @return The other object type ID or <code>null</code> if no object
+ * digest info is set.
+ */
+ public String getDigestAlgorithm()
+ {
+ if (holder.getObjectDigestInfo() != null)
+ {
+ return holder.getObjectDigestInfo().getDigestAlgorithm().getAlgorithm()
+ .getId();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the hash if an object digest info is used.
+ *
+ * @return The hash or <code>null</code> if no object digest info is set.
+ */
+ public byte[] getObjectDigest()
+ {
+ if (holder.getObjectDigestInfo() != null)
+ {
+ return holder.getObjectDigestInfo().getObjectDigest().getBytes();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the digest algorithm ID if an object digest info is used.
+ *
+ * @return The digest algorithm ID or <code>null</code> if no object
+ * digest info is set.
+ */
+ public String getOtherObjectTypeID()
+ {
+ if (holder.getObjectDigestInfo() != null)
+ {
+ holder.getObjectDigestInfo().getOtherObjectTypeID().getId();
+ }
+ return null;
+ }
+
+ private GeneralNames generateGeneralNames(X509Principal principal)
+ {
+ return GeneralNames.getInstance(new DERSequence(new GeneralName(principal)));
+ }
+
+ private boolean matchesDN(X509Principal subject, GeneralNames targets)
+ {
+ GeneralName[] names = targets.getNames();
+
+ for (int i = 0; i != names.length; i++)
+ {
+ GeneralName gn = names[i];
+
+ if (gn.getTagNo() == GeneralName.directoryName)
+ {
+ try
+ {
+ if (new X509Principal(((ASN1Encodable)gn.getName()).toASN1Primitive()
+ .getEncoded()).equals(subject))
+ {
+ return true;
+ }
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private Object[] getNames(GeneralName[] names)
+ {
+ List l = new ArrayList(names.length);
+
+ for (int i = 0; i != names.length; i++)
+ {
+ if (names[i].getTagNo() == GeneralName.directoryName)
+ {
+ try
+ {
+ l.add(new X500Principal(
+ ((ASN1Encodable)names[i].getName()).toASN1Primitive().getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("badly formed Name object");
+ }
+ }
+ }
+
+ return l.toArray(new Object[l.size()]);
+ }
+
+ private Principal[] getPrincipals(GeneralNames names)
+ {
+ Object[] p = this.getNames(names.getNames());
+ List l = new ArrayList();
+
+ for (int i = 0; i != p.length; i++)
+ {
+ if (p[i] instanceof Principal)
+ {
+ l.add(p[i]);
+ }
+ }
+
+ return (Principal[])l.toArray(new Principal[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 Principal[] getEntityNames()
+ {
+ if (holder.getEntityName() != null)
+ {
+ return getPrincipals(holder.getEntityName());
+ }
+
+ 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 Principal[] getIssuer()
+ {
+ if (holder.getBaseCertificateID() != null)
+ {
+ return getPrincipals(holder.getBaseCertificateID().getIssuer());
+ }
+
+ 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(Certificate cert)
+ {
+ if (!(cert instanceof X509Certificate))
+ {
+ return false;
+ }
+
+ X509Certificate x509Cert = (X509Certificate)cert;
+
+ try
+ {
+ if (holder.getBaseCertificateID() != null)
+ {
+ return holder.getBaseCertificateID().getSerial().hasValue(x509Cert.getSerialNumber())
+ && matchesDN(PrincipalUtil.getIssuerX509Principal(x509Cert), holder.getBaseCertificateID().getIssuer());
+ }
+
+ if (holder.getEntityName() != null)
+ {
+ if (matchesDN(PrincipalUtil.getSubjectX509Principal(x509Cert),
+ holder.getEntityName()))
+ {
+ return true;
+ }
+ }
+ if (holder.getObjectDigestInfo() != null)
+ {
+ MessageDigest md = null;
+ try
+ {
+ md = MessageDigest.getInstance(getDigestAlgorithm(), "BC");
+
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ switch (getDigestedObjectType())
+ {
+ case ObjectDigestInfo.publicKey:
+ // TODO: DSA Dss-parms
+ md.update(cert.getPublicKey().getEncoded());
+ break;
+ case ObjectDigestInfo.publicKeyCert:
+ md.update(cert.getEncoded());
+ break;
+ }
+ if (!Arrays.areEqual(md.digest(), getObjectDigest()))
+ {
+ return false;
+ }
+ }
+ }
+ catch (CertificateEncodingException 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();
+ }
+
+ public boolean match(Object obj)
+ {
+ if (!(obj instanceof X509Certificate))
+ {
+ return false;
+ }
+
+ return match((Certificate)obj);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/AttributeCertificateIssuer.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/AttributeCertificateIssuer.java
new file mode 100644
index 00000000..385bfa4f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/AttributeCertificateIssuer.java
@@ -0,0 +1,210 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.security.cert.CertSelector;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.DERSequence;
+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.jce.X509Principal;
+import com.android.internal.org.bouncycastle.util.Selector;
+
+/**
+ * Carrying class for an attribute certificate issuer.
+ * @deprecated use org.bouncycastle.cert.AttributeCertificateIssuer
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AttributeCertificateIssuer
+ implements CertSelector, 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(X500Principal principal)
+ throws IOException
+ {
+ this(new X509Principal(principal.getEncoded()));
+ }
+
+ public AttributeCertificateIssuer(X509Principal principal)
+ {
+ form = new V2Form(GeneralNames.getInstance(new DERSequence(new GeneralName(principal))));
+ }
+
+ private Object[] 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)
+ {
+ try
+ {
+ l.add(new X500Principal(
+ ((ASN1Encodable)names[i].getName()).toASN1Primitive().getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("badly formed Name object");
+ }
+ }
+ }
+
+ return l.toArray(new Object[l.size()]);
+ }
+
+ /**
+ * Return any principal objects inside the attribute certificate issuer
+ * object.
+ *
+ * @return an array of Principal objects (usually X500Principal)
+ */
+ public Principal[] getPrincipals()
+ {
+ Object[] p = this.getNames();
+ List l = new ArrayList();
+
+ for (int i = 0; i != p.length; i++)
+ {
+ if (p[i] instanceof Principal)
+ {
+ l.add(p[i]);
+ }
+ }
+
+ return (Principal[])l.toArray(new Principal[l.size()]);
+ }
+
+ private boolean matchesDN(X500Principal subject, GeneralNames targets)
+ {
+ GeneralName[] names = targets.getNames();
+
+ for (int i = 0; i != names.length; i++)
+ {
+ GeneralName gn = names[i];
+
+ if (gn.getTagNo() == GeneralName.directoryName)
+ {
+ try
+ {
+ if (new X500Principal(((ASN1Encodable)gn.getName()).toASN1Primitive().getEncoded()).equals(subject))
+ {
+ return true;
+ }
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public Object clone()
+ {
+ return new AttributeCertificateIssuer(AttCertIssuer.getInstance(form));
+ }
+
+ public boolean match(Certificate cert)
+ {
+ if (!(cert instanceof X509Certificate))
+ {
+ return false;
+ }
+
+ X509Certificate x509Cert = (X509Certificate)cert;
+
+ if (form instanceof V2Form)
+ {
+ V2Form issuer = (V2Form)form;
+ if (issuer.getBaseCertificateID() != null)
+ {
+ return issuer.getBaseCertificateID().getSerial().hasValue(x509Cert.getSerialNumber())
+ && matchesDN(x509Cert.getIssuerX500Principal(), issuer.getBaseCertificateID().getIssuer());
+ }
+
+ GeneralNames name = issuer.getIssuerName();
+ if (matchesDN(x509Cert.getSubjectX500Principal(), name))
+ {
+ return true;
+ }
+ }
+ else
+ {
+ GeneralNames name = (GeneralNames)form;
+ if (matchesDN(x509Cert.getSubjectX500Principal(), name))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ 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 X509Certificate))
+ {
+ return false;
+ }
+
+ return match((Certificate)obj);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/ExtCertificateEncodingException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/ExtCertificateEncodingException.java
new file mode 100644
index 00000000..a899acdd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/ExtCertificateEncodingException.java
@@ -0,0 +1,21 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import java.security.cert.CertificateEncodingException;
+
+class ExtCertificateEncodingException
+ extends CertificateEncodingException
+{
+ Throwable cause;
+
+ ExtCertificateEncodingException(String message, Throwable cause)
+ {
+ super(message);
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/ExtendedPKIXBuilderParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/ExtendedPKIXBuilderParameters.java
new file mode 100644
index 00000000..7e7d63dd
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/ExtendedPKIXBuilderParameters.java
@@ -0,0 +1,213 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import com.android.internal.org.bouncycastle.util.Selector;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.PKIXParameters;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509CertSelector;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This class contains extended parameters for PKIX certification path builders.
+ *
+ * @see java.security.cert.PKIXBuilderParameters
+ * @see com.android.internal.org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi
+ * @deprecated use PKIXExtendedBuilderParameters
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ExtendedPKIXBuilderParameters extends ExtendedPKIXParameters
+{
+
+ private int maxPathLength = 5;
+
+ private Set excludedCerts = Collections.EMPTY_SET;
+
+ /**
+ * Excluded certificates are not used for building a certification path.
+ * <p>
+ * The returned set is immutable.
+ *
+ * @return Returns the excluded certificates.
+ */
+ public Set getExcludedCerts()
+ {
+ return Collections.unmodifiableSet(excludedCerts);
+ }
+
+ /**
+ * Sets the excluded certificates which are not used for building a
+ * certification path. If the <code>Set</code> is <code>null</code> an
+ * empty set is assumed.
+ * <p>
+ * The given set is cloned to protect it against subsequent modifications.
+ *
+ * @param excludedCerts The excluded certificates to set.
+ */
+ public void setExcludedCerts(Set excludedCerts)
+ {
+ if (excludedCerts == null)
+ {
+ excludedCerts = Collections.EMPTY_SET;
+ }
+ else
+ {
+ this.excludedCerts = new HashSet(excludedCerts);
+ }
+ }
+
+ /**
+ * Creates an instance of <code>PKIXBuilderParameters</code> with the
+ * specified <code>Set</code> of most-trusted CAs. Each element of the set
+ * is a {@link TrustAnchor TrustAnchor}.
+ *
+ * <p>
+ * Note that the <code>Set</code> is copied to protect against subsequent
+ * modifications.
+ *
+ * @param trustAnchors a <code>Set</code> of <code>TrustAnchor</code>s
+ * @param targetConstraints a <code>Selector</code> specifying the
+ * constraints on the target certificate or attribute
+ * certificate.
+ * @throws InvalidAlgorithmParameterException if <code>trustAnchors</code>
+ * is empty.
+ * @throws NullPointerException if <code>trustAnchors</code> is
+ * <code>null</code>
+ * @throws ClassCastException if any of the elements of
+ * <code>trustAnchors</code> is not of type
+ * <code>java.security.cert.TrustAnchor</code>
+ */
+ public ExtendedPKIXBuilderParameters(Set trustAnchors,
+ Selector targetConstraints)
+ throws InvalidAlgorithmParameterException
+ {
+ super(trustAnchors);
+ setTargetConstraints(targetConstraints);
+ }
+
+ /**
+ * Sets the maximum number of intermediate non-self-issued certificates in a
+ * certification path. The PKIX <code>CertPathBuilder</code> must not
+ * build paths longer then this length.
+ * <p>
+ * A value of 0 implies that the path can only contain a single certificate.
+ * A value of -1 does not limit the length. The default length is 5.
+ *
+ * <p>
+ *
+ * The basic constraints extension of a CA certificate overrides this value
+ * if smaller.
+ *
+ * @param maxPathLength the maximum number of non-self-issued intermediate
+ * certificates in the certification path
+ * @throws InvalidParameterException if <code>maxPathLength</code> is set
+ * to a value less than -1
+ *
+ * @see com.android.internal.org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi
+ * @see #getMaxPathLength
+ */
+ public void setMaxPathLength(int maxPathLength)
+ {
+ if (maxPathLength < -1)
+ {
+ throw new InvalidParameterException("The maximum path "
+ + "length parameter can not be less than -1.");
+ }
+ this.maxPathLength = maxPathLength;
+ }
+
+ /**
+ * Returns the value of the maximum number of intermediate non-self-issued
+ * certificates in the certification path.
+ *
+ * @return the maximum number of non-self-issued intermediate certificates
+ * in the certification path, or -1 if no limit exists.
+ *
+ * @see #setMaxPathLength(int)
+ */
+ public int getMaxPathLength()
+ {
+ return maxPathLength;
+ }
+
+ /**
+ * Can alse handle <code>ExtendedPKIXBuilderParameters</code> and
+ * <code>PKIXBuilderParameters</code>.
+ *
+ * @param params Parameters to set.
+ * @see com.android.internal.org.bouncycastle.x509.ExtendedPKIXParameters#setParams(java.security.cert.PKIXParameters)
+ */
+ protected void setParams(PKIXParameters params)
+ {
+ super.setParams(params);
+ if (params instanceof ExtendedPKIXBuilderParameters)
+ {
+ ExtendedPKIXBuilderParameters _params = (ExtendedPKIXBuilderParameters) params;
+ maxPathLength = _params.maxPathLength;
+ excludedCerts = new HashSet(_params.excludedCerts);
+ }
+ if (params instanceof PKIXBuilderParameters)
+ {
+ PKIXBuilderParameters _params = (PKIXBuilderParameters) params;
+ maxPathLength = _params.getMaxPathLength();
+ }
+ }
+
+ /**
+ * Makes a copy of this <code>PKIXParameters</code> object. Changes to the
+ * copy will not affect the original and vice versa.
+ *
+ * @return a copy of this <code>PKIXParameters</code> object
+ */
+ public Object clone()
+ {
+ ExtendedPKIXBuilderParameters params = null;
+ try
+ {
+ params = new ExtendedPKIXBuilderParameters(getTrustAnchors(),
+ getTargetConstraints());
+ }
+ catch (Exception e)
+ {
+ // cannot happen
+ throw new RuntimeException(e.getMessage());
+ }
+ params.setParams(this);
+ return params;
+ }
+
+ /**
+ * Returns an instance of <code>ExtendedPKIXParameters</code> which can be
+ * safely casted to <code>ExtendedPKIXBuilderParameters</code>.
+ * <p>
+ * This method can be used to get a copy from other
+ * <code>PKIXBuilderParameters</code>, <code>PKIXParameters</code>,
+ * and <code>ExtendedPKIXParameters</code> instances.
+ *
+ * @param pkixParams The PKIX parameters to create a copy of.
+ * @return An <code>ExtendedPKIXBuilderParameters</code> instance.
+ */
+ public static ExtendedPKIXParameters getInstance(PKIXParameters pkixParams)
+ {
+ ExtendedPKIXBuilderParameters params;
+ try
+ {
+ params = new ExtendedPKIXBuilderParameters(pkixParams
+ .getTrustAnchors(), X509CertStoreSelector
+ .getInstance((X509CertSelector) pkixParams
+ .getTargetCertConstraints()));
+ }
+ catch (Exception e)
+ {
+ // cannot happen
+ throw new RuntimeException(e.getMessage());
+ }
+ params.setParams(pkixParams);
+ return params;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/ExtendedPKIXParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/ExtendedPKIXParameters.java
new file mode 100644
index 00000000..9a28dd17
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/ExtendedPKIXParameters.java
@@ -0,0 +1,662 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.cert.CertSelector;
+import java.security.cert.CertStore;
+import java.security.cert.PKIXParameters;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509CertSelector;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import com.android.internal.org.bouncycastle.util.Selector;
+import com.android.internal.org.bouncycastle.util.Store;
+
+/**
+ * This class extends the PKIXParameters with a validity model parameter.
+ *
+ * @deprecated use PKIXExtendedParameters
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ExtendedPKIXParameters
+ extends PKIXParameters
+{
+
+ private List stores;
+
+ private Selector selector;
+
+ private boolean additionalLocationsEnabled;
+
+ private List additionalStores;
+
+ private Set trustedACIssuers;
+
+ private Set necessaryACAttributes;
+
+ private Set prohibitedACAttributes;
+
+ private Set attrCertCheckers;
+
+ /**
+ * Creates an instance of <code>PKIXParameters</code> with the specified
+ * <code>Set</code> of most-trusted CAs. Each element of the set is a
+ * {@link TrustAnchor TrustAnchor}.
+ * <p>
+ * Note that the <code>Set</code>
+ * is copied to protect against subsequent modifications.
+ * </p>
+ *
+ * @param trustAnchors a <code>Set</code> of <code>TrustAnchor</code>s
+ * @throws InvalidAlgorithmParameterException if the specified
+ * <code>Set</code> is empty.
+ * @throws NullPointerException if the specified <code>Set</code> is
+ * <code>null</code>
+ * @throws ClassCastException if any of the elements in the <code>Set</code>
+ * is not of type <code>java.security.cert.TrustAnchor</code>
+ */
+ public ExtendedPKIXParameters(Set trustAnchors)
+ throws InvalidAlgorithmParameterException
+ {
+ super(trustAnchors);
+ stores = new ArrayList();
+ additionalStores = new ArrayList();
+ trustedACIssuers = new HashSet();
+ necessaryACAttributes = new HashSet();
+ prohibitedACAttributes = new HashSet();
+ attrCertCheckers = new HashSet();
+ }
+
+ /**
+ * Returns an instance with the parameters of a given
+ * <code>PKIXParameters</code> object.
+ *
+ * @param pkixParams The given <code>PKIXParameters</code>
+ * @return an extended PKIX params object
+ */
+ public static ExtendedPKIXParameters getInstance(PKIXParameters pkixParams)
+ {
+ ExtendedPKIXParameters params;
+ try
+ {
+ params = new ExtendedPKIXParameters(pkixParams.getTrustAnchors());
+ }
+ catch (Exception e)
+ {
+ // cannot happen
+ throw new RuntimeException(e.getMessage());
+ }
+ params.setParams(pkixParams);
+ return params;
+ }
+
+ /**
+ * Method to support <code>clone()</code> under J2ME.
+ * <code>super.clone()</code> does not exist and fields are not copied.
+ *
+ * @param params Parameters to set. If this are
+ * <code>ExtendedPKIXParameters</code> they are copied to.
+ */
+ protected void setParams(PKIXParameters params)
+ {
+ setDate(params.getDate());
+ setCertPathCheckers(params.getCertPathCheckers());
+ setCertStores(params.getCertStores());
+ setAnyPolicyInhibited(params.isAnyPolicyInhibited());
+ setExplicitPolicyRequired(params.isExplicitPolicyRequired());
+ setPolicyMappingInhibited(params.isPolicyMappingInhibited());
+ setRevocationEnabled(params.isRevocationEnabled());
+ setInitialPolicies(params.getInitialPolicies());
+ setPolicyQualifiersRejected(params.getPolicyQualifiersRejected());
+ setSigProvider(params.getSigProvider());
+ setTargetCertConstraints(params.getTargetCertConstraints());
+ try
+ {
+ setTrustAnchors(params.getTrustAnchors());
+ }
+ catch (Exception e)
+ {
+ // cannot happen
+ throw new RuntimeException(e.getMessage());
+ }
+ if (params instanceof ExtendedPKIXParameters)
+ {
+ ExtendedPKIXParameters _params = (ExtendedPKIXParameters) params;
+ validityModel = _params.validityModel;
+ useDeltas = _params.useDeltas;
+ additionalLocationsEnabled = _params.additionalLocationsEnabled;
+ selector = _params.selector == null ? null
+ : (Selector) _params.selector.clone();
+ stores = new ArrayList(_params.stores);
+ additionalStores = new ArrayList(_params.additionalStores);
+ trustedACIssuers = new HashSet(_params.trustedACIssuers);
+ prohibitedACAttributes = new HashSet(_params.prohibitedACAttributes);
+ necessaryACAttributes = new HashSet(_params.necessaryACAttributes);
+ attrCertCheckers = new HashSet(_params.attrCertCheckers);
+ }
+ }
+
+ /**
+ * This is the default PKIX validity model. Actually there are two variants
+ * of this: The PKIX model and the modified PKIX model. The PKIX model
+ * verifies that all involved certificates must have been valid at the
+ * current time. The modified PKIX model verifies that all involved
+ * certificates were valid at the signing time. Both are indirectly choosen
+ * with the {@link PKIXParameters#setDate(java.util.Date)} method, so this
+ * methods sets the Date when <em>all</em> certificates must have been
+ * valid.
+ */
+ public static final int PKIX_VALIDITY_MODEL = 0;
+
+ /**
+ * This model uses the following validity model. Each certificate must have
+ * been valid at the moment where is was used. That means the end
+ * certificate must have been valid at the time the signature was done. The
+ * CA certificate which signed the end certificate must have been valid,
+ * when the end certificate was signed. The CA (or Root CA) certificate must
+ * have been valid, when the CA certificate was signed and so on. So the
+ * {@link PKIXParameters#setDate(java.util.Date)} method sets the time, when
+ * the <em>end certificate</em> must have been valid.
+ * <p>
+ * It is used e.g.
+ * in the German signature law.
+ * </p>
+ */
+ public static final int CHAIN_VALIDITY_MODEL = 1;
+
+ private int validityModel = PKIX_VALIDITY_MODEL;
+
+ private boolean useDeltas = false;
+
+ /**
+ * Defaults to <code>false</code>.
+ *
+ * @return Returns if delta CRLs should be used.
+ */
+ public boolean isUseDeltasEnabled()
+ {
+ return useDeltas;
+ }
+
+ /**
+ * Sets if delta CRLs should be used for checking the revocation status.
+ *
+ * @param useDeltas <code>true</code> if delta CRLs should be used.
+ */
+ public void setUseDeltasEnabled(boolean useDeltas)
+ {
+ this.useDeltas = useDeltas;
+ }
+
+ /**
+ * @return Returns the validity model.
+ * @see #CHAIN_VALIDITY_MODEL
+ * @see #PKIX_VALIDITY_MODEL
+ */
+ public int getValidityModel()
+ {
+ return validityModel;
+ }
+
+ /**
+ * Sets the Java CertStore to this extended PKIX parameters.
+ *
+ * @throws ClassCastException if an element of <code>stores</code> is not
+ * a <code>CertStore</code>.
+ */
+ public void setCertStores(List stores)
+ {
+ if (stores != null)
+ {
+ Iterator it = stores.iterator();
+ while (it.hasNext())
+ {
+ addCertStore((CertStore)it.next());
+ }
+ }
+ }
+
+ /**
+ * Sets the Bouncy Castle Stores for finding CRLs, certificates, attribute
+ * certificates or cross certificates.
+ * <p>
+ * The <code>List</code> is cloned.
+ *
+ * @param stores A list of stores to use.
+ * @see #getStores
+ * @throws ClassCastException if an element of <code>stores</code> is not
+ * a {@link Store}.
+ */
+ public void setStores(List stores)
+ {
+ if (stores == null)
+ {
+ this.stores = new ArrayList();
+ }
+ else
+ {
+ for (Iterator i = stores.iterator(); i.hasNext();)
+ {
+ if (!(i.next() instanceof Store))
+ {
+ throw new ClassCastException(
+ "All elements of list must be "
+ + "of type com.android.internal.org.bouncycastle.util.Store.");
+ }
+ }
+ this.stores = new ArrayList(stores);
+ }
+ }
+
+ /**
+ * Adds a Bouncy Castle {@link Store} to find CRLs, certificates, attribute
+ * certificates or cross certificates.
+ * <p>
+ * This method should be used to add local stores, like collection based
+ * X.509 stores, if available. Local stores should be considered first,
+ * before trying to use additional (remote) locations, because they do not
+ * need possible additional network traffic.
+ * <p>
+ * If <code>store</code> is <code>null</code> it is ignored.
+ *
+ * @param store The store to add.
+ * @see #getStores
+ */
+ public void addStore(Store store)
+ {
+ if (store != null)
+ {
+ stores.add(store);
+ }
+ }
+
+ /**
+ * Adds an additional Bouncy Castle {@link Store} to find CRLs, certificates,
+ * attribute certificates or cross certificates.
+ * <p>
+ * You should not use this method. This method is used for adding additional
+ * X.509 stores, which are used to add (remote) locations, e.g. LDAP, found
+ * during X.509 object processing, e.g. in certificates or CRLs. This method
+ * is used in PKIX certification path processing.
+ * <p>
+ * If <code>store</code> is <code>null</code> it is ignored.
+ *
+ * @param store The store to add.
+ * @see #getStores()
+ * @deprecated use addStore().
+ */
+ public void addAdditionalStore(Store store)
+ {
+ if (store != null)
+ {
+ additionalStores.add(store);
+ }
+ }
+
+ /**
+ * @deprecated
+ */
+ public void addAddionalStore(Store store)
+ {
+ addAdditionalStore(store);
+ }
+
+ /**
+ * Returns an immutable <code>List</code> of additional Bouncy Castle
+ * <code>Store</code>s used for finding CRLs, certificates, attribute
+ * certificates or cross certificates.
+ *
+ * @return an immutable <code>List</code> of additional Bouncy Castle
+ * <code>Store</code>s. Never <code>null</code>.
+ *
+ * @see #addAdditionalStore(Store)
+ */
+ public List getAdditionalStores()
+ {
+ return Collections.unmodifiableList(additionalStores);
+ }
+
+ /**
+ * Returns an immutable <code>List</code> of Bouncy Castle
+ * <code>Store</code>s used for finding CRLs, certificates, attribute
+ * certificates or cross certificates.
+ *
+ * @return an immutable <code>List</code> of Bouncy Castle
+ * <code>Store</code>s. Never <code>null</code>.
+ *
+ * @see #setStores(List)
+ */
+ public List getStores()
+ {
+ return Collections.unmodifiableList(new ArrayList(stores));
+ }
+
+ /**
+ * @param validityModel The validity model to set.
+ * @see #CHAIN_VALIDITY_MODEL
+ * @see #PKIX_VALIDITY_MODEL
+ */
+ public void setValidityModel(int validityModel)
+ {
+ this.validityModel = validityModel;
+ }
+
+ public Object clone()
+ {
+ ExtendedPKIXParameters params;
+ try
+ {
+ params = new ExtendedPKIXParameters(getTrustAnchors());
+ }
+ catch (Exception e)
+ {
+ // cannot happen
+ throw new RuntimeException(e.getMessage());
+ }
+ params.setParams(this);
+ return params;
+ }
+
+ /**
+ * Returns if additional {@link X509Store}s for locations like LDAP found
+ * in certificates or CRLs should be used.
+ *
+ * @return Returns <code>true</code> if additional stores are used.
+ */
+ public boolean isAdditionalLocationsEnabled()
+ {
+ return additionalLocationsEnabled;
+ }
+
+ /**
+ * Sets if additional {@link X509Store}s for locations like LDAP found in
+ * certificates or CRLs should be used.
+ *
+ * @param enabled <code>true</code> if additional stores are used.
+ */
+ public void setAdditionalLocationsEnabled(boolean enabled)
+ {
+ additionalLocationsEnabled = enabled;
+ }
+
+ /**
+ * Returns the required constraints on the target certificate or attribute
+ * certificate. The constraints are returned as an instance of
+ * <code>Selector</code>. If <code>null</code>, no constraints are
+ * defined.
+ *
+ * <p>
+ * The target certificate in a PKIX path may be a certificate or an
+ * attribute certificate.
+ * <p>
+ * Note that the <code>Selector</code> returned is cloned to protect
+ * against subsequent modifications.
+ *
+ * @return a <code>Selector</code> specifying the constraints on the
+ * target certificate or attribute certificate (or <code>null</code>)
+ * @see #setTargetConstraints
+ * @see X509CertStoreSelector
+ * @see X509AttributeCertStoreSelector
+ */
+ public Selector getTargetConstraints()
+ {
+ if (selector != null)
+ {
+ return (Selector) selector.clone();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Sets the required constraints on the target certificate or attribute
+ * certificate. The constraints are specified as an instance of
+ * <code>Selector</code>. If <code>null</code>, no constraints are
+ * defined.
+ * <p>
+ * The target certificate in a PKIX path may be a certificate or an
+ * attribute certificate.
+ * <p>
+ * Note that the <code>Selector</code> specified is cloned to protect
+ * against subsequent modifications.
+ *
+ * @param selector a <code>Selector</code> specifying the constraints on
+ * the target certificate or attribute certificate (or
+ * <code>null</code>)
+ * @see #getTargetConstraints
+ * @see X509CertStoreSelector
+ * @see X509AttributeCertStoreSelector
+ */
+ public void setTargetConstraints(Selector selector)
+ {
+ if (selector != null)
+ {
+ this.selector = (Selector) selector.clone();
+ }
+ else
+ {
+ this.selector = null;
+ }
+ }
+
+ /**
+ * Sets the required constraints on the target certificate. The constraints
+ * are specified as an instance of <code>X509CertSelector</code>. If
+ * <code>null</code>, no constraints are defined.
+ *
+ * <p>
+ * This method wraps the given <code>X509CertSelector</code> into a
+ * <code>X509CertStoreSelector</code>.
+ * <p>
+ * Note that the <code>X509CertSelector</code> specified is cloned to
+ * protect against subsequent modifications.
+ *
+ * @param selector a <code>X509CertSelector</code> specifying the
+ * constraints on the target certificate (or <code>null</code>)
+ * @see #getTargetCertConstraints
+ * @see X509CertStoreSelector
+ */
+ public void setTargetCertConstraints(CertSelector selector)
+ {
+ super.setTargetCertConstraints(selector);
+ if (selector != null)
+ {
+ this.selector = X509CertStoreSelector
+ .getInstance((X509CertSelector) selector);
+ }
+ else
+ {
+ this.selector = null;
+ }
+ }
+
+ /**
+ * Returns the trusted attribute certificate issuers. If attribute
+ * certificates is verified the trusted AC issuers must be set.
+ * <p>
+ * The returned <code>Set</code> consists of <code>TrustAnchor</code>s.
+ * <p>
+ * The returned <code>Set</code> is immutable. Never <code>null</code>
+ *
+ * @return Returns an immutable set of the trusted AC issuers.
+ */
+ public Set getTrustedACIssuers()
+ {
+ return Collections.unmodifiableSet(trustedACIssuers);
+ }
+
+ /**
+ * Sets the trusted attribute certificate issuers. If attribute certificates
+ * is verified the trusted AC issuers must be set.
+ * <p>
+ * The <code>trustedACIssuers</code> must be a <code>Set</code> of
+ * <code>TrustAnchor</code>
+ * <p>
+ * The given set is cloned.
+ *
+ * @param trustedACIssuers The trusted AC issuers to set. Is never
+ * <code>null</code>.
+ * @throws ClassCastException if an element of <code>stores</code> is not
+ * a <code>TrustAnchor</code>.
+ */
+ public void setTrustedACIssuers(Set trustedACIssuers)
+ {
+ if (trustedACIssuers == null)
+ {
+ this.trustedACIssuers.clear();
+ return;
+ }
+ for (Iterator it = trustedACIssuers.iterator(); it.hasNext();)
+ {
+ if (!(it.next() instanceof TrustAnchor))
+ {
+ throw new ClassCastException("All elements of set must be "
+ + "of type " + TrustAnchor.class.getName() + ".");
+ }
+ }
+ this.trustedACIssuers.clear();
+ this.trustedACIssuers.addAll(trustedACIssuers);
+ }
+
+ /**
+ * Returns the neccessary attributes which must be contained in an attribute
+ * certificate.
+ * <p>
+ * The returned <code>Set</code> is immutable and contains
+ * <code>String</code>s with the OIDs.
+ *
+ * @return Returns the necessary AC attributes.
+ */
+ public Set getNecessaryACAttributes()
+ {
+ return Collections.unmodifiableSet(necessaryACAttributes);
+ }
+
+ /**
+ * Sets the neccessary which must be contained in an attribute certificate.
+ * <p>
+ * The <code>Set</code> must contain <code>String</code>s with the
+ * OIDs.
+ * <p>
+ * The set is cloned.
+ *
+ * @param necessaryACAttributes The necessary AC attributes to set.
+ * @throws ClassCastException if an element of
+ * <code>necessaryACAttributes</code> is not a
+ * <code>String</code>.
+ */
+ public void setNecessaryACAttributes(Set necessaryACAttributes)
+ {
+ if (necessaryACAttributes == null)
+ {
+ this.necessaryACAttributes.clear();
+ return;
+ }
+ for (Iterator it = necessaryACAttributes.iterator(); it.hasNext();)
+ {
+ if (!(it.next() instanceof String))
+ {
+ throw new ClassCastException("All elements of set must be "
+ + "of type String.");
+ }
+ }
+ this.necessaryACAttributes.clear();
+ this.necessaryACAttributes.addAll(necessaryACAttributes);
+ }
+
+ /**
+ * Returns the attribute certificates which are not allowed.
+ * <p>
+ * The returned <code>Set</code> is immutable and contains
+ * <code>String</code>s with the OIDs.
+ *
+ * @return Returns the prohibited AC attributes. Is never <code>null</code>.
+ */
+ public Set getProhibitedACAttributes()
+ {
+ return Collections.unmodifiableSet(prohibitedACAttributes);
+ }
+
+ /**
+ * Sets the attribute certificates which are not allowed.
+ * <p>
+ * The <code>Set</code> must contain <code>String</code>s with the
+ * OIDs.
+ * <p>
+ * The set is cloned.
+ *
+ * @param prohibitedACAttributes The prohibited AC attributes to set.
+ * @throws ClassCastException if an element of
+ * <code>prohibitedACAttributes</code> is not a
+ * <code>String</code>.
+ */
+ public void setProhibitedACAttributes(Set prohibitedACAttributes)
+ {
+ if (prohibitedACAttributes == null)
+ {
+ this.prohibitedACAttributes.clear();
+ return;
+ }
+ for (Iterator it = prohibitedACAttributes.iterator(); it.hasNext();)
+ {
+ if (!(it.next() instanceof String))
+ {
+ throw new ClassCastException("All elements of set must be "
+ + "of type String.");
+ }
+ }
+ this.prohibitedACAttributes.clear();
+ this.prohibitedACAttributes.addAll(prohibitedACAttributes);
+ }
+
+ /**
+ * Returns the attribute certificate checker. The returned set contains
+ * {@link PKIXAttrCertChecker}s and is immutable.
+ *
+ * @return Returns the attribute certificate checker. Is never
+ * <code>null</code>.
+ */
+ public Set getAttrCertCheckers()
+ {
+ return Collections.unmodifiableSet(attrCertCheckers);
+ }
+
+ /**
+ * Sets the attribute certificate checkers.
+ * <p>
+ * All elements in the <code>Set</code> must a {@link PKIXAttrCertChecker}.
+ * <p>
+ * The given set is cloned.
+ *
+ * @param attrCertCheckers The attribute certificate checkers to set. Is
+ * never <code>null</code>.
+ * @throws ClassCastException if an element of <code>attrCertCheckers</code>
+ * is not a <code>PKIXAttrCertChecker</code>.
+ */
+ public void setAttrCertCheckers(Set attrCertCheckers)
+ {
+ if (attrCertCheckers == null)
+ {
+ this.attrCertCheckers.clear();
+ return;
+ }
+ for (Iterator it = attrCertCheckers.iterator(); it.hasNext();)
+ {
+ if (!(it.next() instanceof PKIXAttrCertChecker))
+ {
+ throw new ClassCastException("All elements of set must be "
+ + "of type " + PKIXAttrCertChecker.class.getName() + ".");
+ }
+ }
+ this.attrCertCheckers.clear();
+ this.attrCertCheckers.addAll(attrCertCheckers);
+ }
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/NoSuchStoreException.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/NoSuchStoreException.java
new file mode 100644
index 00000000..008f558a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/NoSuchStoreException.java
@@ -0,0 +1,14 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class NoSuchStoreException
+ extends Exception
+{
+ public NoSuchStoreException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/PKIXAttrCertChecker.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/PKIXAttrCertChecker.java
new file mode 100644
index 00000000..24d26554
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/PKIXAttrCertChecker.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import java.security.cert.CertPath;
+import java.security.cert.CertPathValidatorException;
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class PKIXAttrCertChecker
+ implements Cloneable
+{
+
+ /**
+ * Returns an immutable <code>Set</code> of X.509 attribute certificate
+ * extensions that this <code>PKIXAttrCertChecker</code> supports or
+ * <code>null</code> if no extensions are supported.
+ * <p>
+ * Each element of the set is a <code>String</code> representing the
+ * Object Identifier (OID) of the X.509 extension that is supported.
+ * <p>
+ * All X.509 attribute certificate extensions that a
+ * <code>PKIXAttrCertChecker</code> might possibly be able to process
+ * should be included in the set.
+ *
+ * @return an immutable <code>Set</code> of X.509 extension OIDs (in
+ * <code>String</code> format) supported by this
+ * <code>PKIXAttrCertChecker</code>, or <code>null</code> if no
+ * extensions are supported
+ */
+ public abstract Set getSupportedExtensions();
+
+ /**
+ * Performs checks on the specified attribute certificate. Every handled
+ * extension is rmeoved from the <code>unresolvedCritExts</code>
+ * collection.
+ *
+ * @param attrCert The attribute certificate to be checked.
+ * @param certPath The certificate path which belongs to the attribute
+ * certificate issuer public key certificate.
+ * @param holderCertPath The certificate path which belongs to the holder
+ * certificate.
+ * @param unresolvedCritExts a <code>Collection</code> of OID strings
+ * representing the current set of unresolved critical extensions
+ * @throws CertPathValidatorException if the specified attribute certificate
+ * does not pass the check.
+ */
+ public abstract void check(X509AttributeCertificate attrCert, CertPath certPath,
+ CertPath holderCertPath, Collection unresolvedCritExts)
+ throws CertPathValidatorException;
+
+ /**
+ * Returns a clone of this object.
+ *
+ * @return a copy of this <code>PKIXAttrCertChecker</code>
+ */
+ public abstract Object clone();
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509Attribute.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509Attribute.java
new file mode 100644
index 00000000..d561b759
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509Attribute.java
@@ -0,0 +1,82 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Object;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.DERSet;
+import com.android.internal.org.bouncycastle.asn1.x509.Attribute;
+
+/**
+ * Class for carrying the values in an X.509 Attribute.
+ * @deprecated see X509CertificateHolder class in the PKIX package.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509Attribute
+ extends ASN1Object
+{
+ Attribute attr;
+
+ /**
+ * @param at an object representing an attribute.
+ */
+ X509Attribute(
+ ASN1Encodable at)
+ {
+ this.attr = Attribute.getInstance(at);
+ }
+
+ /**
+ * Create an X.509 Attribute with the type given by the passed in oid and
+ * the value represented by an ASN.1 Set containing value.
+ *
+ * @param oid type of the attribute
+ * @param value value object to go into the atribute's value set.
+ */
+ public X509Attribute(
+ String oid,
+ ASN1Encodable value)
+ {
+ this.attr = new Attribute(new ASN1ObjectIdentifier(oid), new DERSet(value));
+ }
+
+ /**
+ * Create an X.59 Attribute with the type given by the passed in oid and the
+ * value represented by an ASN.1 Set containing the objects in value.
+ *
+ * @param oid type of the attribute
+ * @param value vector of values to go in the attribute's value set.
+ */
+ public X509Attribute(
+ String oid,
+ ASN1EncodableVector value)
+ {
+ this.attr = new Attribute(new ASN1ObjectIdentifier(oid), new DERSet(value));
+ }
+
+ public String getOID()
+ {
+ return attr.getAttrType().getId();
+ }
+
+ public ASN1Encodable[] getValues()
+ {
+ ASN1Set s = attr.getAttrValues();
+ ASN1Encodable[] values = new ASN1Encodable[s.size()];
+
+ for (int i = 0; i != s.size(); i++)
+ {
+ values[i] = (ASN1Encodable)s.getObjectAt(i);
+ }
+
+ return values;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ return attr.toASN1Primitive();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509AttributeCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509AttributeCertificate.java
new file mode 100644
index 00000000..49ec8297
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509AttributeCertificate.java
@@ -0,0 +1,104 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.X509Extension;
+import java.util.Date;
+
+/**
+ * Interface for an X.509 Attribute Certificate.
+ * @deprecated use X509CertificateHolder class in the PKIX package.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface X509AttributeCertificate
+ extends X509Extension
+{
+ /**
+ * Return the version number for the certificate.
+ *
+ * @return the version number.
+ */
+ public int getVersion();
+
+ /**
+ * Return the serial number for the certificate.
+ *
+ * @return the serial number.
+ */
+ public BigInteger getSerialNumber();
+
+ /**
+ * Return the date before which the certificate is not valid.
+ *
+ * @return the "not valid before" date.
+ */
+ public Date getNotBefore();
+
+ /**
+ * Return the date after which the certificate is not valid.
+ *
+ * @return the "not valid afer" date.
+ */
+ public Date getNotAfter();
+
+ /**
+ * Return the holder of the certificate.
+ *
+ * @return the holder.
+ */
+ public AttributeCertificateHolder getHolder();
+
+ /**
+ * Return the issuer details for the certificate.
+ *
+ * @return the issuer details.
+ */
+ public AttributeCertificateIssuer getIssuer();
+
+ /**
+ * Return the attributes contained in the attribute block in the certificate.
+ *
+ * @return an array of attributes.
+ */
+ public X509Attribute[] getAttributes();
+
+ /**
+ * Return the attributes with the same type as the passed in oid.
+ *
+ * @param oid the object identifier we wish to match.
+ * @return an array of matched attributes, null if there is no match.
+ */
+ public X509Attribute[] getAttributes(String oid);
+
+ public boolean[] getIssuerUniqueID();
+
+ public void checkValidity()
+ throws CertificateExpiredException, CertificateNotYetValidException;
+
+ public void checkValidity(Date date)
+ throws CertificateExpiredException, CertificateNotYetValidException;
+
+ public byte[] getSignature();
+
+ public void verify(PublicKey key, String provider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException;
+
+ /**
+ * Return an ASN.1 encoded byte array representing the attribute certificate.
+ *
+ * @return an ASN.1 encoded byte array.
+ * @throws IOException if the certificate cannot be encoded.
+ */
+ public byte[] getEncoded()
+ throws IOException;
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509CRLStoreSelector.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509CRLStoreSelector.java
new file mode 100644
index 00000000..09af8a5a
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509CRLStoreSelector.java
@@ -0,0 +1,332 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CRL;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLSelector;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.util.Arrays;
+import com.android.internal.org.bouncycastle.util.Selector;
+import com.android.internal.org.bouncycastle.x509.extension.X509ExtensionUtil;
+
+/**
+ * This class is a Selector implementation for X.509 certificate revocation
+ * lists.
+ *
+ * @see com.android.internal.org.bouncycastle.util.Selector
+ * @see com.android.internal.org.bouncycastle.x509.X509Store
+ * @see com.android.internal.org.bouncycastle.jce.provider.X509StoreCRLCollection
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509CRLStoreSelector
+ extends X509CRLSelector
+ implements Selector
+{
+ private boolean deltaCRLIndicator = false;
+
+ private boolean completeCRLEnabled = false;
+
+ private BigInteger maxBaseCRLNumber = null;
+
+ private byte[] issuingDistributionPoint = null;
+
+ private boolean issuingDistributionPointEnabled = false;
+
+ private X509AttributeCertificate attrCertChecking;
+
+ /**
+ * Returns if the issuing distribution point criteria should be applied.
+ * Defaults to <code>false</code>.
+ * <p>
+ * You may also set the issuing distribution point criteria if not a missing
+ * issuing distribution point should be assumed.
+ *
+ * @return Returns if the issuing distribution point check is enabled.
+ */
+ public boolean isIssuingDistributionPointEnabled()
+ {
+ return issuingDistributionPointEnabled;
+ }
+
+ /**
+ * Enables or disables the issuing distribution point check.
+ *
+ * @param issuingDistributionPointEnabled <code>true</code> to enable the
+ * issuing distribution point check.
+ */
+ public void setIssuingDistributionPointEnabled(
+ boolean issuingDistributionPointEnabled)
+ {
+ this.issuingDistributionPointEnabled = issuingDistributionPointEnabled;
+ }
+
+ /**
+ * Sets the attribute certificate being checked. This is not a criterion.
+ * Rather, it is optional information that may help a {@link X509Store} find
+ * CRLs that would be relevant when checking revocation for the specified
+ * attribute certificate. If <code>null</code> is specified, then no such
+ * optional information is provided.
+ *
+ * @param attrCert the <code>X509AttributeCertificate</code> being checked (or
+ * <code>null</code>)
+ * @see #getAttrCertificateChecking()
+ */
+ public void setAttrCertificateChecking(X509AttributeCertificate attrCert)
+ {
+ attrCertChecking = attrCert;
+ }
+
+ /**
+ * Returns the attribute certificate being checked.
+ *
+ * @return Returns the attribute certificate being checked.
+ * @see #setAttrCertificateChecking(X509AttributeCertificate)
+ */
+ public X509AttributeCertificate getAttrCertificateChecking()
+ {
+ return attrCertChecking;
+ }
+
+ public boolean match(Object obj)
+ {
+ if (!(obj instanceof X509CRL))
+ {
+ return false;
+ }
+ X509CRL crl = (X509CRL)obj;
+ ASN1Integer dci = null;
+ try
+ {
+ byte[] bytes = crl
+ .getExtensionValue(Extension.deltaCRLIndicator.getId());
+ if (bytes != null)
+ {
+ dci = ASN1Integer.getInstance(X509ExtensionUtil
+ .fromExtensionValue(bytes));
+ }
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ if (isDeltaCRLIndicatorEnabled())
+ {
+ if (dci == null)
+ {
+ return false;
+ }
+ }
+ if (isCompleteCRLEnabled())
+ {
+ if (dci != null)
+ {
+ return false;
+ }
+ }
+ if (dci != null)
+ {
+
+ if (maxBaseCRLNumber != null)
+ {
+ if (dci.getPositiveValue().compareTo(maxBaseCRLNumber) == 1)
+ {
+ return false;
+ }
+ }
+ }
+ if (issuingDistributionPointEnabled)
+ {
+ byte[] idp = crl
+ .getExtensionValue(Extension.issuingDistributionPoint
+ .getId());
+ if (issuingDistributionPoint == null)
+ {
+ if (idp != null)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (!Arrays.areEqual(idp, issuingDistributionPoint))
+ {
+ return false;
+ }
+ }
+
+ }
+ return super.match((X509CRL)obj);
+ }
+
+ public boolean match(CRL crl)
+ {
+ return match((Object)crl);
+ }
+
+ /**
+ * Returns if this selector must match CRLs with the delta CRL indicator
+ * extension set. Defaults to <code>false</code>.
+ *
+ * @return Returns <code>true</code> if only CRLs with the delta CRL
+ * indicator extension are selected.
+ */
+ public boolean isDeltaCRLIndicatorEnabled()
+ {
+ return deltaCRLIndicator;
+ }
+
+ /**
+ * If this is set to <code>true</code> the CRL reported contains the delta
+ * CRL indicator CRL extension.
+ * <p>
+ * {@link #setCompleteCRLEnabled(boolean)} and
+ * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other.
+ *
+ * @param deltaCRLIndicator <code>true</code> if the delta CRL indicator
+ * extension must be in the CRL.
+ */
+ public void setDeltaCRLIndicatorEnabled(boolean deltaCRLIndicator)
+ {
+ this.deltaCRLIndicator = deltaCRLIndicator;
+ }
+
+ /**
+ * Returns an instance of this from a <code>X509CRLSelector</code>.
+ *
+ * @param selector A <code>X509CRLSelector</code> instance.
+ * @return An instance of an <code>X509CRLStoreSelector</code>.
+ * @exception IllegalArgumentException if selector is null or creation
+ * fails.
+ */
+ public static X509CRLStoreSelector getInstance(X509CRLSelector selector)
+ {
+ if (selector == null)
+ {
+ throw new IllegalArgumentException(
+ "cannot create from null selector");
+ }
+ X509CRLStoreSelector cs = new X509CRLStoreSelector();
+ cs.setCertificateChecking(selector.getCertificateChecking());
+ cs.setDateAndTime(selector.getDateAndTime());
+ try
+ {
+ cs.setIssuerNames(selector.getIssuerNames());
+ }
+ catch (IOException e)
+ {
+ // cannot happen
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ cs.setIssuers(selector.getIssuers());
+ cs.setMaxCRLNumber(selector.getMaxCRL());
+ cs.setMinCRLNumber(selector.getMinCRL());
+ return cs;
+ }
+
+ public Object clone()
+ {
+ X509CRLStoreSelector sel = X509CRLStoreSelector.getInstance(this);
+ sel.deltaCRLIndicator = deltaCRLIndicator;
+ sel.completeCRLEnabled = completeCRLEnabled;
+ sel.maxBaseCRLNumber = maxBaseCRLNumber;
+ sel.attrCertChecking = attrCertChecking;
+ sel.issuingDistributionPointEnabled = issuingDistributionPointEnabled;
+ sel.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint);
+ return sel;
+ }
+
+ /**
+ * If <code>true</code> only complete CRLs are returned. Defaults to
+ * <code>false</code>.
+ *
+ * @return <code>true</code> if only complete CRLs are returned.
+ */
+ public boolean isCompleteCRLEnabled()
+ {
+ return completeCRLEnabled;
+ }
+
+ /**
+ * If set to <code>true</code> only complete CRLs are returned.
+ * <p>
+ * {@link #setCompleteCRLEnabled(boolean)} and
+ * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other.
+ *
+ * @param completeCRLEnabled <code>true</code> if only complete CRLs
+ * should be returned.
+ */
+ public void setCompleteCRLEnabled(boolean completeCRLEnabled)
+ {
+ this.completeCRLEnabled = completeCRLEnabled;
+ }
+
+ /**
+ * Get the maximum base CRL number. Defaults to <code>null</code>.
+ *
+ * @return Returns the maximum base CRL number.
+ * @see #setMaxBaseCRLNumber(BigInteger)
+ */
+ public BigInteger getMaxBaseCRLNumber()
+ {
+ return maxBaseCRLNumber;
+ }
+
+ /**
+ * Sets the maximum base CRL number. Setting to <code>null</code> disables
+ * this cheack.
+ * <p>
+ * This is only meaningful for delta CRLs. Complete CRLs must have a CRL
+ * number which is greater or equal than the base number of the
+ * corresponding CRL.
+ *
+ * @param maxBaseCRLNumber The maximum base CRL number to set.
+ */
+ public void setMaxBaseCRLNumber(BigInteger maxBaseCRLNumber)
+ {
+ this.maxBaseCRLNumber = maxBaseCRLNumber;
+ }
+
+ /**
+ * Returns the issuing distribution point. Defaults to <code>null</code>,
+ * which is a missing issuing distribution point extension.
+ * <p>
+ * The internal byte array is cloned before it is returned.
+ * <p>
+ * The criteria must be enable with
+ * {@link #setIssuingDistributionPointEnabled(boolean)}.
+ *
+ * @return Returns the issuing distribution point.
+ * @see #setIssuingDistributionPoint(byte[])
+ */
+ public byte[] getIssuingDistributionPoint()
+ {
+ return Arrays.clone(issuingDistributionPoint);
+ }
+
+ /**
+ * Sets the issuing distribution point.
+ * <p>
+ * The issuing distribution point extension is a CRL extension which
+ * identifies the scope and the distribution point of a CRL. The scope
+ * contains among others information about revocation reasons contained in
+ * the CRL. Delta CRLs and complete CRLs must have matching issuing
+ * distribution points.
+ * <p>
+ * The byte array is cloned to protect against subsequent modifications.
+ * <p>
+ * You must also enable or disable this criteria with
+ * {@link #setIssuingDistributionPointEnabled(boolean)}.
+ *
+ * @param issuingDistributionPoint The issuing distribution point to set.
+ * This is the DER encoded OCTET STRING extension value.
+ * @see #getIssuingDistributionPoint()
+ */
+ public void setIssuingDistributionPoint(byte[] issuingDistributionPoint)
+ {
+ this.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint);
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509CertStoreSelector.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509CertStoreSelector.java
new file mode 100644
index 00000000..fad3661f
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509CertStoreSelector.java
@@ -0,0 +1,90 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import java.io.IOException;
+import java.security.cert.Certificate;
+import java.security.cert.X509CertSelector;
+import java.security.cert.X509Certificate;
+
+import com.android.internal.org.bouncycastle.util.Selector;
+
+/**
+ * This class is a Selector implementation for X.509 certificates.
+ *
+ * @see com.android.internal.org.bouncycastle.util.Selector
+ * @see com.android.internal.org.bouncycastle.x509.X509Store
+ * @see com.android.internal.org.bouncycastle.jce.provider.X509StoreCertCollection
+ * @deprecated use the classes under org.bouncycastle.cert.selector
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509CertStoreSelector
+ extends X509CertSelector
+ implements Selector
+{
+ public boolean match(Object obj)
+ {
+ if (!(obj instanceof X509Certificate))
+ {
+ return false;
+ }
+
+ X509Certificate other = (X509Certificate)obj;
+
+ return super.match(other);
+ }
+
+ public boolean match(Certificate cert)
+ {
+ return match((Object)cert);
+ }
+
+ public Object clone()
+ {
+ X509CertStoreSelector selector = (X509CertStoreSelector)super.clone();
+
+ return selector;
+ }
+
+ /**
+ * Returns an instance of this from a <code>X509CertSelector</code>.
+ *
+ * @param selector A <code>X509CertSelector</code> instance.
+ * @return An instance of an <code>X509CertStoreSelector</code>.
+ * @exception IllegalArgumentException if selector is null or creation fails.
+ */
+ public static X509CertStoreSelector getInstance(X509CertSelector selector)
+ {
+ if (selector == null)
+ {
+ throw new IllegalArgumentException("cannot create from null selector");
+ }
+ X509CertStoreSelector cs = new X509CertStoreSelector();
+ cs.setAuthorityKeyIdentifier(selector.getAuthorityKeyIdentifier());
+ cs.setBasicConstraints(selector.getBasicConstraints());
+ cs.setCertificate(selector.getCertificate());
+ cs.setCertificateValid(selector.getCertificateValid());
+ cs.setMatchAllSubjectAltNames(selector.getMatchAllSubjectAltNames());
+ try
+ {
+ cs.setPathToNames(selector.getPathToNames());
+ cs.setExtendedKeyUsage(selector.getExtendedKeyUsage());
+ cs.setNameConstraints(selector.getNameConstraints());
+ cs.setPolicy(selector.getPolicy());
+ cs.setSubjectPublicKeyAlgID(selector.getSubjectPublicKeyAlgID());
+ cs.setSubjectAlternativeNames(selector.getSubjectAlternativeNames());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("error in passed in selector: " + e);
+ }
+ cs.setIssuer(selector.getIssuer());
+ cs.setKeyUsage(selector.getKeyUsage());
+ cs.setPrivateKeyValid(selector.getPrivateKeyValid());
+ cs.setSerialNumber(selector.getSerialNumber());
+ cs.setSubject(selector.getSubject());
+ cs.setSubjectKeyIdentifier(selector.getSubjectKeyIdentifier());
+ cs.setSubjectPublicKey(selector.getSubjectPublicKey());
+ return cs;
+ }
+
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509CollectionStoreParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509CollectionStoreParameters.java
new file mode 100644
index 00000000..97873685
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509CollectionStoreParameters.java
@@ -0,0 +1,72 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * This class contains a collection for collection based <code>X509Store</code>s.
+ *
+ * @see com.android.internal.org.bouncycastle.x509.X509Store
+ * @hide This class is not part of the Android public SDK API
+ *
+ */
+public class X509CollectionStoreParameters
+ implements X509StoreParameters
+{
+ private Collection collection;
+
+ /**
+ * Constructor.
+ * <p>
+ * The collection is copied.
+ * </p>
+ *
+ * @param collection
+ * The collection containing X.509 object types.
+ * @throws NullPointerException if <code>collection</code> is <code>null</code>.
+ */
+ public X509CollectionStoreParameters(Collection collection)
+ {
+ if (collection == null)
+ {
+ throw new NullPointerException("collection cannot be null");
+ }
+ this.collection = collection;
+ }
+
+ /**
+ * Returns a shallow clone. The returned contents are not copied, so adding
+ * or removing objects will effect this.
+ *
+ * @return a shallow clone.
+ */
+ public Object clone()
+ {
+ return new X509CollectionStoreParameters(collection);
+ }
+
+ /**
+ * Returns a copy of the <code>Collection</code>.
+ *
+ * @return The <code>Collection</code>. Is never <code>null</code>.
+ */
+ public Collection getCollection()
+ {
+ return new ArrayList(collection);
+ }
+
+ /**
+ * Returns a formatted string describing the parameters.
+ *
+ * @return a formatted string describing the parameters
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append("X509CollectionStoreParameters: [\n");
+ sb.append(" collection: " + collection + "\n");
+ sb.append("]");
+ return sb.toString();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509StoreParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509StoreParameters.java
new file mode 100644
index 00000000..4f80000e
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509StoreParameters.java
@@ -0,0 +1,9 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface X509StoreParameters
+{
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509StoreSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509StoreSpi.java
new file mode 100644
index 00000000..22ee2e64
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509StoreSpi.java
@@ -0,0 +1,16 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import com.android.internal.org.bouncycastle.util.Selector;
+
+import java.util.Collection;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class X509StoreSpi
+{
+ public abstract void engineInit(X509StoreParameters parameters);
+
+ public abstract Collection engineGetMatches(Selector selector);
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509Util.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509Util.java
new file mode 100644
index 00000000..2074c0ca
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509Util.java
@@ -0,0 +1,425 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DERNull;
+// 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 com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.internal.org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
+// Android-removed: Unsupported algorithms
+// 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.jce.X509Principal;
+import com.android.internal.org.bouncycastle.util.Strings;
+
+class X509Util
+{
+ private static Hashtable algorithms = new Hashtable();
+ private static Hashtable params = new Hashtable();
+ private static Set noParams = new HashSet();
+
+ 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("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);
+ 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);
+ // 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:
+ // noParams.add(OIWObjectIdentifiers.dsaWithSHA1);
+ noParams.add(NISTObjectIdentifiers.dsa_with_sha224);
+ noParams.add(NISTObjectIdentifiers.dsa_with_sha256);
+ noParams.add(NISTObjectIdentifiers.dsa_with_sha384);
+ noParams.add(NISTObjectIdentifiers.dsa_with_sha512);
+
+ //
+ // RFC 4491
+ //
+ // BEGIN Android-removed: Unsupported algorithms
+ // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
+ // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
+ // END Android-removed: Unsupported algorithms
+
+ //
+ // explicit params
+ //
+ AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
+ params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20));
+
+ AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE);
+ params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28));
+
+ AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE);
+ params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32));
+
+ AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE);
+ params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48));
+
+ AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE);
+ params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64));
+ }
+
+ private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int saltSize)
+ {
+ return new RSASSAPSSparams(
+ hashAlgId,
+ new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId),
+ new ASN1Integer(saltSize),
+ new ASN1Integer(1));
+ }
+
+ static ASN1ObjectIdentifier getAlgorithmOID(
+ String algorithmName)
+ {
+ algorithmName = Strings.toUpperCase(algorithmName);
+
+ if (algorithms.containsKey(algorithmName))
+ {
+ return (ASN1ObjectIdentifier)algorithms.get(algorithmName);
+ }
+
+ return new ASN1ObjectIdentifier(algorithmName);
+ }
+
+ static AlgorithmIdentifier getSigAlgID(
+ ASN1ObjectIdentifier sigOid,
+ String algorithmName)
+ {
+ if (noParams.contains(sigOid))
+ {
+ return new AlgorithmIdentifier(sigOid);
+ }
+
+ algorithmName = Strings.toUpperCase(algorithmName);
+
+ if (params.containsKey(algorithmName))
+ {
+ return new AlgorithmIdentifier(sigOid, (ASN1Encodable)params.get(algorithmName));
+ }
+ else
+ {
+ return new AlgorithmIdentifier(sigOid, DERNull.INSTANCE);
+ }
+ }
+
+ static Iterator getAlgNames()
+ {
+ Enumeration e = algorithms.keys();
+ List l = new ArrayList();
+
+ while (e.hasMoreElements())
+ {
+ l.add(e.nextElement());
+ }
+
+ return l.iterator();
+ }
+
+ static Signature getSignatureInstance(
+ String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return Signature.getInstance(algorithm);
+ }
+
+ static Signature getSignatureInstance(
+ String algorithm,
+ String provider)
+ throws NoSuchProviderException, NoSuchAlgorithmException
+ {
+ if (provider != null)
+ {
+ return Signature.getInstance(algorithm, provider);
+ }
+ else
+ {
+ return Signature.getInstance(algorithm);
+ }
+ }
+
+ static byte[] calculateSignature(
+ ASN1ObjectIdentifier sigOid,
+ String sigName,
+ PrivateKey key,
+ SecureRandom random,
+ ASN1Encodable object)
+ throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException
+ {
+ Signature sig;
+
+ if (sigOid == null)
+ {
+ throw new IllegalStateException("no signature algorithm specified");
+ }
+
+ sig = X509Util.getSignatureInstance(sigName);
+
+ if (random != null)
+ {
+ sig.initSign(key, random);
+ }
+ else
+ {
+ sig.initSign(key);
+ }
+
+ sig.update(object.toASN1Primitive().getEncoded(ASN1Encoding.DER));
+
+ return sig.sign();
+ }
+
+ static byte[] calculateSignature(
+ ASN1ObjectIdentifier sigOid,
+ String sigName,
+ String provider,
+ PrivateKey key,
+ SecureRandom random,
+ ASN1Encodable object)
+ throws IOException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, SignatureException
+ {
+ Signature sig;
+
+ if (sigOid == null)
+ {
+ throw new IllegalStateException("no signature algorithm specified");
+ }
+
+ sig = X509Util.getSignatureInstance(sigName, provider);
+
+ if (random != null)
+ {
+ sig.initSign(key, random);
+ }
+ else
+ {
+ sig.initSign(key);
+ }
+
+ sig.update(object.toASN1Primitive().getEncoded(ASN1Encoding.DER));
+
+ return sig.sign();
+ }
+
+ static X509Principal convertPrincipal(
+ X500Principal principal)
+ {
+ try
+ {
+ return new X509Principal(principal.getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("cannot convert principal");
+ }
+ }
+
+ static class Implementation
+ {
+ Object engine;
+ Provider provider;
+
+ Implementation(
+ Object engine,
+ Provider provider)
+ {
+ this.engine = engine;
+ this.provider = provider;
+ }
+
+ Object getEngine()
+ {
+ return engine;
+ }
+
+ Provider getProvider()
+ {
+ return provider;
+ }
+ }
+
+ /**
+ * see if we can find an algorithm (or its alias and what it represents) in
+ * the property table for the given provider.
+ */
+ static Implementation getImplementation(
+ String baseName,
+ String algorithm,
+ Provider prov)
+ throws NoSuchAlgorithmException
+ {
+ algorithm = Strings.toUpperCase(algorithm);
+
+ String alias;
+
+ while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null)
+ {
+ algorithm = alias;
+ }
+
+ String className = prov.getProperty(baseName + "." + algorithm);
+
+ if (className != null)
+ {
+ try
+ {
+ Class cls;
+ ClassLoader clsLoader = prov.getClass().getClassLoader();
+
+ if (clsLoader != null)
+ {
+ cls = clsLoader.loadClass(className);
+ }
+ else
+ {
+ cls = Class.forName(className);
+ }
+
+ return new Implementation(cls.newInstance(), prov);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new IllegalStateException(
+ "algorithm " + algorithm + " in provider " + prov.getName() + " but no class \"" + className + "\" found!");
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException(
+ "algorithm " + algorithm + " in provider " + prov.getName() + " but class \"" + className + "\" inaccessible!");
+ }
+ }
+
+ throw new NoSuchAlgorithmException("cannot find implementation " + algorithm + " for provider " + prov.getName());
+ }
+
+ /**
+ * return an implementation for a given algorithm/provider.
+ * If the provider is null, we grab the first avalaible who has the required algorithm.
+ */
+ static Implementation getImplementation(
+ String baseName,
+ String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ Provider[] prov = Security.getProviders();
+
+ //
+ // search every provider looking for the algorithm we want.
+ //
+ for (int i = 0; i != prov.length; i++)
+ {
+ //
+ // try case insensitive
+ //
+ Implementation imp = getImplementation(baseName, Strings.toUpperCase(algorithm), prov[i]);
+ if (imp != null)
+ {
+ return imp;
+ }
+
+ try
+ {
+ imp = getImplementation(baseName, algorithm, prov[i]);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // continue
+ }
+ }
+
+ throw new NoSuchAlgorithmException("cannot find implementation " + algorithm);
+ }
+
+ static Provider getProvider(String provider)
+ throws NoSuchProviderException
+ {
+ Provider prov = Security.getProvider(provider);
+
+ if (prov == null)
+ {
+ throw new NoSuchProviderException("Provider " + provider + " not found");
+ }
+
+ return prov;
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V1CertificateGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V1CertificateGenerator.java
new file mode 100644
index 00000000..035ab5d7
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V1CertificateGenerator.java
@@ -0,0 +1,381 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Iterator;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+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.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.V1TBSCertificateGenerator;
+import com.android.internal.org.bouncycastle.asn1.x509.X509Name;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory;
+import com.android.internal.org.bouncycastle.jcajce.util.BCJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.jce.X509Principal;
+
+/**
+ * class to produce an X.509 Version 1 certificate.
+ * @deprecated use org.bouncycastle.cert.X509v1CertificateBuilder.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509V1CertificateGenerator
+{
+ private final JcaJceHelper bcHelper = new BCJcaJceHelper(); // needed to force provider loading
+ private final CertificateFactory certificateFactory = new CertificateFactory();
+
+ private V1TBSCertificateGenerator tbsGen;
+ private ASN1ObjectIdentifier sigOID;
+ private AlgorithmIdentifier sigAlgId;
+ private String signatureAlgorithm;
+
+ public X509V1CertificateGenerator()
+ {
+ tbsGen = new V1TBSCertificateGenerator();
+ }
+
+ /**
+ * reset the generator
+ */
+ public void reset()
+ {
+ tbsGen = new V1TBSCertificateGenerator();
+ }
+
+ /**
+ * set the serial number for the certificate.
+ */
+ public void setSerialNumber(
+ BigInteger serialNumber)
+ {
+ if (serialNumber.compareTo(BigInteger.ZERO) <= 0)
+ {
+ throw new IllegalArgumentException("serial number must be a positive integer");
+ }
+
+ tbsGen.setSerialNumber(new ASN1Integer(serialNumber));
+ }
+
+ /**
+ * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the
+ * certificate.
+ */
+ public void setIssuerDN(
+ X500Principal issuer)
+ {
+ try
+ {
+ tbsGen.setIssuer(new X509Principal(issuer.getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("can't process principal: " + e);
+ }
+ }
+
+ /**
+ * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the
+ * certificate.
+ */
+ public void setIssuerDN(
+ X509Name issuer)
+ {
+ tbsGen.setIssuer(issuer);
+ }
+
+ public void setNotBefore(
+ Date date)
+ {
+ tbsGen.setStartDate(new Time(date));
+ }
+
+ public void setNotAfter(
+ Date date)
+ {
+ tbsGen.setEndDate(new Time(date));
+ }
+
+ /**
+ * Set the subject distinguished name. The subject describes the entity associated with the public key.
+ */
+ public void setSubjectDN(
+ X500Principal subject)
+ {
+ try
+ {
+ tbsGen.setSubject(new X509Principal(subject.getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("can't process principal: " + e);
+ }
+ }
+
+ /**
+ * Set the subject distinguished name. The subject describes the entity associated with the public key.
+ */
+ public void setSubjectDN(
+ X509Name subject)
+ {
+ tbsGen.setSubject(subject);
+ }
+
+ public void setPublicKey(
+ PublicKey key)
+ {
+ try
+ {
+ tbsGen.setSubjectPublicKeyInfo(SubjectPublicKeyInfo.getInstance(key.getEncoded()));
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("unable to process key - " + e.toString());
+ }
+ }
+
+ /**
+ * Set the signature algorithm. This can be either a name or an OID, names
+ * are treated as case insensitive.
+ *
+ * @param signatureAlgorithm string representation of the algorithm name.
+ */
+ public void setSignatureAlgorithm(
+ String signatureAlgorithm)
+ {
+ this.signatureAlgorithm = signatureAlgorithm;
+
+ try
+ {
+ sigOID = X509Util.getAlgorithmOID(signatureAlgorithm);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("Unknown signature type requested");
+ }
+
+ sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm);
+
+ tbsGen.setSignature(sigAlgId);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider "BC".
+ * @deprecated use generate(key, "BC")
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key)
+ throws SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generateX509Certificate(key, "BC", null);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new SecurityException("BC provider not installed!");
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider "BC" and the passed in source of randomness
+ * @deprecated use generate(key, random, "BC")
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key,
+ SecureRandom random)
+ throws SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generateX509Certificate(key, "BC", random);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new SecurityException("BC provider not installed!");
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing, and the passed in source
+ * of randomness (if required).
+ * @deprecated use generate()
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key,
+ String provider)
+ throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
+ {
+ return generateX509Certificate(key, provider, null);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing, and the passed in source
+ * of randomness (if required).
+ * @deprecated use generate()
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key,
+ String provider,
+ SecureRandom random)
+ throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generate(key, provider, random);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw e;
+ }
+ catch (SignatureException e)
+ {
+ throw e;
+ }
+ catch (InvalidKeyException e)
+ {
+ throw e;
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new SecurityException("exception: " + e);
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider.
+ * <p>
+ * <b>Note:</b> this differs from the deprecated method in that the default provider is
+ * used - not "BC".
+ * </p>
+ */
+ public X509Certificate generate(
+ PrivateKey key)
+ throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ return generate(key, (SecureRandom)null);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider and the passed in source of randomness
+ * <p>
+ * <b>Note:</b> this differs from the deprecated method in that the default provider is
+ * used - not "BC".
+ * </p>
+ */
+ public X509Certificate generate(
+ PrivateKey key,
+ SecureRandom random)
+ throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ TBSCertificate tbsCert = tbsGen.generateTBSCertificate();
+ byte[] signature;
+
+ try
+ {
+ signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCert);
+ }
+ catch (IOException e)
+ {
+ throw new ExtCertificateEncodingException("exception encoding TBS cert", e);
+ }
+
+ return generateJcaObject(tbsCert, signature);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing, and the passed in source
+ * of randomness (if required).
+ */
+ public X509Certificate generate(
+ PrivateKey key,
+ String provider)
+ throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ return generate(key, provider, null);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing, and the passed in source
+ * of randomness (if required).
+ */
+ public X509Certificate generate(
+ PrivateKey key,
+ String provider,
+ SecureRandom random)
+ throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ TBSCertificate tbsCert = tbsGen.generateTBSCertificate();
+ byte[] signature;
+
+ try
+ {
+ signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCert);
+ }
+ catch (IOException e)
+ {
+ throw new ExtCertificateEncodingException("exception encoding TBS cert", e);
+ }
+
+ return generateJcaObject(tbsCert, signature);
+ }
+
+ private X509Certificate generateJcaObject(TBSCertificate tbsCert, byte[] signature)
+ throws CertificateEncodingException
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(tbsCert);
+ v.add(sigAlgId);
+ v.add(new DERBitString(signature));
+
+ try
+ {
+ return (X509Certificate)certificateFactory.engineGenerateCertificate(
+ new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER)));
+ }
+ catch (Exception e)
+ {
+ throw new ExtCertificateEncodingException("exception producing certificate object", e);
+ }
+ }
+
+ /**
+ * Return an iterator of the signature names supported by the generator.
+ *
+ * @return an iterator containing recognised names.
+ */
+ public Iterator getSignatureAlgNames()
+ {
+ return X509Util.getAlgNames();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V2AttributeCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V2AttributeCertificate.java
new file mode 100644
index 00000000..6ae4aeec
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V2AttributeCertificate.java
@@ -0,0 +1,352 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.text.ParseException;
+import java.util.ArrayList;
+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.ASN1Encoding;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.DERBitString;
+import com.android.internal.org.bouncycastle.asn1.x509.AttributeCertificate;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.Extensions;
+import com.android.internal.org.bouncycastle.util.Arrays;
+
+/**
+ * An implementation of a version 2 X.509 Attribute Certificate.
+ * @deprecated use org.bouncycastle.cert.X509AttributeCertificateHolder
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509V2AttributeCertificate
+ implements X509AttributeCertificate
+{
+ private AttributeCertificate cert;
+ private Date notBefore;
+ private Date notAfter;
+
+ private static AttributeCertificate getObject(InputStream in)
+ throws IOException
+ {
+ try
+ {
+ return AttributeCertificate.getInstance(new ASN1InputStream(in).readObject());
+ }
+ catch (IOException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new IOException("exception decoding certificate structure: " + e.toString());
+ }
+ }
+
+ public X509V2AttributeCertificate(
+ InputStream encIn)
+ throws IOException
+ {
+ this(getObject(encIn));
+ }
+
+ public X509V2AttributeCertificate(
+ byte[] encoded)
+ throws IOException
+ {
+ this(new ByteArrayInputStream(encoded));
+ }
+
+ X509V2AttributeCertificate(
+ AttributeCertificate cert)
+ throws IOException
+ {
+ this.cert = cert;
+
+ try
+ {
+ this.notAfter = cert.getAcinfo().getAttrCertValidityPeriod().getNotAfterTime().getDate();
+ this.notBefore = cert.getAcinfo().getAttrCertValidityPeriod().getNotBeforeTime().getDate();
+ }
+ catch (ParseException e)
+ {
+ throw new IOException("invalid data structure in certificate!");
+ }
+ }
+
+ public int getVersion()
+ {
+ return cert.getAcinfo().getVersion().intValueExact() + 1;
+ }
+
+ public BigInteger getSerialNumber()
+ {
+ return cert.getAcinfo().getSerialNumber().getValue();
+ }
+
+ public AttributeCertificateHolder getHolder()
+ {
+ return new AttributeCertificateHolder((ASN1Sequence)cert.getAcinfo().getHolder().toASN1Primitive());
+ }
+
+ public AttributeCertificateIssuer getIssuer()
+ {
+ return new AttributeCertificateIssuer(cert.getAcinfo().getIssuer());
+ }
+
+ public Date getNotBefore()
+ {
+ return notBefore;
+ }
+
+ public Date getNotAfter()
+ {
+ return notAfter;
+ }
+
+ public boolean[] getIssuerUniqueID()
+ {
+ DERBitString id = cert.getAcinfo().getIssuerUniqueID();
+
+ if (id != null)
+ {
+ byte[] bytes = id.getBytes();
+ boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
+
+ for (int i = 0; i != boolId.length; i++)
+ {
+ boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
+ }
+
+ return boolId;
+ }
+
+ return null;
+ }
+
+ public void checkValidity()
+ throws CertificateExpiredException, CertificateNotYetValidException
+ {
+ this.checkValidity(new Date());
+ }
+
+ public void checkValidity(
+ Date date)
+ throws CertificateExpiredException, CertificateNotYetValidException
+ {
+ if (date.after(this.getNotAfter()))
+ {
+ throw new CertificateExpiredException("certificate expired on " + this.getNotAfter());
+ }
+
+ if (date.before(this.getNotBefore()))
+ {
+ throw new CertificateNotYetValidException("certificate not valid till " + this.getNotBefore());
+ }
+ }
+
+ public byte[] getSignature()
+ {
+ return cert.getSignatureValue().getOctets();
+ }
+
+ public final void verify(
+ PublicKey key,
+ String provider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
+ {
+ Signature signature = null;
+
+ if (!cert.getSignatureAlgorithm().equals(cert.getAcinfo().getSignature()))
+ {
+ throw new CertificateException("Signature algorithm in certificate info not same as outer certificate");
+ }
+
+ signature = Signature.getInstance(cert.getSignatureAlgorithm().getAlgorithm().getId(), provider);
+
+ signature.initVerify(key);
+
+ try
+ {
+ signature.update(cert.getAcinfo().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new SignatureException("Exception encoding certificate info object");
+ }
+
+ if (!signature.verify(this.getSignature()))
+ {
+ throw new InvalidKeyException("Public key presented not for certificate signature");
+ }
+ }
+
+ public byte[] getEncoded()
+ throws IOException
+ {
+ return cert.getEncoded();
+ }
+
+ public byte[] getExtensionValue(String oid)
+ {
+ Extensions extensions = cert.getAcinfo().getExtensions();
+
+ if (extensions != null)
+ {
+ Extension ext = extensions.getExtension(new ASN1ObjectIdentifier(oid));
+
+ if (ext != null)
+ {
+ try
+ {
+ return ext.getExtnValue().getEncoded(ASN1Encoding.DER);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("error encoding " + e.toString());
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private Set getExtensionOIDs(
+ boolean critical)
+ {
+ Extensions extensions = cert.getAcinfo().getExtensions();
+
+ if (extensions != null)
+ {
+ Set set = new HashSet();
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ Extension ext = extensions.getExtension(oid);
+
+ if (ext.isCritical() == critical)
+ {
+ set.add(oid.getId());
+ }
+ }
+
+ return set;
+ }
+
+ return null;
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(false);
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(true);
+ }
+
+ public boolean hasUnsupportedCriticalExtension()
+ {
+ Set extensions = getCriticalExtensionOIDs();
+
+ return extensions != null && !extensions.isEmpty();
+ }
+
+ public X509Attribute[] getAttributes()
+ {
+ ASN1Sequence seq = cert.getAcinfo().getAttributes();
+ X509Attribute[] attrs = new X509Attribute[seq.size()];
+
+ for (int i = 0; i != seq.size(); i++)
+ {
+ attrs[i] = new X509Attribute((ASN1Encodable)seq.getObjectAt(i));
+ }
+
+ return attrs;
+ }
+
+ public X509Attribute[] getAttributes(String oid)
+ {
+ ASN1Sequence seq = cert.getAcinfo().getAttributes();
+ List list = new ArrayList();
+
+ for (int i = 0; i != seq.size(); i++)
+ {
+ X509Attribute attr = new X509Attribute((ASN1Encodable)seq.getObjectAt(i));
+ if (attr.getOID().equals(oid))
+ {
+ list.add(attr);
+ }
+ }
+
+ if (list.size() == 0)
+ {
+ return null;
+ }
+
+ return (X509Attribute[])list.toArray(new X509Attribute[list.size()]);
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+
+ if (!(o instanceof X509AttributeCertificate))
+ {
+ return false;
+ }
+
+ X509AttributeCertificate other = (X509AttributeCertificate)o;
+
+ try
+ {
+ byte[] b1 = this.getEncoded();
+ byte[] b2 = other.getEncoded();
+
+ return Arrays.areEqual(b1, b2);
+ }
+ catch (IOException e)
+ {
+ return false;
+ }
+ }
+
+ public int hashCode()
+ {
+ try
+ {
+ return Arrays.hashCode(this.getEncoded());
+ }
+ catch (IOException e)
+ {
+ return 0;
+ }
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V3CertificateGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V3CertificateGenerator.java
new file mode 100644
index 00000000..655ed66c
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V3CertificateGenerator.java
@@ -0,0 +1,535 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Iterator;
+
+import javax.security.auth.x500.X500Principal;
+
+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.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+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.x509.AlgorithmIdentifier;
+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.asn1.x509.X509ExtensionsGenerator;
+import com.android.internal.org.bouncycastle.asn1.x509.X509Name;
+import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory;
+import com.android.internal.org.bouncycastle.jcajce.util.BCJcaJceHelper;
+import com.android.internal.org.bouncycastle.jcajce.util.JcaJceHelper;
+import com.android.internal.org.bouncycastle.jce.X509Principal;
+import com.android.internal.org.bouncycastle.x509.extension.X509ExtensionUtil;
+
+/**
+ * class to produce an X.509 Version 3 certificate.
+ * @deprecated use org.bouncycastle.cert.X509v3CertificateBuilder.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509V3CertificateGenerator
+{
+ private final JcaJceHelper bcHelper = new BCJcaJceHelper(); // needed to force provider loading
+ private final CertificateFactory certificateFactory = new CertificateFactory();
+
+ private V3TBSCertificateGenerator tbsGen;
+ private ASN1ObjectIdentifier sigOID;
+ private AlgorithmIdentifier sigAlgId;
+ private String signatureAlgorithm;
+ private X509ExtensionsGenerator extGenerator;
+
+ public X509V3CertificateGenerator()
+ {
+ tbsGen = new V3TBSCertificateGenerator();
+ extGenerator = new X509ExtensionsGenerator();
+ }
+
+ /**
+ * reset the generator
+ */
+ public void reset()
+ {
+ tbsGen = new V3TBSCertificateGenerator();
+ extGenerator.reset();
+ }
+
+ /**
+ * set the serial number for the certificate.
+ */
+ public void setSerialNumber(
+ BigInteger serialNumber)
+ {
+ if (serialNumber.compareTo(BigInteger.ZERO) <= 0)
+ {
+ throw new IllegalArgumentException("serial number must be a positive integer");
+ }
+
+ tbsGen.setSerialNumber(new ASN1Integer(serialNumber));
+ }
+
+ /**
+ * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the
+ * certificate.
+ */
+ public void setIssuerDN(
+ X500Principal issuer)
+ {
+ try
+ {
+ tbsGen.setIssuer(new X509Principal(issuer.getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("can't process principal: " + e);
+ }
+ }
+
+ /**
+ * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the
+ * certificate.
+ */
+ public void setIssuerDN(
+ X509Name issuer)
+ {
+ tbsGen.setIssuer(issuer);
+ }
+
+ public void setNotBefore(
+ Date date)
+ {
+ tbsGen.setStartDate(new Time(date));
+ }
+
+ public void setNotAfter(
+ Date date)
+ {
+ tbsGen.setEndDate(new Time(date));
+ }
+
+ /**
+ * Set the subject distinguished name. The subject describes the entity associated with the public key.
+ */
+ public void setSubjectDN(
+ X500Principal subject)
+ {
+ try
+ {
+ tbsGen.setSubject(new X509Principal(subject.getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("can't process principal: " + e);
+ }
+ }
+
+ /**
+ * Set the subject distinguished name. The subject describes the entity associated with the public key.
+ */
+ public void setSubjectDN(
+ X509Name subject)
+ {
+ tbsGen.setSubject(subject);
+ }
+
+ public void setPublicKey(
+ PublicKey key)
+ throws IllegalArgumentException
+ {
+ try
+ {
+ tbsGen.setSubjectPublicKeyInfo(
+ SubjectPublicKeyInfo.getInstance(new ASN1InputStream(key.getEncoded()).readObject()));
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("unable to process key - " + e.toString());
+ }
+ }
+
+ /**
+ * Set the signature algorithm. This can be either a name or an OID, names
+ * are treated as case insensitive.
+ *
+ * @param signatureAlgorithm string representation of the algorithm name.
+ */
+ public void setSignatureAlgorithm(
+ String signatureAlgorithm)
+ {
+ this.signatureAlgorithm = signatureAlgorithm;
+
+ try
+ {
+ sigOID = X509Util.getAlgorithmOID(signatureAlgorithm);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("Unknown signature type requested: " + signatureAlgorithm);
+ }
+
+ sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm);
+
+ tbsGen.setSignature(sigAlgId);
+ }
+
+ /**
+ * Set the subject unique ID - note: it is very rare that it is correct to do this.
+ */
+ public void setSubjectUniqueID(boolean[] uniqueID)
+ {
+ tbsGen.setSubjectUniqueID(booleanToBitString(uniqueID));
+ }
+
+ /**
+ * Set the issuer unique ID - note: it is very rare that it is correct to do this.
+ */
+ public void setIssuerUniqueID(boolean[] uniqueID)
+ {
+ tbsGen.setIssuerUniqueID(booleanToBitString(uniqueID));
+ }
+
+ private 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);
+ }
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 3)
+ */
+ public void addExtension(
+ String oid,
+ boolean critical,
+ ASN1Encodable value)
+ {
+ this.addExtension(new ASN1ObjectIdentifier(oid), critical, value);
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 3)
+ */
+ public void addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ ASN1Encodable value)
+ {
+ extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value);
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 3)
+ * The value parameter becomes the contents of the octet string associated
+ * with the extension.
+ */
+ public void addExtension(
+ String oid,
+ boolean critical,
+ byte[] value)
+ {
+ this.addExtension(new ASN1ObjectIdentifier(oid), critical, value);
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 3)
+ */
+ public void addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ byte[] value)
+ {
+ extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value);
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 3)
+ * copying the extension value from another certificate.
+ * @throws CertificateParsingException if the extension cannot be extracted.
+ */
+ public void copyAndAddExtension(
+ String oid,
+ boolean critical,
+ X509Certificate cert)
+ throws CertificateParsingException
+ {
+ byte[] extValue = cert.getExtensionValue(oid);
+
+ if (extValue == null)
+ {
+ throw new CertificateParsingException("extension " + oid + " not present");
+ }
+
+ try
+ {
+ ASN1Encodable value = X509ExtensionUtil.fromExtensionValue(extValue);
+
+ this.addExtension(oid, critical, value);
+ }
+ catch (IOException e)
+ {
+ throw new CertificateParsingException(e.toString());
+ }
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 3)
+ * copying the extension value from another certificate.
+ * @throws CertificateParsingException if the extension cannot be extracted.
+ */
+ public void copyAndAddExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ X509Certificate cert)
+ throws CertificateParsingException
+ {
+ this.copyAndAddExtension(oid.getId(), critical, cert);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider "BC".
+ * @deprecated use generate(key, "BC")
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key)
+ throws SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generateX509Certificate(key, "BC", null);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new SecurityException("BC provider not installed!");
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider "BC", and the passed in source of randomness
+ * (if required).
+ * @deprecated use generate(key, random, "BC")
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key,
+ SecureRandom random)
+ throws SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generateX509Certificate(key, "BC", random);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new SecurityException("BC provider not installed!");
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing.
+ * @deprecated use generate()
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key,
+ String provider)
+ throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
+ {
+ return generateX509Certificate(key, provider, null);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing and the supplied source
+ * of randomness, if required.
+ * @deprecated use generate()
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key,
+ String provider,
+ SecureRandom random)
+ throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generate(key, provider, random);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw e;
+ }
+ catch (SignatureException e)
+ {
+ throw e;
+ }
+ catch (InvalidKeyException e)
+ {
+ throw e;
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new SecurityException("exception: " + e);
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider.
+ * <p>
+ * <b>Note:</b> this differs from the deprecated method in that the default provider is
+ * used - not "BC".
+ * </p>
+ */
+ public X509Certificate generate(
+ PrivateKey key)
+ throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ return generate(key, (SecureRandom)null);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider, and the passed in source of randomness
+ * (if required).
+ * <p>
+ * <b>Note:</b> this differs from the deprecated method in that the default provider is
+ * used - not "BC".
+ * </p>
+ */
+ public X509Certificate generate(
+ PrivateKey key,
+ SecureRandom random)
+ throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ TBSCertificate tbsCert = generateTbsCert();
+ byte[] signature;
+
+ try
+ {
+ signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCert);
+ }
+ catch (IOException e)
+ {
+ throw new ExtCertificateEncodingException("exception encoding TBS cert", e);
+ }
+
+ try
+ {
+ return generateJcaObject(tbsCert, signature);
+ }
+ catch (Exception e)
+ {
+ throw new ExtCertificateEncodingException("exception producing certificate object", e);
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing.
+ */
+ public X509Certificate generate(
+ PrivateKey key,
+ String provider)
+ throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ return generate(key, provider, null);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing and the supplied source
+ * of randomness, if required.
+ */
+ public X509Certificate generate(
+ PrivateKey key,
+ String provider,
+ SecureRandom random)
+ throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ TBSCertificate tbsCert = generateTbsCert();
+ byte[] signature;
+
+ try
+ {
+ signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCert);
+ }
+ catch (IOException e)
+ {
+ throw new ExtCertificateEncodingException("exception encoding TBS cert", e);
+ }
+
+ try
+ {
+ return generateJcaObject(tbsCert, signature);
+ }
+ catch (Exception e)
+ {
+ throw new ExtCertificateEncodingException("exception producing certificate object", e);
+ }
+ }
+
+ private TBSCertificate generateTbsCert()
+ {
+ if (!extGenerator.isEmpty())
+ {
+ tbsGen.setExtensions(extGenerator.generate());
+ }
+
+ return tbsGen.generateTBSCertificate();
+ }
+
+ private X509Certificate generateJcaObject(TBSCertificate tbsCert, byte[] signature)
+ throws Exception
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(tbsCert);
+ v.add(sigAlgId);
+ v.add(new DERBitString(signature));
+
+ return (X509Certificate)certificateFactory.engineGenerateCertificate(
+ new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER)));
+ }
+
+ /**
+ * Return an iterator of the signature names supported by the generator.
+ *
+ * @return an iterator containing recognised names.
+ */
+ public Iterator getSignatureAlgNames()
+ {
+ return X509Util.getAlgNames();
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/extension/AuthorityKeyIdentifierStructure.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/extension/AuthorityKeyIdentifierStructure.java
new file mode 100644
index 00000000..cc07aaa3
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/extension/AuthorityKeyIdentifierStructure.java
@@ -0,0 +1,149 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509.extension;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.PublicKey;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
+import com.android.internal.org.bouncycastle.asn1.x509.Extension;
+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.SubjectPublicKeyInfo;
+import com.android.internal.org.bouncycastle.asn1.x509.X509Extension;
+import com.android.internal.org.bouncycastle.jce.PrincipalUtil;
+
+/**
+ * A high level authority key identifier.
+ * @deprecated use JcaX509ExtensionUtils and AuthorityKeyIdentifier.getInstance()
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AuthorityKeyIdentifierStructure
+ extends AuthorityKeyIdentifier
+{
+ /**
+ * Constructor which will take the byte[] returned from getExtensionValue()
+ *
+ * @param encodedValue a DER octet encoded string with the extension structure in it.
+ * @throws IOException on parsing errors.
+ */
+ public AuthorityKeyIdentifierStructure(
+ byte[] encodedValue)
+ throws IOException
+ {
+ super((ASN1Sequence)X509ExtensionUtil.fromExtensionValue(encodedValue));
+ }
+
+ /**
+ * Constructor which will take an extension
+ *
+ * @param extension a X509Extension object containing an AuthorityKeyIdentifier.
+ * @deprecated use constructor that takes Extension
+ */
+ public AuthorityKeyIdentifierStructure(
+ X509Extension extension)
+ {
+ super((ASN1Sequence)extension.getParsedValue());
+ }
+
+ /**
+ * Constructor which will take an extension
+ *
+ * @param extension a X509Extension object containing an AuthorityKeyIdentifier.
+ */
+ public AuthorityKeyIdentifierStructure(
+ Extension extension)
+ {
+ super((ASN1Sequence)extension.getParsedValue());
+ }
+
+ private static ASN1Sequence fromCertificate(
+ X509Certificate certificate)
+ throws CertificateParsingException
+ {
+ try
+ {
+ if (certificate.getVersion() != 3)
+ {
+ GeneralName genName = new GeneralName(PrincipalUtil.getIssuerX509Principal(certificate));
+ SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(certificate.getPublicKey().getEncoded());
+
+ return (ASN1Sequence)new AuthorityKeyIdentifier(
+ info, new GeneralNames(genName), certificate.getSerialNumber()).toASN1Primitive();
+ }
+ else
+ {
+ GeneralName genName = new GeneralName(PrincipalUtil.getIssuerX509Principal(certificate));
+
+ byte[] ext = certificate.getExtensionValue(Extension.subjectKeyIdentifier.getId());
+
+ if (ext != null)
+ {
+ ASN1OctetString str = (ASN1OctetString)X509ExtensionUtil.fromExtensionValue(ext);
+
+ return (ASN1Sequence)new AuthorityKeyIdentifier(
+ str.getOctets(), new GeneralNames(genName), certificate.getSerialNumber()).toASN1Primitive();
+ }
+ else
+ {
+ SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(certificate.getPublicKey().getEncoded());
+
+ return (ASN1Sequence)new AuthorityKeyIdentifier(
+ info, new GeneralNames(genName), certificate.getSerialNumber()).toASN1Primitive();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException("Exception extracting certificate details: " + e.toString());
+ }
+ }
+
+ private static ASN1Sequence fromKey(
+ PublicKey pubKey)
+ throws InvalidKeyException
+ {
+ try
+ {
+ SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded());
+
+ return (ASN1Sequence)new AuthorityKeyIdentifier(info).toASN1Primitive();
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeyException("can't process key: " + e);
+ }
+ }
+
+ /**
+ * Create an AuthorityKeyIdentifier using the passed in certificate's public
+ * key, issuer and serial number.
+ *
+ * @param certificate the certificate providing the information.
+ * @throws CertificateParsingException if there is a problem processing the certificate
+ */
+ public AuthorityKeyIdentifierStructure(
+ X509Certificate certificate)
+ throws CertificateParsingException
+ {
+ super(fromCertificate(certificate));
+ }
+
+ /**
+ * Create an AuthorityKeyIdentifier using just the hash of the
+ * public key.
+ *
+ * @param pubKey the key to generate the hash from.
+ * @throws InvalidKeyException if there is a problem using the key.
+ */
+ public AuthorityKeyIdentifierStructure(
+ PublicKey pubKey)
+ throws InvalidKeyException
+ {
+ super(fromKey(pubKey));
+ }
+}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/extension/X509ExtensionUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/extension/X509ExtensionUtil.java
new file mode 100644
index 00000000..4e6c808b
--- /dev/null
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/extension/X509ExtensionUtil.java
@@ -0,0 +1,115 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.internal.org.bouncycastle.x509.extension;
+
+import java.io.IOException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+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.ASN1String;
+import com.android.internal.org.bouncycastle.asn1.DEROctetString;
+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.Extension;
+import com.android.internal.org.bouncycastle.asn1.x509.GeneralName;
+import com.android.internal.org.bouncycastle.util.Integers;
+
+
+/**
+ * @deprecated use org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils
+ * @hide This class is not part of the Android public SDK API
+ */
+public class X509ExtensionUtil
+{
+ /**
+ * @deprecated use org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils.parseExtensionValue()
+ */
+ public static ASN1Primitive fromExtensionValue(
+ byte[] encodedValue)
+ throws IOException
+ {
+ ASN1OctetString octs = (ASN1OctetString)ASN1Primitive.fromByteArray(encodedValue);
+
+ return ASN1Primitive.fromByteArray(octs.getOctets());
+ }
+
+ /**
+ * @deprecated use org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils.getIssuerAlternativeNames()
+ */
+ public static Collection getIssuerAlternativeNames(X509Certificate cert)
+ throws CertificateParsingException
+ {
+ byte[] extVal = cert.getExtensionValue(Extension.issuerAlternativeName.getId());
+
+ return getAlternativeNames(extVal);
+ }
+
+ /**
+ * @deprecated use org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils.getSubjectAlternativeNames()
+ */
+ public static Collection getSubjectAlternativeNames(X509Certificate cert)
+ throws CertificateParsingException
+ {
+ byte[] extVal = cert.getExtensionValue(Extension.subjectAlternativeName.getId());
+
+ return getAlternativeNames(extVal);
+ }
+
+ private static Collection getAlternativeNames(byte[] extVal)
+ throws CertificateParsingException
+ {
+ if (extVal == null)
+ {
+ return Collections.EMPTY_LIST;
+ }
+ try
+ {
+ Collection temp = new ArrayList();
+ Enumeration it = DERSequence.getInstance(fromExtensionValue(extVal)).getObjects();
+ while (it.hasMoreElements())
+ {
+ GeneralName genName = GeneralName.getInstance(it.nextElement());
+ List list = new ArrayList();
+ list.add(Integers.valueOf(genName.getTagNo()));
+ switch (genName.getTagNo())
+ {
+ case GeneralName.ediPartyName:
+ case GeneralName.x400Address:
+ case GeneralName.otherName:
+ list.add(genName.getName().toASN1Primitive());
+ break;
+ case GeneralName.directoryName:
+ list.add(X500Name.getInstance(genName.getName()).toString());
+ break;
+ case GeneralName.dNSName:
+ case GeneralName.rfc822Name:
+ case GeneralName.uniformResourceIdentifier:
+ list.add(((ASN1String)genName.getName()).getString());
+ break;
+ case GeneralName.registeredID:
+ list.add(ASN1ObjectIdentifier.getInstance(genName.getName()).getId());
+ break;
+ case GeneralName.iPAddress:
+ list.add(DEROctetString.getInstance(genName.getName()).getOctets());
+ break;
+ default:
+ throw new IOException("Bad tag number: " + genName.getTagNo());
+ }
+
+ temp.add(list);
+ }
+ return Collections.unmodifiableCollection(temp);
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException(e.getMessage());
+ }
+ }
+}
diff --git a/srcgen/core-platform-api.txt b/srcgen/core-platform-api.txt
deleted file mode 100644
index 9c723a95..00000000
--- a/srcgen/core-platform-api.txt
+++ /dev/null
@@ -1,173 +0,0 @@
-field:com.android.org.bouncycastle.asn1.DERNull#INSTANCE
-field:com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers#sha256WithRSAEncryption
-field:com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers#sha512WithRSAEncryption
-field:com.android.org.bouncycastle.asn1.x500.style.BCStyle#C
-field:com.android.org.bouncycastle.asn1.x500.style.BCStyle#CN
-field:com.android.org.bouncycastle.asn1.x500.style.BCStyle#E
-field:com.android.org.bouncycastle.asn1.x500.style.BCStyle#L
-field:com.android.org.bouncycastle.asn1.x500.style.BCStyle#O
-field:com.android.org.bouncycastle.asn1.x500.style.BCStyle#OU
-field:com.android.org.bouncycastle.asn1.x500.style.BCStyle#ST
-field:com.android.org.bouncycastle.asn1.x509.GeneralName#dNSName
-field:com.android.org.bouncycastle.asn1.x509.GeneralName#iPAddress
-field:com.android.org.bouncycastle.asn1.x509.GeneralName#otherName
-field:com.android.org.bouncycastle.asn1.x509.X509Name#CN
-field:com.android.org.bouncycastle.asn1.x509.X509Name#DefaultSymbols
-field:com.android.org.bouncycastle.asn1.x509.X509Name#O
-field:com.android.org.bouncycastle.asn1.x509.X509Name#OU
-field:com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers#ecdsa_with_SHA256
-method:com.android.org.bouncycastle.asn1.ASN1BitString#hashCode()
-method:com.android.org.bouncycastle.asn1.ASN1EncodableVector#add(ASN1Encodable)
-method:com.android.org.bouncycastle.asn1.ASN1EncodableVector#ASN1EncodableVector()
-method:com.android.org.bouncycastle.asn1.ASN1InputStream#ASN1InputStream(byte[])
-method:com.android.org.bouncycastle.asn1.ASN1InputStream#ASN1InputStream(InputStream)
-method:com.android.org.bouncycastle.asn1.ASN1InputStream#readObject()
-method:com.android.org.bouncycastle.asn1.ASN1Integer#ASN1Integer(BigInteger)
-method:com.android.org.bouncycastle.asn1.ASN1Null#hashCode()
-method:com.android.org.bouncycastle.asn1.ASN1Object#ASN1Object()
-method:com.android.org.bouncycastle.asn1.ASN1Object#getEncoded()
-method:com.android.org.bouncycastle.asn1.ASN1Object#getEncoded(String)
-method:com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier#ASN1ObjectIdentifier(String)
-method:com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier#getId()
-method:com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier#getInstance(Object)
-method:com.android.org.bouncycastle.asn1.ASN1OctetString#getOctets()
-method:com.android.org.bouncycastle.asn1.ASN1OctetString#hashCode()
-method:com.android.org.bouncycastle.asn1.ASN1Primitive#fromByteArray(byte[])
-method:com.android.org.bouncycastle.asn1.ASN1Primitive#toASN1Primitive()
-method:com.android.org.bouncycastle.asn1.ASN1Sequence#getObjectAt(int)
-method:com.android.org.bouncycastle.asn1.ASN1Sequence#hashCode()
-method:com.android.org.bouncycastle.asn1.ASN1Sequence#size()
-method:com.android.org.bouncycastle.asn1.ASN1TaggedObject#getObject()
-method:com.android.org.bouncycastle.asn1.ASN1TaggedObject#hashCode()
-method:com.android.org.bouncycastle.asn1.DERBitString#DERBitString(byte[])
-method:com.android.org.bouncycastle.asn1.DERInteger#DERInteger(long)
-method:com.android.org.bouncycastle.asn1.DEROctetString#DEROctetString(byte[])
-method:com.android.org.bouncycastle.asn1.DERSequence#DERSequence()
-method:com.android.org.bouncycastle.asn1.DERSequence#DERSequence(ASN1EncodableVector)
-method:com.android.org.bouncycastle.asn1.DERTaggedObject#DERTaggedObject(int,ASN1Encodable)
-method:com.android.org.bouncycastle.asn1.DERUTF8String#DERUTF8String(String)
-method:com.android.org.bouncycastle.asn1.DERUTF8String#getString()
-method:com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo#getInstance(Object)
-method:com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo#getPrivateKeyAlgorithm()
-method:com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo#parsePrivateKey()
-method:com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier#AlgorithmIdentifier(ASN1ObjectIdentifier)
-method:com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier#AlgorithmIdentifier(ASN1ObjectIdentifier,ASN1Encodable)
-method:com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier#getAlgorithm()
-method:com.android.org.bouncycastle.asn1.x509.BasicConstraints#getInstance(Object)
-method:com.android.org.bouncycastle.asn1.x509.BasicConstraints#isCA()
-method:com.android.org.bouncycastle.asn1.x509.Certificate#getInstance(Object)
-method:com.android.org.bouncycastle.asn1.x509.GeneralName#GeneralName(int,ASN1Encodable)
-method:com.android.org.bouncycastle.asn1.x509.GeneralName#GeneralName(int,String)
-method:com.android.org.bouncycastle.asn1.x509.GeneralName#getTagNo()
-method:com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo#getInstance(Object)
-method:com.android.org.bouncycastle.asn1.x509.Time#Time(Date)
-method:com.android.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator#generateTBSCertificate()
-method:com.android.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator#setEndDate(Time)
-method:com.android.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator#setIssuer(X509Name)
-method:com.android.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator#setSerialNumber(ASN1Integer)
-method:com.android.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator#setSignature(AlgorithmIdentifier)
-method:com.android.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator#setStartDate(Time)
-method:com.android.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator#setSubjectPublicKeyInfo(SubjectPublicKeyInfo)
-method:com.android.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator#setSubject(X509Name)
-method:com.android.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator#V3TBSCertificateGenerator()
-method:com.android.org.bouncycastle.asn1.x509.X509Name#getInstance(Object)
-method:com.android.org.bouncycastle.asn1.x509.X509Name#getOIDs()
-method:com.android.org.bouncycastle.asn1.x509.X509Name#getValues()
-method:com.android.org.bouncycastle.asn1.x509.X509Name#toString(boolean,Hashtable)
-method:com.android.org.bouncycastle.asn1.x509.X509Name#X509Name(String)
-method:com.android.org.bouncycastle.crypto.digests.GeneralDigest#finish()
-method:com.android.org.bouncycastle.crypto.digests.GeneralDigest#processBlock()
-method:com.android.org.bouncycastle.crypto.digests.GeneralDigest#update(byte[],int,int)
-method:com.android.org.bouncycastle.crypto.digests.MD4Digest#MD4Digest()
-method:com.android.org.bouncycastle.crypto.digests.MD4Digest#doFinal(byte[],int)
-method:com.android.org.bouncycastle.crypto.digests.SHA1Digest#SHA1Digest()
-method:com.android.org.bouncycastle.crypto.digests.SHA1Digest#doFinal(byte[],int)
-method:com.android.org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator#generateDerivedParameters(int)
-method:com.android.org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator#init(byte[],byte[])
-method:com.android.org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator#OpenSSLPBEParametersGenerator()
-method:com.android.org.bouncycastle.crypto.params.KeyParameter#getKey()
-method:com.android.org.bouncycastle.crypto.PBEParametersGenerator#PBEParametersGenerator()
-method:com.android.org.bouncycastle.crypto.PBEParametersGenerator#PKCS5PasswordToBytes(char[])
-method:com.android.org.bouncycastle.jcajce.util.DefaultJcaJceHelper#createCipher(String)
-method:com.android.org.bouncycastle.jce.provider.BouncyCastleProvider#BouncyCastleProvider()
-method:com.android.org.bouncycastle.jce.provider.X509CertificateObject#X509CertificateObject(com.android.org.bouncycastle.asn1.x509.Certificate)
-method:com.android.org.bouncycastle.jce.X509Principal#X509Principal(byte[])
-method:com.android.org.bouncycastle.jce.X509Principal#X509Principal(Vector,Hashtable)
-method:com.android.org.bouncycastle.util.io.pem.PemHeader#PemHeader(String,String)
-method:com.android.org.bouncycastle.util.io.pem.PemObject#getContent()
-method:com.android.org.bouncycastle.util.io.pem.PemObject#getType()
-method:com.android.org.bouncycastle.util.io.pem.PemObject#PemObject(String,byte[])
-method:com.android.org.bouncycastle.util.io.pem.PemObject#PemObject(String,List,byte[])
-method:com.android.org.bouncycastle.util.io.pem.PemReader#PemReader(Reader)
-method:com.android.org.bouncycastle.util.io.pem.PemReader#readPemObject()
-method:com.android.org.bouncycastle.util.io.pem.PemWriter#PemWriter(Writer)
-method:com.android.org.bouncycastle.util.io.pem.PemWriter#writeObject(PemObjectGenerator)
-method:com.android.org.bouncycastle.x509.X509V1CertificateGenerator#generate(PrivateKey,String)
-method:com.android.org.bouncycastle.x509.X509V1CertificateGenerator#setIssuerDN(X500Principal)
-method:com.android.org.bouncycastle.x509.X509V1CertificateGenerator#setNotAfter(Date)
-method:com.android.org.bouncycastle.x509.X509V1CertificateGenerator#setNotBefore(Date)
-method:com.android.org.bouncycastle.x509.X509V1CertificateGenerator#setPublicKey(PublicKey)
-method:com.android.org.bouncycastle.x509.X509V1CertificateGenerator#setSerialNumber(BigInteger)
-method:com.android.org.bouncycastle.x509.X509V1CertificateGenerator#setSignatureAlgorithm(String)
-method:com.android.org.bouncycastle.x509.X509V1CertificateGenerator#setSubjectDN(X500Principal)
-method:com.android.org.bouncycastle.x509.X509V1CertificateGenerator#X509V1CertificateGenerator()
-method:com.android.org.bouncycastle.x509.X509V3CertificateGenerator#generate(PrivateKey)
-method:com.android.org.bouncycastle.x509.X509V3CertificateGenerator#setIssuerDN(X500Principal)
-method:com.android.org.bouncycastle.x509.X509V3CertificateGenerator#setNotAfter(Date)
-method:com.android.org.bouncycastle.x509.X509V3CertificateGenerator#setNotBefore(Date)
-method:com.android.org.bouncycastle.x509.X509V3CertificateGenerator#setPublicKey(PublicKey)
-method:com.android.org.bouncycastle.x509.X509V3CertificateGenerator#setSerialNumber(BigInteger)
-method:com.android.org.bouncycastle.x509.X509V3CertificateGenerator#setSignatureAlgorithm(String)
-method:com.android.org.bouncycastle.x509.X509V3CertificateGenerator#setSubjectDN(X500Principal)
-method:com.android.org.bouncycastle.x509.X509V3CertificateGenerator#X509V3CertificateGenerator()
-type:com.android.org.bouncycastle.asn1.ASN1BitString
-type:com.android.org.bouncycastle.asn1.ASN1Encodable
-type:com.android.org.bouncycastle.asn1.ASN1EncodableVector
-type:com.android.org.bouncycastle.asn1.ASN1InputStream
-type:com.android.org.bouncycastle.asn1.ASN1Integer
-type:com.android.org.bouncycastle.asn1.ASN1Null
-type:com.android.org.bouncycastle.asn1.ASN1Object
-type:com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier
-type:com.android.org.bouncycastle.asn1.ASN1OctetString
-type:com.android.org.bouncycastle.asn1.ASN1Primitive
-type:com.android.org.bouncycastle.asn1.ASN1Sequence
-type:com.android.org.bouncycastle.asn1.ASN1TaggedObject
-type:com.android.org.bouncycastle.asn1.DERBitString
-type:com.android.org.bouncycastle.asn1.DERInteger
-type:com.android.org.bouncycastle.asn1.DERNull
-type:com.android.org.bouncycastle.asn1.DEROctetString
-type:com.android.org.bouncycastle.asn1.DERSequence
-type:com.android.org.bouncycastle.asn1.DERTaggedObject
-type:com.android.org.bouncycastle.asn1.DERUTF8String
-type:com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers
-type:com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo
-type:com.android.org.bouncycastle.asn1.x500.style.BCStyle
-type:com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier
-type:com.android.org.bouncycastle.asn1.x509.BasicConstraints
-type:com.android.org.bouncycastle.asn1.x509.Certificate
-type:com.android.org.bouncycastle.asn1.x509.GeneralName
-type:com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
-type:com.android.org.bouncycastle.asn1.x509.TBSCertificate
-type:com.android.org.bouncycastle.asn1.x509.Time
-type:com.android.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator
-type:com.android.org.bouncycastle.asn1.x509.X509Name
-type:com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers
-type:com.android.org.bouncycastle.crypto.CipherParameters
-type:com.android.org.bouncycastle.crypto.digests.GeneralDigest
-type:com.android.org.bouncycastle.crypto.digests.MD4Digest
-type:com.android.org.bouncycastle.crypto.digests.SHA1Digest
-type:com.android.org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator
-type:com.android.org.bouncycastle.crypto.params.KeyParameter
-type:com.android.org.bouncycastle.crypto.PBEParametersGenerator
-type:com.android.org.bouncycastle.jcajce.util.DefaultJcaJceHelper
-type:com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
-type:com.android.org.bouncycastle.jce.provider.X509CertificateObject
-type:com.android.org.bouncycastle.jce.X509Principal
-type:com.android.org.bouncycastle.util.io.pem.PemHeader
-type:com.android.org.bouncycastle.util.io.pem.PemObject
-type:com.android.org.bouncycastle.util.io.pem.PemObjectGenerator
-type:com.android.org.bouncycastle.util.io.pem.PemReader
-type:com.android.org.bouncycastle.util.io.pem.PemWriter
-type:com.android.org.bouncycastle.util.Iterable
-type:com.android.org.bouncycastle.x509.X509V1CertificateGenerator
-type:com.android.org.bouncycastle.x509.X509V3CertificateGenerator
diff --git a/srcgen/unsupported-app-usage.json b/srcgen/unsupported-app-usage.json
index d30c351f..5a7651e5 100644
--- a/srcgen/unsupported-app-usage.json
+++ b/srcgen/unsupported-app-usage.json
@@ -8,7 +8,9 @@
"@location": "method:com.android.org.bouncycastle.asn1.ASN1EncodableVector#add(ASN1Encodable)"
},
{
- "@location": "method:com.android.org.bouncycastle.asn1.ASN1InputStream#ASN1InputStream(InputStream)"
+ "@location": "method:com.android.org.bouncycastle.asn1.ASN1InputStream#ASN1InputStream(InputStream)",
+ "maxTargetSdk": 30,
+ "trackingBug": 170729553
},
{
"@location": "method:com.android.org.bouncycastle.asn1.ASN1InputStream#ASN1InputStream(byte[])"
@@ -23,25 +25,35 @@
"@location": "method:com.android.org.bouncycastle.asn1.DERBitString#DERBitString(byte[])"
},
{
- "@location": "method:com.android.org.bouncycastle.asn1.DEREncodableVector#DEREncodableVector()"
+ "@location": "method:com.android.org.bouncycastle.asn1.DEREncodableVector#DEREncodableVector()",
+ "maxTargetSdk": 30,
+ "trackingBug": 170729553
},
{
"@location": "method:com.android.org.bouncycastle.asn1.DERInteger#DERInteger(long)"
},
{
- "@location": "method:com.android.org.bouncycastle.asn1.DERInteger#DERInteger(BigInteger)"
+ "@location": "method:com.android.org.bouncycastle.asn1.DERInteger#DERInteger(BigInteger)",
+ "maxTargetSdk": 30,
+ "trackingBug": 170729553
},
{
"@location": "field:com.android.org.bouncycastle.asn1.DERNull#INSTANCE"
},
{
- "@location": "method:com.android.org.bouncycastle.asn1.DERObjectIdentifier#DERObjectIdentifier(String)"
+ "@location": "method:com.android.org.bouncycastle.asn1.DERObjectIdentifier#DERObjectIdentifier(String)",
+ "maxTargetSdk": 30,
+ "trackingBug": 170729553
},
{
- "@location": "method:com.android.org.bouncycastle.asn1.DEROctetString#DEROctetString(byte[])"
+ "@location": "method:com.android.org.bouncycastle.asn1.DEROctetString#DEROctetString(byte[])",
+ "maxTargetSdk": 30,
+ "trackingBug": 170729553
},
{
- "@location": "method:com.android.org.bouncycastle.asn1.DEROutputStream#DEROutputStream(OutputStream)"
+ "@location": "method:com.android.org.bouncycastle.asn1.DEROutputStream#DEROutputStream(OutputStream)",
+ "maxTargetSdk": 30,
+ "trackingBug": 170729553
},
{
"@location": "method:com.android.org.bouncycastle.asn1.DERSequence#DERSequence()"
@@ -50,7 +62,9 @@
"@location": "method:com.android.org.bouncycastle.asn1.DERSequence#DERSequence(ASN1EncodableVector)"
},
{
- "@location": "method:com.android.org.bouncycastle.asn1.DERSet#DERSet(ASN1EncodableVector)"
+ "@location": "method:com.android.org.bouncycastle.asn1.DERSet#DERSet(ASN1EncodableVector)",
+ "maxTargetSdk": 30,
+ "trackingBug": 170729553
},
{
"@location": "field:com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers#sha256WithRSAEncryption"
@@ -65,7 +79,9 @@
"@location": "method:com.android.org.bouncycastle.asn1.x509.Certificate#getInstance(Object)"
},
{
- "@location": "method:com.android.org.bouncycastle.asn1.x509.DigestInfo#DigestInfo(AlgorithmIdentifier,byte[])"
+ "@location": "method:com.android.org.bouncycastle.asn1.x509.DigestInfo#DigestInfo(AlgorithmIdentifier,byte[])",
+ "maxTargetSdk": 30,
+ "trackingBug": 170729553
},
{
"@location": "method:com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo#getInstance(Object)"
@@ -101,19 +117,27 @@
"@location": "method:com.android.org.bouncycastle.asn1.x509.V3TBSCertificateGenerator#setSubjectPublicKeyInfo(SubjectPublicKeyInfo)"
},
{
- "@location": "method:com.android.org.bouncycastle.asn1.x509.X509Name#X509Name(ASN1Sequence)"
+ "@location": "method:com.android.org.bouncycastle.asn1.x509.X509Name#X509Name(ASN1Sequence)",
+ "maxTargetSdk": 30,
+ "trackingBug": 170729553
},
{
"@location": "method:com.android.org.bouncycastle.asn1.x509.X509Name#X509Name(String)"
},
{
- "@location": "field:com.android.org.bouncycastle.asn1.x509.X509Name#CN"
+ "@location": "field:com.android.org.bouncycastle.asn1.x509.X509Name#CN",
+ "maxTargetSdk": 30,
+ "trackingBug": 170729553
},
{
- "@location": "method:com.android.org.bouncycastle.asn1.x509.X509Name#getOIDs()"
+ "@location": "method:com.android.org.bouncycastle.asn1.x509.X509Name#getOIDs()",
+ "maxTargetSdk": 30,
+ "trackingBug": 170729553
},
{
- "@location": "method:com.android.org.bouncycastle.asn1.x509.X509Name#getValues()"
+ "@location": "method:com.android.org.bouncycastle.asn1.x509.X509Name#getValues()",
+ "maxTargetSdk": 30,
+ "trackingBug": 170729553
},
{
"@location": "field:com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers#ecdsa_with_SHA256"
diff --git a/srcgen_platform/generate_android_src.sh b/srcgen_platform/generate_android_src.sh
new file mode 100755
index 00000000..6e5b4447
--- /dev/null
+++ b/srcgen_platform/generate_android_src.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if [[ -z "${ANDROID_BUILD_TOP}" ]]; then
+ echo "Missing environment variables. Did you run build/envsetup.sh and lunch?" >&2
+ exit 1
+fi
+
+PROJECT_DIR=external/bouncycastle
+
+PACKAGE_TRANSFORMATIONS="\
+ org.bouncycastle:com.android.internal.org.bouncycastle \
+"
+
+MODULE_DIRS="\
+ bcprov \
+"
+DEFAULT_CONSTRUCTORS_FILE=${BOUNCY_CASTLE_DIR}/srcgen/default-constructors.txt
+
+REPACKAGED_DIR="${ANDROID_BUILD_TOP}/${PROJECT_DIR}/repackaged_platform"
+
+SOURCE_DIRS="\
+ src/main/java \
+"
+
+SRCGEN_DIR=${PROJECT_DIR}/srcgen_platform
+
+# Repackage the project's source.
+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/
+